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: 116/183
Findings: 2
Award: $7.37
🌟 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
When the user makes a deposit, this variable idToBlockOfLastDeposit[id]
takes a value 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); }
When withdrawing, there is a check that reverts if idToBlockOfLastDeposit[id] == block.number
. That was made to prevent flashloan attack (when deposit and withdraw in same block).
This can be used by an attacker to DOS withdrawing user's assets: he can frontrun withdrawing transaction by making a call deposit(victimsId, vault, 0)
on behalf of user, thus idToBlockOfLastDeposit[id] == block.number
will be true. It is possible due to lack of access control in deposit()
function.
DOSing of withdraw()
function.
Manual review.
Make sure that msg.sender == dNft.ownerOf(id)
:
function deposit( uint id, address vault, uint amount ) external isValidDNft(id) + isDNftOwner(id) { idToBlockOfLastDeposit[id] = block.number; Vault _vault = Vault(vault); _vault.asset().safeTransferFrom(msg.sender, address(vault), amount); _vault.deposit(id, amount); }
Access Control
#0 - c4-pre-sort
2024-04-27T11:38:36Z
JustDravee marked the issue as duplicate of #1103
#1 - c4-pre-sort
2024-04-27T11:45:36Z
JustDravee marked the issue as duplicate of #489
#2 - c4-pre-sort
2024-04-29T09:28:36Z
JustDravee marked the issue as sufficient quality report
#3 - c4-judge
2024-05-05T20:38:17Z
koolexcrypto marked the issue as unsatisfactory: Invalid
#4 - c4-judge
2024-05-05T20:39:23Z
koolexcrypto marked the issue as unsatisfactory: Invalid
#5 - c4-judge
2024-05-05T20:39:26Z
koolexcrypto marked the issue as unsatisfactory: Invalid
#6 - c4-judge
2024-05-05T21:37:40Z
koolexcrypto marked the issue as nullified
#7 - c4-judge
2024-05-05T21:37:44Z
koolexcrypto marked the issue as not nullified
#8 - c4-judge
2024-05-08T15:28:01Z
koolexcrypto marked the issue as duplicate of #1001
#9 - c4-judge
2024-05-11T19:49:59Z
koolexcrypto marked the issue as satisfactory
🌟 Selected for report: TheSavageTeddy
Also found by: 0x175, 0x486776, 0xnev, AamirMK, AlexCzm, ArmedGoose, BiasedMerc, CaeraDenoir, Egis_Security, Jorgect, KYP, MrPotatoMagic, PoeAudits, SBSecurity, SovaSlava, VAD37, adam-idarrha, alix40, carrotsmuggler, d_tony7470, dimulski, grearlake, josephdara, ljj, n0kto, okolicodes, sashik_eth, sil3th, turvy_fuzz
7.3512 USDC - $7.35
https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L94 https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L119
Attacker can prevent removing vaults for anyone by depositing on behalf of user id.
The vaults contained in the vaults[id]
array are very important for the user, because they are used to determine prices and collatRatio
. The protocol allows users to create an array of 10 vaults and edit it. Editing is possible using the functions remove()
:
function remove( uint id, address vault ) external isDNftOwner(id) { if (Vault(vault).id2asset(id) > 0) revert VaultHasAssets(); ///DOS if (!vaults[id].remove(vault)) revert VaultNotAdded(); emit Removed(id, vault); }
The vulnerability is in this check: if (!vaults[id].remove(vault)) revert VaultNotAdded();
An attacker can exploit this by making a small deposit(1 wei) through the deposit()
function, where there is no check to see if the depositor is isDNftOwner(id)
:
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); } function deposit( uint id, uint amount ) external onlyVaultManager { id2asset[id] += amount; emit Deposit(id, amount); }
As a result, it will increase the value of id2asset[id]
, making removing not possible, because the check (Vault(vault).id2asset(id) > 0)
will always be true.
DOSing of remove()
function.
Manual review.
Make sure that msg.sender == dNft.ownerOf(id)
:
function deposit( uint id, address vault, uint amount ) external isValidDNft(id) + isDNftOwner(id) { idToBlockOfLastDeposit[id] = block.number; Vault _vault = Vault(vault); _vault.asset().safeTransferFrom(msg.sender, address(vault), amount); _vault.deposit(id, amount); }
Access Control
#0 - c4-pre-sort
2024-04-27T13:34:48Z
JustDravee marked the issue as duplicate of #489
#1 - c4-pre-sort
2024-04-29T09:28:33Z
JustDravee marked the issue as sufficient quality report
#2 - c4-judge
2024-05-05T20:38:17Z
koolexcrypto marked the issue as unsatisfactory: Invalid
#3 - c4-judge
2024-05-05T20:39:23Z
koolexcrypto marked the issue as unsatisfactory: Invalid
#4 - c4-judge
2024-05-05T20:39:26Z
koolexcrypto marked the issue as unsatisfactory: Invalid
#5 - c4-judge
2024-05-05T21:39:26Z
koolexcrypto marked the issue as nullified
#6 - c4-judge
2024-05-05T21:39:31Z
koolexcrypto marked the issue as not nullified
#7 - c4-judge
2024-05-05T21:39:38Z
koolexcrypto marked the issue as not a duplicate
#8 - c4-judge
2024-05-05T21:39:48Z
koolexcrypto marked the issue as nullified
#9 - c4-judge
2024-05-05T21:39:53Z
koolexcrypto marked the issue as not nullified
#10 - c4-judge
2024-05-05T21:40:02Z
koolexcrypto marked the issue as not a duplicate
#11 - c4-judge
2024-05-06T08:54:42Z
koolexcrypto marked the issue as duplicate of #118
#12 - c4-judge
2024-05-11T12:24:06Z
koolexcrypto marked the issue as satisfactory