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: 26/185
Findings: 3
Award: $145.34
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 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
2.3307 USDC - $2.33
https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTDepositPool.sol#L79 https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTDepositPool.sol#L83
Deriving the price with balanceOf()
is dangerous as it can easily be manipulated by direct transfers.
In the getAssetDistributionData() function, the asset lying in the LRTDepositPool is retrieved using balanceOf(address(this)):
assetLyingInDepositPool = IERC20(asset).balanceOf(address(this));
Similarly, the assets in :NodeDelegator are obtained through balanceOf(nodeDelegator):
assetLyingInNDCs += IERC20(asset).balanceOf(nodeDelegatorQueue[i]);
Deriving the price with balanceOf is dangerous as balanceOf may be gamed. Consider univ2 as an example; Exploiters can send tokens into the pool and pump the price, successfully manipulating the price.
Similar finding: https://solodit.xyz/issues/m-05-pair-price-may-be-manipulated-by-direct-transfers-code4rena-caviar-caviar-contest-git
Manual review
Consider tracking balances, using state variables, similarly to how Uniswap V2.
Oracle
#0 - c4-pre-sort
2023-11-16T23:09:18Z
raymondfam marked the issue as insufficient quality report
#1 - c4-pre-sort
2023-11-16T23:11:19Z
raymondfam marked the issue as duplicate of #435
#2 - c4-judge
2023-12-01T17:57:07Z
fatherGoose1 marked the issue as unsatisfactory: Invalid
#3 - 0xbtk
2023-12-02T18:12:15Z
Hey @fatherGoose1, I think #788 is a duplicate of #42. Could you please check? It is similar to #53, #157, etc.
The finding indicates that "Exploiters can manipulate the price by sending tokens into the pool and pumping the price," and the suggested fix is accurate.
Thanks for your time and consideration.
#4 - fatherGoose1
2023-12-04T17:58:06Z
This report does not go into enough detail to accurately depict the attack path. I recommend spending more time on your submissions to fully describe the ultimate impact and attack methodology.
#5 - 0xbtk
2023-12-04T19:04:31Z
Hi @fatherGoose1, I agree with you. I didn't invest much time in this contest, only jumping in during the last two hours. At that point, it seemed straightforward, so I provided a brief explanation. However, labeling it as unsatisfactory seems too strict. A valid submission should be valued for identifying the vulnerability's root cause and providing clear proof. Also, there are similar issues like #264 that got through without adding much proof.
Wouldn't partial credit be more fitting here?
#6 - c4-judge
2023-12-05T17:49:25Z
fatherGoose1 marked the issue as not a duplicate
#7 - c4-judge
2023-12-05T17:49:41Z
fatherGoose1 marked the issue as duplicate of #42
#8 - c4-judge
2023-12-05T17:50:10Z
fatherGoose1 marked the issue as partial-50
#9 - fatherGoose1
2023-12-05T17:51:51Z
@0xbtk bumped to 50%. I agree that I was too strict with this submission. The root issue is clearly explained, though I put weight in the recommendation section, where supporting details or links to suitable code would be welcomed (like #264)
#10 - c4-judge
2023-12-08T18:55:40Z
fatherGoose1 changed the severity to 3 (High Risk)
🌟 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-L144
There is no slippage control on depositAsset()
of LRTDepositPool
, which expose user to sandwich attack.
Any deposit can be sandwiched in LRTDepositPool
, especially when the pool is not balanced.
Bob, a normal user, calls depositAsset()
. Since there is no minAmountOut
, which means that the deposit can be executed at any price. As a result, when Eve sandwiches the deposit , Bob deposit the tokens without minting any, effectively giving away tokens for free.
A Detailed Guide To Sandwich Attacks In DeFi.
Add a minAmountOut
in depositAsset()
MEV
#0 - c4-pre-sort
2023-11-16T23:51:04Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-11-16T23:51:12Z
raymondfam marked the issue as duplicate of #39
#2 - c4-pre-sort
2023-11-17T06:43:21Z
raymondfam marked the issue as duplicate of #148
#3 - c4-judge
2023-11-29T19:11: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#L73-L89
The inability of LRTConfig to remove old assets can result in a potential DoS on LRTOracle.
The Manager can introduce a new asset to LRTConfig using:
function _addNewSupportedAsset(address asset, uint256 depositLimit) private { UtilLib.checkNonZeroAddress(asset); if (isSupportedAsset[asset]) { revert AssetAlreadySupported(); } isSupportedAsset[asset] = true; supportedAssetList.push(asset); depositLimitByAsset[asset] = depositLimit; emit AddedNewSupportedAsset(asset, depositLimit); }
LRTOracle's getRSETHPrice() function iterates through all assets to retrieve prices. If one of these assets, especially an upgradeable contract, is compromised, an attacker can DoS on LRTOracle by manipulating certain view functions to consistently revert, such as in the example below:
assetLyingInDepositPool = IERC20(asset).balanceOf(address(this));
Manual review
Add a function to allow the manager to remove an asset.
Other
#0 - c4-pre-sort
2023-11-17T00:10:38Z
raymondfam marked the issue as insufficient quality report
#1 - c4-pre-sort
2023-11-17T00:11:02Z
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:26Z
fatherGoose1 marked the issue as grade-b