Skip to content

Latest commit

 

History

History
50 lines (40 loc) · 1.83 KB

File metadata and controls

50 lines (40 loc) · 1.83 KB

Urban Obsidian Jay

High

Initial Liquidity Deposited as Part of Trading Could Be Consumed.

Summary

In L1057, the rounding mode is not optimal. https://github.com/sherlock-audit/2024-12-ethos-update/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L1057

Root Cause

In the _calcCost() function, the cost is rounded down for TRUST and rounded up for DISTRUST. If there are more calls to buyVotes() than sellVotes() for TRUST, or fewer calls buyVotes() than sellVotes() for DISTRUST, the initial liquidity is decreased.

Internal pre-conditions

N/A

External pre-conditions

N/A

Attack Path

  1. Buy one TRUST vote n times and then sell all these votes at once.
  2. Buy n DISTRUST votes at once and then sell these one by one n times. At this point the marketFunds is decreased by approximately n-1. The expected value of a random number in the range [0,1) is 0.5. Thus, the decreased value can be approximated as: 0.5 * (TRUST_buytimes - TRUST_selltimes) - 0.5 * (DISTRUST_buytimes - DISTRUST_selltimes) = (n-1). This is not an exact value, but n could be larger as neccesary. Thus the initial Liquidity could be consumed.

Impact

In Summary:

The contract must never pay out the initial liquidity deposited as part of trading. The only way to access those funds is to graduate the market.

However, the initial liquidity could be consumed.

PoC

    function _calcCost(
        ...
    ) private pure returns (uint256 cost) {
        ...
        cost = positiveCostRatio.mulDiv(
            market.basePrice,
            1e18,
1057        isPositive ? Math.Rounding.Floor : Math.Rounding.Ceil
        );
    }
    The

Mitigation

Consider adjusting the rounding mode in the calculation of cost separately when buying and selling to avoid unintended consumption of the initial liquidity.