# Order Encoding



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](/docs/integration-reference/evm-limit-orders/orders)
for field meanings, pricing and lifecycle methods.

## Signature domain [#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:

```text
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](https://github.com/1inch/limit-order-protocol/blob/4.3.2/contracts/OrderLib.sol#L33-L65),
[settlement domain](https://github.com/1inch/limit-order-protocol/blob/4.3.2/contracts/LimitOrderProtocol.sol#L31-L44).

## Rate payload [#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` |

```solidity
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 [#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:

```text
offsets = sum(end[i] << (32 * i))
extension = bytes32(offsets) || field[0] || ... || field[7] || customData
```

`customData` 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](https://github.com/1inch/limit-order-protocol/blob/4.3.2/contracts/libraries/ExtensionLib.sol),
[offset slicing](https://github.com/1inch/limit-order-protocol/blob/4.3.2/contracts/libraries/OffsetsLib.sol),
[salt binding](https://github.com/1inch/limit-order-protocol/blob/4.3.2/contracts/OrderLib.sol#L153-L161).

### Public fee extension [#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 [#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](/docs/integration-reference/evm-limit-orders/order-book-api#generate-publish-and-list-orders).

| 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]

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](https://github.com/1inch/limit-order-protocol/blob/4.3.2/contracts/libraries/MakerTraitsLib.sol#L10-L46).

## Taker traits and fill arguments [#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:

```text
args = [20-byte target, if bit 251 is set] || extension || interaction
interaction = [20-byte callback target] || callback data
```

Without 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](/docs/integration-reference/evm-limit-orders/quotes-and-execution).

Source: [taker-trait masks](https://github.com/1inch/limit-order-protocol/blob/4.3.2/contracts/libraries/TakerTraitsLib.sol#L27-L45),
[argument parsing](https://github.com/1inch/limit-order-protocol/blob/4.3.2/contracts/OrderMixin.sol#L451-L482).
