Staking Operations

This page covers validator staking, delegation pool management, and token transfers on Starknet.

Prerequisites

Environment Setup

Before running any staking commands, source the appropriate setup script to configure environment variables for all accounts and contract addresses.

Mainnet

export STARKNET_NETWORK=mainnet
export STARKNET_RPC=https://starknet-mainnet.public.blastapi.io

export VALIDATOR_KEYSTORE=~/.starknet/${STARKNET_NETWORK}/signers/validator.json
export VALIDATOR_ACCOUNT=~/.starknet/${STARKNET_NETWORK}/accounts/validator.json

export REWARDS_KEYSTORE=~/.starknet/${STARKNET_NETWORK}/signers/rewards.json
export REWARDS_ACCOUNT=~/.starknet/${STARKNET_NETWORK}/accounts/rewards.json

export OPERATOR_KEYSTORE=~/.starknet/${STARKNET_NETWORK}/signers/operator.json
export OPERATOR_ACCOUNT=~/.starknet/${STARKNET_NETWORK}/accounts/operator.json

# Contract addresses
export STAKING_CONTRACT_ADDRESS=0x00ca1702e64c81d9a07b86bd2c540188d92a2c73cf5cc0e508d949015e7e84a7
export STRK_CONTRACT_ADDRESS=0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d

Sepolia (Testnet)

export STARKNET_NETWORK=sepolia
export STARKNET_RPC=https://starknet-sepolia.drpc.org

export VALIDATOR_KEYSTORE=~/.starknet/${STARKNET_NETWORK}/signers/validator.json
export VALIDATOR_ACCOUNT=~/.starknet/${STARKNET_NETWORK}/accounts/validator.json

export REWARDS_KEYSTORE=~/.starknet/${STARKNET_NETWORK}/signers/rewards.json
export REWARDS_ACCOUNT=~/.starknet/${STARKNET_NETWORK}/accounts/rewards.json

export OPERATOR_KEYSTORE=~/.starknet/${STARKNET_NETWORK}/signers/operator.json
export OPERATOR_ACCOUNT=~/.starknet/${STARKNET_NETWORK}/accounts/operator.json

# Contract addresses
export STAKING_CONTRACT_ADDRESS=0x03745ab04a431fc02871a139be6b93d9260b0ff3e779ad9c8b377183b23109f1
export STRK_CONTRACT_ADDRESS=0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d

Initial Stake

Staking requires two transactions: first approve the STRK spend, then call stake on the staking contract. This creates a new delegation pool.

Approve STRK Spend

starkli invoke \
    --account=${VALIDATOR_ACCOUNT} \
    --keystore=${VALIDATOR_KEYSTORE} \
    ${STRK_CONTRACT_ADDRESS} approve ${STAKING_CONTRACT_ADDRESS} u256:20000000000000000000000

Register Stake

starkli invoke \
    --account=${VALIDATOR_ACCOUNT} \
    --keystore=${VALIDATOR_KEYSTORE} \
    ${STAKING_CONTRACT_ADDRESS} stake \
    ${REWARDS_ADDRESS} \
    ${OPERATOR_ADDRESS} \
    0x43c33c1937564800000 \
    0x01 \
    0x2bc

NOTE: The stake transaction emits a NewDelegationPool event. Record the pool contract address from this event for use in delegation operations.

export DELEGATION_POOL_CONTRACT_ADDRESS=<address from NewDelegationPool event>

Increase Stake

To add more STRK to an existing validator stake:

starkli invoke \
    --account=${VALIDATOR_ACCOUNT} \
    --keystore=${VALIDATOR_KEYSTORE} \
    ${STRK_CONTRACT_ADDRESS} approve ${STAKING_CONTRACT_ADDRESS} u256:2000000000000000000

starkli invoke \
    --account=${VALIDATOR_ACCOUNT} \
    --keystore=${VALIDATOR_KEYSTORE} \
    ${STAKING_CONTRACT_ADDRESS} increase_stake ${VALIDATOR_ADDRESS} 0x1bc16d674ec80000

Delegation

Enter Delegation Pool

A delegator can stake STRK into the validator's delegation pool:

starkli invoke \
    --account=${STAKER_ACCOUNT} \
    --keystore=${STAKER_KEYSTORE} \
    ${STRK_CONTRACT_ADDRESS} approve ${DELEGATION_POOL_CONTRACT_ADDRESS} u256:5000000000000000000

starkli invoke \
    --account=${STAKER_ACCOUNT} \
    --keystore=${STAKER_KEYSTORE} \
    ${DELEGATION_POOL_CONTRACT_ADDRESS} enter_delegation_pool ${STAKER_REWARDS_ADDRESS} 5000000000000000000

Increase Delegation

starkli invoke \
    --account=${STAKER_ACCOUNT} \
    --keystore=${STAKER_KEYSTORE} \
    ${STRK_CONTRACT_ADDRESS} approve ${DELEGATION_POOL_CONTRACT_ADDRESS} u256:3000000000000000000

starkli invoke \
    --account=${STAKER_ACCOUNT} \
    --keystore=${STAKER_KEYSTORE} \
    ${DELEGATION_POOL_CONTRACT_ADDRESS} add_to_delegation_pool ${STAKER_REWARDS_ADDRESS} 5000000000000000000

Token Transfers

Transfer ETH

eth is a hard-coded address in the Starknet address book:

starkli invoke \
    --account=${SENDER_ACCOUNT} \
    --keystore=${SENDER_KEYSTORE} \
    eth transfer ${RECIPIENT_ADDRESS} u256:50000000000000000000

Transfer STRK

starkli invoke \
    --account=${SENDER_ACCOUNT} \
    --keystore=${SENDER_KEYSTORE} \
    ${STRK_CONTRACT_ADDRESS} transfer ${RECIPIENT_ADDRESS} u256:50000000000000000000