Ripe Sage Ant
High
Variable marketFunds
is incorrectly updated in ReputationMarket.buyVotes()
. Therefore withdrawGraduatedMarketFunds()
will revert. As a result admin can't withdraw ETH from market.
Additionally it voilates stated in Readme:
What properties/invariants do you want to hold even if breaking them has a low/unknown impact?
The vouch and vault contracts must never revert a transaction due to running out of funds.
-In buyVotes() marketFunds
is incorrectly updated. It uses fundsPaid
which consists of "paidPrice" + "fees". Problem is that it only must contain "paidPrice" value without fees.
-In sellVotes() marketFunds
is incorrectly updated. It uses funds after fees are deducted.
Correct way to update is to use purchase amount after fees deducted in buy; and amount before fees deducted in sell.
Sooner or later revert happens, I will describe simpler scenario:
- Suppose protocolFee is 5%, donation is 5%;
initialLiquidity = 0 ETH
. - User executes
buyVotes()
. Purchase amount is 0.9 ETH; protocolFee = 0.05 ETH; donationFee = 0.05 ETH.marketFunds += 1 ETH
, should be 0.9 ETH. - User executes
sellVotes()
to sell bought votes. He receives 0.81 ETH; protocolFee = 0.045 ETH; donationFee = 0.045 ETH.marketFunds = 1 ETH - 0.81 ETH = 0.19 ETH
, should be 0 ETH. - Market is graduated and
withdrawGraduatedMarketFunds()
is called. In case there is balance, donationFee = 0.095 ETH can't be withdrawn; otherwise it will revert with insufficient balance.
So marketFunds
always overestimate real funds, so sooner or later either party loses funds.
- Donation fees can't be withdrawn
- Graduated market funds can't be withdrawn
- It violates Readme because there will be reverts due to running out of funds
No response
Correct way to update is to use purchase amount after fees deducted in buy; and amount before fees deducted in sell.