LogoLogo
  • Overview
    • Introduction
    • Table of Contents
  • Token Information
    • Symmio Foundation
  • Protocol Architecture
    • Protocol Introduction
    • Technical Documentation
      • Building an Application with SYMM
        • Introduction and Diamond Explainer
        • Querying Info from the SYMM Diamond
        • MultiAccount
        • Creating an Account and Depositing Funds
        • Sending a Quote
        • Closing a Quote
        • Instant Trading
          • Instant Login (EOA)
          • Instant Login (Account Abstraction)
          • Sending a Quote (Instant Open)
          • Sending a Quote (Instant Close)
        • Frequently Used Queries
      • Solver Docs
        • Solver Docs (github)
        • Solver Implementation Guide (High Level Overview)
        • Building a Solver on SYMMIO
          • 1. Intent Creation
          • 2. Seeing the Intent
          • 3. Hedging Off-Chain
          • 4. Opening/Closing a Position On-Chain
          • Creating the APIs
            • GET Contract Symbols
            • GET Open Interest
            • GET Notional Cap
            • GET Price Range
            • GET Error Codes
            • GET Get Locked Params
            • GET Get Funding Info
            • POST Position State
          • Solver Flow Summary Example
          • Recommended Architecture for Solvers
          • Glossary
        • Conditional Orders Handler
        • Rasa Solver TP/SL Implementation
        • Instant Trading
          • Instant Trading (Solvers)
          • Rasa Instant Trading Implementation
          • Instant Trading Condition Checks
        • Fetching Gas Prices Script
        • How to Add a Market as a Solver
        • Verifying Account Abstracted Instant Actions (ERC-4337)
      • Frontend Docs
        • Setting up a Frontend with SYMMIO
        • Frontend SDK Setup Guide
        • MultiAccount Deployment Guide
        • Instant Trading (Frontends)
          • Account Abstracted Instant Actions (Frontends)
        • Implement a Trading Bot on Symmio (OLD)
          • Setup
          • Creating a Sub-Account
          • Minting Collateral Tokens (Optional)
          • Depositing and Allocating Tokens
          • Obtaining Muon Signatures
          • Sending a Quote
          • Monitoring Price for Execution
      • Contract Docs
        • SYMMIO CORE v0.82
        • Contracts Documentation 0.8.2
          • Main Flow
          • The SYMM Diamond
          • Facets
            • Account Facet
            • Control Facet
            • Funding Rate Facet
            • PartyA Facet
            • PartyB Facet
            • Liquidation Facet
            • View Facet
          • MultiAccount
            • PartyA
            • PartyB
          • SYMM App (Muon)
            • LibMuon
            • MuonStorage
        • Contracts Documentation 0.8.3
          • Facets
            • Control Facet
            • Account Facet
            • PartyA Facet
            • PartyB Facet
            • View Facet
            • Bridge Facet
            • Liquidation Facet (Implementation)
          • Modified Events
          • New Events
          • MuonStorage
        • Contracts Documentation 0.8.4
          • Main Flow (0.8.4)
          • The SYMM Diamond (0.8.4)
          • Facets
            • Account Facet (0.8.4)
            • Bridge Facet (0.8.4)
            • Control Facet (0.8.4)
            • Force Actions Facet (0.8.4)
            • Funding Rate Facet (0.8.4)
            • Liquidations Facet (0.8.4)
            • PartyA Facet (0.8.4)
            • PartyB Group Actions Facet (0.8.4)
            • PartyB Quote Actions Facet (0.8.4)
            • PartyB Position Actions Facet (0.8.4)
            • Settlement Facet (0.8.4)
            • View Facet (0.8.4)
          • MultiAccount (0.8.4)
            • SymmioPartyA
            • SymmioPartyB
          • SYMM App (Muon)
            • LibMuon (0.8.4)
            • MuonStorage (0.8.4)
      • Contract Addresses / Solver Endpoints
        • Mantle
        • Mode
        • IOTA
        • Base
        • BSC
        • Arbitrum
        • Polygon
        • Berachain
        • Solver Endpoints and Addresses
          • Perps Hub
          • Rasa Capital
          • Rasa Capital (Zero Spread)
          • Zenith
      • How to Query our Contracts
      • Muon API Queries
      • Solver Error Codes
      • Interacting with SYMMIO Contracts
    • Protocol higher level architecture
      • 12-Hour Fraud Proof Window
      • PartyB
      • Solver Settings
      • Max Leverage
      • Maintenance Margin (CVA) Calculations
    • Symmio Whitepaper
  • Building on Symmio
    • Builders introduction
    • Solving for Symmio
      • Solver documentation
      • Solver - Example Flow
    • Trading Fees
      • Perps - Settlement Costs
      • Pair Trading - Settlement costs
    • Exchanges (Frontends)
      • Frontend Introduction
      • SDK - SYMM client
      • Trade on Symmio
  • Legal & Brand & Security
    • Security (Audits / Bugbounty)
      • Bug bounty / Coverage
        • How to contact ?
      • Audits
        • SYMM - V0.8 - 0.81
          • Sherlock Audit - Jun 15, 2023
          • Smart State - Jul 2, 2023
        • SYMM - 0.82
          • Sherlock Audit -Aug 30, 2023
        • SYMM - 0.83
          • Sherlock Audit - Jun 17, 2024
        • SYMM - 0.84
          • Sherlock Audit - Oct 3, 2024
        • Vaults
          • Sherlock Audit - Jan 2, 2024
    • Terms of Service & Licensing
      • TRADEMARK & COPYRIGHT NOTICE
      • CONTACT US
      • TERMS OF SERVICE
      • FRONTEND LICENSE
        • Frontend Modifications
        • Frontend Use Grants
      • CONTRACT LICENSE
        • Contract Use Grants
        • Contract Modifications
    • Brand - Assets Logos
