You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Instead of rounding in favor of the protocol (aka rounding up when user buying, rounding down when user selling), the calculation will round down when buying/selling TRUST vote, and round up when buying/selling DISTRUST vote
Internal Pre-conditions
Admin creates a market with no/very small amount of creation cost
The base price of that market is mildly odd, which makes room for rounding
External Pre-conditions
None
Attack Path
The initial market will be: vote of TRUST=1, vote of DISTRUST=1, basePrice = 1.111e18, liquidation parameter = 100, marketFunds = 0 because the admin can create markets with 0 amount of ether cost
User A buy 100 DISTRUST -> _calcCost() = 68083609502231759384 ~ 68.08e18 -> marketFund = 68083609502231759384
User A sell 9 DISTRUST -> _calCost() = 7200065779706726078 ~ 7.2e18 -> marketFund = 68083609502231759384 - 7200065779706726078 = 60883543722525033306
User A sell 11 DISTRUST -> _calCost() = 7200065779706726078 ~ 7.2e18 ->marketFund = 60883543722525033306 - 8548283373986344155= 52335260348538689151
User A sell 80 DISTRUST, drain the whole market -> _calCost() = 52335260348538689152 ~ 52.33e18 -> marketFund = 52335260348538689151 - 52335260348538689152 = -1. Because marketFund is uint256 type, the transaction revert
Instead, user A sell 79 DISTRUST -> _calCost() = 51778371604325108785 ~ 51.78e18 -> marketFund = 52335260348538689151 - 51778371604325108785 = 556888744213580366 -> not reverted
Impact
As a result, user A can't sell the last DISTRUST vote, leading to losing ~0.55e18 ETH
Abundant Orchid Copperhead
Medium
Wrong rounding direction will lead to user can't sell the last votes in the market due to underflow
Summary
Wrong rounding direction in
_calcCost()
will lead to the user not being able to sell the last votes in the market due to underflowRoot Cause
https://github.com/sherlock-audit/2024-12-ethos-update/blob/c3a2b007d0ddfcb476f300f8b766808f0e3e2dfd/ethos/packages/contracts/contracts/ReputationMarket.sol#L1057
This calculation has wrong rounding:
Instead of rounding in favor of the protocol (aka rounding up when user buying, rounding down when user selling), the calculation will round down when buying/selling TRUST vote, and round up when buying/selling DISTRUST vote
Internal Pre-conditions
External Pre-conditions
None
Attack Path
TRUST=1
, vote ofDISTRUST=1
,basePrice = 1.111e18
,liquidation parameter = 100
,marketFunds = 0
because the admin can create markets with 0 amount of ether cost_calcCost() = 68083609502231759384 ~ 68.08e18
->marketFund = 68083609502231759384
_calCost() = 7200065779706726078 ~ 7.2e18
->marketFund = 68083609502231759384 - 7200065779706726078 = 60883543722525033306
_calCost() = 7200065779706726078 ~ 7.2e18
->marketFund = 60883543722525033306 - 8548283373986344155= 52335260348538689151
_calCost() = 52335260348538689152 ~ 52.33e18
->marketFund = 52335260348538689151 - 52335260348538689152 = -1
. Because marketFund is uint256 type, the transaction revert_calCost() = 51778371604325108785 ~ 51.78e18
->marketFund = 52335260348538689151 - 51778371604325108785 = 556888744213580366
-> not revertedImpact
As a result, user A can't sell the last DISTRUST vote, leading to losing ~0.55e18 ETH
PoC
No response
Mitigation
https://github.com/sherlock-audit/2024-12-ethos-update/blob/c3a2b007d0ddfcb476f300f8b766808f0e3e2dfd/ethos/packages/contracts/contracts/ReputationMarket.sol#L1054-L1058
The text was updated successfully, but these errors were encountered: