The StakingPool contract is susceptible to a reentrancy attack due to the lack of reentrancy guards in the _depositLiquidity function. A malicious strategy contract can exploit this vulnerability to make reentrant calls back into the StakingPool.deposit function, potentially manipulating the contract's state, stealing funds, or causing unexpected behavior.
This function is called by the deposit function, which is a critical function that allows users to stake their tokens and mint liquid staking tokens.
The vulnerability arises because _depositLiquidity directly calls strategy.deposit without any reentrancy guards. If a malicious strategy contract is added to the StakingPool, it can make a reentrant call back into the StakingPool.deposit function during the execution of _depositLiquidity. This reentrant call can potentially manipulate the contract's state, steal funds, or cause the original deposit function to revert unexpectedly.
In both the deposit function and the _depositLiquidity function, where the calls to _depositLiquidity and strategy.deposit are made without reentrancy protection. These unprotected calls can be exploited by a malicious strategy contract to perform reentrant calls.
Here's how the bug happens:
A user calls the deposit function with _amount = 0 and provides deposit data for a malicious strategy.
Inside deposit, the _depositLiquidity function is called with the provided deposit data.
_depositLiquidity iterates over the strategies and calls the deposit function of each strategy, passing the deposit data.
If a malicious strategy is encountered, its deposit function can make a reentrant call back into the StakingPool.deposit function.
The reentrant call to deposit can execute malicious code, potentially manipulating the contract's state or stealing funds.
The reentrant call can also cause the original deposit function to revert, violating the noReentrancyInCriticalFunctions rule.
If a malicious strategy is added to the pool, it can exploit the reentrancy vulnerability to steal funds from users or manipulate the contract's state.
Manual Review
Implement reentrancy guards in the StakingPool contract. The deposit function and the other external functions that call _depositLiquidity should be protected with a reentrancy guard, such as the nonReentrant modifier from OpenZeppelin.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.