Skip to main content
The Orderbook supports multiple fee types—protocol fees, royalties, and marketplace fees—that are automatically distributed when trades execute.

Fee Types

FeeRecipientSet By
Protocol FeeImmutableFixed by protocol
Royalty FeeNFT CreatorSet on NFT contract
Maker FeeListing marketplaceOrder creator
Taker FeeFilling marketplaceOrder filler

How Fees Work

When a trade executes, fees are deducted from the payment. All fees are paid by the buyer, and the seller receives the sale price minus the deducted fees.
Fee Units: Fees are specified in the smallest unit of the currency (wei for native tokens, smallest decimal unit for ERC-20s). For example:
  • 1 IMX = 1,000,000,000,000,000,000 wei (18 decimals)
  • Fee of “10000000000000000” = 0.01 IMX
Fees are notional amounts, not percentages. If an order is partially filled, fees are automatically pro-rated by the orderbook.

Protocol Fee

The protocol fee is a small percentage that supports the Immutable ecosystem.
NetworkProtocol Fee
Mainnet2%
Testnet2%
The protocol fee is non-negotiable and applies to all trades on the Orderbook.

Royalties

Royalties ensure creators earn from secondary sales. They’re set on the NFT contract and enforced by the Orderbook.

Setting Royalties

Royalties are configured when deploying your NFT contract. For complete setup instructions, see Deploying Contracts with Royalties and Royalty Configuration.
// In your ERC-721 contract
function royaltyInfo(uint256 tokenId, uint256 salePrice)
    external
    view
    returns (address receiver, uint256 royaltyAmount)
{
    // 5% royalty to the creator
    return (creatorAddress, (salePrice * 500) / 10000);
}

Typical Royalty Rates

Game TypeTypical Royalty
Gaming items2-5%
Collectibles5-10%
Art5-15%
Royalty Enforcement:
  • Royalties must be implemented via the Operator Allowlist to be enforced
  • The orderbook automatically queries royalty information using the ERC-2981 interface when creating orders
  • Royalty amounts are re-validated during order fulfillment
  • zkEVM limitation: Royalties can only be paid to a single wallet address. If you need to split royalties among multiple wallets, contact your Immutable account manager about fee splitter contracts.

Marketplace Fees

Marketplaces can add their own fees on top of protocol fees and royalties.

Maker Fees

Set by the marketplace where the order is created:
const { result } = await orderbookClient.createListing({
  orderComponents: prepareListing.orderComponents,
  orderHash: prepareListing.orderHash,
  orderSignature: signature,
  makerFees: [
    {
      recipientAddress: MARKETPLACE_FEE_WALLET,
      amount: '10000000000000000', // 0.01 IMX flat fee
    },
  ],
});

Taker Fees

Set by the marketplace where the order is filled:
const { actions } = await orderbookClient.fulfillOrder(
  orderId,
  buyerAddress,
  [
    {
      recipientAddress: MARKETPLACE_FEE_WALLET,
      amount: '10000000000000000', // 0.01 IMX flat fee
    },
  ]
);

Maker vs Taker Fee Flexibility

Fee TypeWhen SetCan Change?
Maker FeeAt listing creationImmutable - To change, must cancel and recreate listing
Taker FeeAt order fulfillmentFlexible - Can be different for each fulfillment
Maker = Liquidity provider (creates order, adds to orderbook) Taker = Liquidity consumer (fills order, removes from orderbook)Marketplaces typically charge makers lower fees to incentivize listing creation.

ERC-1155 Partial Fill Fee Rules

For ERC-1155 tokens that support partial fills, taker fees must reflect the full order amount, not the partial fill amount:
// ❌ WRONG: Scaling fee for partial fill
const listing = { sell: { amount: '10' }, buy: { amount: '1000000000000000000' } }; // 10 items at 0.1 IMX each
const amountToFill = '5'; // Buying 5 of 10
const takerFee = '5000000000000000'; // 0.005 IMX (scaled) - INCORRECT

