40,000 USDC
View results
Submission Details
Severity: medium

Dishonest party can force the other party to receive fewer funds than expected

Summary

The buyer or seller can act dishonestly and force the other party to receive fewer funds than expected due to unnecessarily initiating a dispute.

Vulnerability Details

If the buyer and the seller end up in a dispute, an arbiter is able to resolve the dispute by calling the resolveDispute function in the Escrow contract. For the arbitration services, the arbiter receives a pre-configured fee (i_arbiterFee), which is deducted from the escrowed funds and transferred to the arbiter's address (i_arbiter).

However, any party (buyer and seller) can initiate a dispute by calling the initiateDispute function, even if there's no legitimate reason for a dispute. The initiator of the dispute could act in a malicious way to cause the other party to receive fewer funds than expected (due to the required arbitration by the arbiter and thus the deduction of the arbiter fee).

For instance, after delivering the goods (e.g., audit report) to the buyer by the seller, the buyer could initiate a dispute, requiring arbitration by the arbiter and thus lowering the payout to the seller.

Escrow.resolveDispute

109: function resolveDispute(uint256 buyerAward) external onlyArbiter nonReentrant inState(State.Disputed) {
110: uint256 tokenBalance = i_tokenContract.balanceOf(address(this));
111: uint256 totalFee = buyerAward + i_arbiterFee; // Reverts on overflow
112: if (totalFee > tokenBalance) {
113: revert Escrow__TotalFeeExceedsBalance(tokenBalance, totalFee);
114: }
115:
116: s_state = State.Resolved;
117: emit Resolved(i_buyer, i_seller);
118:
119: if (buyerAward > 0) {
120: i_tokenContract.safeTransfer(i_buyer, buyerAward);
121: }
122: if (i_arbiterFee > 0) {
123: i_tokenContract.safeTransfer(i_arbiter, i_arbiterFee);
124: }
125: tokenBalance = i_tokenContract.balanceOf(address(this));
126: if (tokenBalance > 0) {
127: i_tokenContract.safeTransfer(i_seller, tokenBalance);
128: }
129: }

Impact

The "winner" of the resolved dispute receives fewer funds due to the deduction of the arbiter fee.

Tools Used

Manual Review

Recommendations

Consider collecting the arbiter fee from both parties (buyer and seller) at the beginning of the escrow, and in case of a dispute, collect the fee from the losing party and return the arbiter fee to the winning party. For more details and inspiration, see the escrow_solidity repository by Shubham Chaudhary

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.