# Dev Gas Revenue Mechanism
The devgas
module of Nibiru Chain shares contract execution fees with smart
contract developers. This aims to increase the adoption of Nibiru by offering
CosmWasm smart contract developers a direct source of income based on usage.
Developers can register their smart contracts such that, every time someone interacts with a registered smart contract, the contract deployer or their assigned withdrawal account receives a part of the transaction fees.
# Table of Contents
- Register a Contract Withdrawal Address
- Update a Contract's Withdrawal Address
- Concepts
- State
- State Transitions
- TxMsgs - devgas
- Ante Handler
- Events
- Module Parameters
- Enable FeeShare Module
- Clients
- gRPC Queries
- Credits: Evmos
# Register a Contract Withdrawal Address
Registers the withdrawal address for the given contract.
# Register Args
contract_bech32 (string, required)
: The bech32 address of the contract whose
interaction fees will be shared.
withdraw_bech32 (string, required)
: The bech32 address where the interaction
fees will be sent every block.
# Description
This command registers the withdrawal address for the given contract. Any time a user interacts with your contract, the funds will be sent to the withdrawal address. It can be any valid address, such as a DAO, normal account, another contract, or a multi-sig.
# Permissions
This command can only be run by the admin of the contract. If there is no admin, then it can only be run by the contract creator.
# Exceptions
withdraw_bech32
can not be the community pool (distribution) address. This is a limitation of the way the SDK handles this module accountFor contracts created or administered by a contract factory, the withdrawal address can only be the same as the contract address. This can be registered by anyone, but it's unchangeable. This is helpful for SubDAOs or public goods to save fees in the treasury.
If you create a contract like this, it's best to create an execution method for withdrawing fees to an account. To do this, you'll need to save the withdrawal address in the contract's state before uploading a non-migratable contract.
# Update a Contract's Withdrawal Address
This can be changed at any time so long as you are still the admin or creator of a contract with the command:
# Update Exception
This can not be done if the contract was created from or is administered by another contract (a contract factory). There is not currently a way for a contract to change its own withdrawal address directly.
# Concepts
# FeeShare
The DevGas (x/devgas
) module is a revenue-per-gas model, which allows
developers to get paid for deploying their decentralized applications (dApps)
on Nibiru. This helps developers to generate revenue every time a user
invokes their contracts to execute a transaction on the chain.
This registration is permissionless to sign up for and begin earning fees from.
By default, 50% of all gas fees for Execute Messages are shared. This
can be changed by governance and implemented by the x/devgas
module.
# Registration
Developers register their contract applications to gain their cut of fees per execution. Any contract can be registered by a developer by submitting a signed transaction. After the transaction is executed successfully, the developer will start receiving a portion of the transaction fees paid when a user interacts with the registered contract. The developer can have the funds sent to their wallet, a DAO, or any other wallet address on the Nibiru.
NOTE: If your contract is part of a development project, please ensure that the deployer of the contract (or the factory/DAO that deployed the contract) is an account that is owned by that project. This avoids the situation, that an individual deployer who leaves your project could become malicious.
# Fee Distribution
As described above, developers will earn a portion of the transaction fee after registering their contracts. To understand how transaction fees are distributed, we will look at the following in detail:
- The transactions eligible are only Wasm Execute Txs (opens new window) (
MsgExecuteContract
).
# WASM Transaction Fees
Users pay transaction fees to pay to interact with smart contracts on Nibiru.
When a transaction is executed, the entire fee amount (gas limit * gas price
)
is sent to the FeeCollector
module account during the Cosmos SDK
AnteHandler (opens new window)
execution.
After this step, the FeeCollector
sends 50% of the funds and splits them
between contracts that were executed on the transaction. If the fees paid are
not accepted by governance, there is no payout to the developers (for example,
niche base tokens) for tax purposes. If a user sends a message and it does not
interact with any contracts (ex: bankSend), then the entire fee is sent to the
FeeCollector
as expected.
# State
The x/devgas
module keeps the following objects in the state:
State Object | Description | Key | Value | Store |
---|---|---|---|---|
FeeShare | Fee split bytecode | []byte{1} + []byte(contract_address) | []byte{feeshare} | KV |
DeployerFeeShares | Contract by deployer address bytecode | []byte{2} + []byte(deployer_address) + []byte(contract_address) | []byte{1} | KV |
FeeSharesByWithdrawer | Contract by withdraw address bytecode | []byte{3} + []byte(withdraw_address) + []byte(contract_address) | []byte{1} | KV |
# State: FeeShare
A FeeShare
defines an instance that organizes fee distribution conditions for
the owner of a given smart contract
# State: ContractAddress
ContractAddress
defines the contract address that has been registered for fee distribution.
# DeployerAddress
A DeployerAddress
is the admin address for a registered contract.
# WithdrawerAddress
The WithdrawerAddress
is the address that receives transaction fees for a registered contract.
# Genesis State
The x/devgas
module's GenesisState
defines the state necessary for initializing the chain from a previously exported height. It contains the module parameters and the fee share for registered contracts:
# State Transitions
The x/devgas
module allows for three types of state transitions:
RegisterFeeShare
, UpdateFeeShare
and CancelFeeShare
. The logic for
distributing transaction fees is handled through the Ante
handler.
# Register Fee Share
A developer registers a contract for receiving transaction fees by defining the contract address and the withdrawal address for fees to be paid too. If this is not set, the developer can not get income from the contract. This is opt-in for tax purposes. When registering for fees to be paid, you MUST be the admin of said wasm contract. The withdrawal address can be the same as the contract's address if you so choose.
- User submits a
RegisterFeeShare
to register a contract address, along with a withdrawal address that they would like to receive the fees to - Check if the following conditions pass:
x/devgas
module is enabled via Governance- the contract was not previously registered
- deployer has a valid account (it has done at least one transaction)
- the contract address exists
- the deployer signing the transaction is the admin of the contract
- the contract is already deployed
- Store an instance of the provided share.
All transactions sent to the registered contract occurring after registration
will have their fees distributed to the developer, according to the global
DeveloperShares
parameter in governance.
# Update Fee Split
A developer updates the withdraw address for a registered contract, defining the contract address and the new withdraw address.
- The user submits a
UpdateFeeShare
- Check if the following conditions pass:
x/devgas
module is enabled- the contract is registered
- the signer of the transaction is the same as the contract admin per the WasmVM
- Update the fee with the new withdrawal address.
After this update, the developer receives the fees on the new withdrawal address.
# Cancel Fee Split
A developer cancels receiving fees for a registered contract, defining the contract address.
- The user submits a
CancelFeeShare
- Check if the following conditions pass:
x/devgas
module is enabled- the contract is registered
- the signer of the transaction is the same as the contract admin per the WasmVM
- Remove share from storage
The developer no longer receives fees from transactions sent to this contract. All fees go to the community.
# TxMsgs - devgas
This section defines the sdk.Msg
concrete types that result in the state
transitions defined on the previous section.
# MsgRegisterFeeShare
Defines a transaction signed by a developer to register a contract for transaction fee distribution. The sender must be an EOA that corresponds to the contract deployer address.
The message content stateless validation fails if:
- Contract bech32 address is invalid
- Deployer bech32 address is invalid
- Withdraw bech32 address is invalid
# MsgUpdateFeeShare
Defines a transaction signed by a developer to update the withdraw address of a contract registered for transaction fee distribution. The sender must be the admin of the contract.
The message content stateless validation fails if:
- Contract bech32 address is invalid
- Deployer bech32 address is invalid
- Withdraw bech32 address is invalid
# MsgCancelFeeShare
Defines a transaction signed by a developer to remove the information for a registered contract. Transaction fees will no longer be distributed to the developer for this smart contract. The sender must be an admin that corresponds to the contract.
The message content stateless validation fails if:
- Contract bech32 address is invalid
- Contract bech32 address is zero
- Deployer bech32 address is invalid
# Ante Handler
The fees module uses the ante handler to distribute fees between developers and the community.
An Ante Decorator executes custom logic after each
successful WasmExecuteMsg transaction. All fees paid by a user for transaction
execution are sent to the FeeCollector
module account during the
AnteHandler
execution before being redistributed to the registered contract
developers.
If the x/devgas
module is disabled or the Wasm Execute Msg transaction
targets an unregistered contract, the handler returns nil
, without performing
any actions. In this case, 100% of the transaction fees remain in the
FeeCollector
module, to be distributed elsewhere.
If the x/devgas
module is enabled and a Wasm Execute Msg transaction
targets a registered contract, the handler sends a percentage of the
transaction fees (paid by the user) to the withdraw address set for that
contract.
- The user submits an Execute transaction (
MsgExecuteContract
) to a smart contract and the transaction is executed successfully - Check if
- fees module is enabled
- the smart contract is registered to receive fee split
- Calculate developer fees according to the
DeveloperShares
parameter. - Check what fees governance allows to be paid in
- Check which contracts the user executed that also have been registered.
- Calculate the total amount of fees to be paid to the developer(s). If multiple, split the 50% between all registered withdrawal addresses.
- Distribute the remaining amount in the
FeeCollector
to validators according to the SDK Distribution Scheme (opens new window).
# Events
The x/devgas
module emits the following events:
# Event: Register Fee Split
Type | Attribute Key | Attribute Value |
---|---|---|
register_feeshare | "contract" | {msg.ContractAddress} |
register_feeshare | "sender" | {msg.DeployerAddress} |
register_feeshare | "withdrawer_address" | {msg.WithdrawerAddress} |
# Event: Update Fee Split
Type | Attribute Key | Attribute Value |
---|---|---|
update_feeshare | "contract" | {msg.ContractAddress} |
update_feeshare | "sender" | {msg.DeployerAddress} |
update_feeshare | "withdrawer_address" | {msg.WithdrawerAddress} |
# Event: Cancel Fee Split
Type | Attribute Key | Attribute Value |
---|---|---|
cancel_feeshare | "contract" | {msg.ContractAddress} |
cancel_feeshare | "sender" | {msg.DeployerAddress} |
# Module Parameters
The fee Split module contains the following parameters:
Key | Type | Default Value |
---|---|---|
EnableFeeShare | bool | true |
DeveloperShares | sdk.Dec | 50% |
AllowedDenoms | []string{} | []string(nil) |
# Enable FeeShare Module
The EnableFeeShare
parameter toggles all state transitions in the module.
When the parameter is disabled, it will prevent any transaction fees from being
distributed to contract deplorers and it will disallow contract registrations,
updates or cancellations.
# Developer Shares Amount
The DeveloperShares
parameter is the percentage of transaction fees that are
sent to the contract deplorers.
# Allowed Denominations
The AllowedDenoms
parameter is used to specify which fees coins will be paid
to contract developers. If this is empty, all fees paid will be split. If not,
only fees specified here will be paid out to the withdrawal address.
# Clients
# Command Line Interface
Find below a list of nibid
commands added with the x/devgas
module. You
can obtain the full list by using the nibid -h
command. A CLI command can
look like this:
# CLI: Queries
Command | Subcommand | Description |
---|---|---|
query feeshare | params | Get devgas params |
query feeshare | contract | Get the devgas for a given contract |
query feeshare | contracts | Get all feeshares |
query feeshare | deployer-contracts | Get all feeshares of a given deployer |
query feeshare | withdrawer-contracts | Get all feeshares of a given withdrawer |
# CLI: Transactions
Command | Subcommand | Description |
---|---|---|
tx feeshare | register | Register a contract for receiving devgas |
tx feeshare | update | Update the withdraw address for a contract |
tx feeshare | cancel | Remove the devgas for a contract |
# gRPC Queries
Verb | Method | Description |
---|---|---|
gRPC | nibiru.devgas.v1.Query/Params | Get devgas params |
gRPC | nibiru.devgas.v1.Query/FeeShare | Get the devgas for a given contract |
gRPC | nibiru.devgas.v1.Query/FeeShares | Get all feeshares |
gRPC | nibiru.devgas.v1.Query/DeployerFeeShares | Get all feeshares of a given deployer |
gRPC | nibiru.devgas.v1.Query/FeeSharesByWithdrawer | Get all feeshares of a given withdrawer |
GET | /nibiru.devgas/v1/params | Get devgas params |
GET | /nibiru.devgas/v1/feeshares/{contract_address} | Get the devgas for a given contract |
GET | /nibiru.devgas/v1/feeshares | Get all feeshares |
GET | /nibiru.devgas/v1/feeshares/{deployer_address} | Get all feeshares of a given deployer |
GET | /nibiru.devgas/v1/feeshares/{withdraw_address} | Get all feeshares of a given withdrawer |
# gRPC Transactions
Verb | Method | Description |
---|---|---|
gRPC | nibiru.devgas.v1.Msg/RegisterFeeShare | Register a contract for receiving devgas |
gRPC | nibiru.devgas.v1.Msg/UpdateFeeShare | Update the withdraw address for a contract |
gRPC | nibiru.devgas.v1.Msg/CancelFeeShare | Remove the devgas for a contract |
POST | /nibiru.devgas/v1/tx/register_feeshare | Register a contract for receiving devgas |
POST | /nibiru.devgas/v1/tx/update_feeshare | Update the withdraw address for a contract |
POST | /nibiru.devgas/v1/tx/cancel_feeshare | Remove the devgas for a contract |