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: 49/185
Findings: 3
Award: $83.44
🌟 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
4.6614 USDC - $4.66
Detailed description of the impact of this finding.
LRTDepositPool.depositAsset() allows one to deposit depositAmount
of asset in exchange of rsethAmountMinted
of rsEth. However, it allows the first depositor to inflate the price of RsETH and then rip off from future depositors.
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
LRTDepositPool.depositAsset() allows the first depositor to inflate the price of RsETH and then rip off from future depositors as follows:
Then Alice, can "donate" a sizable amount of asset, say 1000e18 to the LRTDepositPool. As a result, now one wei of RsETH is worthy of 1000e18 + 1 of the asset.
Now another user, Jack deposits 2000e18 to LRTDepositPool, he will only get 1 wei of RsETH also due to division loss in the following line:
rsethAmountToMint = (amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice();
Now the price of RsETH becomes: (3000e18+1) / 2 = 1500e18. So effectively Alice steals 500 eth asset from Jack. If she can withdraw the asset now, she will get 1500e18 asset, gaining 500 eth asset.
If Jack withdraw the asset now, he will only get 1500et18, and lost 500 et18.
Alice might rip off from future depositors in a similar manner due to the highly inflated price of RsEth and the division precision loss.
VSCode
There are many ways to prevent such first depositor attack:
Math
#0 - c4-pre-sort
2023-11-16T21:14:55Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-11-16T21:15:02Z
raymondfam marked the issue as duplicate of #42
#2 - c4-judge
2023-12-01T17:06:10Z
fatherGoose1 marked the issue as satisfactory
🌟 Selected for report: crack-the-kelp
Also found by: 0xDING99YA, 0xffchain, Aymen0909, Bauchibred, DanielArmstrong, Pechenite, Stormy, T1MOH, ZanyBonzy, ast3ros, bLnk, chaduke, crack-the-kelp, deepkin, deth, jasonxiale, jayfromthe13th, lsaudit, nmirchev8, osmanozdemir1, roleengineer, tallo, zhaojie
76.0163 USDC - $76.02
Detailed description of the impact of this finding. LRTConfig.updateAssetStrategy() fails to withdraw funds from the old strategy before setting a new strategy for the asset. There are two impacts for this: 1) The funds in the old strategy might be lost; 2) the total value for the asset returned by getTotalAssetDeposits() will be wrong since it does not include the portion in the old strategy; 3) Then the LRTOracle.getRSETHPrice() will return a smaller value too. Such price drop might lead trading that take advantage of the situation.
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
LRTConfig.updateAssetStrategy() allows the admin to change the strategy for an asset to a new one.
However, the function fails to withdraw the funding from the old strategy first and as a result those funding might be lost. In addition, the following impacts will ensure:
VSCode
Make sure the balance for the strategy is zero before changing an old strategy to a new one.
Invalid Validation
#0 - c4-pre-sort
2023-11-16T20:57:02Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-11-16T20:57:11Z
raymondfam marked the issue as duplicate of #197
#2 - c4-judge
2023-12-01T17:24:53Z
fatherGoose1 marked the issue as unsatisfactory: Invalid
#3 - c4-judge
2023-12-04T16:41:52Z
fatherGoose1 changed the severity to 2 (Med Risk)
#4 - c4-judge
2023-12-08T17:26:24Z
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
QA1. It might overwrite an existing key:
Mitigation:
function _setToken(bytes32 key, address val) private { UtilLib.checkNonZeroAddress(val); - if (tokenMap[key] == val) { + if (tokenMap[key] != address(0)) { revert ValueAlreadyInUse(); } tokenMap[key] = val; emit SetToken(key, val); }
QA2. LRTConfigRoleChecker.lrtConfigAddr() has the danger to lose the admin for the newly set lrtConfigAddr.
The function is only callable by the current LRTAdmin, which might not be the LRTAdmin for the newly set lrtConfigAddr. If an invalid lrtConfigAddr is set, then there is no way to correct it.
Mitigation: ensure that the current LRTadmin will also be the LRTAdmin for the new lrtConfigAddr. After that, one can also transfer the LRTadmin to another use using a two-step procedure.
QA3. There is no mechanism to check whether duplicate nodeDelegatorContract is added to the array or not.
Impact: getTotalAssetDeposits() might return the wrong total value since the balance for the duplicate nodeDelegatorContract will be doubly accounted. A user might not be able to deposit asset due to falsely inflated total deposit amount.
Mitigation:
Introduce a mapping so that one can check whether we are adding a new nodeDelegatorContract or not to avoid adding duplicate. Otherwise, the limit maxNodeDelegatorCount
might be wasted due to duplicates.
QA4. LRTDepositPool.updateMaxNodeDelegatorCount() might decrease maxNodeDelegatorCount
, but fails to check that the new maxNodeDelegatorCount_
might result that the number of nodeDelegators already exceeds the new limit.
Mitigation:
Check and ensure the new maxNodeDelegatorCount_
is not small than the number of current nodeDelegators. Otherwise, the function should revert.
QA5. getAssetPrice() fails to check that assetPriceOracle[asset] == address(0). It is possible that the Oracle for the asset has not been set yet.
Mitigation: check and ensure assetPriceOracle[asset] != address(0).
QA6. NodeDelegator.transferBackToLRTDepositPool() fails to check that lrtDepositPool != address(0). When lrtDepositPool == address(0), the function will send tokens to the zero address.
Mitigation: check and make sure lrtDepositPool != address(0)
QA7. The NodeDelegator contract has not function to withdraw assets from a strategy.
Impact: the funds deposited into a strategy is lost since there is no function to withdraw them from the strategy.
Mitigation: add a function to allow a user to withdraw funds from a strategy.
#0 - c4-pre-sort
2023-11-18T00:46:44Z
raymondfam marked the issue as sufficient quality report
#1 - c4-judge
2023-12-01T16:31:26Z
fatherGoose1 marked the issue as grade-b