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: 112/246
Findings: 3
Award: $30.95
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 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#L211-L216 https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L91-L95
The function Reth.ethPerDerivative
function is used by Steth.stake
to attribute shares to a user after they have deposited ETH to the Reth
contract. The problem is that this function may yield different results depending on the result of Reth.poolCanDeposit
function, which checks whether or not rETH deposit pool has room users amount, and uses either Rocket Pool or Uniswap. It is possible that, during derivative.deposit{value: ethAmount}();
, Reth.poolCanDeposit
returns true
, while during derivative.ethPerDerivative
, Reth.poolCanDeposit
returns false
. This will lead to a higher or lower share amount than what the user is owed.
stake
s ETH into SafEth
SafEth
uses Reth
as one of the derivatives. When depositing, poolCanDeposit
returns true, as the Rocket Pool can receive the ether amount. The user's ether is deposited using Rocket poolSafEth
calls ethPerDerivative
to calculate how much derivative was received per user ether amount. This time, poolCanDeposit
returns false, and the returned value of ethPerDerivative
is Uniswap's poolPrice
.Manual review
Change the derivative's deposit
function to return a tuple with amount of ether deposited and amount of derivative received (for example, function deposit() external payable onlyOwner returns (uint256 derivativeAmount, uint256 receivedEthValue)
. This will abstract away from the SafEth
contract the internal calculations of each derivative contract.
#0 - c4-pre-sort
2023-04-04T17:40:48Z
0xSorryNotSorry marked the issue as duplicate of #1004
#1 - c4-judge
2023-04-21T14:03:44Z
Picodes marked the issue as duplicate of #1125
#2 - c4-judge
2023-04-21T14:20:36Z
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#L215 https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/derivatives/SfrxEth.sol#L116
Some derivative contracts use price pool as price oracles, which is vulnerable price manipulation attacks, such as flash loan attacks and read-only reentrancy attacks.
For example, the function SfrxEth.ethPerDerivative
(used by both SafEth.stake
and SafEth.unstake
) uses curve's FRX/ETH pool to calculate the conversion between ETH and frxETH. As Curve has recently published, together with ChainSecurity's finding, there is a security concern where a well capitalized actor or a flash loan enabled adversary can execute a large swap on Curve to temporarily distort the prices of the two coins involved as compared to the wider market prices for those assets.
This means that an attacker can manipulate the price of the derivative in relationship to ETH to their advantage, either in stake
or unstake
.
SafEth.stake
and deposits some ETH, getting some SafEth
tokens in returnSafEth.unstake
and drains the SfrxEth
vault, as the ethPerDerivative
value will be incorrect, withdrawing more ETH than what they should.Manual review
stake
/unstake
functions.#0 - c4-pre-sort
2023-04-04T16:02:50Z
0xSorryNotSorry marked the issue as duplicate of #1035
#1 - c4-judge
2023-04-21T13:55:38Z
Picodes marked the issue as satisfactory
🌟 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
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L88 https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L95
Because of rounding errors on SafEth.stake
, the total ether amount passed to derivative contracts will not always be equal to msg.value
. As a result, some ether will be stuck on the SafEth
contract.
1 ether
msg.value/3
etherSafEth
ether will be stuck with 1 weiManual review
Refund the user back with the amount of ether that was not used to fund the derivative contracts.
#0 - c4-pre-sort
2023-04-01T11:09:47Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T16:21:34Z
0xSorryNotSorry marked the issue as duplicate of #455
#2 - c4-judge
2023-04-24T21:25:11Z
Picodes marked the issue as satisfactory
#3 - c4-judge
2023-04-24T21:41:47Z
Picodes changed the severity to 2 (Med Risk)