Skip to content

Latest commit

 

History

History
72 lines (41 loc) · 3.53 KB

002.md

File metadata and controls

72 lines (41 loc) · 3.53 KB

Joyous Raisin Yak

Medium

Lack of Slippage Control in _buyBack Function Can Lead to Token Losses Due to Market Volatility

Summary

The _buyBack function in AmirX.sol does not implement slippage controls, which could lead to users receiving significantly fewer tokens than expected due to rapid price movement, potentially enabling price manipulation or leading to losses during the buyback process.

Root Cause

In AmirX.sol, the _buyBack() function executes swaps through an aggregator without specifying a minimum output, which exposes it to fluctuations in token value during the buyback process. Additionally, the reliance on a weak ownership check (require(msg.sender == owner)) to authorize buybacks further compromises security.

Example: In AmirX.sol lines 202-230, the _buyBack() function executes swaps without slippage protection. There is no check to ensure that the output received during a swap is above an acceptable minimum.

Internal pre-conditions

  1. No slippage protection is enforced in _buyBack(), allowing the function to proceed regardless of the resulting amount from a swap.
  2. Ownership checks rely on the weak condition require(msg.sender == owner), instead of a more secure role-based permission system.

External pre-conditions

  1. An attacker or market manipulator can influence token prices between the initiation and completion of the _buyBack() function.
  2. The price volatility of the token being swapped can cause a significant deviation from the expected outcome.

Attack Path

  1. User B initiates a buyback, triggering the _buyBack() function.
  2. Attacker A manipulates the price of the token involved in the buyback.
  3. Since there is no slippage control, the _buyBack() proceeds with the manipulated price, resulting in a significantly lower output than expected.

Impact

The lack of slippage control means that tokens involved in a buyback may end up being exchanged at unfavorable rates, leading to user losses. Furthermore, an attacker could repeatedly manipulate prices to exploit buybacks, resulting in ongoing financial losses and undermining the stability of the buyback mechanism.

PoC

function _buyBack(uint256 amount) internal {
    require(msg.sender == owner, "Only owner"); // Weak ownership check

    // No slippage tolerance control
    uint256 received = swapAggregator.swap(amount);
    require(received > 0, "Swap returned zero tokens");
}

### Mitigation

**Introduce Slippage Control**: Add a `minAmountOut` parameter to ensure that the transaction only proceeds if the output is above a specified threshold. This mitigates risks related to price fluctuations and prevents unfavorable trades during the buyback:

```solidity
function _buyBack(uint256 amount, uint256 minAmountOut) internal {
    require(hasRole(BUYBACK_MANAGER_ROLE, msg.sender), "Caller is not authorized to buyback");
    uint256 received = swapAggregator.swap(amount);
    require(received >= minAmountOut, "Received less than minimum slippage amount");
}
Replace Weak Ownership Check: Strengthen ownership controls by utilizing role-based permissions through OpenZeppelin’s AccessControl:

`require(hasRole(BUYBACK_MANAGER_ROLE, msg.sender), "Caller is not authorized to buyback");`

Test Recommendations:

Slippage Testing: Implement test cases to simulate fluctuations in token prices during buyback operations, ensuring the transaction reverts if minAmountOut is not met.
Role-Based Testing: Ensure that only authorized roles (i.e., accounts with BUYBACK_MANAGER_ROLE) can initiate buybacks.