When transferring an ERC-721 token from Layer 1 (L1) to Layer 2 (L2), L2 uses the withdraw_auto_from_l1 function to automatically process the message and transfer the ERC-721 to OwnerL2. However, if a startRequestCancellation is successfully initiated on L1, the corresponding ERC-721 can still be returned, leading to the duplication of what should be a unique asset across different chains.
After withdraw_auto_from_l1 processes the message, it fails to inform L1 to clear the l1ToL2Messages()[msgHash]. This results in an inability to verify on L1 whether the message has been processed, allowing it to remain indefinitely.
Configure STARKLANE_L2_ADDRESS and STARKLANE_L2_SELECTOR in apps/blockchain/ethernum/.env for the local environment. Set STARKLANE_L2_SELECTOR to 0x03593216f3a8b22f4cf375e5486e3d13bfde9d0f26976d20ac6f653c73f7e507.
Run source .env in the terminal.
Configure and start the L1 and L2 bridges. Use the following to mint an ERC-721 on L1 and authorize the bridge:
Transfer the NFT with tokenId 3 from L1 to L2:
Observe the terminal running katana --messaging ./data/anvil.messaging.json --seed 0 for output like:
This indicates L2 received a message from L1.
0x5fc8d32690cc91d4c39d9d3abcbd16989f875707 specifies the L2 Bridge address and 0x101, 0xab756952842d1873926c758ea8766f16, 0x7008d3618b32bb5267157ede26bf43ce, 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0, 0x0, 0x70997970c51812dc3a010c7d01b50e0d17dc79c8, 0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03, 0x0, 0x6576657261695f313233, 0xa, 0x0, 0x4556525f313233, 0x7, 0x0, 0x0, 0x0, 0x1, 0x3, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0 is the serialized Request.
Verify the ERC-721 on L1 is transferred to the L1 Bridge using:
Expected result:0x0000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707($BRIDGE_L1_ADDR)
On L2, check the deployed contract address using:
Note the L2 ERC-721 address in $ERC721_DEPLOY_L2_ADDR.
Confirm the ERC-721 is transferred to the correct L2 user using:
Expected result:0x06162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03($STARKNET_USER_ACCOUNT_ADDR)
On L1, attempt to reclaim the ERC-721 using:
Finally, cancel the request:
Verify ERC-721 ownership reverts to the user:
Expected owner address:0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8($ETHEREUM_USER_ADDR)
This vulnerability compromises the uniqueness of the NFT, posing significant risks to the project. Even with potential audits of startRequestCancellation messages, the inherent user and NFT project concerns remain. This can sharply decrease user participation and could lead to NFT projects declaring the related L2 contracts as illegitimate.
Manual Review
L2 should notify L1 to set l1ToL2Messages()[msgHash] to zero after processing messages from L1. Additionally, when transferring from L1 to L2, the ERC-721 on the L1 Bridge should be subject to a locking period during which it cannot be withdrawn. This is to prevent scenarios where the ERC-721 on L1 can be returned while L2 is processing a cross-chain block, mitigating the risk of accidental duplications.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.