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: 64/246
Findings: 5
Award: $84.12
🌟 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 function ethPerDerivative returns the price of WstETH in terms of stETH. The underlying token we desire is ETH. Since stETH does not have the same value as ETH, the output price incorrect.
The function ethPerDerivative only converts WstETH to stETH. Thus, ethPerDerivative() returns the value of WstETH in terms of stETH.
function ethPerDerivative(uint256 _amount) public view returns (uint256) { return IWStETH(WST_ETH).getStETHByWstETH(10 ** 18); }
Manually
Add extra steps to approximate the rate for converting stETH to ETH.
#0 - c4-pre-sort
2023-04-01T07:58:27Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T17:23:54Z
0xSorryNotSorry marked the issue as duplicate of #588
#2 - c4-judge
2023-04-21T17:09:06Z
Picodes marked the issue as satisfactory
#3 - c4-judge
2023-04-22T09:05:02Z
Picodes marked the issue as partial-25
#4 - c4-judge
2023-04-24T20:45:46Z
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
Reth.poolPrice uses the UniV3Pool.slot0 to calculate the price in terms of ETH. slot0 is the most recent data point and is therefore extremely easy to manipulate.
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); }
Reth.poolPrice uses the UniV3Pool.slot0 to calculate the price in terms of ETH. slot0 is the most recent data point and is therefore extremely easy to manipulate.
VS
#0 - c4-pre-sort
2023-03-31T18:40:35Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T11:36:11Z
0xSorryNotSorry marked the issue as duplicate of #601
#2 - c4-judge
2023-04-21T16:11:57Z
Picodes marked the issue as duplicate of #1125
#3 - c4-judge
2023-04-21T16:14:32Z
Picodes marked the issue as satisfactory
🌟 Selected for report: ladboy233
Also found by: 0xkazim, 0xnev, Bauer, J4de, Matin, UniversalCrypto, cryptothemex, jasonxiale, juancito, koxuan, latt1ce, neumo
48.6252 USDC - $48.63
https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L173-L174 https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/SfrxEth.sol#L74-L75
Division before before which can incur loss of precision, those two functions are used to swap token. So it could lead to token lost.
uint256 minOut = ((((rethPerEth * msg.value) / 10 ** 18) * ((10 ** 18 - maxSlippage))) / 10 ** 18);
uint256 minOut = (((ethPerDerivative(_amount) * _amount) / 10 ** 18) * (10 ** 18 - maxSlippage)) / 10 ** 18;
Manual Review
Consider always implementing multiplication first when it involves multiplication and division operation and division should always come last to increase precision.
#0 - c4-pre-sort
2023-04-03T09:07:50Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T16:40:53Z
0xSorryNotSorry marked the issue as duplicate of #1044
#2 - c4-judge
2023-04-22T10:33:09Z
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/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/SafEth.sol#L88 https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/SafEth.sol#L149-L150
function stake and function rebalanceToWeights will generate some dust eth, which will be locked in the contract
Take function stake as an examle,
In L88-L91, the function will split the ETH into pieces, and deposit those pieces into different derivatives.
But after depist the ETH, the function doesn't send the dust back to user. And the dust ETH is locked in the contract
function stake() external payable { ... for (uint i = 0; i < derivativeCount; i++) { ... uint256 ethAmount = (msg.value * weight) / totalWeight; // split the ETH into pieces uint256 depositAmount = derivative.deposit{value: ethAmount}(); // deposit the ETH } }
VS
#0 - c4-pre-sort
2023-04-03T08:53:35Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T16:29:14Z
0xSorryNotSorry marked the issue as duplicate of #455
#2 - c4-judge
2023-04-24T21:21:20Z
Picodes marked the issue as satisfactory