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: 236/246
Findings: 1
Award: $0.14
🌟 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/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L211-L216 https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L228-L242
Price Oracle Manipulation - pricing information for the safEth derivative's underlying assets comes from a single source for each asset, which makes the protocol vulnerable to price oracle manipulation attacks. The generally accepted best practice is to get pricing information from a decentralized oracle like Chainlink
When a user calls the stake() function in SafEth.sol in order to stake ETH and mint the safEth derivative, the function determines the value of the underlying assets by calling the ethPerDerivative function for each underlying, aggregating the results, and assigning the total value to the underlyingValue variable.
function ethPerDerivative(uint256 _amount) public view returns (uint256) { if (poolCanDeposit(_amount)) return RocketTokenRETHInterface(rethAddress()).getEthValue(10 ** 18); else return (poolPrice() * 10 ** 18) / (10 ** 18); }
Reth.sol For the underlying rETH (rocket pool) asset specifically, in the case that rocket pool is unable to accept new deposits, ethPerDerivative calls the poolPrice() function in the Reth.sol contract by directly querying the rETH-WETH price from the Uniswap V3 pool which effectively provides the rETH price in terms of ETH.
function poolPrice() private view returns (uint256) { address rocketTokenRETHAddress = RocketStorageInterface( ROCKET_STORAGE_ADDRESS ).getAddress( keccak256( abi.encodePacked("contract.address", "rocketTokenRETH") ) ); IUniswapV3Factory factory = IUniswapV3Factory(UNI_V3_FACTORY); IUniswapV3Pool pool = IUniswapV3Pool( factory.getPool(rocketTokenRETHAddress, W_ETH_ADDRESS, 500) ); (uint160 sqrtPriceX96, , , , , , ) = pool.slot0(); return (sqrtPriceX96 * (uint(sqrtPriceX96)) * (1e18)) >> (96 * 2); }
An attacker can wait for a situation where Rocket Pool is not accepting deposits, and the protocol is relying on Uniswap for the rETH price. The attacker can then manipulate the rETH-WETH price by using a flash loan or other means to obtain a large amount of rETH and drive the price of rETH down through Uniswap. Then, they have the option stake ETH into safETH and obtain a higher number of rETH than its true market value. This exposes Asymmetry to a number of risks including:
Manual Review
Have a failsafe mechanism in place if a price manipulation occurs by using a decentralized Oracle like Chainlink to obtain the rETH price from multiple sources. When its time to execute the trade on Uniswap, if the price on Uniswap falls outside of a band of acceptable variability in relation to the Chainlink price, the trade can be put on hold or diverted to another pool with accurate pricing, which would mitigate the impact of a price manipulation attack. Reference - https://consensys.github.io/smart-contract-best-practices/attacks/oracle-manipulation/
#0 - c4-pre-sort
2023-04-04T11:23:49Z
0xSorryNotSorry marked the issue as duplicate of #601
#1 - c4-judge
2023-04-21T16:14:47Z
Picodes marked the issue as satisfactory
#2 - c4-judge
2023-04-21T16:15:26Z
Picodes marked the issue as duplicate of #1125