Omniscia Alliance Block Audit
AutoStake Manual Review Findings
AutoStake Manual Review Findings
ASE-01M: Invalid Restake of Exited Stakes
Type | Severity | Location |
---|---|---|
Logical Fault | Major | AutoStake.sol:L133-L140 |
Description:
The restakeIntoRewardPool
function restakes the stakingToken
balance of the contract bak to the rewardPool
, however, it does not take into account the amount of stakes that are meant to exit via exitStake
and thus prohibits these from ever being withdrawn as the code was not updated from the Harvest implementation.
Example:
contracts/autostake-features/AutoStake.sol
133function restakeIntoRewardPool() internal {134 if(stakingToken.balanceOf(address(this)) != 0){135 // stake back to the pool136 stakingToken.safeApprove(address(rewardPool), 0);137 stakingToken.safeApprove(address(rewardPool), stakingToken.balanceOf(address(this)));138 rewardPool.stake(stakingToken.balanceOf(address(this)));139 }140}
Attack Diagram:
sequenceDiagram
User->>AutoStaker: Performs a valid `stake()` invocation
Note right of User: Time passes and stake can be withdrawn
User->>AutoStaker: Initiates a stake withdrawal via `exit()`
User->>AutoStaker: Decides to stake to the contract again via `stake()`
User->>AutoStaker: Attempts to finalize their exit via `completeExit()` but fail to do so due to the contract lacking the necessary balance
Recommendation:
We advise that the approval and stake calculation of L137 and L138 perform a subtraction of the exitStake
from the evaluated contract balance to ensure the stakes that are pending exit can be withdrawn.
Alleviation:
The code statements were adjusted to calculate the appropriate amount to stake instead of the full balance.