Restaking will not work as expected. People using BoostAggregator will have to unstake, withdraw, deposit again in order to restake their token.
Proof of Concept
function restakeToken(uint256 tokenId) external {
IncentiveKey storage incentiveId = stakedIncentiveKey[tokenId];
if (incentiveId.startTime != 0) _unstakeToken(incentiveId, tokenId, true); // @audit - boolean passed should be false, instead of true
(IUniswapV3Pool pool, int24 tickLower, int24 tickUpper, uint128 liquidity) =
NFTPositionInfo.getPositionInfo(factory, nonfungiblePositionManager, tokenId);
_stakeToken(tokenId, pool, tickLower, tickUpper, liquidity);
}
_unstakeToken receives a boolean argument isNotRestake with the idea that if an incentive has ended, adversary can call restake on any token and stake it into the next incentive. The problem is that restakeToken passes true instead of false and corrupts the logic. Because of this, any users using BoostAggregator will have to unstake and withdraw their tokens and redeposit them into the UniswapV3Staker via the BoostAggregator, which is not only inconvenient, but also costs a lot of gas.
Lines of code
https://github.com/code-423n4/2023-05-maia/blob/main/src/uni-v3-staker/UniswapV3Staker.sol#L342 https://github.com/code-423n4/2023-05-maia/blob/main/src/uni-v3-staker/UniswapV3Staker.sol#L374
Vulnerability details
Impact
Restaking will not work as expected. People using
BoostAggregator
will have to unstake, withdraw, deposit again in order to restake their token.Proof of Concept
_unstakeToken
receives a boolean argumentisNotRestake
with the idea that if an incentive has ended, adversary can call restake on any token and stake it into the next incentive. The problem is thatrestakeToken
passestrue
instead offalse
and corrupts the logic. Because of this, any users usingBoostAggregator
will have to unstake and withdraw their tokens and redeposit them into theUniswapV3Staker
via theBoostAggregator
, which is not only inconvenient, but also costs a lot of gas.Tools Used
Manual review
Recommended Mitigation Steps
pass false as an argument in #L342
Assessed type
Context