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: 128/185
Findings: 1
Award: $2.76
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 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
An erroneus deposit limit setting inside LRTConfig
could block deposit functionalities inside LRTDepositPool
due to Overflow
error.
Let's we see LRTDepositPool.sol#L53-L58
/// @notice gets the current limit of asset deposit /// @param asset Asset address /// @return currentLimit Current limit of asset deposit function getAssetCurrentLimit(address asset) public view override returns (uint256) { return lrtConfig.depositLimitByAsset(asset) - getTotalAssetDeposits(asset); }
So, getAssetCurrentLimit()
simple compute a difference between lrtConfig.depositLimitByAsset()
and getTotalAssetDeposits()
, with respect to asset parameter.
However, while totalAssetDeposit
can never be more then assetDepositLimit
, thanks to check inside depositAsset()
at
LRTDepositPool.sol#L132-L134,
an account with MANAGER role
could accidentally set the assetDepositLimit
with a value lower than current totalAssetDeposit
, using
LRTConfig.sol#L91-L104
/// @dev Updates the deposit limit for an asset /// @param asset Asset address /// @param depositLimit New deposit limit function updateAssetDepositLimit( address asset, uint256 depositLimit ) external onlyRole(LRTConstants.MANAGER) onlySupportedAsset(asset) { depositLimitByAsset[asset] = depositLimit; emit AssetDepositLimitUpdate(asset, depositLimit); }
We write own test inside LRTDepositPoolTest.t.sol/LRTDepositPoolGetAssetCurrentLimit
function test_zzzGetAssetCurrentLimitAfterAssetIsDeposited() external { vm.startPrank(manager); lrtConfig.updateAssetDepositLimit(address(stETH), 10 ether); vm.stopPrank(); // deposit 1 ether stETH vm.startPrank(alice); stETH.approve(address(lrtDepositPool), 6 ether); lrtDepositPool.depositAsset(address(stETH), 6 ether); vm.stopPrank(); assertEq(lrtDepositPool.getAssetCurrentLimit(address(stETH)), 4 ether, "Asset current limit is not set"); vm.startPrank(manager); lrtConfig.updateAssetDepositLimit(address(stETH), 4 ether); vm.stopPrank(); lrtDepositPool.getAssetCurrentLimit(address(stETH)); }
The result is
Test result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 5.51ms Ran 1 test suites: 0 tests passed, 1 failed, 0 skipped (1 total tests) Failing tests: Encountered 1 failing test in test/LRTDepositPoolTest.t.sol:LRTDepositPoolGetAssetCurrentLimit [FAIL. Reason: Arithmetic over/underflow] test_zzzGetAssetCurrentLimitAfterAssetIsDeposited() (gas: 215238)
Visual ispection and Foundry
It should be better to avoid an arbitrary update of depositLimit by MANAGER. Otherwise, we could use:
/// @notice gets the current limit of asset deposit /// @param asset Asset address /// @return currentLimit Current limit of asset deposit function getAssetCurrentLimit(address asset) public view override returns (uint256) { if(lrtConfig.depositLimitByAsset(asset) >= getTotalAssetDeposits(asset)) return lrtConfig.depositLimitByAsset(asset) - getTotalAssetDeposits(asset); else return 0; }
Under/Overflow
#0 - c4-pre-sort
2023-11-16T18:43:12Z
raymondfam marked the issue as insufficient quality report
#1 - c4-pre-sort
2023-11-16T18:43:28Z
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:42Z
fatherGoose1 marked the issue as grade-b