Validators
Validators are staked network participants who solve AI inference tasks and verify solution validity through voting. They earn fees and mining rewards for their work.
The Validator Data Structure
The Validator struct tracks all on-chain data for each validator, including their staked balance, active status, and withdraw requests.
Properties
- Name
staked
- Type
- uint256
- required
- Defaults to
- Description
How much the validator has staked
- Name
addr
- Type
- address
- required
- Defaults to
- Description
Address of the validator
- Name
since
- Type
- uint256
- required
- Defaults to
- Description
Timestamp when validator first staked minimum amount (V2+)
Validator Stake Compounding (V6+)
What Changed in V6
Previously, validators received rewards via direct token transfers. In V6:
- Solution fees → Added directly to validator stake
- Mining rewards → Added directly to validator stake
- Contestation rewards → Added directly to validator stake
Benefits
- Automatic compounding - No manual restaking required
- Gas efficient - No transfer transactions needed
- Increased voting power - Your stake grows with earnings
- Simplified operations - One less thing to manage
How to Access Your Earnings
To withdraw your accumulated earnings:
- Initiate a validator withdraw request with
initiateValidatorWithdraw(amount)
- Wait for the unlock period (
exitValidatorMinUnlockTime
- typically 24 hours) - Call
validatorWithdraw(count, recipient)
to receive your tokens
Your staked balance includes all your original stake plus all accumulated rewards.
Retrieve validator
Look up a validator by their address.
Request
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/EngineV1.sol/EngineV1.json';
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
const engine = new ethers.Contract(
Config.engineAddress,
EngineArtifact.abi,
provider,
)
// validator address here
const address = '0x...'
const validator = await engine.validators(address);
const { staked, addr } = validator;
Deposit to become validator
Anyone can deposit AIUS tokens for any address to help them become or remain a validator. To be an active validator, you must maintain a staked balance of at least validatorMinimum
(a percentage of total supply).
The only things that reduce your staked balance are:
- Being slashed for losing a contestation vote
- Initiating a withdraw request
Request
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/V2_EngineV6.sol/V2_EngineV6.json';
import BaseTokenArtifact from './artifacts/BaseToken.sol/BaseToken.json';
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
const wallet = new ethers.Wallet(
process.env.PRIVATE_KEY,
provider,
);
const engine = new ethers.Contract(
Config.engineAddress,
EngineArtifact.abi,
wallet,
)
const baseToken = new ethers.Contract(
Config.baseTokenAddress,
BaseTokenArtifact.abi,
wallet,
)
// Get minimum validator stake required
const minStake = await engine.getValidatorMinimum()
// Approve tokens
await baseToken.approve(engine.address, minStake)
// Deposit for yourself (or another address)
const validatorAddress = wallet.address
const tx = await engine.validatorDeposit(validatorAddress, minStake)
const receipt = await tx.wait();
Withdraw validator stake
Withdrawing your stake is a three-step process:
Step 1: Initiate Withdraw
- Call
initiateValidatorWithdraw(amount)
- Receive a request ID (counter)
- Tokens are locked but still count toward your stake
Step 2: Wait for Unlock
- Wait
exitValidatorMinUnlockTime
(typically 24 hours) - Check unlock time via
pendingValidatorWithdrawRequests
- You can cancel the request if needed
Step 3: Complete Withdraw
- Call
validatorWithdraw(requestId, recipientAddress)
- Tokens are transferred to recipient
- Your staked balance is reduced
If your staked balance minus pending withdraws falls below validatorMinimum
, you cannot submit solutions or vote on contestations.
Request
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/V2_EngineV6.sol/V2_EngineV6.json';
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
const wallet = new ethers.Wallet(
process.env.PRIVATE_KEY,
provider,
);
const engine = new ethers.Contract(
Config.engineAddress,
EngineArtifact.abi,
wallet,
)
// Step 1: Initiate withdraw
const withdrawAmount = ethers.utils.parseEther('100')
const initTx = await engine.initiateValidatorWithdraw(withdrawAmount)
const initReceipt = await initTx.wait()
// Get the request ID from the event
const event = initReceipt.events.find(e => e.event === 'ValidatorWithdrawInitiated')
const requestId = event.args.count
// Step 2: Check unlock time
const request = await engine.pendingValidatorWithdrawRequests(
wallet.address,
requestId
)
console.log('Unlock time:', new Date(request.unlockTime * 1000))
// Optional: Cancel the request
// await engine.cancelValidatorWithdraw(requestId)
// Step 3: After unlock time passes, complete withdraw
const withdrawTx = await engine.validatorWithdraw(requestId, wallet.address)
const withdrawReceipt = await withdrawTx.wait()