Omniscia Alliance Block Audit

AutoStake Manual Review Findings

AutoStake Manual Review Findings

ASE-01M: Invalid Restake of Exited Stakes

TypeSeverityLocation
Logical FaultMajorAutoStake.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 pool
136 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.