Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rich Grey Crocodile - Tokens waiting in _rewardsSwapAmountInOverride to be re-tried is not re-tried before setShares in TokenRewards.sol #553

Open
sherlock-admin3 opened this issue Feb 17, 2025 · 0 comments

Comments

@sherlock-admin3
Copy link
Contributor

Rich Grey Crocodile

Medium

Tokens waiting in _rewardsSwapAmountInOverride to be re-tried is not re-tried before setShares in TokenRewards.sol

Vulnerability Details

https://github.com/sherlock-audit/2025-01-peapods-finance/blob/d28eb19f4b39d3db7997477460f9f9c76839cb0c/contracts/contracts/TokenRewards.sol#L292-L319

Whenever the reward tokens come in to TokenRewards.sol:

function _swapForRewards(uint256 _amountIn, uint256 _amountOut, uint256 _adminAmt) internal {
    if (_rewardsSwapAmountInOverride > 0) {
        _adminAmt = (_adminAmt * _rewardsSwapAmountInOverride) / _amountIn;
        _amountOut = (_amountOut * _rewardsSwapAmountInOverride) / _amountIn;
        _amountIn = _rewardsSwapAmountInOverride;
    }
    uint256 _balBefore = IERC20(rewardsToken).balanceOf(address(this));
    IERC20(PAIRED_LP_TOKEN).safeIncreaseAllowance(address(DEX_ADAPTER), _amountIn);
    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);
    }
}

There are some tokens that will be added to the variable _rewardsSwapAmountInOverride due to the fact that it needs to be re-tried since it failed to swap (maybe cause the DEX didn't have enough liquidity etc etc)

However, we can see that setShares does not attempt to re-try the amounts sitting there atleast once.

Impact

  1. Alice is a shareholder of TokenRewards.sol
  2. Rewards come in and it is attempted to be swapped
  3. The swap failed due to lack of liqudity from the DEX, and the token amounts are sent to _rewardsSwapAmountInOverride
  4. Some time passes (and now maybe the DEX has sufficient liquidity)
  5. Bob becomes a shareholder of TokenRewards.sol through setShares

Since setShares does not retry the amounts sitting in _rewardsSwapAmountInOverride atleast once at the start, Bob's shares will now include the value of the rewards, unfairly dilutiing Alice's shares of the rewards.

Recommendation

At the starting of setShares, retry _rewardsSwapAmountInOverride once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant