Magic Basil Caterpillar
High
In current ReputationMarket contract logic, marketFunds[profileId] state variable was wrongly updated.Due to which entryprotocolfee+donationfee was wrongly collected twice from contract in 2 different ways.1) directly when buying votes.2)In form of withdrawGraduatedMarketFunds. which will make future transactions revert due to insufficient Eth balance of ReputationMarket, eventually users loss funds.
If users wants to buy votes then they call ReputationMarket::buyVotes function https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L442 Then it internally calls _calculateBuy function which will returns votesBought, fundsPaid, protocolFee,donation,minVotePrice,maxVotePrice https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L451-L459 now let's see _calculateBuy function logic, It internally calls previewFees function to calculate protocolFee,donation and fundsAvailable after deducting protocolFee+donation from msg.value. https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L960 https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L1141-L1153 Then it calculates no of votes user can buy with remaining fundsAvailable and fundsPaid to buy those votes. https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L970-L976 until now fundsPaid = amount used to buy votes. but now we are adding protocolfee+donation to fundsPaid making it,fundsPaid = amount used to buyvotes + protocolFee+donation. https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L978 Then buyVotes function internally calls applyFees function to send protocol fee to protocal and update donationEscrow variable such that profileId owner can withdraw donations. https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L464 https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L1116-L1127 now it updates marketFunds[profileId] += fundsPaid; https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L481 In this whole process, first we are sending protocol fee to protocol and adding donations to donationEscrow[profileId]. and again we are adding fundsPaid to marketFunds[profileId] . marketFunds[profileId] += fundsPaid which equals to marketFunds[profileId] += amount to buy votes +protocolFee+donations.as fundsPaid is wrongly updated to amount to buy votes +protocolFee+donations instead of amount to buy votes. After graduation of a market, user with role GRADUATION_WITHDRAWAL can withdraw marketFunds(marketFunds[profileId]). https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L660-L678 which means protocolFee+donation was collecting twice from the contract which will break accounting of the contract. so user transactions in future will revert due to out of funds(contract not having enough Eth to give to users who sell there votes and while withdrawing GraduatedMarketFunds).
No response
No response
No response
wrongly collecting protocolFee+donation from ReputationMarket twice for every time a user buys votes, which will break accounting of the contract(Eth balance of contract is not enough to pay to users who sell their votes and at time of withdrawing GraduatedMarketFunds in future).so users loss there funds.
No response
modify code here,
https://github.com/sherlock-audit/2024-11-ethos-network-ii/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L481
with this,
marketFunds[profileId] += (fundsPaid-protocolFee-donation);
so that marketFunds[profileId] is correctly updated.