Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

Leftover Liquidity Problem in _depositLiquidity Function

Description

The _depositLiquidity function handles the deposit of liquidity into multiple strategies. It attempts to deposit liquidity into strategies one by one, moving to the next strategy if the current one is full. However, there is a critical issue: leftover liquidity can remain in the contract if not all liquidity is successfully deposited across the strategies. This leftover liquidity issue arises when the contract does not fully utilize the available liquidity, leaving tokens idle in the contract instead of being invested in strategies.

The main problem is that no check is made after the loop to ensure all tokens were deposited into strategies. This could lead to liquidity being left in the contract without being deployed as intended, causing inefficiencies in fund utilization and lower yields for users.

Example:

If 100 tokens are available for deposit, and Strategy A can only accept 50, the remaining 50 tokens may stay in the contract if subsequent strategies cannot accept the rest. This results in idle liquidity that is not used effectively.

Impact

  • ** Idle Liquidity**: Any leftover tokens remain in the contract, preventing them from being utilized in strategies, which reduces the overall efficiency of the system and potential yield.

  • Lost Revenue: Users may lose potential revenue from these unutilized tokens since the system does not fully invest them.

  • Unexpected Contract Behavior: Users expect the contract to use the entire deposit. The fact that some tokens remain in the contract could lead to confusion and frustration for users.

Recommendations

The leftover liquidity issue in the _depositLiquidity function can cause inefficiencies by leaving some tokens idle in the contract. By adding a check after the loop and handling the leftover liquidity, this issue can be resolved, ensuring that all tokens are either deposited or the transaction fails gracefully. This will lead to more efficient fund utilization and greater transparency for users.

function _depositLiquidity(bytes[] calldata _data) private {
uint256 toDeposit = token.balanceOf(address(this));
if (toDeposit > 0) {
for (uint256 i = 0; i < strategies.length; i++) {
IStrategy strategy = IStrategy(strategies[i]);
uint256 strategyCanDeposit = strategy.canDeposit();
if (strategyCanDeposit >= toDeposit) {
strategy.deposit(toDeposit, _data[i]);
toDeposit = 0; // All liquidity deposited
break;
} else if (strategyCanDeposit > 0) {
strategy.deposit(strategyCanDeposit, _data[i]);
toDeposit -= strategyCanDeposit;
}
}
}
// Proactive check to ensure no leftover liquidity
if (toDeposit > 0) {
revert("Not all liquidity was deposited into strategies");
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
11 months ago
inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.