Order Encoding
EIP-712 types, rate payload, extension offsets and maker/taker trait bitfields.
An order signs token quantities, addresses and execution permissions. Its extension carries the rate inputs and callback targets; the signed salt binds those bytes. See the order contract reference for field meanings, pricing and lifecycle methods.
Signature domain
The four order address fields use the upstream Address wrapper:
uint256 in calldata, with the address in the low 160 bits. MakerTraits
and TakerTraits also encode as uint256. EIP-712 instead types the four
address fields as address, in this exact order:
Order(uint256 salt,address maker,address receiver,address makerAsset,address takerAsset,uint256 makingAmount,uint256 takingAmount,uint256 makerTraits)| Domain field | Value |
|---|---|
name | 1inch Limit Order Protocol |
version | 4 |
chainId | Execution chain ID |
verifyingContract | Execution chain's LimitOrderProtocol address |
hashOrder returns the EIP-712 digest. DOMAIN_SEPARATOR returns the domain
separator. A different chain or settlement produces a different digest.
EOA fill signatures use compact EIP-2098 r and vs; contract fills pass
ERC-1271 signature bytes to the maker.
Source: order type and hash, settlement domain.
Rate payload
The payload identifies the registered PT, derivative kind, quote kind and
signed APY. It occupies the extension's customData tail. For YT orders,
the PT still identifies the market; the getter resolves YT from that PT.
customData is exactly 36 packed bytes, with no ABI tuple padding:
| Bytes | Type | Value |
|---|---|---|
0 | uint8 | Version 1 |
1 | uint8 | Derivative: 0 PT, 1 YT |
2 | uint8 | Quote: 0 underlying, 1 IBT, 2 vault share |
3 | uint8 | Flags 0 |
4..23 | address | Registered PT |
24..35 | uint96 | Big-endian impliedApyWad; 5% is 50000000000000000 |
function decodeRateOrderData(bytes calldata data)
external pure returns (RateOrderDataV1 memory);The decoder returns the fields above in that order, emits no events and
reverts with InvalidRateData() for another length, version, enum,
nonzero flags or zero PT. Market registration, maturity and APY bounds
are checked during pricing.
Extension
An extension starts with a 32-byte offset header, followed by eight dynamic
fields and then customData. The header stores cumulative end offsets
relative to the first byte after the header. Empty fields repeat the
previous offset.
| Index | Dynamic field | Content |
|---|---|---|
0 | Maker asset suffix | Bytes appended to maker-token transferFrom calldata. |
1 | Taker asset suffix | Bytes appended to taker-token transferFrom calldata. |
2 | Making amount data | Packed 20-byte getter address, then getter-local data. |
3 | Taking amount data | Packed 20-byte getter address, then getter-local data. |
4 | Predicate | Settlement predicate calldata. |
5 | Maker permit | Packed 20-byte token address, then permit data. |
6 | Pre-interaction | Callback data, optionally prefixed by a packed 20-byte target address. |
7 | Post-interaction | Callback data, optionally prefixed by a packed 20-byte target address. |
For cumulative ends end[0]..end[7], encode:
offsets = sum(end[i] << (32 * i))
extension = bytes32(offsets) || field[0] || ... || field[7] || customDatacustomData starts at 32 + end[7]; it has no ninth offset. Set the maker's
extension flag and bind the low 160 bits of salt to the low 160 bits of
keccak256(extension). Missing, unexpected or hash-mismatched extensions
fail settlement validation.
For pre/post-interactions, fields shorter than 20 bytes call the maker with the whole field as data; otherwise, the first 20 bytes select the target.
Source: extension fields, offset slicing, salt binding.
Public fee extension
A public fee order sends payment to SpectraRateFeeTaker, which splits it
between maker and fee collector. Its receiver, both getters and
post-interaction target must name that fee taker.
| Index | Field | Bytes | Cumulative end |
|---|---|---|---|
0 | Maker asset suffix | Empty | 0 |
1 | Taker asset suffix | Empty | 0 |
2 | Making amount data | 20-byte fee-taker address | 20 |
3 | Taking amount data | 20-byte fee-taker address | 40 |
4 | Predicate | Empty | 40 |
5 | Maker permit | Empty | 40 |
6 | Pre-interaction | Empty | 40 |
7 | Post-interaction | 20-byte fee-taker address | 60 |
Append the 36-byte rate payload: total extension length is
32 + 60 + 36 = 128 bytes. No getter-local or post-interaction extra data
is appended. Set the post-interaction flag and leave maker native unwrap
clear. For a fee-free rate order, the rate getter likewise requires empty
getter-local data, reverting with NonEmptyExtraData() otherwise.
Order-book admission profile
The order-book API accepts Spectra's canonical public fee-order profile,
not arbitrary 1inch orders. Submit the generated order, including its
extension and indexed terms, in the
POST /create request.
| Part | Required profile |
|---|---|
| Assets and rate payload | Match the registered PT/YT market, direction and supported quote token. |
| Receiver | The configured SpectraRateFeeTaker. |
| Extension | The exact public fee extension above: both amount getters and post-interaction target the configured fee taker, with no custom extra data. |
| Salt | Binds the extension hash. |
| Maker traits | The exact partial/multiple-fill, post-interaction, extension and series-0 epoch profile below; no additional flags. |
| Indexed terms | orderType, makerTokenType, pt, impliedRate, expiry and nonce must match the decoded signed data. |
| Amounts | Positive makingAmount and takingAmount, in their respective token base units. |
Orders that fail this canonical validation are rejected with HTTP 422 and
code: ORDER_VALIDATION_FAILED. Malformed request bodies return HTTP 400.
Passing encoding checks does not bypass signature, funding or live-order
admission checks.
The order contains no numeric fee field. It selects the configured
fee-taker contract, which reads its live fee(). An alternate fee receiver,
different getters or custom fee payloads fail canonical validation. Adding
a fee property to the JSON request does not override the fee.
Maker traits
Maker traits are signed permissions. Partial and multiple fills must both be enabled to use remaining-amount storage and series epochs. Otherwise, settlement uses nonce-bit invalidation.
| Bits | Meaning | Public fee-order profile |
|---|---|---|
0..79 | Low 80 bits of allowed immediate caller; zero allows any caller | 0 |
80..119 | Expiry, Unix seconds; zero means no expiry | Selected expiry |
120..159 | Nonce or signed epoch | Current epoch |
160..199 | Series | 0 |
247 | Unwrap taker-paid WETH for maker | Clear |
248 | Maker uses Permit2 | Clear |
249 | Has extension | Set |
250 | Check series epoch | Set |
251 | Call post-interaction | Set |
252 | Call pre-interaction | Clear |
254 | Allow multiple fills | Set |
255 | Forbid partial fills | Clear |
Other bits are unused. Series 0 groups the maker's orders across markets;
advancing it leaves other series and orders without epoch checks unaffected.
The caller restriction compares only low 80 address bits; an exact
full-address allowlist requires a separate pre-interaction guard.
Upstream expiry fails only when a nonzero expiry is strictly earlier than the current timestamp. An expiry strictly before maturity is an order-construction policy; the rate getter independently rejects execution at maturity.
Source: maker traits.
Taker traits and fill arguments
Taker traits are supplied with each fill. They choose the amount mode, bound execution price and delimit packed fill arguments.
| Bits | Meaning |
|---|---|
0..183 | Threshold amount; mask (1 << 184) - 1 |
200..223 | Interaction length in bytes, uint24 |
224..247 | Extension length in bytes, uint24 |
251 | First 20 bytes of args are the maker-asset target |
252 | Taker uses Permit2 |
253 | Skip maker permit |
254 | Unwrap maker-sent WETH for taker |
255 | Maker-amount mode; clear selects taking-amount mode |
Other bits are unused. In maker-amount mode, the threshold is maximum payment for the requested maker quantity. In taking-amount mode, it is minimum maker quantity for the requested payment. Zero disables the threshold; clamped fills preserve the proportional price constraint.
For an Args fill entry point, concatenate:
args = [20-byte target, if bit 251 is set] || extension || interaction
interaction = [20-byte callback target] || callback dataWithout the target flag, maker assets go to the immediate caller. Extension
and interaction lengths come from their trait fields. No-Args methods
supply neither extension nor interaction. The batch filler supplies its own
target and lengths; see batch settlement.
Source: taker-trait masks, argument parsing.