Skip to content

Latest commit

 

History

History
85 lines (57 loc) · 2.78 KB

File metadata and controls

85 lines (57 loc) · 2.78 KB

Fast Khaki Raccoon

Medium

_swapForRewards math is wrong, which would send a bigger fee to the admin

Summary

_swapForRewards wrongly calculates the new amounts using an outdated value, which would cause the admin to receive a higher fee

Root Cause

depositFromPairedLpToken would first reduce _adminAmt, then use it to calculate _amountOut.

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

        uint256 _adminAmt = _getAdminFeeFromAmount(_amountTkn);
        _amountTkn -= _adminAmt;

        // ...

        uint256 _amountOut = _token0 == PAIRED_LP_TOKEN
            ? (_rewardsPriceX96 * _amountTkn) / FixedPoint96.Q96
            : (_amountTkn * FixedPoint96.Q96) / _rewardsPriceX96;

        _swapForRewards(_amountTkn, _amountOut, _adminAmt);

Later it would use the same reduced amount to calculate the new amounts if _rewardsSwapAmountInOverride > 0, not knowing that _amountOut (converted back into _amountIn ) + _adminAmt > _amountIn, which would result in _adminAmt + _amountIn (needed for _amountOut) to be bigger than _rewardsSwapAmountInOverride

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

    function _swapForRewards(uint256 _amountIn, uint256 _amountOut, uint256 _adminAmt) internal {
        if (_rewardsSwapAmountInOverride > 0) {
            _adminAmt = (_adminAmt * _rewardsSwapAmountInOverride) / _amountIn;
            _amountOut = (_amountOut * _rewardsSwapAmountInOverride) / _amountIn;
            _amountIn = _rewardsSwapAmountInOverride;
        }

Internal Pre-conditions

No response

External Pre-conditions

No response

Attack Path

  1. 1k for swap, fee 10%, price - 2 USD
  2. Admin fee = 1k * 10% = 100 fee
  3. Out = 900 / 2 = 450

results: in = 900, fee = 100, out = 450

  1. _rewardsSwapAmountInOverride = 50
  2. admin = 100 * 50 / 900 = 5.55
  3. out = 450 * 50 / 900 = 25
  4. in = 50

As we can see out _rewardsSwapAmountInOverride is 50, however we need 50 for the 25 out (as price is 2 USD), and out fee is 5.5, which is outside this 50, and not 10% of it, but 11%, which is a 10% increase in fee.

Impact

Admin receives a higher fee Math is wrong Fee is outside the prev. _rewardsSwapAmountInOverride value, resulting in a bigger swap and a higher fee.

PoC

No response

Mitigation

Add the _adminAmt to _amountIn when in the if:

        if (_rewardsSwapAmountInOverride > 0) {
            _amountIn += _adminAmt;
            _adminAmt = (_adminAmt * _rewardsSwapAmountInOverride) / _amountIn;
            _amountOut = (_amountOut * _rewardsSwapAmountInOverride) / _amountIn;
            _amountIn = _rewardsSwapAmountInOverride;
        }