Skip to content

Latest commit

 

History

History
96 lines (67 loc) · 2.84 KB

File metadata and controls

96 lines (67 loc) · 2.84 KB

Main Honeysuckle Tarantula

High

ProtocolFee for selling in ReputationalMarket should be deducted from the buyer's proceeds received, not from the balance of the protocol

Summary

Let's consider the function sellVotes.

function sellVotes(
    uint256 profileId,
    bool isPositive,
    uint256 amount
  ) public whenNotPaused activeMarket(profileId) nonReentrant {
    _checkMarketExists(profileId);

    // calculate the amount of votes to sell and the funds received
    (
      uint256 votesSold,
      uint256 fundsReceived,
      ,
      uint256 protocolFee,
      uint256 minVotePrice,
      uint256 maxVotePrice
    ) = _calculateSell(markets[profileId], profileId, isPositive, amount);

    // update the market state
    markets[profileId].votes[isPositive ? TRUST : DISTRUST] -= votesSold;
    votesOwned[msg.sender][profileId].votes[isPositive ? TRUST : DISTRUST] -= votesSold;

    // apply protocol fees
    applyFees(protocolFee, 0, profileId);

    // send the proceeds to the seller
    _sendEth(fundsReceived);
    // tally market funds
    marketFunds[profileId] -= fundsReceived;
    emit VotesSold(
      profileId,
      msg.sender,
      isPositive,
      votesSold,
      fundsReceived,
      block.timestamp,
      minVotePrice,
      maxVotePrice
    );
    _emitMarketUpdate(profileId);
  }

Let's consider the function sellVotes.

This function has two variables that are responsible for the number of ether. fundsReceived - the amount for which all votes are sold. The protocol sends this amount to the seller.

protocolFee - protocol commission from the sale. It goes to protocolFeeAddress.

However, protocolFee must be subtracted from fundsReceived, otherwise it violates the counting of all funds on the contract, namely there is a miscalculation between marketFunds and the actual amount of eth on the contract.

Let's look at an example. Let there be 200 eth on the contract. MarketFunds = 200. User sells votes for 100 ETH (fundsReceived = 100ETH. ProtocolFee = 5 ETH.).

Thus, after the function is executed, marketFunds = 200 - fundsReceived = 100. However, there will be only 95 on the contract. Since 100 will go to the buyer and 5 to the protocolFeeAddress.

Thus, after this, calling the withdrawGraduatedMarketFunds function will DOS due to lack of funds.

Root Cause

ProtocolFee should be subtracted from fundsReceived. Roughly speaking - the user should pay the commission, not the protocol.

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

No response

Impact

  • DoS functions withdrawGraduatedMarketFunds.
  • protocol loses commissions (loss of funds)

PoC

No response

Mitigation

fundsReceived -= protocolFee