📑Specification

Perennial's intent system has a light footprint onchain. It uses a few modules ot extend the standard update() functionality of the markets.

Intent Structure

Intents take the form of an EIP-712 signed message. Below is the structure of an intent order:

{
  "amount":            // The size and direction of the order being opened by the taker
                       //       - Positive opens long / Negative opens short
                       //       - The maker will open the opposite side of the order
                       //       - To close, open an order in the opposite direction
  "price":             // The price to execute the order at
  "fee":               // The solver fee, a percentage of the substractive interface fee
  "originator":        // The referral address of the originator of the order (ex. the interface)
  "solver":            // The referral address of the solver of the order (ex. the router)   
  "collateralization": // The minimium collateralization ratio that must be maintained after the order is executed
  "common": {
    "account": // The target account of the message (usually the account on behalf of which the action is being performed)
    "signer":  // EOA signing the message (usually either the account or a delegate of the account)
    "domain":  // ensures the message is unique to a particular protocol version, chain, and verifier
    "nonce":   // per-sender nonce which is automatically cancelled upon validation
    "group":   // per-sender nonce which must be manually cancelled with a GroupCancellation message
    "expiry":  // prevents this message from having the intended effect after a specified timestamp
  }
}

Market - Update()

These signed Intents submitted by a Maker to the intent specific update() function on each market instance.

/// @notice Updates both the long and short positions of an intent order
/// @dev - One side is specified in the signed intent, while the sender is assumed to be the counterparty
///      - The sender is charged the settlement fee
/// @param account The account that is filling this intent (maker)
/// @param intent The intent that is being filled
/// @param signature The signature of the intent that is being filled
function update(address account, Intent calldata intent, bytes memory signature) external nonReentrant whenNotPaused {
    if (intent.fee.gt(UFixed6Lib.ONE)) revert MarketInvalidIntentFeeError();

    verifier.verifyIntent(intent, signature);

    _updateIntent(
        account,
        address(0),
        intent.amount.mul(Fixed6Lib.NEG_ONE),
        intent.price,
        address(0),
        address(0),
        UFixed6Lib.ZERO,
        UFixed6Lib.ZERO,
        true,
        false
    ); // account
    _updateIntent(
        intent.common.account,
        intent.common.signer,
        intent.amount,
        intent.price,
        intent.originator,
        intent.solver,
        intent.fee,
        intent.collateralization,
        false,
        true
    ); // signer
}

See the file here

Intent Verifier

Key to operation of the intent system is the intent verifier. This contract checks the validity of the intent, the signature, and if the signer is approved as a signer on the account.

You can learn more about this module here

Other Modules

Last updated