Skip to content

Instantly share code, notes, and snippets.

@patcito
Created April 21, 2026 15:22
Show Gist options
  • Select an option

  • Save patcito/194c86920a026b1448ab2823ccdb3b74 to your computer and use it in GitHub Desktop.

Select an option

Save patcito/194c86920a026b1448ab2823ccdb3b74 to your computer and use it in GitHub Desktop.
Leverage / Spot order payloads for wS-USDC 1 USDC margin 5x

Leverage / Spot order payloads — wS-USDC, 1 USDC margin

Live dev values (fetch at runtime, do not hardcode):

curl -sS https://api.opbalance.com/mm/leverage/config
{
  "chainId": 146,
  "signingChainId": 146,
  "sessionManager": "0x52Ef449D44cC4205fa44bF644dEE15611FC30734",
  "sessionManagerDomainName": "ftUSD SessionManager",
  "leverageRfqEngine": "0x8f143D84Ebf0751E56437A62BAB0528d1c8657BF",
  "executorAddress": "0x794EB780F0F50591f376ea1f1492e0FD5d234d46",
  "mode": "executor"
}

Two hard rules:

  • session.target must equal leverageRfqEngine from the config above (this is the EIP-712 target field inside the SessionCall typed data you sign — if it drifts, the engine reverts silently).
  • session.executor must equal executorAddress. Our executor wallet submits the on-chain tx and the engine checks sessionCall.executor == msg.sender; any other value reverts with LeverageSessionExecutorMismatch.

Before any leverage open works, user needs:

  1. 1 USDC (or equivalent) deposited into PositionsManager as margin (one-time)
  2. approveEngine(engine, wS, max) and approveEngine(engine, USDC, max) on PM
  3. approveBorrow(engine, wS, max) and approveBorrow(engine, USDC, max) on PM

These are normal tx the wallet sends to PM 0x82fFB119eeEd117BAe7A2Cf38CE52eAbA3871821.


