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

If the arbiter is prevented from receiving the arbiter fee, disputes can not be resolved and funds may be stuck forever

Summary

The Escrow.resolveDispute function transfers the arbiter fee to the arbiter address. If the arbiter address is prevented (e.g., blacklisted) from receiving tokens, disputes can not be resolved, and funds may be stuck forever in the contract.

Vulnerability Details

If the arbiter address i_arbiter is blocklisted for the given token i_tokenContract (e.g., $USDC), and there's a fee configured (i.e., i_arbiterFee is non-zero), the dispute can not be resolved, and funds may be stuck forever in the contract due to the token transfer in line 123 reverting.

Escrow.sol#L123

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

Escrowed funds may be stuck forever in the contract due to the inability to transfer the arbiter fee to the arbiter address in case of a dispute.

Tools Used

Manual Review

Recommendations

Instead of sending the tokens directly to the arbiter while resolving a dispute, consider storing the collected fee in a separate accounting storage variable and have the arbiter claim the fee from the contract.

Moreover, this pattern can be universally applied to all token transfers in the contract to reduce the risk of funds getting stuck in the contract.

Support

FAQs

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