Powered by GitBook
LogoLogo

All rights to the people (c) 2023 Symmetry Labs A.G.

On this page
  • Parameter Breakdown
  • partyBsWhiteList[]
  • symbolId
  • positionType
  • orderType
  • price
  • quantity
  • cva, lf, partyAmm, partyBmm
  • maxFundingRate
  • deadline
  • affiliate
  • upnlSig
  • Parameter Encoding for sendQuoteWithAffiliate
  • Finding the Quote ID
  1. Protocol Architecture
  2. Technical Documentation
  3. Building an Application with SYMM

Sending a Quote

Sending a quote is a core action on the SYMM platform. It allows Party A to signal an intent to trade by submitting a detailed quote request. To ensure that the quote is accepted and ultimately opened by a hedger (Party B), you must follow the steps below and provide accurate parameters. Debugging is difficult with MultiAccount as the transaction could fail for a number of reasons.

sendQuoteWithAffiliate() should be used to send quotes.

Function Signature

function sendQuoteWithAffiliate(
    address[] memory partyBsWhiteList,
    uint256 symbolId,
    PositionType positionType,
    OrderType orderType,
    uint256 price,
    uint256 quantity,
    uint256 cva,
    uint256 lf,
    uint256 partyAmm,
    uint256 partyBmm,
    uint256 maxFundingRate,
    uint256 deadline,
    address affiliate,
    SingleUpnlAndPriceSig memory upnlSig
) external returns (uint256);

Parameter Breakdown

partyBsWhiteList[]

An array of Party B addresses (hedgers/solvers) that Party A is willing to trade with. Example:

const partyBsWhiteList = [solverAddress1, solverAddress2];

symbolId

The identifier for the trading symbol.


positionType

Enum indicating the type of position:

enum PositionType { LONG, SHORT }

Use 0 for LONG positions and 1 for SHORT positions.


orderType

Enum indicating the order type:

enum OrderType { LIMIT, MARKET }

Use 0 for LIMIT orders and 1 for MARKET orders.


price

For LIMIT orders:

This is the exact price (in 18 decimals) at which you wish to open the position.

For MARKET orders:

