> ## Documentation Index
> Fetch the complete documentation index at: https://docs.convallax.com/llms.txt
> Use this file to discover all available pages before exploring further.

# fill()

> Atomically mint an option, lock collateral, and pay premium on ConvallaxRFQSettlement using a signed maker Order.

Execute an option trade in a single atomic transaction on the `ConvallaxRFQSettlement` contract. The taker calls this function with the signed `Order` and `makerSignature` received from [`POST /quote-requests/:id/commit`](/api-reference/trading/commit).

`fill()` is **atomic mint-on-fill**: it calls `ConvallaxCore.mintFor(...)` to pull collateral from the writer, mint fresh option tokens to the holder, and move the premium — all or nothing. Option tokens are **minted on demand**; there is no pre-minted inventory and no token transfer between parties.

**Contract:** `ConvallaxRFQSettlement` — `0x3E583BC44157c91F8c534372A3e91c371841107A`

## Function Signature

```solidity theme={null}
function fill(Order calldata order, bytes calldata makerSignature) external
```

## Parameters

<ParamField body="order" type="Order" required>
  The EIP-712 `Order` struct signed by the market maker.

  <Expandable title="Order struct">
    <ParamField body="order.maker" type="address" required>
      Market maker wallet address.
    </ParamField>

    <ParamField body="order.seriesId" type="uint256" required>
      Option series ID (= ERC-1155 token ID).
    </ParamField>

    <ParamField body="order.optionAmount" type="uint256" required>
      Option tokens to mint (6 decimals).
    </ParamField>

    <ParamField body="order.premiumAmount" type="uint256" required>
      USDC premium to pay (6 decimals).
    </ParamField>

    <ParamField body="order.makerSelling" type="bool" required>
      `true` = taker goes long: the maker posts collateral, the option is minted to the taker, and premium flows taker → maker. `false` = taker goes short: the taker posts collateral, the option is minted to the maker, and premium flows maker → taker.
    </ParamField>

    <ParamField body="order.taker" type="address" required>
      `address(0)` for open orders, or a specific taker address.
    </ParamField>

    <ParamField body="order.validUntil" type="uint256" required>
      Order expiry (Unix timestamp).
    </ParamField>

    <ParamField body="order.nonce" type="uint256" required>
      Single-use replay protection nonce.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="makerSignature" type="bytes" required>
  EIP-712 signature from the maker over the `Order` struct.
</ParamField>

## Behavior

Internally, `fill()` calls `ConvallaxCore.mintFor(seriesId, optionAmount, writer, holder)`, which pulls collateral from the `writer`, mints fresh option tokens to the `holder`, and records the `writer` for writer claims at settlement. The settlement contract moves the premium separately.

| `makerSelling` | Direction        | Collateral poster (writer) | Tokens minted to (holder) | Premium flow  |
| -------------- | ---------------- | -------------------------- | ------------------------- | ------------- |
| `true`         | Taker goes long  | Maker → Core               | Taker                     | Taker → Maker |
| `false`        | Taker goes short | Taker → Core               | Maker                     | Maker → Taker |

The fill is **atomic** — collateral, premium, and minting all execute in a single transaction or the entire call reverts. Collateral is locked only when the trade executes. The nonce is consumed to prevent replay.

## Prerequisites

Settlement requires two USDC approvals — there are **no** ERC-1155 / `setApprovalForAll` approvals. Each party approves only the contract relevant to its role:

1. **Collateral approval** — The party posting collateral (the writer) must `usdc.approve(coreAddress, collateral)` so `ConvallaxCore` can pull it.
2. **Premium approval** — The party paying premium must `usdc.approve(settlementAddress, premium)` so `ConvallaxRFQSettlement` can pull it.
3. **Sufficient balances** — Both parties must hold enough USDC for their respective obligations.

For a standard **long** fill (`makerSelling = true`): the **maker approves Core** (collateral) and the **taker approves Settlement** (premium). For a **short** fill (`makerSelling = false`): the **taker approves Core** (collateral) and the **maker approves Settlement** (premium).

<Tip>
  A market maker that quotes **both** directions should approve **both** Core (collateral) and Settlement (premium) for USDC.
</Tip>

The collateral amount equals the writer's maximum loss:

```
Call:  collateral = optionAmount × (100 − strikeBps) / 100
Put:   collateral = optionAmount × strikeBps / 100
```

(6-decimal raw USDC units, integer division.)

## Example

```javascript theme={null}
import { ethers } from 'ethers';

const settlement = new ethers.Contract(
  '0x3E583BC44157c91F8c534372A3e91c371841107A',
  ['function fill(tuple(address maker, uint256 seriesId, uint256 optionAmount, uint256 premiumAmount, bool makerSelling, address taker, uint256 validUntil, uint256 nonce) order, bytes makerSignature) external'],
  signer
);

// order and makerSignature from POST /quote-requests/:id/commit response
const tx = await settlement.fill(order, makerSignature);
await tx.wait();
```

## Nonce Cancellation

Makers can pre-emptively cancel a nonce to prevent a pending order from being filled:

```solidity theme={null}
function cancelNonce(uint256 nonce) external
```

This marks the nonce as used, so any order signed with that nonce will revert with `NonceAlreadyUsed` if someone tries to fill it.

## Reverts

| Condition                                       | Reason                 |
| ----------------------------------------------- | ---------------------- |
| `optionAmount` or `premiumAmount` is zero       | `InvalidAmount`        |
| Nonce already used or cancelled                 | `NonceAlreadyUsed`     |
| `block.timestamp > validUntil`                  | `OrderExpired`         |
| Recovered signer ≠ `order.maker`                | `InvalidSignature`     |
| `order.taker` ≠ `address(0)` and ≠ `msg.sender` | `InvalidTaker`         |
| Insufficient balance                            | ERC-20/ERC-1155 revert |
