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
Incremental Cost Calculation for Voting Markets Using LMSR"
Summary
In the current implementation of the buyVotes function within the smart contract, the process for purchasing votes does not properly account for the incremental increase in price as more votes are bought. The contract currently calculates the cost for a given number of votes (e.g., 8 votes) as if the price for all the votes is fixed, which leads to inaccurate cost calculations, particularly in markets where the price of votes increases as more votes are bought. This report identifies the issue, explains why it occurs, and provides a recommended solution to correct the logic.
The primary issue identified in the buyVotes function is that users are paying the same price for each vote, even though the expected behavior (according to the LMSR pricing model) is that the price should increase as more votes are bought.
Root Cause
Simplified Cost Calculation: The function _calcCost computes the cost for purchasing the total number of votes (e.g., 8 votes) without taking into account how the market conditions change with each additional vote purchased.
Fixed Price Assumption: The price is treated as constant for all votes, ignoring the fact that the cost per vote typically increases as more votes are purchased. This results in a miscalculation of the total cost, as the price is not adjusted to reflect the updated state of the market after each vote purchase.
LMSR is wrong
The relevant function used for cost calculation is _cost(), which implements the LMSR formula. This formula computes the cost based on the current number of "yes" and "no" votes, and the liquidity parameter (b). However, the calculation is done for the total number of votes, rather than incrementally for each vote as it is purchased.
The original code calculates the total cost by considering the initial state and the final state using the LMSR formula, without breaking it down into individual vote increments.
Incorrect Pricing: The primary impact of this issue is that users will be able to purchase more votes than they can afford. This is because the contract assumes the price is fixed and does not adjust for the increasing price of votes. As a result, users may be charged less than they should be, and the market may not receive the correct amount of funds for the votes purchased.
Market Inaccuracy: The market state will not be updated correctly when multiple votes are bought. This means that the overall liquidity of the market is not accurately reflected, which could lead to issues with market balance, such as incorrect vote distribution and a mismatch between the number of votes bought and the available liquidity.
Potential Exploitation: In some scenarios, this could lead to users exploiting the pricing logic by purchasing a larger number of votes for less than the true cost, impacting the fairness and integrity of the vote-buying system.
PoC
Problem
You want to calculate the price of each individual vote and then sum them up. For each vote added, the price should be recalculated, as the price of votes changes with each increment.
Current Approach in Original Code
The original code calculates the cost between two states (the initial and the final) using the LMSR formula. This is done in a single calculation, not accounting for the incremental change in price for each vote.
Desired Approach
Instead of calculating the price in one go, we want to calculate the price for each vote individually and then accumulate the cost over all votes.
Steps in the Proof of Concept
Initialize starting state:
Begin with 0 yesVotes and 0 noVotes.
For each vote:
For every vote, you need to calculate the price change based on the current state (i.e., the number of yesVotes and noVotes at that point).
Accumulate cost:
After calculating the price for a vote, add it to the total cost.
Repeat until all votes are processed:
Each time you add a new vote, you need to recalculate the price based on the new number of yesVotes and noVotes.
Example Breakdown
Variables:
yesVotes: Number of "yes" votes.
noVotes: Number of "no" votes.
cost: Total accumulated cost.
Process:
Start with 0 votes:
yesVotes = 0
noVotes = 0
cost = 0
For each vote (i.e., vote 1, vote 2, ..., vote N):
For vote 1: Calculate the cost for 1 "yes" vote (yesVotes = 1 and noVotes = 0).
Use LMSR to calculate the price of 1 "yes" vote.
Add the calculated price to the total cost.
For vote 2: Now calculate the cost for 1 "yes" and 1 "no" vote (yesVotes = 1 and noVotes = 1).
Use LMSR to calculate the price with this new state.
Add this price to the total cost.
Repeat the process for each subsequent vote.
Result: The total cost will be the sum of the prices calculated for each individual vote.
Mitigation
No response
The text was updated successfully, but these errors were encountered:
Unique Currant Sheep
High
Incremental Cost Calculation for Voting Markets Using LMSR"
Summary
In the current implementation of the buyVotes function within the smart contract, the process for purchasing votes does not properly account for the incremental increase in price as more votes are bought. The contract currently calculates the cost for a given number of votes (e.g., 8 votes) as if the price for all the votes is fixed, which leads to inaccurate cost calculations, particularly in markets where the price of votes increases as more votes are bought. This report identifies the issue, explains why it occurs, and provides a recommended solution to correct the logic.
The primary issue identified in the buyVotes function is that users are paying the same price for each vote, even though the expected behavior (according to the LMSR pricing model) is that the price should increase as more votes are bought.
Root Cause
Simplified Cost Calculation: The function _calcCost computes the cost for purchasing the total number of votes (e.g., 8 votes) without taking into account how the market conditions change with each additional vote purchased.
Fixed Price Assumption: The price is treated as constant for all votes, ignoring the fact that the cost per vote typically increases as more votes are purchased. This results in a miscalculation of the total cost, as the price is not adjusted to reflect the updated state of the market after each vote purchase.
LMSR is wrong
The relevant function used for cost calculation is _cost(), which implements the LMSR formula. This formula computes the cost based on the current number of "yes" and "no" votes, and the liquidity parameter (b). However, the calculation is done for the total number of votes, rather than incrementally for each vote as it is purchased.
The original code calculates the total cost by considering the initial state and the final state using the LMSR formula, without breaking it down into individual vote increments.
https://github.com/sherlock-audit/2024-12-ethos-update/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L440-L497
Internal Pre-conditions
No response
External Pre-conditions
No response
Attack Path
No response
Impact
Incorrect Pricing: The primary impact of this issue is that users will be able to purchase more votes than they can afford. This is because the contract assumes the price is fixed and does not adjust for the increasing price of votes. As a result, users may be charged less than they should be, and the market may not receive the correct amount of funds for the votes purchased.
Market Inaccuracy: The market state will not be updated correctly when multiple votes are bought. This means that the overall liquidity of the market is not accurately reflected, which could lead to issues with market balance, such as incorrect vote distribution and a mismatch between the number of votes bought and the available liquidity.
Potential Exploitation: In some scenarios, this could lead to users exploiting the pricing logic by purchasing a larger number of votes for less than the true cost, impacting the fairness and integrity of the vote-buying system.
PoC
Problem
You want to calculate the price of each individual vote and then sum them up. For each vote added, the price should be recalculated, as the price of votes changes with each increment.
Current Approach in Original Code
The original code calculates the cost between two states (the initial and the final) using the LMSR formula. This is done in a single calculation, not accounting for the incremental change in price for each vote.
Desired Approach
Instead of calculating the price in one go, we want to calculate the price for each vote individually and then accumulate the cost over all votes.
Steps in the Proof of Concept
Initialize starting state:
Begin with 0 yesVotes and 0 noVotes.
For each vote:
For every vote, you need to calculate the price change based on the current state (i.e., the number of yesVotes and noVotes at that point).
Accumulate cost:
After calculating the price for a vote, add it to the total cost.
Repeat until all votes are processed:
Each time you add a new vote, you need to recalculate the price based on the new number of yesVotes and noVotes.
Example Breakdown
Variables:
yesVotes: Number of "yes" votes.
noVotes: Number of "no" votes.
cost: Total accumulated cost.
Process:
Start with 0 votes:
yesVotes = 0
noVotes = 0
cost = 0
For each vote (i.e., vote 1, vote 2, ..., vote N):
For vote 1: Calculate the cost for 1 "yes" vote (yesVotes = 1 and noVotes = 0).
Use LMSR to calculate the price of 1 "yes" vote.
Add the calculated price to the total cost.
For vote 2: Now calculate the cost for 1 "yes" and 1 "no" vote (yesVotes = 1 and noVotes = 1).
Use LMSR to calculate the price with this new state.
Add this price to the total cost.
Repeat the process for each subsequent vote.
Result: The total cost will be the sum of the prices calculated for each individual vote.
Mitigation
No response
The text was updated successfully, but these errors were encountered: