Stage: Confirm Payment & Failure Handling

📝 Overview After the selected PMM submits the payment via makePayment() along with a paymentTxId, the trade progresses to the CONFIRM_PAYMENT stage. During this stage, the MPC is responsible for verifying that the submitted payment was correctly executed according to protocol expectations—this includes validating the amounts, destination chain, and the correctness of the paymentTxId. If the payment is valid, the MPC calls confirmPayment(), advancing the trade to the CONFIRM_SETTLEMENT stage. If validation fails or discrepancies are detected (e.g., incorrect payment amount or malformed paymentTxId), the trade is flagged and transitioned to the WARNING stage, allowing for potential correction or retry.

Key responsibilities of the MPC during this phase:

  • Serves as the final verifier of the payment submitted by the PMM.

  • Performs off-chain validation of the payment’s authenticity, correctness, and cryptographic signature.

  • Advances the trade to the settlement stage or flags it for manual review.

Possible Scenarios

✅ Successful Payment Confirmation

  • The MPC confirms the payment by calling confirmPayment().

  • Trade transitions from CONFIRM_PAYMENT to CONFIRM_SETTLEMENT.

  • A PaymentConfirmed event is emitted to document the confirmation for off-chain monitoring and traceability.

  • Once confirmed, the payment becomes immutable and cannot be re-submitted.

⚠️ Important: This confirmation step is irreversible. Once submitted, the trade cannot return to previous stages, and the recorded paymentTxId is considered final. Only trusted MPC Nodes may perform this action after thorough off-chain verification.

❌ Failure: Invalid Payment

  • If the MPC detects an inconsistency (e.g., wrong amount, wrong chain, malformed paymentTxId), the trade is flagged and transitioned to the WARNING stage.

  • This action opens a retry window for the PMM to resubmit a correct payment before the scriptTimeout expires.

  • The PMM is expected to resolve the issue to allow the trade to proceed.

✅ On Successful Payment Confirmation: confirmPayment()

function confirmPayment(bytes32 tradeId, bytes calldata signature) external;

🔐 Permissioned Execution

  • Only callable through the Router contract.

  • The requester must be an authorized MPC Node.

🔎 Trade Stage Validation

  • Confirms the trade is in the CONFIRM_PAYMENT stage.

  • Ensures the trade has not exceeded the allowed scriptTimeout.

🔑 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

  • Sets the trade stage to CONFIRM_SETTLEMENT.

  • Marks the trade’s paymentTxId as confirmed by MPC.

  • Locks further modifications to the payment.

📢 Event Emission

  • Emits the PaymentConfirmed event, signaling successful payment confirmation to the PMM.

❌ Invalid Payment: report()

function report(bytes32 tradeId, bytes calldata msgError, bytes calldata signature) external;

📝 Note If the MPC identifies any issues with the submitted payment, it may flag the trade by invoking report(). This transitions the trade to the WARNING stage, enabling the PMM to retry the payment submission.

🔐 Permissioned Execution

  • Can only be called through the Router contract.

  • The requester must be an authorized MPC Node.

🔎 Constraints & Behavior

  • The trade must not already be finalized (COMPLETED, FAILURE, or REFUNDED).

  • Reporting at this stage does not require waiting for the scriptTimeout.

⚠️ Valid Reasons to Report Failure

  • Invalid or missing payment data.

  • Incorrect payment amount or destination.

  • Invalid or unrecognized paymentTxId.

🔑 Signature Verification

  • The failure message is signed using EIP-712 format to ensure authenticity.

  • The signer must be a valid MPC signer for the relevant source chain.

🔁 Trade State Transition

  • Logs failure details including msgError and the stage (CONFIRM_PAYMENT) in which the failure occurred.

  • Progress the trade to the WARNING stage, opening the window for retry.

📢 Event Emission

  • Emits a FailureReported event, capturing the failed stage and error details for transparency and monitoring.

Queryable Trade Data

📝 Note After the payment confirmation phase—whether the trade advances to CONFIRM_SETTLEMENT or transitions to FAILURE—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 Payment Confirmation

🔍 Get Trade Stage

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

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

🔍 Get Trade Finalization

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

Returns the finalization details for the trade, including paymentTxId, isConfirmed = true, and other information to support PMM in tracking payment progress and future audits.

❌ Invalid Payment

🔍 Get Trade Stage

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

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

🔍 Get failure details

function getFailureInfo(bytes32 tradeId) external view returns (FailureDetails memory)

Returns error metadata associated with the failed trade, including the stage and reason for the error. Based on this information, the PMM can take appropriate actions, such as retrying the payment.