Platform: Code4rena
Start Date: 24/03/2023
Pot Size: $49,200 USDC
Total HM: 20
Participants: 246
Period: 6 days
Judge: Picodes
Total Solo HM: 1
Id: 226
League: ETH
Rank: 149/246
Findings: 2
Award: $17.67
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: adriro
Also found by: 0xMirce, 0xRajkumar, 0xepley, BPZ, Bahurum, Bauer, Co0nan, Emmanuel, Franfran, HollaDieWaldfee, IgorZuk, MiloTruck, NoamYakov, RedTiger, Ruhum, T1MOH, Tricko, ad3sh_, auditor0517, bin2chen, carrotsmuggler, eyexploit, handsomegiraffe, igingu, jasonxiale, koxuan, lukris02, monrel, nadin, peanuts, rbserver, rvierdiiev, shaka, sinarette, tnevler, y1cunhui
4.5426 USDC - $4.54
The unstake()
function calls the withdraw()
function of every derivative. The WstEth.withdraw()
function calls IStEthEthPool(LIDO_CRV_POOL).exchange()
to swap its stETH tokens with ETH. However, the min_dy
argument that is passed to this function is miscalculated.
The function calculates minOut
like that
uint256 minOut = (stEthBal * (10 ** 18 - maxSlippage)) / 10 ** 18;
and passes its value to the exchange()
function as its min_dy
argument. In our case, this argument specifies the minimum amount of ETH that the contract is willing to accept in exchange to the amount of stETH tokens it swaps.
The miscalculation here is that minOut
is calculated in units stETH, instead of ETH. This means that if ETH is more expensive than stETH, minOut
would be larger than intended - too large that the exchange()
would have to revert because it couldn't offer the contract the minimum amount of ETH it asked to receive for the swap to succeed.
Because of the calculation of minOut
take the maxSlippage
in consideration - the ration between the prices of ETH and stETH must be smaller than 1e18 - maxSlippage
for the exchange()
function to revert.
If the ratio between the prices of ETH and stETH is smaller than 1e18 - maxSlippage
- every call to unstake()
would revert and fail. All the funds would be frozen until either:
1e18 - maxSlippage
by itselfmaxSlippage
just enough to make that ratio above 1e18 - maxSlippage
Manual code review.
Fix the calculation of minOut
so it will be in units of ETH, not stETH.
#0 - c4-pre-sort
2023-04-04T17:10:24Z
0xSorryNotSorry marked the issue as duplicate of #588
#1 - c4-judge
2023-04-22T09:05:38Z
Picodes marked the issue as satisfactory