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

Jolly Denim Mouse - Missing Slippage checks in buyVotes function #139

Open
sherlock-admin4 opened this issue Dec 30, 2024 · 0 comments
Open

Comments

@sherlock-admin4
Copy link
Contributor

Jolly Denim Mouse

Medium

Missing Slippage checks in buyVotes function

Summary

The buyVotes function fails to validate that the final adjusted vote count (currentVotesToBuy) remains above the specified minVotesToBuy after the dynamic adjustment loop. This allows a purchase to complete with fewer votes than the user expects, violating the slippage protection intended by the minVotesToBuy parameter.

Root Cause

In the buyVotes function, while there is a minVotesToBuy parameter, it only validates that the ETH provided (msg.value) is sufficient to cover the cost of minVotesToBuy votes::
https://github.com/sherlock-audit/2024-12-ethos-update/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L440

uint256 pricePerVote = votesToSell > 0 ? proceedsBeforeFees / votesToSell : 0;
if (pricePerVote < minimumVotePrice) {
    revert SellSlippageLimitExceeded(minimumVotePrice, pricePerVote);
}

However, this does not ensure that the final adjusted vote count (currentVotesToBuy) after the loop still satisfies minVotesToBuy. If the buyer initially specifies a high maxVotesToBuy, the dynamic adjustment loop may decrement the votes to a value below minVotesToBuy due to insufficient funds.

while (totalCostIncludingFees > msg.value) {
    currentVotesToBuy--;
    (purchaseCostBeforeFees, protocolFee, donation, totalCostIncludingFees) = _calculateBuy(
        markets[profileId],
        isPositive,
        currentVotesToBuy
    );
}

Here, no validation after loop if currentVotesToBuy >= minVotesToBuy.

Without a subsequent check, it’s possible for currentVotesToBuy to fall below minVotesToBuy, contradicting the user's expectation of receiving at least minVotesToBuy votes.

Internal Pre-conditions

No response

External Pre-conditions

No response

Attack Path

No response

Impact

Users may receive fewer votes than expected

PoC

No response

Mitigation

Add a post-loop validation:

if (currentVotesToBuy < minVotesToBuy) revert SlippageExceeded();
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

1 participant