Challenge Process

An order can be challenged under specific conditions to ensure the integrity of the transaction. The following details outline the challenge process, the conditions under which an order can be challenged, and the steps involved.

Key Functions

These are the additional key functions in order to ensure a viable challenge process.

challengeMatch

Challenges the results of createMatch by sending LayerZero messages to the destination chain to verify if the user actually received what they asked for.

  • Core Event: ChallengeRaised

  • Callable By: Public

cancelOrder

Allows the wallet that placed the trade to cancel it before createMatch.

  • Core Event: OrderCancelled

  • Callable By: Whoever placed the order (Taker if takerFlag, Maker if makerFlag)

unwindMatch

Allows the maker on the destination chain to unwind the match on the source chain.

  • Core Event: MatchUnwound

  • Callable By: Only Maker

An order can be challenged if and only if: The order is a taker order and the challenge occurs after createMatch but before finalizeMatch.

Challenge Process

Initiating the Challenge

The challengeMatch function is called for the taker order with index i on the source chain. This action starts the challenge process. A LayerZero message is sent to the destination chain. The payload of this message contains detailed information about the taker order i and the source chain.

Locking State

Once the challenge is initiated, the order state, funds, and bond are locked up until the challenge is completed. This ensures that no further actions can be taken on the order while the challenge is being resolved.

Initiating Challenge & Locking Funds

Processing on the Destination Chain

The LayerZero message arrives on the destination chain. The destination chain then checks the following cases:

  • No match object: If there is no match object for the order, the order is automatically canceled, and challenge.result is set to true.

  • Bad order: If the order has incorrect details such as the wrong asset, source link, address, or amount, challenge.result is set to true.

  • Order already paid out: If the order was correct and has already been paid out, challenge.result remains false.

  • Taker-to-Taker case: If the order is between two takers, and the order has been created but not yet paid out, the system will trigger finalizeMatch. If finalizeMatch fails, challenge.result is set to true; otherwise, it remains false.

finalizeMatch triggered successfully - challenge.match set to false

Returning the Result

After evaluating the cases, the destination chain automatically triggers an lzSend back to the source chain. The source chain receives the result of the challenge in challenge.result.

Handling the Result

If challenge.result is true:

  • Funds are returned to the taker.

  • The bond is taken from the guarantor and distributed, with 90% going to whoever initiated the challenge and 10% to the developers as a tithe.

challenge.result set to true - Funds reverted & bond seized

If challenge.result is false:

  • Nothing happens, but the order cannot be challenged again.

challenge.result set to false - Transaction proceeds as intended

This process ensures that orders are correctly validated and any discrepancies are addressed through a structured and transparent challenge mechanism.


Additional Cases

Unwinding

Unwinding: The wallet to which the match is addressed (the maker) can call unwindMatch after createMatch but before finalizeMatch. This action resets the order to its state before createMatch. As a result:

Funds are returned to the taker, the bond is returned to the guarantor and no fees are collected.

Expiration/Cancelation

Expiration/Cancelation: If an order is canceled or expires, the createMatch function will fail. Once a match is created, an order cannot expire. It must either be filled, unwound, or challenged.

Taker <- -> Taker

If a market maker places a high priority on security, they have the option to assume the role of a taker.

Matching Process:

The guarantor matches the taker and the maker by calling createMatch on the source chain. Funds are pulled from the guarantor (typically around 10% of the taker's size) and funds are pulled from the taker.

Execution:

The maker pays the taker through executeMatch on the destination chain. Funds are then moved from the maker to the taker via the contract.

Finalization:

The guarantor (or maker) waits for a period greater than the min_block_stability. The guarantor (or maker) then pays the maker and returns the bond with interest by calling finalizeMatch on the source chain. Funds are then released to the maker and the bond plus a fee is sent to the guarantor.

Last updated