The price a quote is opened at includes the spread that a solver charges. In order for your MARKET quote to be accepted, you should send an price slightly adjusted from the current market price depending on the position type. This is an adjusted price includes a slippage buffer (e.g., 5%).

  • LONG Order: Increase the price you receive from Muon by 5% (your position opens slightly higher to reflect the hedger's spread)

  • SHORT Order: Decrease the price you receive from Muon by 5% (your position opens slightly lower to reflect the hedger's spread)


quantity

The total order quantity in 18‑decimal format. For example, a 5 ETH order would be 5e18.

cva, lf, partyAmm, partyBmm

These represent the locked value parameters—fractions (as percentages) of the notional value that define the risk and margin requirements.

  • cva: Credit Valuation Adjustment. Either partyA (the user) or partyB (the hedger) can get liquidated and cva is the penalty that the liquidated side should pay to the other.

  • lf (Liquidator Fee): Fee reserved for liquidators.

  • partyAmm (Party A Maintenance Margin): Margin required for Party A.

  • partyBmm (Party B Maintenance Margin): Margin required for Party B.

The general formula to send these values as parameters are described below:

LockedParam (Wei) = (Notional Value * lockedParam) / (100 * leverage)

      //CVA
      const cvaWei = notionalValue
      * (new BigNumber(lockedParams.cva))
      / (new BigNumber(100)) 
      / (new BigNumber(lockedParams.leverage))
      / (new BigNumber(1e18));
      console.log("cva: ", cvaWei);
      //LF
      const lfWei = notionalValue
      * (new BigNumber(lockedParams.lf))
      / (new BigNumber(100)) 
      / (new BigNumber(lockedParams.leverage))
      / (new BigNumber(1e18));
      //Maintenance Margins
      const partyAmmWei = notionalValue
      * (new BigNumber(lockedParams.partyAmm))
      / (new BigNumber(100)) 
      / (new BigNumber(lockedParams.leverage))
      / (new BigNumber(1e18));
      
      const partyBmmWei = notionalValue
      * (new BigNumber(lockedParams.partyBmm))
      / (new BigNumber(100)) 
      / (new BigNumber(1e18));

The notional value must be calculated based on the price you wish to send to the contract, not the Muon price. It should reflect the hedger's spread.

Formula for MARKET orders:

notionalValue = (quantity * adjustedPrice)

Formula for LIMIT orders:

notionalValue = (quantity * requestedPrice)

Example Response:

{"cva":"0.7","lf":"0.3","leverage":"1.0","partyAmm":"99.0","partyBmm":"0","message":"Success"}

maxFundingRate

The maximum funding rate allowed by Party A, converted to 18 decimals (this is usually 200e18)

deadline

A Unix timestamp marking the expiry of the quote. Ensure it’s set far enough in the future for a solver to act.

affiliate

The affiliate address. This is the frontend's MultiAccount contract address.

upnlSig

This is A SingleUpnlAndPriceSig struct that confirms:

  • reqId: A unique request identifier.

  • timestamp: When the signature was generated.

  • upnl: The unrealized profit and loss for Party A.

  • price: The verified asset price (in 18 decimals).

  • gatewaySignature: A signature from the trusted gateway.

  • sigs: A Schnorr signature (with signature, owner, and nonce fields).

This data is obtained from the Muon oracle by calling the uPnl_A_withSymbolPrice method.

Example Query:

https://muon-oracle4.rasa.capital/v1/?app=symmio&method=uPnl_A_withSymbolPrice&params[partyA]=0xYourAddress&params[chainId]=42161&params[symbolId]=4&params[symmio]=0xSymmioDiamondAddress

Script Example for fetching and formatting the upnlSig for a sendQuoteWithAffiliate using axios and web3:

require('dotenv').config()
const { Web3 } = require('web3');
// Provide a valid provider URL; you can use your own Infura project URL or another provider.
const web3 = new Web3(new Web3.providers.HttpProvider(process.env.PROVIDER_URL));
const axios = require("axios");

async function getMuonSig(account, chainId, contractAddress, symbolId) {
  const url = "https://muon-oracle4.rasa.capital/v1/";
  const params = {
    app: "symmio",
    method: "uPnl_A_withSymbolPrice",
    "params[partyA]": account,
    "params[chainId]": chainId.toString(),
    "params[symbolId]": symbolId.toString(),
    "params[symmio]": contractAddress
  };

  try {
    const response = await axios.get(url, { params });
    if (!response.data || !response.data.result) {
      throw new Error("Unexpected response structure: " + JSON.stringify(response.data));
    }

    const result = response.data.result;
    if (!result.data) {
      throw new Error("Missing data in result");
    }
    const data = result.data;
    const reqId = result.reqId;
    const timestamp = data.timestamp ? data.timestamp : "0";
    const uPnl = data.result && data.result.uPnl ? data.result.uPnl : "0";
    const price = data.result && data.result.price ? data.result.price : "0";
    const gatewaySignature = result.nodeSignature;
    const sigs = (result.signatures && result.signatures.length > 0)
      ? result.signatures[0]
      : { signature: "0", owner: "0x0" };
    const nonce = data.init && data.init.nonceAddress ? data.init.nonceAddress : "0x0";

    const upnlSigFormatted = {
      reqId: web3.utils.hexToBytes(reqId),
      timestamp: timestamp.toString(),
      upnl: uPnl.toString(),
      price: price.toString(),
      gatewaySignature: web3.utils.hexToBytes(gatewaySignature),
      sigs: {
        signature: sigs.signature.toString(),
        owner: sigs.owner,
        nonce: nonce
      }
    };

    return upnlSigFormatted;
  } catch (error) {
    console.error("Error fetching Muon signature:", error);
    throw error;
  }
}

// Example usage:
(async () => {
  try {
    const account = ""; // Replace with your Party A address
    const chainId = 42161; // Example: Arbitrum chain ID
    const contractAddress = ""; // SYMM Diamond address
    const symbolId = 1; // Example symbolId 1 = BTCUSDT
    const muonSig = await getMuonSig(account, chainId, contractAddress, symbolId);
    console.log("Muon Signature:", muonSig);
  } catch (error) {
    console.error(error);
  }
})();

Parameter Encoding for sendQuoteWithAffiliate

When sending a quote using sendQuoteWithAffiliate(), you must encode the function call with the SYMM Diamond’s ABI before forwarding it through your MultiAccount contract. This ensures that the parameters are formatted correctly and that the Diamond delegates the call to the appropriate facet.

The transaction payload before encoding should be formatted like this:

      //Max funding and deadline
      const sendQuoteWithAffiliateParameters = [
        partyBsWhiteList,
        symbolId,
        positionType,
        orderType,
        requestPrice.toString(), //the MARKET price (with added slippage) or if LIMIT, any price
        requestedQuantityWei.toString(),
        cvaWei.toString(), 
        lfWei.toString(),
        partyAmmWei.toString(),
        partyBmmWei.toString(), 
        maxFundingRate.toString(), 
        deadline.toString(),
        affiliate,
        upnlSigFormatted //signature from muon
    ];

Steps to Encode and Send a Quote:

  1. Encode the Function Call:

    Use Web3’s ABI encoding to convert the sendQuoteWithAffiliate function call into a byte string. For example:

    const encodedSendQuoteWithAffiliateData = web3.eth.abi.encodeFunctionCall(
      sendQuoteWithAffiliateFunctionAbi,
      sendQuoteWithAffiliateParameters
    );
    • sendQuoteWithAffiliateFunctionAbi: The ABI definition for the sendQuoteWithAffiliate function.

    • sendQuoteParameters: An array containing all parameters in the order defined by the function signature.

  2. Prepare the Call Data:

    The MultiAccount contract’s _call() method expects an array where:

    • The first element is the sub‑account address.

    • The second element is an array containing your encoded function call.

    const _callData = [ subAccountAddress, [ encodedSendQuoteWithAffiliateData ] ];
  3. Send the Transaction:

    Finally, forward the encoded call through your MultiAccount contract.

    const sendQuoteWithAffiliateReceipt = await multiAccountContract.methods._call(..._callData).send({
      from: account.address,
      gas: adjustedGasLimit.toString(),
      gasPrice: sendQuotePrice.toString()
    });

By following these steps, you can successfully encode and send a quote with affiliate information using the sendQuoteWithAffiliate() function in SYMM.


Finding the Quote ID

Once you send a quote using the sendQuoteWithAffiliate() function, the system will emit a SendQuote event. This event confirms that your quote has been successfully submitted and provides a unique identifier (the quoteId) along with key details of your quote. For example, the event is defined as follows:

event SendQuote(
    address partyA,
    uint256 quoteId,
    address[] partyBsWhiteList,
    uint256 symbolId,
    PositionType positionType,
    OrderType orderType,
    uint256 price,
    uint256 marketPrice,
    uint256 quantity,
    uint256 cva,
    uint256 lf,
    uint256 partyAmm,
    uint256 partyBmm,
    uint256 tradingFee,
    uint256 deadline
);

PreviousCreating an Account and Depositing FundsNextClosing a Quote

Last updated 2 months ago

Use the function on the SYMM Diamond to see available symbols, or query a solver’s supported symbols from the (RASA).

Query the solver’s endpoint. Multiply the notional value by the returned percentage (divided by 100) for each parameter. If you sent a MARKET order, make sure that the notional is calculated based on the adjustedPrice you sent (with the slippage included)

You can obtain this from the solver's endpoint (RASA)

You can use this ID to track and query your quote later, using .

getQuote()
getSymbols()
contract-symbols endpoint
get_locked_params
contract-symbols