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

Division by Zero Vulnerability in SolidlyV2AMO.sol Leading to Denial of Service #2

Open
CipherHawk0 opened this issue Oct 11, 2024 · 1 comment

Comments

@CipherHawk0
Copy link

Summary

The missing zero-check on boostReserve in the _validateSwap function will cause a division by zero error for users, as an attacker can manipulate the BOOST-USD liquidity pool to set boostReserve to zero and trigger the error, resulting in a denial of service.

Root Cause

In SolidlyV2AMO.sol, the _validateSwap function lacks a zero-check on boostReserve before performing division, leading to a potential division by zero error.

Relevant Code Snippet:
function _validateSwap(bool boostForUsd) internal view override {
(uint256 boostReserve, uint256 usdReserve) = getReserves();
if (boostForUsd && boostReserve >= usdReserve)
revert InvalidReserveRatio({ratio: (FACTOR * usdReserve) / boostReserve});
if (!boostForUsd && usdReserve >= boostReserve)
revert InvalidReserveRatio({ratio: (FACTOR * usdReserve) / boostReserve});
}

Internal pre-conditions

1.The boostReserve variable in the BOOST-USD pool is zero.

External pre-conditions

1.An attacker manipulates the BOOST-USD liquidity pool to reduce boostReserve to zero by swapping out all BOOST tokens.

Attack Path

1.Attacker swaps all BOOST tokens out of the BOOST-USD pool, setting boostReserve to zero.
2.User calls the mintSellFarm or unfarmBuyBurn function.
3.The function internally calls _validateSwap, which attempts to compute (FACTOR * usdReserve) / boostReserve.
4,Since boostReserve is zero, a division by zero error occurs, causing the transaction to revert.
5.As a result, users cannot execute critical AMO functions, leading to a denial of service.

Impact

The users cannot execute mintSellFarm and unfarmBuyBurn functions, leading to a denial of service in maintaining the BOOST token's peg. The protocol's ability to perform AMO operations is hindered until the issue is resolved.

PoC

To demonstrate the vulnerability, follow these steps:

1.Setup:
Deploy the SolidlyV2AMO contract with appropriate parameters.
Ensure the BOOST-USD pool exists and is connected to the contract.

2.Manipulate Pool Reserves:
An attacker uses a large amount of USD tokens to swap for all available BOOST tokens in the pool.
This action drains BOOST tokens from the pool, setting boostReserve to zero.

3.Trigger the Vulnerability:
-A user calls the mintSellFarm function:
solidlyV2AMO.mintSellFarm();

-The function internally calls _validateSwap, which then calls getReserves:
(uint256 boostReserve, uint256 usdReserve) = getReserves();

-Since boostReserve is zero, the following division causes a division by zero error:
(FACTOR * usdReserve) / boostReserve

4.Result:
The transaction reverts due to the division by zero.
The user is unable to perform the intended AMO operation.

Mitigation

-->Add a zero-check for boostReserve in the _validateSwap function to prevent division by zero:

function _validateSwap(bool boostForUsd) internal view override {
(uint256 boostReserve, uint256 usdReserve) = getReserves();
if (boostReserve == 0) revert InvalidReserveRatio({ratio: 0});
if (boostForUsd && boostReserve >= usdReserve)
revert InvalidReserveRatio({ratio: (FACTOR * usdReserve) / boostReserve});
if (!boostForUsd && usdReserve >= boostReserve)
revert InvalidReserveRatio({ratio: (FACTOR * usdReserve) / boostReserve});
}

-->Explanation:
-By checking if boostReserve is zero and reverting early, we prevent the division by zero error.
-The InvalidReserveRatio error is emitted with a ratio of zero for clarity.

-->Additional Recommendations:
1.Validate Reserves: Ensure both boostReserve and usdReserve are non-zero before performing operations dependent on them.

2.Mitigate Pool Manipulation:
-Implement mechanisms to prevent or reduce the impact of pool reserve manipulation, such as using time-weighted average prices (TWAP).
-Use robust oracle systems to fetch reserve data.

3.Enhance Error Handling:
-Provide descriptive error messages to aid in debugging and monitoring.
-Consider emitting events when critical conditions like zero reserves are detected.

-->By implementing the recommended fix and additional safeguards, the contract can prevent this issue and maintain reliable AMO operations.

@mz8t
Copy link

mz8t commented Oct 13, 2024

The initial condition is not valid: the Boost reserve cannot be zero since we are using xyz-type pools
( xyz pools are native in v2, and for the version/audit we are using full-range pools in v3 )

Extending the AMO to finite ranges actually requires more tools!

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

2 participants