Skip to content

Latest commit

 

History

History
69 lines (48 loc) · 2.61 KB

File metadata and controls

69 lines (48 loc) · 2.61 KB

Fast Khaki Raccoon

Medium

Users can prevent reward accrual in order to capture rewards distributed before they have joined

Summary

Sometimes rewards may not be accrued, which would enable users to claim them even if they have joined the pool after they have been distributed.

Root Cause

If the pool has high slippage it would revert the bellow try inside _swapForRewards which would enter us in the catch, which would just store the rewards, allowing the next caller of depositFromPairedLpToken or depositRewards to accrue them.

https://github.com/sherlock-audit/2025-01-peapods-finance/blob/main/contracts/contracts/TokenRewards.sol#L300-L318

        try DEX_ADAPTER.swapV3Single(
            PAIRED_LP_TOKEN,
            rewardsToken,
            REWARDS_POOL_FEE,
            _amountIn,
            _amountIn == REWARDS_SWAP_OVERRIDE_MIN 
                ? 0 
                : (_amountOut * (1000 - REWARDS_SWAP_SLIPPAGE)) / 1000,
            address(this)
        ) {
            _rewardsSwapAmountInOverride = 0;
            if (_adminAmt > 0) {
                _processAdminFee(_adminAmt);
            }
            _depositRewards(rewardsToken, IERC20(rewardsToken).balanceOf(address(this)) - _balBefore);
        } catch {
            _rewardsSwapAmountInOverride = _amountIn / 2 < REWARDS_SWAP_OVERRIDE_MIN 
                ? REWARDS_SWAP_OVERRIDE_MIN 
                : _amountIn / 2;

            IERC20(PAIRED_LP_TOKEN).safeDecreaseAllowance(address(DEX_ADAPTER), _amountIn);
            emit RewardSwapError(_amountIn);
        }

Internal Pre-conditions

No response

External Pre-conditions

No response

Attack Path

  1. There are rewards to be processed
  2. The TWAP price to be calculated has a deviation % compared to the current spot price bigger than the slippage (can be purposefully manipulated by Alice by swapping enough to go over the allowed slippage compared to the TWAP price)
  3. Alice stakes and due to the slippage, we go in the catch block where the rewards are stored to be processed for next time, the reward per share is not updated
  4. Alice can now claim her rewards which will update the reward per share based on the rewards that were supposed to be processed last time but weren't due to the slippage revert
  5. Alice got rewards for a period she wasn't staked in which breaks the intended functionality, leads to a profit for Alice and leads to a loss of funds for other stakers

Impact

Users would claim rewards for time that they were not staked in.

PoC

No response

Mitigation

A simple fix would be to make the catch swap with lower slippage protection.