Platform: Code4rena
Start Date: 04/03/2024
Pot Size: $88,500 USDC
Total HM: 31
Participants: 105
Period: 11 days
Judge: ronnyx2017
Total Solo HM: 7
Id: 342
League: ETH
Rank: 96/105
Findings: 1
Award: $10.29
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Bauchibred
Also found by: 0x11singh99, 0x175, 0xAlix2, 0xDemon, 0xGreyWolf, 0xPhantom, 0xspryon, 14si2o_Flint, Arabadzhiev, Aymen0909, Bigsam, BowTiedOriole, CRYP70, DanielArmstrong, FastChecker, JecikPo, KupiaSec, MohammedRizwan, Norah, Timenov, Topmark, VAD37, adeolu, btk, crypticdefense, cryptphi, givn, grearlake, jnforja, kennedy1030, kfx, ktg, lanrebayode77, n1punp, santiellena, stonejiajia, t4sk, thank_you, tpiliposian, wangxx2026, y0ng0p3, zaevlad
10.2896 USDC - $10.29
The functions deposit()
, mint()
, deposit() with permit2
, mint() with permit2
, withdraw()
, redeem()
invokes _convertToAssets()
or _convertToShares
which relies heavily on an exchange rate / exchangeRateX96
that can change often.
It is reasonable that as the lender deposits (sends input tokens) to the vault, he/she should receive the rightful amount of shares
on that moment. Also, when the lender redeems his/her collateral he/she should receive the rightful amount of assets
on that moment.
If the token amount to be received (whether that be assets or shares) is less than what he/she expects, the transaction should revert. Hence the purpose of slippage protection.
Manual Review
Here's an example of redeem
implementation with slippage protection.
function redeem(uint256 shares, address receiver, address owner) external override returns (uint256) { (uint256 assets,) = _withdraw(receiver, owner, shares, true); return assets; } ++ function redeem(uint256 shares, address receiver, address owner, uint256 minAssets) external override returns (uint256) { ++ (uint256 assets,) = _withdraw(receiver, owner, shares, true); ++ if (assets < minAssets) revert TooMuchSlippageNotAllowed(); ++ return assets; ++ }
Implement this pattern to the rest of the functions: deposit()
, mint()
, deposit() with permit2
, mint() with permit2
, withdraw()
.
Other
#0 - c4-pre-sort
2024-03-18T18:36:49Z
0xEVom marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-03-18T18:36:51Z
0xEVom marked the issue as primary issue
#2 - 0xEVom
2024-03-19T15:01:05Z
Setting as primary since this is the most comprehensive submission in listing occurrences. However, none of the duplicates demonstrate a direct loss of funds and if the shares rate is not directly manipulatable via MEV, this is likely low severity.
As pointed out in #337, the ERC-4626 standard recommends adding additional functions to account for slippage.
#3 - 0xEVom
2024-03-21T07:52:02Z
#181 seems to provide a reasonable POC
#4 - kalinbas
2024-03-26T22:44:08Z
The exchange rate of shares is only updated once per block. It can not be directly manipulated by whales depositing or withdrawing because it only is affected by the interest rate (which takes effect in the following blocks). There is no point in frontrunning a deposit or withdraw tx. So slippage control is not needed here.
#5 - c4-sponsor
2024-03-26T22:44:15Z
kalinbas (sponsor) disputed
#6 - jhsagd76
2024-03-31T03:20:40Z
I believe this is only a valid issue for mint
, but it would only occur when there is a significant fluctuation in network gas fees causing transactions to remain unconfirmed for a long time. The change in shares rate is mostly due to interest which makes the impact of this issue very slight. Marked as low.
#7 - c4-judge
2024-03-31T03:21:21Z
jhsagd76 changed the severity to QA (Quality Assurance)
#8 - jhsagd76
2024-03-31T03:21:29Z
L-B
#9 - c4-judge
2024-03-31T15:54:59Z
jhsagd76 marked the issue as grade-b
#10 - c4-judge
2024-04-03T00:30:45Z
This previously downgraded issue has been upgraded by jhsagd76
#11 - c4-judge
2024-04-03T00:32:14Z
jhsagd76 changed the severity to QA (Quality Assurance)