Verifier Rewards

Verifiers are responsible for securing transactions with chains connected to the Axelar Network via the Axelar Amplifier. Verifiers vote on the truthfulness of transactions posted to the network and create signatures for outgoing messages. In compensation for these activities and the associated decentralized node running costs, verifiers earn rewards provided by each chain integrator.

Rewards are calculated based on counted contributions. A contribution is counted whenever a poll ends based on the verifiers who voted, and when a verifier signs an event. Contributions are tracked in the verifier rewards contract.

Contributions are assessed per epoch (a length of time configured by governance). At the conclusion of an epoch, a message can be sent to the rewards contract to process rewards for the most recent window. Rewards are calculated based on a percentage of all traffic for a given chain and paid in AXL.

Your browser does not support SVG

💡

The EndBlocker is code that executes at the end of each block so that rewards are distributed automatically. It has not yet been implemented in the Axelar Amplifier.

Your browser does not support SVG

  1. The relayer picks up a callContract() event and calls verify_messages() on the Axelar gateway.
  2. The Axelar gateway calls verify_messages() on the voting verifier, which begins the voting process with the verifier set.
  3. Once enough votes have been cast for the message, a record_participation() event is emitted to the rewards contract.
  4. The rewards contract keeps a tally of how many events each verifier correctly participated in.

The destination chain uses the prover rather than the voting verifier to pass the message.

  1. The multisig prover gets the messages and their contents from the gateway and calls start_signing_session() on the multisig contract, which begins the signing process with the verifier set.
  2. Registered chains, who have their own sets of verifiers, become aware that there is a signing session for the chain they support with their public keys and start signing.
  3. Once enough signatures have been gathered, a signed batch will be created and eventually relayed back to the source chain.
  4. If a verifier signed during a certain grace period, the multisig contract emits a record_participation() event to the rewards contract.
  5. The rewards contract keeps a tally of how many events each verifier correctly participated in.

Each integrated chain has two pools that must be funded independently. There is one rewards pool for signing and one pool for voting.

Reward pools are not tied to an epoch. If earned rewards are not claimed, they will continue to grow. If rewards are being earned but the pool has not been sufficiently funded, these rewards can be funded and claimed at a later date. Integrators should ensure that pools always have enough funds so that verifiers can get their rewards quickly.

Rewards are calculated through the following parameters, which are first configured during contract instantiation. These parameters can be modified through governance:

  • epoch_duration — How often rewards are calculated, specified in number of blocks. For example, an epoch_duration of 500 blocks will reward verifiers for their participation in each 500-block window.
  • rewards_per_epoch — The total number of tokens distributed as rewards per epoch, split equally amongst all participating verifiers for a given epoch. The same for both signing and voting.
  • participation_threshold — The participation threshold that verifiers must meet to receive given rewards in a given epoch, specified as a fraction between 0 (exclusive) and 1 (exclusive). Verifiers must participate in at least this fraction of all events in a given epoch to receive rewards. Participation is reset at the beginning of each epoch, so participation in previous epochs does not affect rewards for future epochs.

Use rewards_pool() to check the funds in a pool:

Terminal window
REWARDS_CONTRACT_ADDRESS="axelar1vaj9sfzc3z0gpel90wu4ljutncutv0wuhvvwfsh30rqxq422z89qnd989l"
export CHAIN_NAME="fantom" export
VOTING_VERIFIER_OR_MULTISIG_CONTRACT_ADDRESS="axelar1ty7mx0cllgz8xuvhn2j7e3qy8999ssgmjtktyqetl335em0g88lq6rjhl2"
# or "axelar1g6520uhs8u37el40wqngf60z06mjgk6z7nezytd2mxrmh7yesnmsyc0zjw"
export RPC="http://devnet-amplifier.axelar.dev:26657"
Terminal window
REWARDS_CONTRACT_ADDRESS="axelar1harq5xe68lzl2kx4e5ch4k8840cgqnry567g0fgw7vt2atcuugrqfa7j5z"
export CHAIN_NAME="test-avalanche" export
VOTING_VERIFIER_OR_MULTISIG_CONTRACT_ADDRESS="axelar1hupk5du59cgu4ps5s637rhakwsq0060ycdp57j2ccevna7wqqzrqnfrr0p"#
or "axelar1l5k8wlzmkmtnvjvs9x77wdcfweucwgums9e8fh0d8cy76ymqc5aqzguqnn"
export RPC="https://tm.axelar-testnet.lava.build:443"

💡

You can get the addresses of the rewards, voting verifier, and multisig contracts through devnet-amplifier.json.

Terminal window
axelard q wasm contract-state smart $REWARDS_CONTRACT_ADDRESS \
'{
"rewards_pool":
{
"pool_id":
{
"chain_name":"'"$CHAIN_NAME"'",
"contract":"'"$VOTING_VERIFIER_OR_MULTISIG_CONTRACT_ADDRESS"'"
}
}
}' \
--node $RPC

Use distribute_rewards() to distribute rewards from a pool:

Terminal window
export REWARDS_CONTRACT_ADDRESS="axelar1vaj9sfzc3z0gpel90wu4ljutncutv0wuhvvwfsh30rqxq422z89qnd989l"
export CHAIN_NAME="avalanche"
export VOTING_VERIFIER_OR_MULTISIG_CONTRACT_ADDRESS="axelar1elaymnd2epmfr498h2x9p2nezc4eklv95uv92u9csfs8wl75w7yqdc0h67" || "0x7eeE33A59Db27d762AA1Fa31b26efeE0dABa1132"
export RPC="http://devnet-amplifier.axelar.dev:26657"
Terminal window
export REWARDS_CONTRACT_ADDRESS="axelar1harq5xe68lzl2kx4e5ch4k8840cgqnry567g0fgw7vt2atcuugrqfa7j5z"
export CHAIN_NAME="test-avalanche"
export VOTING_VERIFIER_OR_MULTISIG_CONTRACT_ADDRESS="axelar1hupk5du59cgu4ps5s637rhakwsq0060ycdp57j2ccevna7wqqzrqnfrr0p" || "0x7eeE33A59Db27d762AA1Fa31b26efeE0dABa1132"
export RPC="https://tm.axelar-testnet.lava.build:443"

💡

You can get the addresses of the rewards, voting verifier, and multisig contracts through devnet-amplifier.json.

Terminal window
axelard tx wasm execute $REWARDS_CONTRACT_ADDRESS \
'{
"distribute_rewards":
{
"pool_id":
{
"chain_name":"'"$CHAIN_NAME"'",
"contract":"'"$VOTING_VERIFIER_OR_MULTISIG_CONTRACT_ADDRESS"'"
},
"epoch_count":10
}
}' \
--keyring-backend test \
--from wallet \
--gas auto --gas-adjustment 1.5 --gas-prices 0.007uamplifier \
--node $RPC

Rewards are distributed to verifiers with a participation rate greater than the threshold as the epoch closes. Rewards are calculated based on the time passed since the last event and the total number of verifiers, and split equally amongst all participating verifiers in the epoch.

epoch_count is the maximum number of historical epochs for which to distribute rewards, starting with the oldest. If not specified, rewards will be distributed for the last 10 epochs.

By default your verifier rewards will be sent to the address of your verifier (change this with ampd set-rewards-proxy). To withdraw your rewards, use ampd’s send-tokens feature.

Terminal window
ampd send-tokens <destination address> <amount with 6 decimals> uaxl

Edit on GitHub