Stage: Make Payment & Failure Handling
📝 Overview
After a PMM is selected, the trade progresses to the MAKE_PAYMENT
stage. In this phase, the selected PMM is responsible for fulfilling the trade by transferring the committed payment to the user and submitting the associated paymentTxId
. The submission can be performed by either the Solver
or the selected PMM
, ensuring transparent on-chain tracking and auditability. If the PMM
fails to make the payment before scriptTimeout
, the MPC
may mark the trade as FAILURE
.
Key responsibilities of the Solver during this phase:
The Solver acts as a coordinator during this stage, with responsibilities that include:
Initiating Payment Submission (Optional): While the selected PMM is primarily responsible for making the payment, the Solver may assist by submitting it if necessary.
Monitoring PMM Activity: Tracks the PMM’s behavior to ensure payment is submitted within the designated timeframe.
Key responsibilities of the PMM during this phase:
The selected PMM is the main executor during this stage, responsible for:
Fulfilling the Payment: Transfers the committed funds to the user using an approved settlement method.
Submitting
paymentTxId
: Publicly announces the payment by submitting a verifiable transaction ID.Signature Authentication: Signs the payment bundle with a valid cryptographic signature to guarantee authenticity and integrity.
Acting Within
tradeTimeout
: Must complete the payment before the user-defined deadline. Delays beyond this threshold may result in rejection by the MPC and potential fund loss.Retrying After Warning: If the payment is marked as failed (e.g., trade is set to WARNING), the PMM can resubmit a corrected payment to recover the trade and avoid penalties.
✅ Successful Payment Submission
The selected PMM (or Solver) submits a valid
paymentTxId
within the permitted window (scriptTimeout
).The trade advances to the next stage (e.g.
CONFIRM_PAYMENT
).A
MadePayment
event is emitted for traceability.Multiple submissions are allowed within the valid timeframe.
Any previous failure state (e.g.,
WARNING
) is cleared.
⚠️ Important: The PMM is responsible for submitting a valid payment before the user-defined deadline (
tradeTimeout
). While this deadline is not strictly enforced—due to factors like network congestion—a slight delay may be tolerated if it falls within a "safety buffer" agreed upon by theSolver
andMPC
. However, if theMPC
deems the payment too delayed, it may reject confirmation, resulting in permanent loss for the PMM—even if payment was technically fulfilled.
❌ Failure: No Payment Submitted & Timeout
If the
PMM
fails to submit a validpaymentTxId
beforescriptTimeout
, the trade is considered stalled.The
MPC
node may invoke thereport()
function to formally mark the trade as failed.
✅ On Successful Make Payment: makePayment()
makePayment()
function makePayment(BundlePayment memory bundle)
🔐 Permissioned Execution
Can only be called through the
Router
contract.The requester must be either the authorized
Solver
or the selected PMM of the trade.Prevents unauthorized entities from injecting invalid payment data.
🔎 Trade Stage Validation
Ensures the trade is currently in the
MAKE_PAYMENT
orCONFIRM_PAYMENT
stage.Prevents duplicate or late submissions after progression or failure.
Clears previous failure records if it's a valid retry.
⏱️ Timeout & Expiry Checks
Validates the trade has not passed its
scriptTimeout
.Ensures the
signedAt
timestamp is newer than any previous payment submission.
🔑 Signature Verification
Confirms the authenticity of the PMM's signature over the bundle.
Verifies the signer is authorized for the selected PMM.
🔁 Trade State Transition
Advances the trade to the
CONFIRM_PAYMENT
stage.Records the
paymentTxId
and other bundle metadata for MPC verification.Logs the submission time for replay protection.
📢 Event Emission
Emits a
MadePayment
event containing trade metadata, paymentTxId, and bundle information.Facilitates monitoring and validation by off-chain services and the MPC.
❌ No Payment & Timeout: report()
report()
function report(bytes32 tradeId, bytes calldata msgError, bytes calldata signature) external;
📝 Note
If the PMM
fails to make the payment before the timeout (scriptTimeout
), the trade enters a finalized state. This failure scenario can be reported by the MPC
once the timeout has been reached.
🔐 Permissioned Execution
Can only be called through the
Router
contract.The requester must be an authorized
MPC Node
.
🔎 Constraints & Behavior
Ensures the trade is still in a valid stage (
MAKE_PAYMENT
) for reporting.Prevents reporting if the trade is already finalized (
COMPLETED
,FAILURE
, orREFUNDED
).This is the stage where reporting does strictly require a timeout delay (
scriptTimeout
).
⚠️ Valid Reasons to Report Failure
No valid payment submitted by the PMM within the allowed timeout window.
🔑 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
Stores failure details, including
msgError
and the failed stage (MAKE_PAYMENT
).Marks the trade as
FAILURE
, blocking any further updates.
🧾 Refund Behavior
Once
scriptTimeout
elapses and the trade is marked asFAILURE
, the user becomes eligible for a refund.
📢 Event Emission
Emits a
FailureReported
event, including failed stage, error reference, which enables public visibility and monitoring of failed trades.
Queryable Trade Data
📝 Note After the make payment phase—regardless of whether the trade proceeds to CONFIRM_PAYMENT or transitions to FAILURE—several public view functions become available to query related data and monitor trade progress. These are essential for frontend rendering, auditability, and off-chain monitoring.
✅ On Successful Make Payment
🔍 Get Trade Stage
function getCurrentStage(bytes32 tradeId) external view returns (uint256);
Returns the current stage of the trade (e.g., CONFIRM_PAYMENT
).
🔍 Get Trade Finalization
function getTradeFinalization(bytes32 tradeId) external view returns (TradeFinalization memory);
Returns finalization details for the trade, including the paymentTxId
and other relevant information used for MPC validation and future audits.
❌ No Payment & Timeout
🔍 Get Trade Stage
function getCurrentStage(bytes32 tradeId) external view returns (uint256);
Returns the current stage of the trade (e.g., FAILURE
).
🔍 Get failure details
function getFailureInfo(bytes32 tradeId) external view returns (FailureDetails memory)
Returns the error metadata associated with the failed trade, including the stage and reason for failure.