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: 32/246
Findings: 4
Award: $209.86
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: monrel
Also found by: 0xRajkumar, 0xfusion, AkshaySrivastav, Bahurum, Brenzee, Cryptor, Dug, Haipls, Koolex, Krace, MiloTruck, RaymondFam, RedTiger, ToonVH, Tricko, Vagner, aga7hokakological, anodaram, bart1e, bin2chen, bytes032, carrotsmuggler, ck, d3e4, giovannidisiena, igingu, juancito, mahdirostami, mert_eren, n33k, nemveer, parsely, pavankv, sashik_eth, shaka, sinarette, ulqiorra, yac
3.4908 USDC - $3.49
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L81 https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L98
An attacker can frontrun the first deposit on the safETH contract. By exploiting a donation attack an attacker can set the price of safETH very high. Because of division rounding the user will then receive less safETH than normal. The attacker can then withdraw his safETH for all (or a portion) of funds in the contract. Thus stealing (a part of) the users deposit.
Assume only 1 derivative exists (wstETH): (1 wstETH = 1 ETH for simplicity)
If multiple derivatives exist an attacker would have to deposit more than 1 wei in step 1 in order to receive a non-zero amount of safETH. This makes the attack less effective but still allows for stealing a part of the first deposit. e.g., Assume 3 derivatives with equal weights exist:
Manual review
Deposit some funds on initialization
#0 - c4-pre-sort
2023-04-03T07:21:27Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T12:49:59Z
0xSorryNotSorry marked the issue as duplicate of #715
#2 - c4-judge
2023-04-21T14:58:42Z
Picodes marked the issue as satisfactory
#3 - c4-judge
2023-04-24T21:39:18Z
Picodes changed the severity to 3 (High Risk)
195.1013 USDC - $195.10
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/derivatives/Reth.sol#L108 https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L118
The withdraw function of the reth derivative contract assumes it can always burn rETH for ETH. This is not the case. If Rocket Pool's deposit pool is empty, rETH.burn() will revert. As a result the derivative's withdraw() will revert (See note in RP docs). Subsequently SafETH.unstake() will also revert. This means that no user will be able to unstake their SafETH as long as Rocket Pool's deposit pool is empty (as seen here this can be an extended period of time (e.g., 5 months).
(note: rebalanceToWeights() will also fail)
#0 - c4-pre-sort
2023-04-04T19:54:46Z
0xSorryNotSorry marked the issue as duplicate of #210
#1 - c4-judge
2023-04-21T16:35:35Z
Picodes marked the issue as satisfactory
🌟 Selected for report: HHK
Also found by: 019EC6E2, 0Kage, 0x52, 0xRobocop, 0xTraub, 0xbepresent, 0xepley, 0xfusion, 0xl51, 4lulz, Bahurum, BanPaleo, Bauer, CodeFoxInc, Dug, HollaDieWaldfee, IgorZuk, Lirios, MadWookie, MiloTruck, RedTiger, Ruhum, SaeedAlipoor01988, Shogoki, SunSec, ToonVH, Toshii, UdarTeam, Viktor_Cortess, a3yip6, auditor0517, aviggiano, bearonbike, bytes032, carlitox477, carrotsmuggler, chalex, deliriusz, ernestognw, fs0c, handsomegiraffe, igingu, jasonxiale, kaden, koxuan, latt1ce, m_Rassska, n1punp, nemveer, nowonder92, peanuts, pontifex, roelio, rvierdiiev, shalaamum, shuklaayush, skidog, tank, teddav, top1st, ulqiorra, wait, wen, yac
0.1353 USDC - $0.14
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/derivatives/Reth.sol#L212
An attacker can manipulate ethPerDerivative() for the rETH-derivative, allowing him to mint cheap SafETH which can then be unstaked at normal prices. If repeated, could drain a large amount of funds.
ethPerDerivative() for rETH changes depending on _amount: either returns the poolPrice or the native rETH price.
An attacker can manipulate the poolPrice to significantly discount rETH (e.g., using flashloan)
Assumptions:
Exploit:
ethPerDerivative() should return the same value regardless of amount. Either the market price or the native price.
#0 - c4-pre-sort
2023-04-04T16:04:31Z
0xSorryNotSorry marked the issue as duplicate of #1035
#1 - toshiSat
2023-04-06T21:01:52Z
This is not a duplicate of #1035
#2 - c4-sponsor
2023-04-06T21:29:56Z
toshiSat marked the issue as sponsor confirmed
#3 - elmutt
2023-04-06T21:30:54Z
We believe this is potentially a real issue and not a duplicate of 1035
#4 - c4-sponsor
2023-04-07T00:37:10Z
elmutt marked the issue as sponsor disputed
#5 - c4-sponsor
2023-04-07T00:37:20Z
elmutt marked the issue as sponsor confirmed
#6 - c4-judge
2023-04-21T13:56:02Z
Picodes marked the issue as satisfactory
11.1318 USDC - $11.13
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L84 https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L87
If no derivatives are active (this can be because none have been added yet OR because all weights are 0), a user calling stake() will lose all ETH that was sent.
If no derivatives have been set up yet the for loop on line 84 will be skipped. If derivatives have been set up but all weights equal zero the if-statement on line 87 will skip all iterations of this loop. In both cases, this will result in totalStakeValueEth being 0. Subsequently, mintAmount will be 0 which means the user will not receive any safETH. As a result the user can not 'unstake' their ETH that was sent to the contract.
Manual review
revert if mintAmount == 0.
#0 - c4-pre-sort
2023-04-03T07:19:48Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T19:19:13Z
0xSorryNotSorry marked the issue as duplicate of #363
#2 - c4-judge
2023-04-21T16:31:42Z
Picodes marked the issue as satisfactory