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

Risk of Permanent Asset Loss Due to Missing Validation.

Summary

Please read this from Trail of Bits: https://github.com/crytic/building-secure-contracts/tree/master/not-so-smart-contracts/cairo/L1_to_L2_address_conversion

The vulnerability arises from a missing validation check in the setL1L2CollectionMapping function.
Specifically, there is no verification to ensure that collectionL2 is less than P (felt252)
Although it is the owner's responsibility to set the correct mapping, the absence of a validation check creates a critical risk.
if owner sets an incorrect collectionL2 there is no opportunity for correction, and the funds could be irretrievably lost.

Vulnerability Details

P = 2^251 + 17 * 2^192 + 1 -> 3618502788666131213697322783095070105623107215331596699973092056135872020481

The vulnerability is centered on the lack of a validation step in the setL1L2CollectionMapping function.
The collectionL2 variable is not checked against P, a crucial upper bound that should be enforced. If collectionL2 exceeds P
it can cause an overflow, which will not revert the transaction. This issue becomes particularly critical if an incorrect collectionL2
value is set in the same block where a user calls depositTokens. Since both actions occur in the same block,
there is no window for the owner to correct the mistake before the user's assets are at risk.

The problem is exacerbated by the fact that the admin is a person who might manually perform these operations,
increasing the likelihood of human error.

function depositTokens(uint256 salt, address collectionL1, snaddress ownerL2, uint256[] calldata ids, bool useAutoBurn) external payable {
//...
req.collectionL1 = collectionL1;
@>>> req.collectionL2 = _l1ToL2Addresses[collectionL1];
//...
}
function setL1L2CollectionMapping(address collectionL1, snaddress collectionL2, bool force) external onlyOwner {
@>>> _setL1L2AddressMapping(collectionL1, collectionL2, force);
emit L1L2CollectionMappingUpdated(collectionL1, snaddress.unwrap(collectionL2));
}
function _setL1L2AddressMapping(address collectionL1, snaddress collectionL2, bool force) internal {
if (((snaddress.unwrap(_l1ToL2Addresses[collectionL1]) == 0) &&
(_l2ToL1Addresses[collectionL2] == address(0))) ||
(force == true))
{
@>>> _l1ToL2Addresses[collectionL1] = collectionL2;
@>>> _l2ToL1Addresses[collectionL2] = collectionL1;
} else {
revert CollectionMappingAlreadySet();
}
}

Impact

The absence of a check on collectionL2 can result in an overflow, causing assets to be sent to an invalid address or lost.

Recommendations

function setL1L2CollectionMapping(address collectionL1, snaddress collectionL2, bool force) external onlyOwner {
+ if (!Cairo.isFelt252(snaddress.unwrap(collectionL2))) {
+ revert CairoWrapError();
+ }
_setL1L2AddressMapping(collectionL1, collectionL2, force);
emit L1L2CollectionMappingUpdated(collectionL1, snaddress.unwrap(collectionL2));
}
Updates

Lead Judging Commences

n0kto Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational / Gas

Please, do not suppose impacts, think about the real impact of the bug and check the CodeHawks documentation to confirm: https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity A PoC always helps to understand the real impact possible.

Support

FAQs

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