Fees
This is an outline of the fees associated the Orderbook.
We support and enforce royalty, maker/taker marketplace and protocol fees on the platform.
Fees
Every order can have a fees
list, which specifies:
recipient
: the fee recipient addressamount
: the fee amount required - this is agnostic to the fungible token type and only calculated based on the buy amount (price)type
: the fee type. This can beROYALTY
,MAKER_ECOSYSTEM
,TAKER_ECOSYSTEM
orPROTOCOL
We store and display the amount for each fee rather than percentage. All fees for an order are paid at the settlement time by the taker (also known as fulfiller) of the order. If an order is only partially filled, the fees are calculated on a pro rata basis.
import { config, orderbook } from '@imtbl/sdk';
type Fee = {
/**
* Fee payable to recipient upon settlement
*/
amount: string;
/**
* Fee type
*/
type: orderbook.FeeType;
/**
* Wallet address of fee recipient
*/
recipient: string;
};
Who pays fees
The buyer of the NFT in a transaction always pays the fees of the transaction. These fees generally include a ROYALTY
, MAKER_ECOSYSTEM
, TAKER_ECOSYSTEM
and PROTOCOL
fee.
The seller of the NFT will not receive the total price of the listing as the above fees will be deducted from the execution price. The seller will receive the base price they entered, which will be lower than the transaction price.
Royalty fees
NFT collection owners can set royalty fees for their collections as stipulated by the ERC2981 standard. This fee is typically collected by a game studio.
The royalty information for an order is automatically calculated by the Orderbook through the ERC2981 interface and based on the price when an off-chain order is created. During order fulfillment the royalty amount is rechecked.
For a deeper dive into the concept of Royalties, see our docs on this topic.
Royalties on zkEVM can only be paid to a single wallet unless a fee splitter contract is utilised. If your application needs to send royalties to multiple wallets please contact your Immutable account manager for information on the fee splitter contract.
Protocol fees
Immutable sets a fixed percentage fee on all orders for providing services on the platform. For both our Immutable X and Immutable zkEVM chains we have a 2% protocol fee set.
Ecosystem fees
Ecosystem fees allow participants in the Immutable ecosystem to set fees for their services. These fees are set by the ecosystem at time of listing creation and fulfillment and are enforced by the order book. Ecosystem participants are usually marketplaces who take either a maker or taker fee for assisting with the creation of the trade.
Maker: A maker is a user who places an order on the marketplace that does not get executed immediately but instead rests on the order book, waiting for another user to take the other side of the trade. Makers add liquidity to the market by creating orders that can be executed in the future. Typically, maker fees are lower than taker fees, and sometimes makers are even rewarded with fee discounts. This is done to encourage users to contribute to the liquidity of the market by placing orders that remain on the order book.
Taker: A taker is a user who places an order that instantly matches with an existing order on the order book, effectively "taking" liquidity from the market. Takers are charged higher fees compared to makers because they execute orders immediately, thereby reducing the available liquidity in the market.
The maker ecosystem fee is calculated and specified by the ecosystem assisting the maker user, in other words the seller creating the listing (i.e. marketplace responsible for adding the order to the orderbook, thereby increasing liquidity). You can do so in the SDK createListing
function call, do note that we expect a fee amount, not a percentage and the system making the SDK call is expected to calculate and make any rounding needed.
Please be advised that all fees and quantities within our system are denoted in the smallest unit of the respective currency, and decimal representations are not supported.
For instance, IMX, which has 18 decimal places, will have a fee of 0.000000000000000001 IMX represented as "1".
Similarly, 1 IMX is represented as "1000000000000000000" in our system.
try {
const order = await sdk.createListing({
orderComponents: listing.orderComponents,
orderHash: listing.orderHash,
orderSignature: signature,
makerFees: [{
amount: '10000000',
recipient: offerer.address,
}],
});
} catch (e) {
console.log(`Listing creation failed with ${e}`);
}
The taker ecosystem fee is calculated and specified by the ecosystem assisting the taker user, in other words the buyer that is accepting the sellers listing creating the listing at the time of execution (i.e. marketplace responsible for executing the order on the orderbook, thereby reducing liquidity).
const { actions } = await sdk.fulfillOrder(orderId, fulfiller.address, [{
amount: '1000000000',
recipient: offerer.address,
}]);
await actionAll(actions, fulfiller, provider);
Rules for setting maker and taker fees
Maker fees can be set by the application that is enabling the user to create an order (i.e. a new listing or sell order).
Taker fees can be set by the application enabling the user to create a trade (Executing orders: A buy order that executes a listing).
- A maker or taker fee can only be assigned to 1 recipient each
- A maker or taker fee can be assigned to the same recipient (i.e. The same marketplace facilitated the listing and the execution)
- Fees are expressed in notional amounts, not %
- Fees can’t be < 0
How are fees enforced?
When using the fulfillOrder
function, the Immutable SDK makes a call to the backend to request
fulfillment-data
, which contains the most up to date fee information as well as a server side signed signature that will be used in the on chain fulfillment process.
Marketplaces should be aware that the order information, in particular fees, might change at the fulfillment time as opposed to displayed in the orderbook when queried through the getListing
and listListings
functions. An example is
if Immutable decided to run a promotional period with reduced protocol fees, an order created at the higher fee will now actually have a lower fee attached.
For a maker marketplace, the fee for orders is fixed and cannot be altered once it has been submitted to the orderbook. To modify the fee, the existing order must be canceled and resubmitted to the orderbook with the updated fee details.
Conversely, a taker marketplace has the flexibility to set their fee at the time of submitting each order to the orderbook for execution, allowing for the creation of custom taker fees for individual trades.
The transaction generated has a default expiration time of 3 minutes, before another request would need to be submitted and fees validated again by the server.
The order information, as well as the expiration time for the server side signature are returned through fulfillOrder
along with the order actions.
(You can read more about actions here)
const {
actions,
order, // up to date order with validated fees
expiration, // the latest user can fulfill the order
} = await sdk.fulfillOrder(orderId, fulfiller.address, [{
amount: '1',
recipient: offerer.address,
}]);
// marketplace should make it clear to user the fees they are subjected to
// as well as the expiration time for this transaction.
await actionAll(actions, fulfiller, provider);