Gaia EVM Devnet
- Introduction
- Connect to the Network
- Run a Full Node
- Get Tokens
- Tooling & Resources
Distribution
Withdraw staking rewards and interact with the community pool
Overview
The Distribution precompile provides access to the Cosmos SDK x/distribution
module, enabling smart contracts to manage staking rewards, interact with the community pool, and handle validator commission operations.
Precompile Address: 0x0000000000000000000000000000000000000801
Related Module: x/distribution
Transaction Methods
claimRewards
Claims staking rewards from multiple validators.
withdrawDelegatorRewards
Withdraws staking rewards from a single, specific validator.
setWithdrawAddress
Sets or changes the withdrawal address for receiving staking rewards.
withdrawValidatorCommission
Withdraws a validator’s accumulated commission rewards.
fundCommunityPool
Sends tokens directly to the community pool.
depositValidatorRewardsPool
Deposits tokens into a specific validator’s rewards pool.
Query Methods
delegationTotalRewards
Retrieves comprehensive reward information for all of a delegator’s positions.
import { ethers } from "ethers";
// ABI definition for the relevant parts of the precompile
const precompileAbi = [
"function delegationTotalRewards(address delegatorAddress) view returns (tuple(string validatorAddress, tuple(string denom, uint256 amount, uint8 precision)[] reward)[] rewards, tuple(string denom, uint256 amount, uint8 precision)[] total)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000801";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Input: The address of the delegator to query
const delegatorAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // Placeholder
async function getTotalRewards() {
try {
const result = await contract.delegationTotalRewards(delegatorAddress);
console.log("Total Rewards:", JSON.stringify({
rewards: result.rewards,
total: result.total
}, null, 2));
} catch (error) {
console.error("Error fetching total rewards:", error);
}
}
getTotalRewards();
delegationRewards
Queries pending rewards for a specific delegation.
import { ethers } from "ethers";
// ABI definition for the function
const precompileAbi = [
"function delegationRewards(address delegatorAddress, string memory validatorAddress) view returns (tuple(string denom, uint256 amount, uint8 precision)[] rewards)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000801";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Inputs
const delegatorAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // Placeholder
const validatorAddress = "artvaloper1..."; // Placeholder
async function getDelegationRewards() {
try {
const rewards = await contract.delegationRewards(delegatorAddress, validatorAddress);
console.log("Delegation Rewards:", JSON.stringify(rewards, null, 2));
} catch (error) {
console.error("Error fetching delegation rewards:", error);
}
}
getDelegationRewards();
delegatorValidators
Retrieves a list of all validators from which a delegator has rewards.
import { ethers } from "ethers";
// ABI definition for the function
const precompileAbi = [
"function delegatorValidators(address delegatorAddress) view returns (string[] validators)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000801";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Input
const delegatorAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // Placeholder
async function getDelegatorValidators() {
try {
const validators = await contract.delegatorValidators(delegatorAddress);
console.log("Validators:", validators);
} catch (error) {
console.error("Error fetching delegator validators:", error);
}
}
getDelegatorValidators();
delegatorWithdrawAddress
Queries the address that can withdraw rewards for a given delegator.
import { ethers } from "ethers";
// ABI definition for the function
const precompileAbi = [
"function delegatorWithdrawAddress(address delegatorAddress) view returns (string withdrawAddress)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000801";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Input
const delegatorAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // Placeholder
async function getWithdrawAddress() {
try {
const withdrawAddress = await contract.delegatorWithdrawAddress(delegatorAddress);
console.log("Withdraw Address:", withdrawAddress);
} catch (error) {
console.error("Error fetching withdraw address:", error);
}
}
getWithdrawAddress();
communityPool
Queries the current balance of the community pool.
import { ethers } from "ethers";
// ABI definition for the function
const precompileAbi = [
"function communityPool() view returns (tuple(string denom, uint256 amount, uint8 precision)[] coins)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000801";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
async function getCommunityPoolBalance() {
try {
const balance = await contract.communityPool();
console.log("Community Pool Balance:", JSON.stringify(balance, null, 2));
} catch (error) {
console.error("Error fetching community pool balance:", error);
}
}
getCommunityPoolBalance();
validatorCommission
Queries the accumulated commission for a specific validator.
import { ethers } from "ethers";
// ABI definition for the function
const precompileAbi = [
"function validatorCommission(string memory validatorAddress) view returns (tuple(string denom, uint256 amount, uint8 precision)[] commission)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000801";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Input
const validatorAddress = "artvaloper1..."; // Placeholder
async function getValidatorCommission() {
try {
const commission = await contract.validatorCommission(validatorAddress);
console.log("Validator Commission:", JSON.stringify(commission, null, 2));
} catch (error) {
console.error("Error fetching validator commission:", error);
}
}
getValidatorCommission();
validatorDistributionInfo
Queries a validator’s commission and self-delegation rewards.
import { ethers } from "ethers";
// ABI definition for the function
const precompileAbi = [
"function validatorDistributionInfo(string memory validatorAddress) view returns (tuple(string operatorAddress, tuple(string denom, uint256 amount, uint8 precision)[] selfBondRewards, tuple(string denom, uint256 amount, uint8 precision)[] commission) distributionInfo)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000801";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Input
const validatorAddress = "artvaloper1..."; // Placeholder
async function getValidatorDistInfo() {
try {
const info = await contract.validatorDistributionInfo(validatorAddress);
console.log("Validator Distribution Info:", JSON.stringify(info, null, 2));
} catch (error) {
console.error("Error fetching validator distribution info:", error);
}
}
getValidatorDistInfo();
validatorOutstandingRewards
Queries the outstanding rewards of a validator.
import { ethers } from "ethers";
// ABI definition for the function
const precompileAbi = [
"function validatorOutstandingRewards(string memory validatorAddress) view returns (tuple(string denom, uint256 amount, uint8 precision)[] rewards)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000801";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Input
const validatorAddress = "artvaloper1..."; // Placeholder
async function getOutstandingRewards() {
try {
const rewards = await contract.validatorOutstandingRewards(validatorAddress);
console.log("Validator Outstanding Rewards:", JSON.stringify(rewards, null, 2));
} catch (error) {
console.error("Error fetching outstanding rewards:", error);
}
}
getOutstandingRewards();
validatorSlashes
Queries slashing events for a validator within a specific height range.
import { ethers } from "ethers";
// ABI definition for the function
const precompileAbi = [
"function validatorSlashes(string memory validatorAddress, uint64 startingHeight, uint64 endingHeight, tuple(bytes key, uint64 offset, uint64 limit, bool countTotal, bool reverse) pageRequest) view returns (tuple(uint64 validatorPeriod, tuple(uint256 amount, uint8 precision) fraction)[] slashes, tuple(bytes nextKey, uint64 total) pageResponse)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000801";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Inputs
const validatorAddress = "artvaloper1..."; // Placeholder
const startingHeight = 1000; // Starting block height
const endingHeight = 2000; // Ending block height
const pageRequest = {
key: "0x",
offset: 0,
limit: 10,
countTotal: true,
reverse: false
};
async function getValidatorSlashes() {
try {
const [slashes, pageResponse] = await contract.validatorSlashes(
validatorAddress,
startingHeight,
endingHeight,
pageRequest
);
console.log("Validator Slashes:", JSON.stringify(slashes, null, 2));
console.log("Page Response:", JSON.stringify(pageResponse, null, 2));
} catch (error) {
console.error("Error fetching validator slashes:", error);
}
}
getValidatorSlashes();
Full Solidity Interface & ABI
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.17;
import "../common/Types.sol";
/// @dev The DistributionI contract's address.
address constant DISTRIBUTION_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000801;
/// @dev The DistributionI contract's instance.
DistributionI constant DISTRIBUTION_CONTRACT = DistributionI(
DISTRIBUTION_PRECOMPILE_ADDRESS
);
struct ValidatorSlashEvent {
uint64 validatorPeriod;
Dec fraction;
}
struct ValidatorDistributionInfo {
string operatorAddress;
DecCoin[] selfBondRewards;
DecCoin[] commission;
}
struct DelegationDelegatorReward {
string validatorAddress;
DecCoin[] reward;
}
/// @author Evmos Team
/// @title Distribution Precompile Contract
/// @dev The interface through which solidity contracts will interact with Distribution
/// @custom:address 0x0000000000000000000000000000000000000801
interface DistributionI {
event ClaimRewards(address indexed delegatorAddress, uint256 amount);
event SetWithdrawerAddress(address indexed caller, string withdrawerAddress);
event WithdrawDelegatorReward(address indexed delegatorAddress, address indexed validatorAddress, uint256 amount);
event WithdrawValidatorCommission(string indexed validatorAddress, uint256 commission);
event FundCommunityPool(address indexed depositor, string denom, uint256 amount);
event DepositValidatorRewardsPool(address indexed depositor, address indexed validatorAddress, string denom, uint256 amount);
function claimRewards(address delegatorAddress, uint32 maxRetrieve) external returns (bool success);
function setWithdrawAddress(address delegatorAddress, string memory withdrawerAddress) external returns (bool success);
function withdrawDelegatorRewards(address delegatorAddress, string memory validatorAddress) external returns (Coin[] calldata amount);
function withdrawValidatorCommission(string memory validatorAddress) external returns (Coin[] calldata amount);
function fundCommunityPool(address depositor, Coin[] memory amount) external returns (bool success);
function depositValidatorRewardsPool(address depositor, string memory validatorAddress, Coin[] memory amount) external returns (bool success);
function validatorDistributionInfo(string memory validatorAddress) external view returns (ValidatorDistributionInfo calldata distributionInfo);
function validatorOutstandingRewards(string memory validatorAddress) external view returns (DecCoin[] calldata rewards);
function validatorCommission(string memory validatorAddress) external view returns (DecCoin[] calldata commission);
function validatorSlashes(string memory validatorAddress, uint64 startingHeight, uint64 endingHeight, PageRequest calldata pageRequest) external view returns (ValidatorSlashEvent[] calldata slashes, PageResponse calldata pageResponse);
function delegationRewards(address delegatorAddress, string memory validatorAddress) external view returns (DecCoin[] calldata rewards);
function delegationTotalRewards(address delegatorAddress) external view returns (DelegationDelegatorReward[] calldata rewards, DecCoin[] calldata total);
function delegatorValidators(address delegatorAddress) external view returns (string[] calldata validators);
function delegatorWithdrawAddress(address delegatorAddress) external view returns (string memory withdrawAddress);
function communityPool() external view returns (DecCoin[] calldata coins);
}
{
"_format": "hh-sol-artifact-1",
"contractName": "DistributionI",
"sourceName": "solidity/precompiles/distribution/DistributionI.sol",
"abi": [
{ "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "delegatorAddress", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "ClaimRewards", "type": "event" },
{ "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "depositor", "type": "address" }, { "indexed": true, "internalType": "address", "name": "validatorAddress", "type": "address" }, { "indexed": false, "internalType": "string", "name": "denom", "type": "string" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "DepositValidatorRewardsPool", "type": "event" },
{ "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "depositor", "type": "address" }, { "indexed": false, "internalType": "string", "name": "denom", "type": "string" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "FundCommunityPool", "type": "event" },
{ "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "caller", "type": "address" }, { "indexed": false, "internalType": "string", "name": "withdrawerAddress", "type": "string" } ], "name": "SetWithdrawerAddress", "type": "event" },
{ "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "delegatorAddress", "type": "address" }, { "indexed": true, "internalType": "address", "name": "validatorAddress", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "WithdrawDelegatorReward", "type": "event" },
{ "anonymous": false, "inputs": [ { "indexed": true, "internalType": "string", "name": "validatorAddress", "type": "string" }, { "indexed": false, "internalType": "uint256", "name": "commission", "type": "uint256" } ], "name": "WithdrawValidatorCommission", "type": "event" },
{ "inputs": [ { "internalType": "address", "name": "delegatorAddress", "type": "address" }, { "internalType": "uint32", "name": "maxRetrieve", "type": "uint32" } ], "name": "claimRewards", "outputs": [ { "internalType": "bool", "name": "success", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" },
{ "inputs": [], "name": "communityPool", "outputs": [ { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint8", "name": "precision", "type": "uint8" } ], "internalType": "struct DecCoin[]", "name": "coins", "type": "tuple[]" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "internalType": "address", "name": "delegatorAddress", "type": "address" }, { "internalType": "string", "name": "validatorAddress", "type": "string" } ], "name": "delegationRewards", "outputs": [ { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint8", "name": "precision", "type": "uint8" } ], "internalType": "struct DecCoin[]", "name": "rewards", "type": "tuple[]" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "internalType": "address", "name": "delegatorAddress", "type": "address" } ], "name": "delegationTotalRewards", "outputs": [ { "components": [ { "internalType": "string", "name": "validatorAddress", "type": "string" }, { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint8", "name": "precision", "type": "uint8" } ], "internalType": "struct DecCoin[]", "name": "reward", "type": "tuple[]" } ], "internalType": "struct DelegationDelegatorReward[]", "name": "rewards", "type": "tuple[]" }, { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint8", "name": "precision", "type": "uint8" } ], "internalType": "struct DecCoin[]", "name": "total", "type": "tuple[]" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "internalType": "address", "name": "delegatorAddress", "type": "address" } ], "name": "delegatorValidators", "outputs": [ { "internalType": "string[]", "name": "validators", "type": "string[]" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "internalType": "address", "name": "delegatorAddress", "type": "address" } ], "name": "delegatorWithdrawAddress", "outputs": [ { "internalType": "string", "name": "withdrawAddress", "type": "string" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "internalType": "address", "name": "depositor", "type": "address" }, { "internalType": "string", "name": "validatorAddress", "type": "string" }, { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "internalType": "struct Coin[]", "name": "amount", "type": "tuple[]" } ], "name": "depositValidatorRewardsPool", "outputs": [ { "internalType": "bool", "name": "success", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" },
{ "inputs": [ { "internalType": "address", "name": "depositor", "type": "address" }, { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "internalType": "struct Coin[]", "name": "amount", "type": "tuple[]" } ], "name": "fundCommunityPool", "outputs": [ { "internalType": "bool", "name": "success", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" },
{ "inputs": [ { "internalType": "address", "name": "delegatorAddress", "type": "address" }, { "internalType": "string", "name": "withdrawerAddress", "type": "string" } ], "name": "setWithdrawAddress", "outputs": [ { "internalType": "bool", "name": "success", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" },
{ "inputs": [ { "internalType": "string", "name": "validatorAddress", "type": "string" } ], "name": "validatorCommission", "outputs": [ { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint8", "name": "precision", "type": "uint8" } ], "internalType": "struct DecCoin[]", "name": "commission", "type": "tuple[]" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "internalType": "string", "name": "validatorAddress", "type": "string" } ], "name": "validatorDistributionInfo", "outputs": [ { "components": [ { "internalType": "string", "name": "operatorAddress", "type": "string" }, { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint8", "name": "precision", "type": "uint8" } ], "internalType": "struct DecCoin[]", "name": "selfBondRewards", "type": "tuple[]" }, { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint8", "name": "precision", "type": "uint8" } ], "internalType": "struct DecCoin[]", "name": "commission", "type": "tuple[]" } ], "internalType": "struct ValidatorDistributionInfo", "name": "distributionInfo", "type": "tuple" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "internalType": "string", "name": "validatorAddress", "type": "string" } ], "name": "validatorOutstandingRewards", "outputs": [ { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint8", "name": "precision", "type": "uint8" } ], "internalType": "struct DecCoin[]", "name": "rewards", "type": "tuple[]" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "internalType": "string", "name": "validatorAddress", "type": "string" }, { "internalType": "uint64", "name": "startingHeight", "type": "uint64" }, { "internalType": "uint64", "name": "endingHeight", "type": "uint64" }, { "components": [ { "internalType": "bytes", "name": "key", "type": "bytes" }, { "internalType": "uint64", "name": "offset", "type": "uint64" }, { "internalType": "uint64", "name": "limit", "type": "uint64" }, { "internalType": "bool", "name": "countTotal", "type": "bool" }, { "internalType": "bool", "name": "reverse", "type": "bool" } ], "internalType": "struct PageRequest", "name": "pageRequest", "type": "tuple" } ], "name": "validatorSlashes", "outputs": [ { "components": [ { "internalType": "uint64", "name": "validatorPeriod", "type": "uint64" }, { "components": [ { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint8", "name": "precision", "type": "uint8" } ], "internalType": "struct Dec", "name": "fraction", "type": "tuple" } ], "internalType": "struct ValidatorSlashEvent[]", "name": "slashes", "type": "tuple[]" }, { "components": [ { "internalType": "bytes", "name": "nextKey", "type": "bytes" }, { "internalType": "uint64", "name": "total", "type": "uint64" } ], "internalType": "struct PageResponse", "name": "pageResponse", "type": "tuple" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "internalType": "address", "name": "delegatorAddress", "type": "address" }, { "internalType": "string", "name": "validatorAddress", "type": "string" } ], "name": "withdrawDelegatorRewards", "outputs": [ { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "internalType": "struct Coin[]", "name": "amount", "type": "tuple[]" } ], "stateMutability": "nonpayable", "type": "function" },
{ "inputs": [ { "internalType": "string", "name": "validatorAddress", "type": "string" } ], "name": "withdrawValidatorCommission", "outputs": [ { "components": [ { "internalType": "string", "name": "denom", "type": "string" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "internalType": "struct Coin[]", "name": "amount", "type": "tuple[]" } ], "stateMutability": "nonpayable", "type": "function" }
]
}
- Overview
- Transaction Methods
- claimRewards
- withdrawDelegatorRewards
- setWithdrawAddress
- withdrawValidatorCommission
- fundCommunityPool
- depositValidatorRewardsPool
- Query Methods
- delegationTotalRewards
- delegationRewards
- delegatorValidators
- delegatorWithdrawAddress
- communityPool
- validatorCommission
- validatorDistributionInfo
- validatorOutstandingRewards
- validatorSlashes
- Full Solidity Interface & ABI