At Genesis
You can either enable revenue sharing at chain genesis or opt out. TheuseRevenueShare field controls whether your chain enables the revenue sharing system feature:
useRevenueShare = true(default for standard configurations):FeeVaults are upgraded and configured to use theFeeSplittercontract as the recipient, L2 as the withdrawal network, and0as the minimum withdrawal amount. The split logic is calculated using theSuperchainRevSharesCalculatorcontract. TheL1Withdrawercontract is set to withdraw the OP portion of fees automatically.useRevenueShare = false:FeeSplitteris deployed but initialized with zero address for thesharesCalculatorfield. No deployment is made for theSuperchainRevSharesCalculatorandL1Withdrawercontracts.FeeVaults are upgraded but initialized using the custom configuration you provide.
useRevenueShare(optional): Enables or disables the revenue sharing system. Defaults totruefor standard configurations,falsefor custom.chainFeesRecipient(required whenuseRevenueShare = true): Address that receives the chain operator’s portion of fee revenue on L2. Must be able to receive ETH.
Since
useRevenueShare defaults to true for standard configurations, you must either provide a chainFeesRecipient address OR explicitly set useRevenueShare = false to opt out. The deployment will fail validation if revenue sharing is enabled without a recipient.Through Deposit Transactions via superchain-ops (Live Chains)
We strongly recommend having the The usage would be very similar to this, but using the correct values as inputs. For instance, the
ProxyAdmin owner on L1, with a multisig compatible with superchain-ops repo to be able to perform the upgrade altogether in an easier way using an audited contract and a tested script.As a reference, here is an example task using the L1PortalExecuteL2Call template:l2Data needs to be the function calldata that will be performed.RevShareContractsUpgrader contract. This process orchestrates multiple atomic operations across chains through the Safe multisig via delegatecall.
Two Upgrade Paths:
-
upgradeAndSetupRevShare()(For first-time setup): Deploys new contract implementations AND initializes them with revenue sharing configuration in one atomic operation. This is the most efficient path as fee vaults are initialized with the correct recipient (FeeSplitter) from the start, preventing any race conditions. -
setupRevShare()(for already-upgraded contracts): Configures existing upgraded contracts via setter functions. Use this when contracts have already been upgraded to revenue-sharing-compatible implementations but need configuration.
SuperchainRevSharesCalculator Configuration
The fee calculation is based on two formulas, where the maximum of the two is used. This means there will be a kink in the function. So the result of the formula can change based on when the underlying vaults are filled in relation to the calls to disburseFees().
Recommendation: Check all the vaults for a period of one day (the default value of feeDisbursementInterval). The recommended path is to check that all (major) additions are at least done once during that period. If there are additions that are done with a lower frequency, then consider increasing the feeDisbursementInterval.
For instance, if the fees from L1_FEE_VAULT compose > 97.5% of the grossRevenue, it will likely mean that the chain will end up paying more fees to OP. This is a very unlikely scenario, but this would be an example of it
$2 and the OP shares is $2.50: A $0.50 loss for the operator.
- The
l1WithdrawerRecipientneeds to be set to the L1FeesDepositoraddress (still to be deployed). - Ensure the
chainFeesRecipientset can receive Ether.
New SharesCalculators Implementations
The *SharesCalculator* is a key component of the integration with the FeeSplitter contract. It is responsible for holding the business logic to properly calculate and divide the amount of fees that each recipient has to receive.
This contract has to be compatible with the ISharesCalculator interface:
- It MUST NOT return an empty array.
- The total returned amount to be disbursed by the
FeeSplitterMUST be equal to the sum of all the vaults’ revenue received as input.
SuperchainRevSharesCalculator contract serves as an example of this integration, which implements the interface.
Its core business logic involves disbursing the maximum value between 2.5% of gross revenue or 15% of net revenue to OP, with the remainder allocated to the recipient specified by the chain.
SuperchainRevSharesCalculator source code
All Configurations
This section aims to describe other important things to bear in mind, regardless of whether the chain uses theSuperchainRevSharesCalculator contract or not.
To update a config on the following contracts, you will need the L2 ProxyAdmin owner role. If this is the aliased L1 ProxyAdmin owner, a deposit transaction will be needed to make this change. The superchain-ops repository has examples on how to do this.
FeeVault Setters:
setMinWithdrawalAmount(): To update the minimum withdrawal amountsetRecipient(): To update the recipient of the fees withdrawn from the vaultssetWithdrawalNetwork(): To update the withdrawal network
FeeSplitter Setters:
setFeeDisbursementInterval(): To update the disbursement intervalsetSharesCalculator(): To update the shares calculator implementation
SuperchainRevSharesCalculator Setters:
setShareRecipient(): To update the share recipient (default config is OP)setRemainderRecipient(): To update the remainder recipient (default config is the chain fees recipient)
L1Withdrawer Setters:
setMinWithdrawalAmount(): Min withdrawal amount needed before initiating the withdrawalsetRecipient(): Recipient on L1 from the fees (default config is theFeesDepositor)setWithdrawalGasLimit(): Gas limit for the withdrawal. Bear in mind that if integrating with theFeesDepositor, the gas needs will vary depending on if theFeesDepositorwill initiate a deposit to OP mainnet or not, based on the balance and the threshold. Nevertheless, there is replayability enabled through the CDM in case it fails due to OOG.
CGT Chains Integration With Revenue Sharing
CurrentL1Withdrawer is not compatible through CGT chains, provoking revenue sharing to be incompatible with CGT chains as is right now. But, if needed, a new L1WithdrawerCGT could be added to satisfy this use case, and that would resolve the issue, given that the system is modular and the rest can function without any modifications.