40,000 USDC
View results
Submission Details
Severity: low
Valid

[M-02] Buyer can decide who is arbiter which can be leveraged against seller

Impact

Escrow.sol#L32-L51

constructor(
uint256 price,
IERC20 tokenContract,
address buyer,
address seller,
-> address arbiter,
uint256 arbiterFee
) {
if (address(tokenContract) == address(0)) revert Escrow__TokenZeroAddress();
if (buyer == address(0)) revert Escrow__BuyerZeroAddress();
if (seller == address(0)) revert Escrow__SellerZeroAddress();
if (arbiterFee >= price) revert Escrow__FeeExceedsPrice(price, arbiterFee);
if (tokenContract.balanceOf(address(this)) < price) revert Escrow__MustDeployWithTokenBalance();
i_price = price;
i_tokenContract = tokenContract;
i_buyer = buyer;
i_seller = seller;
///@audit buyer decides who is arbiter
-> i_arbiter = arbiter;
i_arbiterFee = arbiterFee;
}

Since buyer decides who is the arbiter, arbiter and buyer can always collude to grief seller. Buyer can always set himself as arbiter or address that he is colluding with and grief seller's payment even when his services were satisfactory.

Proof of Concept

Consider the scenario where buyer delays payment after an audit, and so seller calls initiateDispute(). However, since arbiter is buyer himself or another address that is colluding with buyer, they can simply set totalFee to be equal to originally deposited token and transfer all funds back to themselves, resulting in seller losing payment for his services.

Tools Used

Manual Analysis

Recommendation

Instead of allowing buyer to decide on arbiter, arbiter should be a fixed/whitelisted trusted address of a codeHawks staff member, who is impartial. This should be combined with the recommendation suggested in [M-01], where a fixed percentage fee should be assigned to arbiter if ever needed to resolve a dispute instead of allowing buyer to decide on value of i_arbiterFee.

Support

FAQs

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