Pallet advanced limit orders#2554
Conversation
| )?; | ||
|
|
||
| // Forward the fee TAO to the order's fee recipient. | ||
| Self::forward_fee(&order.signer, &order.fee_recipient, fee_tao); |
There was a problem hiding this comment.
should handle the failure of forward_fee. otherwise the user could use fee_rate and its balance to avoid pay it.
l0r1s
left a comment
There was a problem hiding this comment.
Looks good, just taking a look at the meta-tx pallet in the polkadot-sdk so we can get the relayer logic for any extrinsic and not coupled to limit orders.
Not in a straight forward manner for a couple of reasons:
In short is meta-tx a good pallet? definitely, but just by itself it does not seem to fulfill the requirements of this pallet. |
|
@gorka-i make sense, thanks for looking at it |
Description
Introduces pallet-limit-orders, a new FRAME pallet that allows users to sign limit orders off-chain and have relayers submit them on-chain. Orders are executed against subnet AMM pools, supporting three order types:
LimitBuy,TakeProfit, andStopLoss.Two execution paths:
execute_orders— processes orders individually, best-effort. Invalid/expired/price-unmet orders are silently skipped; the call always returns Ok.execute_batched_orders(netuid, orders) — atomic batch for a single subnet. Nets buy and sell sides before touching the AMM pool (reduced price impact). Fails the entire call if any orderis invalid.
Validation enforced on both paths:
Sr25519-only signatures (Ed25519|ECDSArejected for now, there is a possibility to add in the future)SubtokenEnabledmust be true for the target subnet.Fee model: per-order
fee_rate: Perbill +fee_recipient: AccountId fields on the order struct. No global protocol fee. Fees are batched per unique recipient and transferred in a single call per recipient at the end of each batch. Enables flexibility of fee-percentage and fee-account per order.Replay protection: executed and cancelled orders are written to
Orders: StorageMap<H256, OrderStatus> by theirblake2_256hash.Open questions / TODOs
LastColdkeyHotkeyStakeBlockon pallet intermediary account — when execute_batched_orders transfers alpha from sellers into the pallet intermediary account, shouldLastColdkeyHotkeyStakeBlockbe updated for the pallet account? If the block tracking is used for rate-limiting or cooldown enforcement, intermediate transfers through the pallet account could trigger unintended restrictions on subsequent operations in the same block.Hotkey ownership verification for the pallet intermediary — the pallet intermediary account stakes/unstakes via PalletHotkey without going through the normal hotkey–coldkey association checks. Should we add an explicit ownership or registration check, or is the pallet account's privileged position sufficient justification to bypass it?
Auto-associate
PalletHotkeywith the pallet coldkey on first use — if the pallet hotkey is not yet registered/associated with the pallet's derived coldkey, another cold-key could potentially claim the hotkey being used by the pallet.TypeScript / e2e tests — no TypeScript integration tests yet. These should cover: order signing, relayer submission flow, fee collection, and the batched netting path against a live node.
Since it's a complex feature, I would like to add
isPalletEnabledstorage item, initially set to false, so that it can be enabled in testnet but not in mainnetBenchmarks
Type of Change
Checklist
./scripts/fix_rust.shto ensure my code is formatted and linted correctlyAdditional Notes
I moved pallets/swap-interface to primitives/swap-interface. it was not a pallet, so I thought it belonged more there