40,000 USDC
View results
Submission Details
Severity: medium

Premature dispute initiation by `Seller` in `Escrow.sol` contract

Summary

The initiateDispute function in the Escrow contract is designed to be called by either the buyer or the seller when the contract is in the Created state. However, if the seller initiates a dispute before the buyer has confirmed receipt, it could potentially lead to unexpected behavior and disrupt the normal workflow of the contract.

Vulnerability Details

The initiateDispute function is designed to allow either the buyer or the seller to initiate a dispute when the contract is in the Created state. It is protected by the onlyBuyerOrSeller and inState(State.Created) modifiers. However, there is no explicit check in the function to prevent the seller from initiating a dispute before the buyer has confirmed receipt. If the seller initiates a dispute prematurely, it could disrupt the normal workflow of the contract and potentially lead to unexpected behavior.

Code Snippet

function initiateDispute() external onlyBuyerOrSeller inState(State.Created) {
if (i_arbiter == address(0)) revert Escrow__DisputeRequiresArbiter();
s_state = State.Disputed;
emit Disputed(msg.sender);
}

Impact

If the seller initiates a dispute before the buyer has confirmed receipt, it could disrupt the normal workflow of the contract and potentially lead to unexpected behavior. This could potentially result in a loss of trust in the platform and could complicate the resolution of disputes.

Tools Used

Manual code review

Recommendations

To mitigate this potential issue, it is recommended to add additional checks in the initiateDispute function to ensure that it cannot be called by the seller before the buyer has confirmed receipt. This could be implemented by adding a boolean state variable that tracks whether the buyer has confirmed receipt, and checking this variable at the beginning of the function, like so:

bool private receiptConfirmed = false;
function initiateDispute() external onlyBuyerOrSeller inState(State.Created) {
require(receiptConfirmed || msg.sender == i_buyer, "Seller cannot initiate dispute before buyer has confirmed receipt");
if (i_arbiter == address(0)) revert Escrow__DisputeRequiresArbiter();
s_state = State.Disputed;
emit Disputed(msg.sender);
}

This would ensure that the initiateDispute function cannot be called by the seller before the buyer has confirmed receipt, thereby preventing the potential issues described above.

Support

FAQs

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