Conventions used below

  • Decimals: wS = 18, USDC = 6.
  • Spot price today ~ 1 wS = 0.0458 USDC. Replace with live price in production.
  • Margin = user equity already sitting in PM (1 USDC = 1_000_000 wei).
  • Leverage = totalNotional / equity. For 5× on 1 USDC margin, total notional is 5 USDC, so we borrow 4 USDC-equivalent on the sell side (equity 1 USDC + borrowed 4 USDC = 5 USDC notional).
  • feeAmount is the relayer/executor fee taken from the borrowed amount. 1% of sellAmount is the current convention in the testtrader; production FE should read this from the relayer fee endpoint.
  • buyAmount:
    • Market: 1 wei (accept any slippage, rely on engine's post-HF check).
    • Limit: the exact minimum buyToken you're willing to accept. If the DEX can't deliver that, the executor keeps the order pending until the market moves in your favor or validTo expires.

All payloads below POST to /mm/leverage/orders via api.opbalance.com/mm/... (dev) or your local http://localhost:8082/leverage/... (bypassing ft-api proxy).


Leverage — OPEN LONG 5× (market)

Borrow 4 USDC, swap to wS, deposit wS as collateral.

{
  "order": {
    "action": 0,
    "user": "<USER_ADDR>",
    "sellToken": "0x29219dd400f2Bf60E5a23d13Be72B486D4038894",
    "buyToken":  "0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38",
    "sellAmount": "4000000",
    "buyAmount":  "1",
    "validTo":   <NOW + 3600>,
    "feeAmount": "40000"
  },
  "orderType": "open",
  "signatureType": "session",
  "sessionCall": {
    "sessionId":  "<SESSION_ID>",
    "target":     "0x8f143D84Ebf0751E56437A62BAB0528d1c8657BF",
    "dataHash":   "<keccak256(encodeLeveragedOrder(order))>",
    "nonce":      0,
    "deadline":   <NOW + 3600>,
    "executor":   "0x794EB780F0F50591f376ea1f1492e0FD5d234d46",
    "feeAmount":  "0"
  },
  "delegateSignature": "0x<session-owner's EIP-712 sig over SessionCall>"
}

Leverage — OPEN LONG 5× (limit at 0.045 USDC/wS)

Same flow, but the executor will hold the order until DEX gives us ≥ 87_000_000_000_000_000_000 wS out of 4 USDC (≈ 0.045 USDC/wS entry price).

{
  "order": {
    "action": 0,
    "user": "<USER_ADDR>",
    "sellToken": "0x29219dd400f2Bf60E5a23d13Be72B486D4038894",
    "buyToken":  "0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38",
    "sellAmount": "4000000",
    "buyAmount":  "87000000000000000000",
    "validTo":   <NOW + 3600>,
    "feeAmount": "40000"
  },
  "orderType": "open",
  "signatureType": "session",
  "sessionCall": { /* same shape as above */ }
}

Leverage — OPEN SHORT 5× (market)

Borrow 4 USDC-equivalent in wS (≈ 87.5 wS at 0.0458 $/wS), swap to USDC, deposit USDC as collateral.

{
  "order": {
    "action": 0,
    "user": "<USER_ADDR>",
    "sellToken": "0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38",
    "buyToken":  "0x29219dd400f2Bf60E5a23d13Be72B486D4038894",
    "sellAmount": "87500000000000000000",
    "buyAmount":  "1",
    "validTo":   <NOW + 3600>,
    "feeAmount": "875000000000000000"
  },
  "orderType": "open",
  "signatureType": "session",
  "sessionCall": { /* same shape */ }
}

Leverage — OPEN SHORT 5× (limit at 0.045 USDC/wS)

Hold until we can sell 87.5 wS for ≥ 3.94 USDC.

{
  "order": {
    "action": 0,
    "user": "<USER_ADDR>",
    "sellToken": "0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38",
    "buyToken":  "0x29219dd400f2Bf60E5a23d13Be72B486D4038894",
    "sellAmount": "87500000000000000000",
    "buyAmount":  "3940000",
    "validTo":   <NOW + 3600>,
    "feeAmount": "875000000000000000"
  },
  "orderType": "open",
  "signatureType": "session",
  "sessionCall": { /* same shape */ }
}

Spot — SWAP (market)

Collateral swap: burn 1 USDC of collateral, deposit wS of equivalent value. No debt change. Useful for switching collateral composition without opening/closing leverage.

{
  "order": {
    "action": 2,
    "user": "<USER_ADDR>",
    "sellToken": "0x29219dd400f2Bf60E5a23d13Be72B486D4038894",
    "buyToken":  "0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38",
    "sellAmount": "1000000",
    "buyAmount":  "1",
    "validTo":   <NOW + 3600>,
    "feeAmount": "10000"
  },
  "orderType": "swap",
  "signatureType": "session",
  "sessionCall": { /* same shape */ }
}

Spot — SWAP (limit at 0.045 USDC/wS)

Only fill if we get ≥ 22 wS out of 1 USDC.

{
  "order": {
    "action": 2,
    "user": "<USER_ADDR>",
    "sellToken": "0x29219dd400f2Bf60E5a23d13Be72B486D4038894",
    "buyToken":  "0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38",
    "sellAmount": "1000000",
    "buyAmount":  "22000000000000000000",
    "validTo":   <NOW + 3600>,
    "feeAmount": "10000"
  },
  "orderType": "swap",
  "signatureType": "session",
  "sessionCall": { /* same shape */ }
}

Close (round-trip)

To close a long, run action: 1 with the inverse direction — sellToken is the collateral you're withdrawing, buyToken is the debt asset you're repaying. sellAmount is the amount of collateral you want to pull out. buyAmount is the minimum debt the DEX swap must produce (market: 1, limit: target repayment).

{
  "order": {
    "action": 1,
    "user": "<USER_ADDR>",
    "sellToken": "0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38",
    "buyToken":  "0x29219dd400f2Bf60E5a23d13Be72B486D4038894",
    "sellAmount": "<amount of wS collateral to withdraw>",
    "buyAmount":  "<min USDC debt to repay, or 1 for market>",
    "validTo":   <NOW + 3600>,
    "feeAmount": "<~1% of sellAmount>"
  },
  "orderType": "close",
  "signatureType": "session",
  "sessionCall": { /* same shape, target/executor from config */ }
}

Quick sanity check

Live working example against the dev setup — open-short 0.001 wS, round-tripped with close:

Full script at leverage-executor/examples/e2e-order-flow.ts (check cmdOpenShort / cmdOpenLong / cmdClose / cmdSwap).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment