Platform: Code4rena
Start Date: 10/11/2023
Pot Size: $28,000 USDC
Total HM: 5
Participants: 185
Period: 5 days
Judge: 0xDjango
Id: 305
League: ETH
Rank: 31/185
Findings: 2
Award: $143.01
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: max10afternoon
Also found by: 0xMilenov, 0xbrett8571, 0xhacksmithh, 0xmystery, Aymen0909, Bauer, Daniel526, PENGUN, Pechenite, Shaheen, adriro, anarcheuz, btk, ck, ge6a, glcanvas, hals, turvy_fuzz
140.2525 USDC - $140.25
https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTDepositPool.sol#L119 https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTDepositPool.sol#L141 https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTOracle.sol#L54
Function LRTDepositPool:depositAsset() does not check the minimum liquidity amount. This makes users' funds vulnerable to sandwich attacks.
depositAsset()
will increase IRSETH(rsETHTokenAddress).totalSupply(), and thus change the exchange rate of RSETH.
return totalETHInPool / rsEthSupply;
Given the current network environment, most transactions in the mempool would be sandwiched. However, users may avoid this attack if they only send tx through Flashbot. I consider this a medium-risk issue.
Let's says a user wants to deposit 1000 LST in the pool hoping to get an expected amount of rsETH back. Attackers sees this and front runs trade as follows:
Mint more rsETH with 10,000 of the LST and extremely change the expected rsETH to mint for that LST
User's tx enter here and execute depositAsset()
.
Trade finalize with unwanted rsETH amount given back to the user since no slippage specified
Visual Studio Code
Function LRTDepositPool:depositAsset() should allow users to provide a min return and check the slippage. Always check how much liquidity a user receives in a transaction. A tx would not be sandwiched if it's not profitable.
We could learn a lot about MEV here.
MEV
#0 - c4-pre-sort
2023-11-16T19:20:39Z
raymondfam marked the issue as insufficient quality report
#1 - c4-pre-sort
2023-11-16T19:20:54Z
raymondfam marked the issue as duplicate of #284
#2 - c4-pre-sort
2023-11-16T20:35:24Z
raymondfam marked the issue as not a duplicate
#3 - c4-pre-sort
2023-11-16T20:35:32Z
raymondfam marked the issue as duplicate of #39
#4 - c4-pre-sort
2023-11-16T20:35:38Z
raymondfam marked the issue as sufficient quality report
#5 - c4-pre-sort
2023-11-17T06:43:15Z
raymondfam marked the issue as duplicate of #148
#6 - c4-judge
2023-11-29T19:10:46Z
fatherGoose1 marked the issue as satisfactory
🌟 Selected for report: m_Rassska
Also found by: 0x1337, 0xAadi, 0xHelium, 0xLeveler, 0xblackskull, 0xbrett8571, 0xepley, 0xffchain, 0xluckhu, 0xmystery, 0xrugpull_detector, 0xvj, ABAIKUNANBAEV, Aamir, AerialRaider, Amithuddar, Bauchibred, Bauer, CatsSecurity, Cryptor, Daniel526, Draiakoo, Eigenvectors, ElCid, GREY-HAWK-REACH, Inspecktor, Juntao, King_, LinKenji, Madalad, MaslarovK, Matin, MatricksDeCoder, McToady, Noro, PENGUN, Pechenite, Phantasmagoria, RaoulSchaffranek, SBSecurity, SandNallani, Shaheen, Soul22, Stormreckson, T1MOH, Tadev, TeamSS, TheSchnilch, Topmark, Tumelo_Crypto, Udsen, Yanchuan, ZanyBonzy, _thanos1, adeolu, adriro, alexfilippov314, almurhasan, amaechieth, anarcheuz, ayden, baice, bareli, boredpukar, bronze_pickaxe, btk, cartlex_, catellatech, chaduke, cheatc0d3, circlelooper, codynhat, crack-the-kelp, critical-or-high, debo, deepkin, desaperh, dipp, eeshenggoh, evmboi32, ge6a, gesha17, glcanvas, gumgumzum, hals, hihen, hunter_w3b, jasonxiale, joaovwfreire, ke1caM, leegh, lsaudit, marchev, merlinboii, niser93, osmanozdemir1, paritomarrr, passion, pep7siup, phoenixV110, pipidu83, poneta, ro1sharkm, rouhsamad, rvierdiiev, sakshamguruji, seerether, shealtielanz, soliditytaker, spark, squeaky_cactus, stackachu, supersizer0x, tallo, taner2344, turvy_fuzz, twcctop, ubl4nk, wisdomn_, xAriextz, zach, zhaojie, zhaojohnson, ziyou-
2.7592 USDC - $2.76
https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTOracle.sol#L70 https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTConfig.sol#L85 https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTConfig.sol#L86
LRTOracle:getRSETHPrice() which is executed in all protocol pricing operations, includes all assets supported in the calculation. This asset is added with the addNewSupportedAsset()
function, However, this sets the asset permanently and can't be undone if the asset returns same values when strategy is no longer handled and the asset is no longer supported on EigenLayer.
_addNewSupportedAsset() function sets assets as supported forever:
function _addNewSupportedAsset(address asset, uint256 depositLimit) private { UtilLib.checkNonZeroAddress(asset); if (isSupportedAsset[asset]) { revert AssetAlreadySupported(); } isSupportedAsset[asset] = true; // @audit supportedAssetList.push(asset); depositLimitByAsset[asset] = depositLimit; emit AddedNewSupportedAsset(asset, depositLimit); }
There is no function that can undo this.
LRTOracle:getRSETHPrice()
function getRSETHPrice() external view returns (uint256 rsETHPrice) { ... address[] memory supportedAssets = lrtConfig.getSupportedAssetList(); uint256 supportedAssetCount = supportedAssets.length; for (uint16 asset_idx; asset_idx < supportedAssetCount;) { address asset = supportedAssets[asset_idx]; uint256 assetER = getAssetPrice(asset); uint256 totalAssetAmt = ILRTDepositPool(lrtDepositPoolAddr).getTotalAssetDeposits(asset); // @audit totalETHInPool += totalAssetAmt * assetER; unchecked { ++asset_idx; } } return totalETHInPool / rsEthSupply; }
Manual Review
Contract should have a removeAsset function
Other
#0 - c4-pre-sort
2023-11-16T23:59:14Z
raymondfam marked the issue as insufficient quality report
#1 - c4-pre-sort
2023-11-16T23:59:31Z
raymondfam marked the issue as duplicate of #38
#2 - c4-judge
2023-12-01T17:45:50Z
fatherGoose1 changed the severity to QA (Quality Assurance)
#3 - c4-judge
2023-12-01T17:47:24Z
fatherGoose1 marked the issue as grade-b