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: 147/246
Findings: 1
Award: $17.68
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: RaymondFam
Also found by: 7siech, LeoGold, Phantasmagoria, SunSec, adeolu, anodaram, aviggiano, chaduke, d3e4, eyexploit, jasonxiale, juancito, koxuan, mojito_auditor, n33k, neumo, rotcivegaf, yac
17.681 USDC - $17.68
In the function SafEth.stake()
, it does a for loop through derivative[]
to deposit on each of them based on weights[]
. However, it rounds down when calculate the ethAmount
to deposit.
for (uint i = 0; i < derivativeCount; i++) { uint256 weight = weights[i]; IDerivative derivative = derivatives[i]; if (weight == 0) continue; // @audit rounding, lock few weis uint256 ethAmount = (msg.value * weight) / totalWeight; // This is slightly less than ethAmount because slippage uint256 depositAmount = derivative.deposit{value: ethAmount}(); uint derivativeReceivedEthValue = (derivative.ethPerDerivative( depositAmount ) * depositAmount) / 10 ** 18; totalStakeValueEth += derivativeReceivedEthValue; }
As a result, a few wei could be locked in the SafEth contract while it should be deposited to any derivative or return to users.
Consider the scenario
weights = [31, 31, 34]
, totalWeights = 97
msg.value = 100
. So now when calculateethAmount_1 = 100 * 31 / 97 = 31 ethAmount_2 = 100 * 31 / 97 = 31 ethAmount_3 = 100 * 34 / 97 = 35 sum = 31 + 31 + 35 = 97
As we can see, total deposited amount is 97
while Bob sent in 100
. There are 3 weis
is locked in contract forever.
Manual Review
Consider depositing all amount left to the last derivative or transfer it back users.
#0 - c4-pre-sort
2023-04-04T16:19:10Z
0xSorryNotSorry marked the issue as duplicate of #455
#1 - c4-judge
2023-04-24T20:58:02Z
Picodes marked the issue as satisfactory