How to manage the fee parameters of your Orbit chain
Different fees get collected for every transaction as part of an Orbit chain activity. These fees are collected as a single amount (the transaction fees) but split internally into different components depending on their purpose. Each component is transferrable to a different fee collector address that is configurable on your chain.
This guide describes the different collected fees and explains how to specify the fee collector address on your chain for each fee type. This guide describes the different fees collected on your chain, how to configure them, and how to specify the fee collector address for each type.
What fees are collected on an Orbit chain?
There are four fee types that are collected on every transaction of an Orbit chain:
-
Orbit base fee: fees paid for executing the transaction on the chain based on the minimum base price configured.
-
Orbit surplus fee: if the chain is congested (i.e., the base price paid for the transaction is higher than the minimum base price), these fees account for executing the transaction on the chain based on any gas price paid above the minimum base price configured.
-
Parent chain base fee: relative fees paid for posting the transaction on the parent chain. This amount is calculated based on the transaction's estimated size and the current view of the parent chain's base fee.
-
Parent chain surplus fee: if configured, these are extra fees rewarded to the batch poster.
You can find more detailed information about these fee types in these pages:
- L2 fees for the Orbit base fee and surplus fee
- L1 fees for the Parent chain base fee and surplus fee
How to configure the fees collected?
Let's see in what ways we can configure each fee type:
Orbit (minimum) base fee
Your chain is configured with a minimum base fee for execution. This value can be obtained by calling the method getMinimumGasPrice()(uint256) of the ArbGasInfo precompile.
cast call --rpc-url $ORBIT_CHAIN_RPC 0x000000000000000000000000000000000000006C "getMinimumGasPrice() (uint256)"
Alternatively, you can use the Orbit SDK to retrieve the minimum Orbit base fee configured:
const orbitChainClient = createPublicClient({
chain: <OrbitChainDefinition>,
transport: http(),
}).extend(arbGasInfoPublicActions);
const orbitMinimumBaseFee = await orbitChainClient.arbGasInfoReadContract({
functionName: 'getMinimumGasPrice',
});
::: note This minimum base fee defines the minimum value that the chain's base fee can have. However, in periods of congestion, the actual base fee might be higher than this minimum. Check the next section "Orbit surplus fee" for more information. :::
To set a new minimum base fee, use the method setMinimumL2BaseFee(uint256) of the ArbOwner precompile, and pass the new minimum base fee in wei. For example:
cast send --rpc-url $ORBIT_CHAIN_RPC --private-key $OWNER_PRIVATE_KEY 0x0000000000000000000000000000000000000070 "setMinimumL2BaseFee(uint256) ()" $NEW_MINIMUM_BASE_FEE_IN_WEI
Or using the Orbit SDK:
const owner = privateKeyToAccount(<OwnerPrivateKey>);
const orbitChainClient = createPublicClient({
chain: <OrbitChainDefinition>,
transport: http(),
}).extend(arbOwnerPublicActions);
const transactionRequest = await orbitChainClient.arbOwnerPrepareTransactionRequest({
functionName: 'setMinimumL2BaseFee',
args: [<NewMinimumBaseFeeInWei>],
upgradeExecutor: false,
account: owner.address,
});
await orbitChainClient.sendRawTransaction({
serializedTransaction: await owner.signTransaction(transactionRequest),
});
Orbit surplus fee
In periods of congestion, the actual base fee of your Orbit chain might be higher than the configured minimum. You can see the current base fee of your chain by calling the method getPricesInWei()(uint256,uint256,uint256,uint256,uint256,uint256) of the ArbGasInfo precompile, and check the last result of the returned tuple.
cast call --rpc-url $ORBIT_CHAIN_RPC 0x000000000000000000000000000000000000006C "getPricesInWei() (uint256,uint256,uint256,uint256,uint256,uint256)"
You can then calculate the current Orbit surplus fees as currentBaseFee - minimumBaseFee.
Note: getPricesInWei() also returns the correspondent fees due to congestion in the second-to-last result of the returned tuple.
Orbit chains automatically adjust the Orbit surplus fee based on the traffic of the chain. If the gas consumed goes over the speed limit, the chain's base fee will start increasing. Likewise, the base fee will gradually go down if demand of gas returns to below the configured speed limit, until it reaches the minimum base fee configured.
Parent chain base fee
To obtain the current parent chain base fee of your chain, you can call the method getL1BaseFeeEstimate()(uint256) of the ArbGasInfo precompile.
cast call --rpc-url $ORBIT_CHAIN_RPC 0x000000000000000000000000000000000000006C "getL1BaseFeeEstimate() (uint256)"
Alternatively, you can use the Orbit SDK to retrieve the current parent chain base fee:
const orbitChainClient = createPublicClient({
chain: <OrbitChainDefinition>,
transport: http(),
}).extend(arbGasInfoPublicActions);
const parentChainBaseFee = await orbitChainClient.arbGasInfoReadContract({
functionName: 'getL1BaseFeeEstimate',
});
You can modify the current estimate of the parent chain base fee by calling the method setL1PricePerUnit(uint256) of the ArbOwner precompile. For example:
cast send --rpc-url $ORBIT_CHAIN_RPC --private-key $OWNER_PRIVATE_KEY 0x0000000000000000000000000000000000000070 "setL1PricePerUnit(uint256) ()" $NEW_PARENT_CHAIN_BASE_FEE
Or using the Orbit SDK:
const owner = privateKeyToAccount(<OwnerPrivateKey>);
const orbitChainClient = createPublicClient({
chain: <OrbitChainDefinition>,
transport: http(),
}).extend(arbOwnerPublicActions);
const transactionRequest = await orbitChainClient.arbOwnerPrepareTransactionRequest({
functionName: 'setL1PricePerUnit',
args: [<NewParentChainBaseFee>],
upgradeExecutor: false,
account: owner.address,
});
await orbitChainClient.sendRawTransaction({
serializedTransaction: await owner.signTransaction(transactionRequest),
});
Orbit chains are configured to automatically adjust the current parent chain base fee estimation based on the batch poster reports sent from the parent chain. That means that even though you can set a new parent chain base fee, the chain will automatically adjust it based on the reports received afterwards.
Orbit chains that use a custom gas token should have their parent chain base fees disabled (set to 0), to avoid charging users for a non-existent parent chain's base fee, as explained in How to use a custom gas token.
Parent chain surplus fee
The parent chain surplus fee collected is based on a reward rate configured in the chain. To obtain this parameter, you can call the method getL1RewardRate()(uint64) of the ArbGasInfo precompile. This function will return the amount of wei per gas unit paid to the appropriate fee collector. For example:
cast call --rpc-url $ORBIT_CHAIN_RPC 0x000000000000000000000000000000000000006C "getL1RewardRate() (uint64)"
Alternatively, you can obtain this information using the Orbit SDK:
const orbitChainClient = createPublicClient({
chain: <OrbitChainDefinition>,
transport: http(),
}).extend(arbGasInfoPublicActions);
const parentChainRewardRate = await orbitChainClient.arbGasInfoReadContract({
functionName: 'getL1RewardRate',
});
To change the reward rate, you can use the method setL1PricingRewardRate(uint64) of the ArbOwner precompile and pass the amount of wei per gas unit to reward. For example:
cast send --rpc-url $ORBIT_CHAIN_RPC --private-key $OWNER_PRIVATE_KEY 0x0000000000000000000000000000000000000070 "setL1PricingRewardRate(uint64) ()" $NEW_REWARD_RATE
Or using the Orbit SDK:
const owner = privateKeyToAccount(<OwnerPrivateKey>);
const orbitChainClient = createPublicClient({
chain: <OrbitChainDefinition>,
transport: http(),
}).extend(arbOwnerPublicActions);
const transactionRequest = await orbitChainClient.arbOwnerPrepareTransactionRequest({
functionName: 'setL1PricingRewardRate',
args: [<NewRewardRate>],
upgradeExecutor: false,
account: owner.address,
});
await orbitChainClient.sendRawTransaction({
serializedTransaction: await owner.signTransaction(transactionRequest),
});
How to configure the fee collector addresses?
Let's now look at how to configure the collector addresses for each fee type.