Main Honeysuckle Tarantula
Medium
Consider the withdrawGraduatedMarketFunds
function. This function withdraws marketFunds eth from the contract.
However, if there is no such amount of ETH on the contract, the function will not work.
function withdrawGraduatedMarketFunds(uint256 profileId) public whenNotPaused {
address authorizedAddress = contractAddressManager.getContractAddressForName(
"GRADUATION_WITHDRAWAL"
);
if (msg.sender != authorizedAddress) {
revert UnauthorizedWithdrawal();
}
_checkMarketExists(profileId);
if (!graduatedMarkets[profileId]) {
revert MarketNotGraduated();
}
if (marketFunds[profileId] == 0) {
revert InsufficientFunds();
}
_sendEth(marketFunds[profileId]);
emit MarketFundsWithdrawn(profileId, msg.sender, marketFunds[profileId]);
marketFunds[profileId] = 0;
}
Now let's look at how market funds are changing.
- marketFunds is assigned an initial value in
_createMarket
.
marketFunds[profileId] = initialLiquidityRequired;
- marketFunds is increases when
buyVotes
is purchased
marketFunds[profileId] += fundsPaid;
- marketFunds [decreases](https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L522 when
sellVotes
are sold.
marketFunds[profileId] -= fundsReceived;
However, in the buyVotes
function, marketFunds does not change by the number of eths that are on the contract.
Let's look at what fundsPaid
consists of.
As you can see from the _calculateBuy
function - fundsPaid = priceForShares + protocolFee + donation
while (fundsAvailable >= votePrice) {
fundsAvailable -= votePrice;
fundsPaid += votePrice;
votesBought++;
market.votes[isPositive ? TRUST : DISTRUST] += 1;
votePrice = _calcVotePrice(market, isPositive);
}
fundsPaid += protocolFee + donation;
However, protocolFee is immediately sent to the feeAddress, i.e., it is not stored on the contract. Donation can be instantly output in the withdrawDonations
function
Thus, the actual amount of eth stored on the contract is less than that specified in marketFunds, so the withdrawGraduatedMarketFunds function will not work in extreme cases where there is no oversupply of ether.
ETH that is not stored on the contract is recorded in marketFunds and is assumed to be ETH that is stored on the contract.
Protocol Fee, Donation in buyVotes
should not go into marketFunds
No response
No response
Let initial liquidity be 100. The price per 1 share is 90. User buys 1 share and its msg.value = 100.
So 5 is protocol fee (max 5%), 5 is donation (max 5%), price = 90.
marketFunds = 200. However, the contract will only hold 190, because protocolFee and donation will be withdrawn
- DoS of core function
- incorrect funds calculation
No response
marketFunds = fundsPaid - protocolFee - donation
Or just don't add these variables to fundsPaid in the ‘calculateBuy` function