// ✅ CORRECT: Fee for full order amount
const takerFee = '10000000000000000'; // 0.01 IMX (1% of full order) - CORRECT
// The orderbook will automatically pro-rate this to 0.005 IMX for the partial fill
For ERC-1155 orders, always provide taker fees for the complete order, even when partially filling. The orderbook automatically pro-rates the fee based on the quantity executed. Setting a scaled-down fee will result in incorrect marketplace compensation.

Fee Validation and Expiration

When fulfilling an order, the orderbook provides up-to-date fee information and validates all fees server-side:
const { actions, order, expiration } = await orderbookClient.fulfillOrder(
  orderId,
  buyerAddress,
  [] // taker fees array
);

console.log({
  order: order,           // Order with CURRENT fees (may differ from listing query)
  expiration: expiration  // Transaction must be submitted within 3 minutes
});

// User must complete transaction before expiration
// After 3 minutes, request new fulfillment data
Important Fee Timing Rules:
  1. Fee changes: Fees at fulfillment time may differ from when the order was queried (e.g., promotional periods with reduced protocol fees)
  2. 3-minute expiration: Transaction data expires 3 minutes after generation. After expiration, request new fulfillment data with updated fees.
  3. Display to users: Always show users the final fee breakdown from the fulfillOrder response before they sign, not from the listing query.

Percentage-Based Fees

Calculate fees as a percentage of the order value:
function calculateFee(orderAmount: string, percentageBps: number): string {
  // BPS = basis points (100 bps = 1%)
  const amount = BigInt(orderAmount);
  const fee = (amount * BigInt(percentageBps)) / BigInt(10000);
  return fee.toString();
}

// 2.5% marketplace fee
const fee = calculateFee(listing.buy.amount, 250);

const { actions } = await orderbookClient.fulfillOrder(
  orderId,
  buyerAddress,
  [{ recipientAddress: MARKETPLACE_WALLET, amount: fee }]
);

Fee Splitting

Distribute fees to multiple recipients:
const makerFees = [
  {
    recipientAddress: PLATFORM_WALLET,
    amount: calculateFee(price, 100), // 1% to platform
  },
  {
    recipientAddress: AFFILIATE_WALLET,
    amount: calculateFee(price, 50),  // 0.5% to affiliate
  },
];

await orderbookClient.createListing({
  // ...
  makerFees,
});

Displaying Fees to Users

Show users the fee breakdown before they trade:
interface FeeBreakdown {
  protocolFee: bigint;
  royalty: bigint;
  makerFee: bigint;
  takerFee: bigint;
  sellerReceives: bigint;
}

function calculateFeeBreakdown(
  salePrice: bigint,
  royaltyBps: number,
  makerFeeBps: number,
  takerFeeBps: number
): FeeBreakdown {
  const protocolFee = (salePrice * 200n) / 10000n; // 2%
  const royalty = (salePrice * BigInt(royaltyBps)) / 10000n;
  const makerFee = (salePrice * BigInt(makerFeeBps)) / 10000n;
  const takerFee = (salePrice * BigInt(takerFeeBps)) / 10000n;
  
  const sellerReceives = salePrice - protocolFee - royalty - makerFee;
  
  return { protocolFee, royalty, makerFee, takerFee, sellerReceives };
}

Example UI

You're selling: Sword of Power #123
Price: 1.00 IMX

Fee Breakdown:
  Protocol Fee (2%):     -0.02 IMX
  Creator Royalty (5%):  -0.05 IMX
  Marketplace Fee (1%):  -0.01 IMX
  ─────────────────────────────────
  You'll receive:         0.92 IMX

Fee Limits

Fee TypeMaximum
Royalty10% recommended, contract-defined
Maker FeeNo protocol limit
Taker FeeNo protocol limit
Total FeesShould not exceed sale price
Keep total fees reasonable (under 15%) to maintain a healthy marketplace. High fees discourage trading.

Next Steps