Reference

Contract Addresses

Deployed contract addresses for Vara.eth on all networks.

Contract Addresses

Hoodi Testnet

ContractAddressDescription
Router0xBC888a8B050B9B76a985d91c815d2c4f2131a58ACore settlement contract. Manages code validation, program creation, and batch commitments.
MiddlewareCheck Router or testnet UIValidator management contract integrated with Symbiotic. Handles operator registration, stake vaults, election, rewards, and slashing.
wVARACheck Router or testnet UIERC-20 wrapped VARA token.
Mirror (per program)Deterministic per programEach program gets its own Mirror proxy. Address = CREATE2(Router, keccak256(codeId, salt)).
MirrorProxyImplementation singletonEIP-1167 minimal proxy implementation used by all Mirror instances.
MirrorProxySmallImplementation singletonGas-optimized variant for programs with minimal state.

For Vara Network bridge contract addresses (Verifier, MessageQueue, BridgingPayment, ERC20Manager, etc.), see the Bridge Developer Hub.

Finding a Program's Mirror Address

The Mirror address is deterministic and available as actorId in the ProgramCreated event:

import { ethers } from "ethers";

const router = new ethers.Contract(ROUTER_ADDRESS, routerAbi, provider);

// Listen for new programs
router.on("ProgramCreated", (actorId, codeId) => {
  console.log(`Program ${actorId} created from code ${codeId}`);
});

Verifying on Etherscan

  1. Go to the Mirror address on Hoodi Etherscan
  2. The contract shows as a proxy (EIP-1167)
  3. If deployed with ABI (createProgramWithAbiInterface), Etherscan shows decoded methods under "Write as Proxy" and "Read as Proxy"

Router Contract Interface

Key Router methods:

interface IRouter {
    // Upload and validate WASM code
    function requestCodeValidation(bytes32 codeId) external;

    // Create a new program instance
    function createProgram(
        bytes32 codeId,
        bytes32 salt,
        address overrideInitializer
    ) external returns (address);

    // Create with ABI for Etherscan integration
    function createProgramWithAbiInterface(
        bytes32 codeId,
        bytes32 salt,
        address overrideInitializer,
        address abiInterface
    ) external returns (address);

    // Events
    event ProgramCreated(address actorId, bytes32 indexed codeId);
    event CodeGotValidated(bytes32 codeId, bool indexed valid);
    event BatchCommitted(bytes32 hash);
    event CodeValidationRequested(bytes32 codeId);
}

Middleware Contract Interface

The Middleware integrates Vara.eth with Symbiotic for validator management. Key functions:

interface IMiddleware {
    // Validator set management
    function makeElectionAt(uint48 ts, uint256 maxValidators)
        external view returns (address[] memory);

    function getOperatorStakeAt(address operator, uint48 ts)
        external view returns (uint256 stake);

    // Operator registration
    function registerOperator() external;
    function disableOperator() external;
    function unregisterOperator(address operator) external;

    // Vault management (by vault owner)
    function registerVault(address vault, address rewards) external;
    function unregisterVault(address vault) external;

    // Rewards distribution (called by Router)
    function distributeOperatorRewards(
        address token,
        uint256 amount,
        bytes32 root
    ) external returns (bytes32);

    // Slashing
    function requestSlash(SlashData[] calldata data) external;
    function executeSlash(SlashIdentifier[] calldata slashes) external;

    // Parameters
    function eraDuration() external view returns (uint48);
    function minVaultEpochDuration() external view returns (uint48);
    function collateral() external view returns (address); // wVARA
}

Source: IMiddleware.sol

Mirror Contract Interface

Every Mirror exposes:

interface IMirror {
    // Primary functions
    function sendMessage(bytes calldata payload, bool callReply)
        external payable returns (bytes32);

    function sendReply(bytes32 repliedTo, bytes calldata payload)
        external payable;

    function claimValue(bytes32 claimedId) external;

    function executableBalanceTopUp(uint128 value) external;

    function transferLockedValueToInheritor() external;

    // State queries
    function stateHash() external view returns (bytes32);
    function nonce() external view returns (uint256);
    function exited() external view returns (bool);
    function inheritor() external view returns (address);
    function initializer() external view returns (address);

    // Events for users (informational)
    event StateChanged(bytes32 stateHash);
    event Message(bytes32 id, address indexed destination, bytes payload, uint128 value);
    event Reply(bytes payload, uint128 value, bytes32 replyTo, bytes4 indexed replyCode);
    event ValueClaimed(bytes32 claimedId, uint128 value);
    event MessageCallFailed(bytes32 id, address indexed destination, uint128 value);
    event ReplyCallFailed(uint128 value, bytes32 replyTo, bytes4 indexed replyCode);

    // Events for validators (requesting)
    event MessageQueueingRequested(
        bytes32 id,
        address indexed source,
        bytes payload,
        uint128 value,
        bool callReply
    );
    event ReplyQueueingRequested(
        bytes32 repliedTo,
        address indexed source,
        bytes payload,
        uint128 value
    );
    event ValueClaimingRequested(bytes32 claimedId, address indexed source);
    event ExecutableBalanceTopUpRequested(uint128 value);
    event OwnedBalanceTopUpRequested(uint128 value);
}

Ethereum Mainnet

Coming Soon

Addresses will be published here at mainnet launch.

On this page