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: 12/185
Findings: 3
Award: $909.99
π Selected for report: 0
π Solo Findings: 0
π Selected for report: m_Rassska
Also found by: 0xDING99YA, Aamir, Bauchibred, CatsSecurity, HChang26, PENGUN, SBSecurity, adriro, almurhasan, anarcheuz, circlelooper, d3e4, deth, jayfromthe13th
902.5718 USDC - $902.57
https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTDepositPool.sol#L109
##root cause The problem is that a user can know which direction the oracle price of an asset against ETH will move before it does, either through watching the asset price against ETH move in advance of the oracle updating, or watching the mempool for oracle update transactions and frontrunning them.
Letβs take example , let assume 1 asset price = 1 ETH, 1 rsETH price = 1 ETH. now the exchange rate of the asset will be updated to 1 asset price = 0.95 ETH. user/MEV can frontrun and let assume users call the function depositAsset with 100 asset amount and mint 100 rsETH (as oracle price is still not updated yet). After the oracle price is updated, the user can backrun(withdraw/redeem his 100 rsETH) because 100 rsETH is now worth 105 asset tokens. So user/mev make a profit of 5 asset tokens.
This can also happen in opposite direction,let assume 1 asset price = 1 ETH, 1 rsETH price = 1 ETH. now the exchange rate of the asset will be updated to 1 asset price = 1.05 ETH. user/MEV(previously deposited) can frontrun and withdraw 100 rsETH (as oracle price is still not updated yet).After the oracle price is updated, the user can backrun and deposit 100 asset tokens, and get 105 rsETH .
If the deposit/withdrawal amount is big enough,protocol can reach a state of big loss.
manual review
implementing a 1 hour waiting period on deposit/ withdrawals or
storing deposits and redemptions and executing them at a future exchange rate or creating pause/unpause for deposit/withdraw assets.
MEV
#0 - c4-pre-sort
2023-11-16T03:11:18Z
raymondfam marked the issue as primary issue
#1 - c4-pre-sort
2023-11-16T03:11:23Z
raymondfam marked the issue as insufficient quality report
#2 - raymondfam
2023-11-16T03:12:11Z
Front-running arbitrage is expected in DeFi.
#3 - c4-pre-sort
2023-11-18T01:30:58Z
raymondfam marked the issue as duplicate of #584
#4 - c4-pre-sort
2023-11-18T01:31:12Z
raymondfam marked the issue as sufficient quality report
#5 - c4-judge
2023-12-01T17:09:01Z
fatherGoose1 marked the issue as unsatisfactory: Invalid
#6 - c4-judge
2023-12-08T17:38:07Z
fatherGoose1 marked the issue as satisfactory
π Selected for report: Krace
Also found by: 0xDING99YA, 0xrugpull_detector, Aamir, AlexCzm, Aymen0909, Banditx0x, Bauer, CatsSecurity, GREY-HAWK-REACH, Madalad, Phantasmagoria, QiuhaoLi, Ruhum, SBSecurity, SandNallani, SpicyMeatball, T1MOH, TheSchnilch, adam-idarrha, adriro, almurhasan, ast3ros, ayden, bronze_pickaxe, btk, chaduke, ck, crack-the-kelp, critical-or-high, deth, gumgumzum, jasonxiale, joaovwfreire, ke1caM, m_Rassska, mahdirostami, mahyar, max10afternoon, osmanozdemir1, peanuts, pep7siup, peter, ptsanev, qpzm, rouhsamad, rvierdiiev, spark, twcctop, ubl4nk, wisdomn_, zach, zhaojie
4.6614 USDC - $4.66
https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTOracle.sol#L78 https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTDepositPool.sol#L109
##summary When the first user enters, totalSupply is set to 1e18.
if (totalSupply == 0) return 1 ether; else return totalETHInPool / rsEthSupply; But the user can immediately withdraw most of his rsETH such that totalSupply << 1e18. The attacker can then increase the totalETHInPool by transferring supported assets to the LRTDepositPool contract.
For subsequent users, the getRSETHPrice will be heavily inflated , The calculation of rsethAmountToMint = (amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice() can be very inaccurate. In the worst case it rounds down to 0 for users that deposit a value that is less than the value that the attacker transferred in.
1.attacker/first depositor mint 10 rsETH and immediately removes all but kept 1 wei. 2.Attacker then directly transfer 10 ETH worth of an asset in LRTDepositPool. 3.When the second user calls the function depositAsset with 5 ETH worth of an asset amount(less than 10 ETH worth of an asset amount), no additional rsETH are minted since rsethAmountToMint is rounded down to 0.
The first user that stakes can manipulate the total supply of rsETH and by doing so create a rounding error for each subsequent user. In the worst case, an attacker can steal all the funds of the next user.
manual review
Math
#0 - c4-pre-sort
2023-11-16T03:14:08Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-11-16T03:14:15Z
raymondfam marked the issue as duplicate of #42
#2 - c4-judge
2023-12-01T17:02:29Z
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/LRTConfig.sol#L94
When the manager calls the function updateAssetDepositLimit, there is no check that depositLimit canβt be less than the previous depositLimit .
manual review
Validate that depositLimit canβt be less than the previous depositLimit when calling the function updateAssetDepositLimit
Invalid Validation
#0 - c4-pre-sort
2023-11-16T07:28:12Z
raymondfam marked the issue as insufficient quality report
#1 - c4-pre-sort
2023-11-16T07:28:26Z
raymondfam marked the issue as duplicate of #69
#2 - c4-judge
2023-11-29T20:58:12Z
fatherGoose1 changed the severity to QA (Quality Assurance)
#3 - c4-judge
2023-11-29T21:02:32Z
fatherGoose1 marked the issue as grade-b