Stage: Refund

📝 Overview After a trade is marked as FAILURE and the associated scriptTimeout has expired, the final step is for the MPC to refund the locked funds to the user. Once the refund transaction is executed, the MPC finalizes the process by calling the refund() function, submitting the refundTxId to log the transaction on-chain and transition the trade to the REFUNDED stage. Alternatively, if the user has already claimed the refund (e.g., via an external mechanism), the MPC is responsible for detecting this and submitting the corresponding transaction ID using the same function.

Key responsibilities of the MPC during this phase:

  • Executes the refund transaction to return funds to the user.

  • Confirms the refund on-chain via refund().

  • Detects and reports externally claimed refunds by submitting the related transaction ID.

⚠️ Important: This function serves as the final closure of a failed trade, ensuring either the protocol or the user receives their rightful refund, and that off-chain data is synced with on-chain state.

Possible Scenarios

✅ Scenario: Refund Execution After Failure

  • The trade has been marked as FAILURE, and the scriptTimeout has elapsed.

  • The MPC initiates the refund transaction, transferring the locked funds back to the user.

  • After success, the MPC calls refund(), providing the associated refundTxId.

  • The trade progresses to the REFUNDED stage, concluding all activity.

  • A Refunded event is emitted for traceability and record-keeping.

❗ Scenario: Refund Already Claimed by User

  • The trade is in the FAILURE stage and has timed out.

  • The user has already independently claimed the refund.

  • The MPC detects the refund and calls refund() with the already executed refundTxId.

  • The trade is transitioned to REFUNDED and marked as finalized.

  • A Refunded event is emitted for logging.

✅ On Successful Refund: refund()

function refund(bytes32 tradeId, bytes calldata refundTxId, bytes calldata signature) external;

🔐 Permissioned Execution

  • Only callable through the Router contract.

  • The requester must be an authorized MPC Node.

🔎 Trade Stage Validation

  • Ensures trade must be in the FAILURE stage.

  • The scriptTimeout must have passed.

🔑 Signature Verification

  • Uses EIP-712 signing with a domain separator to ensure data integrity and prevents spoofing or tampering.

  • Validates that the signer is an MPC signer for the specified source chain.

🔁 Trade State Transition

  • Updates the trade stage to REFUNDED.

  • Records the provided refundTxId as part of the finalization metadata.

  • Removes the trade from the pending list.

📢 Event Emission

  • Emits a Refunded event signaling trade already refunded and finalized.

Queryable Trade Data

📝 Note After refund is fulfilled, several public view functions become available to query related data and track trade progress. These are essential for frontend rendering, auditability, and off-chain monitoring.

✅ On Successful Refund

🔍 Get Trade Stage

function getCurrentStage(bytes32 tradeId) external view returns (uint256);

Returns the current stage of the trade (e.g., REFUNDED).

🔍 Get Trade Finalization

function getTradeFinalization(bytes32 tradeId) external view returns (TradeFinalization memory);

Returns the finalization details for the trade, including the refundTxId, to support future audits.