Stage: PMM Selection & Failure Handling
📝 Overview
The SELECT_PMM
stage takes place after the MPC
has confirmed the deposit. At this stage, the Solver
is responsible for selecting the optimal PMM
(Professional Market Maker) based on user RFQ
constraints. If no valid PMM is matched before the scriptTimeout
, the MPC
will mark the trade as FAILURE
.
Key responsibilities of the Solver during this phase:
Selecting the optimal PMM that offers a valid quote based on the user's RFQ (
minAmountOut
).Verifying the PMM's quote is still valid (not expired) and corresponds to a valid pre-signed settlement.
Submitting proof (signed data) from both the selected PMM and the user to validate mutual agreement on trade terms.
Ensuring protocol and affiliate fees are within acceptable bounds and the final amount out meets user expectations.
Possible Scenarios
✅ Successful PMM Selection:
If the Solver provides a valid PMM quote and all signature verifications pass, the protocol:
Validates and stores the selected PMM's data.
Calculates and locks protocol/affiliate fees.
Emits a
SelectedPMM
event.Advances the trade to the
MAKE_PAYMENT
stage.
❌ No Match / Timeout:
If no suitable PMM is selected before the timeout (scriptTimeout
), the trade is considered stalled.
The
MPC
may later mark the trade asFailure
, halting further progression.After the full grace period (
scriptTimeout
), the trade becomes eligible for a refund.No settlement or payment occurs, and user funds are returned through the protocol's refund path.
✅ On PMM match: selectPMM()
selectPMM()
function selectPMM(bytes32 tradeId, PMMSelection calldata info) external;
🔐 Permissioned Execution
Can only be called through the
Router
contract.The requester must be the same authorized
Solver
who originally submitted the trade.Prevents unauthorized or malicious PMM selection attempts.
🔎 Trade Stage Validation
Ensures the trade is currently at the
SELECT_PMM
stage.Prevents out-of-sequence execution and misuse of expired trade sessions.
Ensures the selected PMM exists within the pre-signed settlement data (
settlementPresigns
).
⏱️ Timeout & Expiry Checks
Confirms the trade has not already timed out (
tradeTimeout
).Validates
tradeTimeout
and confirms it does not exceed the originalscriptTimeout
.Verifies the PMM's signature has not expired (
sigExpiry
).
💸 Fee Validation
Calculates protocol (
pFeeAmount
) and affiliate (aFeeAmount
) fees based on the quotedamountOut
.Ensures that
amountOut - totalFeeAmount
meets or exceeds the user-definedminAmountOut
.Reverts with
InsufficientQuoteAmount
if the quote is below expectations.
🔑 Signature Verification
Validates the selected PMM’s signature by hashing relevant fields and verifying against the PMM signer.
Checks that the selected PMM address matches the address in the pre-signed settlement proof.
Validates the user’s RFQ signature to confirm agreement on minAmountOut, tradeTimeout, and affiliate details.
🔁 Trade State Transition
Saves the calculated
totalFeeAmount
,pFeeAmount
, andaFeeAmount
in the trade’s fee record.Records the selected PMM’s information on-chain.
Advances the trade to the next stage (e.g.
MAKE_PAYMENT
).
📢 Event Emission
Emits the
SelectedPMM
event which signals the successful PMM selection and allows off-chain systems to initiate payment processes.
❌ No PMM match & Timeout: report()
report()
function report(bytes32 tradeId, bytes calldata msgError, bytes calldata signature) external;
📝 Note
If no suitable PMM is selected 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
The trade must not already be finalized (
COMPLETED
,FAILURE
, orREFUNDED
).This is the stage where reporting does strictly require a timeout delay (
scriptTimeout
).
⚠️ Valid Reasons to Report Failure
No valid PMM is selected 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 (SELECT_PMM
).The trade is immediately marked as
FAILURE
, halting any further progression.
🧾 Refund Behavior
Once the
scriptTimeout
elapses, the user’s funds are eligible for automatic refund.
📢 Event Emission
Emits a
FailureReported
event, including failed stage, error reference, which enables public inspection and monitoring of failed trades.
Queryable Trade Data
📝 Note
After the pmm selection phase—whether the trade advances to MAKE_PAYMENT
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 PMM Selection
🔍 Get Trade Stage
function getCurrentStage(bytes32 tradeId) external view returns (uint256);
Returns the current stage of the trade (e.g., MAKE_PAYMENT
).
🔍 Get PMM Selection
function getPMMSelection(bytes32 tradeId) external view returns (PMMSelection memory);
Returns a struct containing the user's RFQ and the selected PMM's quote.
❌ On No Matching PMM & 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.