Platform: Code4rena
Start Date: 13/02/2024
Pot Size: $24,500 USDC
Total HM: 5
Participants: 84
Period: 6 days
Judge: 0xA5DF
Id: 331
League: ETH
Rank: 21/84
Findings: 1
Award: $242.11
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: SpicyMeatball
Also found by: BowTiedOriole, Breeje, CaeraDenoir, JohnSmith, Krace, Meera, PumpkingWok, SovaSlava, SpicyMeatball, d3e4, juancito, kutugu, nuthan2x, rokinot, rouhsamad, web3pwn
242.1143 USDC - $242.11
LiquidInfrastructureERC20 can't withdraw any ERC20 from managed NFTs.
In some scenarios, if more than one NFT managed contracts are released, the withdraw can be stuck until at least one NFT managed is added.
// 4 NFT managed contracts added function test_withdraw() public { // Withdraw from all except the last one liERC20.withdrawFromManagedNFTs(3); uint256 nextWithdrawal = liERC20.nextWithdrawal(); // 3 // release 2 managed NFTs liERC20.releaseManagedNFT(address(liNFT1), address(this)); liERC20.releaseManagedNFT(address(liNFT2), address(this)); // withdraw nr withdrawals -> 1 liERC20.withdrawFromManagedNFTs(1); nextWithdrawal = liERC20.nextWithdrawal(); // remain 3 // withdraw nr withdrawals -> 2 liERC20.withdrawFromManagedNFTs(2); nextWithdrawal = liERC20.nextWithdrawal(); // remain 3 // withdraw nr withdrawals -> 0 liERC20.withdrawFromManagedNFTs(0); nextWithdrawal = liERC20.nextWithdrawal(); // remain 3 // Withdraw() is in stuck until at least a new managed NFT will be added liNFT1.transferFrom(address(this), address(liERC20), 1); liERC20.addManagedNFT(address(liNFT1)); liERC20.withdrawFromManagedNFTs(1); nextWithdrawal = liERC20.nextWithdrawal(); // reset to 0 }
Here in the test, 4 NFT managed contracts have been added. The first withdraw function withdraws from all except the last one, then 2 NFT managed are removed.
At this point the nextWithdrawal = 3
and ManagedNFTs.length = 2
, so the limit
calculated in withdrawFromManagedNFTs(numWithdrawal)
will be always 2, the min between the managed nft length and numWithdrawals + nextWithdrawal
, whatever will be the numWithdrawal
pass as input param. the next for loop will be always skipped because nextWithdrawal > limit
, and the nextWithdrawal
won't change. It can be "fixed" adding at least one nft managed so ManagedNFTs.length > 2
and the for loop can be executed at least one time to reset nextWithdrawal
.
Foundry
An easy solution can be to include a check within releaseManagedNFT()
. It may revert if nextWithdrawal != 0
.
Token-Transfer
#0 - c4-pre-sort
2024-02-21T05:45:15Z
0xRobocop marked the issue as duplicate of #130
#1 - c4-judge
2024-03-03T13:00:28Z
0xA5DF marked the issue as satisfactory