Closing a position
Last updated
Closing is one EIP-712 op. The trick is signerAccount.addr: for closes it's the virtual account, not the sub-account.
Why? Because as far as the Symmio core is concerned, it's that virtual address that holds the quote. The core looks up quotes[quoteId].partyA and checks that the caller (after the AccountLayer's signer-context forwarding) matches. That partyA is the VA. Sign as the sub-account and the core rejects the call with an authorization error that doesn't exactly say "wrong account"; it just fails.
Slippage runs in the opposite direction to opens: when you close a long, you're selling, so you accept a lower price; when you close a short, you're buying back, so you accept a higher price.
CLOSE LONG
price = mark × (1 − slippage / 100)
CLOSE SHORT
price = mark × (1 + slippage / 100)
Quantize to price_precision and convert to wei.
SignedOperationThe envelope is the same SignedOperation struct as for opens, the domain is the same SymmioInstantLayer, and the signer is the same session key. The fields that differ:
target: Symmio Core (same as sendQuote)
signerAccount.addr: virtual account
callData: selector 0x501e891f followed by ABI-encoded (quoteId: uint256, closePrice: uint256, quantityToClose: uint256, orderType: uint8, deadline: uint256). orderType = 1 for MARKET.
POST <instant-close endpoint>
Content-Type: application/json
[
{
"signedOperation": { ... },
"signature": "0x..."
}
]Note the array. Open is a JSON object, close is a JSON array. Mixing them up may cause failures on the server side.
The solver responds with 200 null when the close is queued. The notifications WS will show FillCloseRequest once it fills on-chain.
Last updated

