NFTBridge
60,000 USDC
View results
Submission Details
Severity: medium
Invalid

Replay Attack Vulnerability in requestHash Function Due to Lack of Chain-Specific Data.

Summary

A potential vulnerability was identified in the requestHash function, which is used for generating a payload hash to send data
from Ethereum L1 to Starknet L2. This function is susceptible to replay attacks in the event of a hard fork.
The replayability arises from the deterministic nature of the hash computation, which could result in identical hash outputs across different chains or forks.

Vulnerability Details

The requestHash function calculates a unique hash based on the provided parameters: salt, collection, toL2Address,
and tokenIds. However, the deterministic nature of the keccak256 hash function, combined with the lack of chain-specific
data within the abi.encodePacked input, makes this function vulnerable to replay attacks.

Copy code
function requestHash(uint256 salt, address collection, snaddress toL2Address, uint256[] memory tokenIds)
internal pure returns(uint256)
{
bytes32 hash = keccak256(
abi.encodePacked(
salt,
uint256(uint160(collection)),
snaddress.unwrap(toL2Address),
tokenIds
)
);
return uint256(hash);
}

The keccak256 function is used to compute the hash, which combines the following inputs:

salt: A unique value provided to ensure hash uniqueness.
collection: An Ethereum address, cast to uint160 and then converted to uint256.
toL2Address: A Starknet address unwrapped from a custom type snaddress.
tokenIds: An array of token IDs.

However, in the case of a blockchain hard fork, the same transaction data might be replayed on the new forked chain,
producing the same hash value. This could potentially lead to duplicate transactions on Starknet L2,
causing unintended behavior or security issues.

Impact

The vulnerability allows for replay attacks.

Tools Used

Recommendations

Modify the requestHash function to include chain-specific data, such as the chainId.

function requestHash(uint256 salt, address collection, snaddress toL2Address, uint256[] memory tokenIds)
internal pure returns(uint256)
{
bytes32 hash = keccak256(
abi.encodePacked(
+ block.chainid, // Adding chain ID to the hash computation
salt,
uint256(uint160(collection)),
snaddress.unwrap(toL2Address),
tokenIds
)
);
return uint256(hash);
}
Updates

Lead Judging Commences

n0kto Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.