Limit Orders
Place an order that opens a position when the market reaches your price. Collateral is locked when the order is placed, and the order is executed by a keeper when the trigger condition is met.
openLimitOrderV2
function openLimitOrderV2(
OpenDataInput memory data,
OracleUpdateData calldata updateData,
uint96 extraFee
) external payable returns (bytes32 orderHash);Same OpenDataInput struct as a market order, with one difference:
| Field | Market order | Limit order |
|---|---|---|
price | Worst acceptable fill price | The limit price |
Everything else — qty at 1e10, tokenIn/lvToken pairing, amountIn covering margin plus fee — behaves identically. broker and extraFee work exactly as they do for market orders; see Brokers & Referrals.
Oracle data is required at placement time even though the order does not fill immediately; it is used to validate the order against the current market.
Example
import { parseUnits } from 'viem'
import { publicClient, walletClient, DIAMOND, USDC, LVUSD } from './config'
import { fetchOracleUpdate } from './oracle'
const OPEN_LIMIT_ABI = [{
type: 'function',
name: 'openLimitOrderV2',
stateMutability: 'payable',
inputs: [
{
name: 'data', type: 'tuple', components: [
{ name: 'pairBase', type: 'address' },
{ name: 'isLong', type: 'bool' },
{ name: 'tokenIn', type: 'address' },
{ name: 'lvToken', type: 'address' },
{ name: 'amountIn', type: 'uint96' },
{ name: 'qty', type: 'uint128' },
{ name: 'price', type: 'uint128' },
{ name: 'stopLoss', type: 'uint128' },
{ name: 'takeProfit', type: 'uint128' },
{ name: 'broker', type: 'uint24' },
],
},
{
name: 'updateData', type: 'tuple', components: [
{ name: 'pythPriceUpdateData', type: 'bytes[]' },
{ name: 'pythProPriceUpdateData', type: 'bytes[]' },
],
},
{ name: 'extraFee', type: 'uint96' },
],
outputs: [{ name: 'orderHash', type: 'bytes32' }],
}] as const
// Buy $100 of BTC if it drops to $95,000, with a stop at $90,000.
const limitPrice = 95_000
const oracle = await fetchOracleUpdate(pairBase, USDC)
const hash = await walletClient.writeContract({
address: DIAMOND,
abi: OPEN_LIMIT_ABI,
functionName: 'openLimitOrderV2',
args: [
{
pairBase,
isLong: true,
tokenIn: USDC,
lvToken: LVUSD,
amountIn: parseUnits('10', 6),
qty: parseUnits((100 / limitPrice).toFixed(10), 10),
price: parseUnits(String(limitPrice), 18),
stopLoss: parseUnits('90000', 18),
takeProfit: 0n,
broker: 0,
},
oracle.updateData,
0n,
],
value: oracle.value,
})
await publicClient.waitForTransactionReceipt({ hash })The orderHash is emitted in the OpenLimitOrder event and returned by getLimitOrders.
Updating TP/SL
Adjust the take-profit and stop-loss that will be applied when the order fills. No oracle data needed.
function updateOrderTp(bytes32 orderHash, uint128 takeProfit) external;
function updateOrderSl(bytes32 orderHash, uint128 stopLoss) external;
function updateOrderTpAndSl(bytes32 orderHash, uint128 takeProfit, uint128 stopLoss) external;const UPDATE_ORDER_ABI = [{
type: 'function',
name: 'updateOrderTpAndSl',
stateMutability: 'nonpayable',
inputs: [
{ name: 'orderHash', type: 'bytes32' },
{ name: 'takeProfit', type: 'uint128' },
{ name: 'stopLoss', type: 'uint128' },
],
outputs: [],
}] as const
await walletClient.writeContract({
address: DIAMOND,
abi: UPDATE_ORDER_ABI,
functionName: 'updateOrderTpAndSl',
args: [orderHash, parseUnits('120000', 18), parseUnits('90000', 18)],
})Pass 0 to clear a stop-loss.
Cancelling
function cancelLimitOrder(bytes32 orderHash) external;
function batchCancelLimitOrders(bytes32[] calldata orderHashes) external;Cancelling returns the locked collateral. No oracle data needed.
const CANCEL_ABI = [
{
type: 'function',
name: 'cancelLimitOrder',
stateMutability: 'nonpayable',
inputs: [{ name: 'orderHash', type: 'bytes32' }],
outputs: [],
},
{
type: 'function',
name: 'batchCancelLimitOrders',
stateMutability: 'nonpayable',
inputs: [{ name: 'orderHashs', type: 'bytes32[]' }],
outputs: [],
},
] as const
await walletClient.writeContract({
address: DIAMOND,
abi: CANCEL_ABI,
functionName: 'batchCancelLimitOrders',
args: [[orderHashA, orderHashB]],
})Order lifecycle
| Event | Meaning |
|---|---|
OpenLimitOrder | Order placed, collateral locked |
ExecuteLimitOrderSuccessful | Trigger hit, position opened |
ExecuteLimitOrderRejected | Trigger hit but the open failed validation; order stays or is refunded |
LimitOrderRefund | Collateral returned |
CancelLimitOrder | Cancelled by the trader |
UpdateOrderTp / UpdateOrderSl | TP/SL changed |
See Events for signatures, and Reading Data for querying live orders.