LogoLogo
  • Tally Docs
  • Tally Features
    • What is Tally?
    • Token Launch
      • Claim
      • Governance Smart Contracts
      • Token Wrapper
      • Delegate Registration & Claim-and-Delegate
    • Value Accrual with Staking
      • Features & Use Cases
      • FAQ
      • Glossary
    • Governance
      • Advanced Features
        • MultiGov
        • Advanced Voting
          • Flexible Voting Extension
          • Signal Voting
            • Snapshot
          • Private Voting
        • Partial Delegation
        • Security Council Elections
        • Chain Integration
        • Proposal Templates
        • Optimistic Governance
        • Gasless Voting and Delegation (Relay)
          • Gasless Voting
          • Gasless Delegation
        • Integrations
          • Karma - Delegate Scoring
          • Discourse
          • Safe
      • Standard Features
    • Tally API
    • Tally Zero
  • How to Use Tally
    • Navigate the Tally homepage
    • Set up a Tally Profile
    • Create Proposals
      • Custom Actions
        • Chain Deployment of Uniswap v3
        • Token Vesting with Hedgey
        • Token Grants with Hedgey
        • Streaming Payments with Sablier
        • Tuple Support
      • Swaps
        • Swaps: FAQs
      • Draft Proposals
      • Test Proposals
    • Execute Proposals
      • Advanced Execution
    • Delegate on Tally
      • Delegates Page
      • Delegate Voting Power
      • Create a Delegate Statement
    • Vote on Tally
    • Stake on Tally
    • Get Notifications on Tally
    • Use Tally with a Gnosis Safe
      • Vote with a Gnosis Safe
      • Zodiac Governor Module for SubDAOs and Grants Programs
      • Upgrade Gnosis Safe to Governor with Zodiac
    • Participate in Security Council Elections
    • Using Ledger with Solana
  • Set up & Technical Documentation
    • Tally Architecture
    • Deploy a Governor DAO
      • Deploy a Governor
        • Deploy a Governor with a new token
      • Add a Governor to an existing token
      • Check for Token Contract Compatibility
        • Network Support
        • OpenZeppelin Governor
        • Compound Governor Bravo
        • Tokens: ERC-20 and NFTs
      • Choose Governor parameters
    • Add a DAO to Tally
      • DAO Admins
      • DAO Settings
    • Use Governor with Gnosis Safe
      • Gnosis Safe Overview
      • Zodiac Governor Module for SubDAOs and Grants Programs
      • Upgrade Gnosis Safe to Governor with Zodiac
    • Staking Contracts
      • Get Started
      • How Staking Works
        • Liquid Staking
          • LST Auto delegates
      • Staking Operator's Guide
      • DeFi Integration Guide
      • FAQ & Troubleshooting
    • Security
    • Chain Compatibility
  • Education
    • Intro to Governance
      • General Ecosystem Info
      • Participating in Governance
    • Governance Concepts
      • Decentralized Governance Overview
      • Onchain vs Offchain Voting
      • Application Layer vs. Base Layer Governance
      • Governance Execution Methods
      • Procedural Governance
      • Vote Delegation
    • Governance Frameworks
      • OpenZeppelin Governor
      • Curve Voting Escrow
      • Multisigs
      • Snapshot Polls
    • DAO Best Practices
      • Running an Onchain DAO Using OpenZeppelin Governor
    • Index of DAOs
      • DAOs on Tally
        • Aave (AAVE)
        • Ampleforth (FORTH)
        • Arbitrum (ARB)
        • Compound (COMP)
        • Gitcoin (GTC)
        • GMX
        • Idle Finance (IDLE)
        • Inverse Finance (INV)
        • PoolTogether (POOL)
        • Uniswap (UNI)
        • ZKsync
      • DAOs Not on Tally
        • Balancer (BAL)
        • Curve (CRV)
        • Index Coop (INDEX)
        • KyberDAO (KNC)
        • MakerDAO (MKR)
        • Sushi (SUSHI)
  • Resources
    • Tally Platform
    • Blog
    • DAO Talk Podcast
    • Newsletter
    • Twitter / X
  • Payment Addresses
Powered by GitBook
On this page
  • In-Depth Technical Walkthrough
  • Configuring Earning Power
  • Resource Usage and Gas Optimization

Was this helpful?

Export as PDF
  1. Set up & Technical Documentation
  2. Staking Contracts

How Staking Works

Understand how Tally's staking contracts work under the hood

PreviousGet StartedNextLiquid Staking

Last updated 12 days ago

Was this helpful?

is a flexible, configurable staking contract. It distributes onchain staking rewards to the holders of an ERC20 token, including DAO governance tokens. The rewards are proportional to with arbitrary reward criteria.

System Architecture

Here's an architecture diagram of the staking smart contracts:

  • Staking is out-of-the-box compatible with existing `ERC20Votes` governance tokens. It supports `ERC20Votes` delegation with the "surrogate factory" pattern. Staking creates a surrogate contract for each delegate. It delegates voting power in each surrogate to the delegate.

  • When Staker receives rewards, it distributes them over a period of time, e.g. 30 days. Distributing over time gives unstaked tokenholders a chance to stake. A smooth schedule also minimizes discontinuities from flash staking.

Core Components

Any instance of Staker needs these pieces to work.

  1. Staker Contract: The main contract that handles staking, reward distribution, and voting power delegation

  2. Earning Power Calculator: Determines how rewards are distributed to stakers

  3. Delegation Surrogate: Manages governance voting power for staked tokens

  4. Reward Notifier(s): Connect reward sources to the staking system

Extensions

Instances of Staker can add these extensions for extra features.

  1. StakerPermitAndStake: Adds EIP-2612 permit functionality for better UX

  2. StakerOnBehalf: Enables signature-based execution of staking actions

  3. StakerCapDeposits: Enforces a cap on the total stake amount

Liquid Staking Token (LST)

The LST, also called stGOV, is the easiest way to get rewards from staking.

  1. The LST is, of course, liquid. Staking positions can be transferred without unstaking.

  2. The LST auto-compounds rewards. Holders will automatically accrue the rewards without having to call claim()

  3. The LST keeps governance power active. When the LST is in DeFi, cold storage, or a centralized exchange, the LST provides a backup plan for governance power.

In-Depth Technical Walkthrough

Tally's Staking contracts are open source:

Staker Contract

The Staker contract is the core of the system. It manages:

  • Staking deposits and withdrawals

  • Reward distribution over time

  • Delegation of voting power

  • Earning power calculation

Staker uses a streaming reward mechanism, where rewards are added as lump sums, then distributed evenly over time. This gives stakers time to respond to changes in reward rates.

// Sample code to create a basic Staker implementation
contract MyStaker is
  Staker,
  StakerDelegateSurrogateVotes,
  StakerPermitAndStake
{
  constructor(
    IERC20 _rewardsToken,
    IERC20Staking _stakeToken,
    IEarningPowerCalculator _earningPowerCalculator,
    uint256 _maxBumpTip,
    address _admin
  )
Staker(_rewardsToken, _stakeToken, _earningPowerCalculator, _maxBumpTip, _admin)
    StakerPermitAndStake(_stakeToken)
    StakerDelegateSurrogateVotes(_stakeToken)
  {}
}

Earning Power Calculation

Staker uses a concept called "Earning Power" to distribute rewards. Every depositor gets Earning Power. Their share of the reward is their earning power divided by the total earning power in Staker, over time. The earning power calculator determines which depositors are eligible for rewards and how much they earn

Flat Earning Power

Oracle-based Earning Power

  • An oracle puts scores onchain

  • The calculator turns earning power on and off based on whether an address's score exceeds a configurable threshold

  • Staker uses the earning power over time to distribute rewards.

. Tally provides two implementations:

// Deploy a simple earning power calculator
IdentityEarningPowerCalculator calculator = new IdentityEarningPowerCalculator();

// Or deploy an oracle-based calculator
BinaryEligibilityOracleEarningPowerCalculator oracleCalculator = 
  new BinaryEligibilityOracleEarningPowerCalculator(
    owner,
    scoreOracle,
    staleOracleWindow,
    oraclePauseGuardian,
    delegateeScoreEligibilityThreshold,
    updateEligibilityDelay
  );

Reward Notifiers

Reward Source Options

Tally's system distributes rewards through a stream mechanism:

  1. Rewards periodically enter the staking system as lump sums

  2. Those rewards stream to stakers over time

  3. Stakers earn proportional to their staked amount

This approach gives stakers time to respond to changes in rewards.

Reward Notifiers

Reward notifiers connect different token sources to the staking system. Tally provides three standard notifiers:

  1. ERC20 transfer() Direct token transfers from a treasury or revenue source

  2. ERC20 transferFrom() Approved transfers from a separate contract or wallet

Each notifier handles capturing rewards from your chosen source and adding them to the staking reward pool.

Reward notifiers are responsible for informing the staking contract about new rewards:

// Example: deploy a transfer reward notifier
TransferRewardNotifier transferNotifier = new TransferRewardNotifier(
  stakerContract,         // The staking contract to notify
  initialRewardAmount,    // Amount to distribute per period
  initialRewardInterval,  // Time between distributions
  owner                   // Admin of the notifier
);

// Transfer reward tokens to the notifier
rewardToken.transfer(address(transferNotifier), totalRewards);

// Call notify to distribute rewards
transferNotifier.notify();

Delegation Surrogates

Staker uses the “surrogate pattern” to make staking compatible with governance tokens. That way, tokenholders don’t have to choose between earning rewards and doing governance.

  1. Staker creates a surrogate contract for each delegate (address receiving voting power)

  2. Surrogate deposits and withdrawals are fully controlled by the staking system. Staker does all the accounting.

  3. The surrogate contract holds staked tokens and delegates all its voting power to the chosen delegatee. That way, staking is compatible with the underlying governance token.

    1. Note that these surrogate contracts allow tokenholders to split up their voting power. i.e. partial delegation

// The staking contract creates a surrogate for each delegatee
function _fetchOrDeploySurrogate(address _delegatee) internal returns (DelegationSurrogate _surrogate) {
  _surrogate = new DelegationSurrogateVotes(stakeToken, _delegatee);
  return _surrogate;
}

Configuring Earning Power

Custom Earning Power Rules

Create custom earning power calculators to incentivize specific behaviors:

  1. Activity-based rewards: Require governance participation to earn full rewards.

  2. Time-weighted staking: Increase rewards for long-term stakers

  3. Protocol usage rewards: Tie rewards to protocol usage

// Example of a custom earning power calculator
contract CustomEarningPowerCalculator is IEarningPowerCalculator {
  function getEarningPower(uint256 _amountStaked, address _staker, address _delegatee)
    external
    view
    returns (uint256)
  {
    // Custom logic to determine earning power
    return _calculateCustomEarningPower(_amountStaked, _staker, _delegatee);
  }

  function getNewEarningPower(
    uint256 _amountStaked,
    address _staker,
    address _delegatee,
    uint256 _oldEarningPower
  ) external view returns (uint256, bool) {
    uint256 newPower = _calculateCustomEarningPower(_amountStaked, _staker, _delegatee);
    bool qualifiedForBump = _isQualifiedForBump(newPower, _oldEarningPower);
    return (newPower, qualifiedForBump);
  }
  
  // Your custom calculation logic
  function _calculateCustomEarningPower(uint256 _amountStaked, address _staker, address _delegatee)
    internal
    view
    returns (uint256)
  {
    // Implementation details
  }
}

Roles

  1. Admin controls:

The admin of the staking contracts can’t touch staked assets. They do control some system parameters:

  • Add and remove reward sources, by enabling and disabling reward notifiers

  • Set the eligibility criteria for rewards, by changing the earning power calculator

  • Change the emergency pause guardian.

  • Override eligibility for a particular address.

  • Set claim fee parameters

  1. Upgrade strategy:

These contracts could be deployed immutable or with the upgradeable proxy pattern

  • To migrate an immutable Staker:

    • Deploy a new staking contract

    • Send rewards there

    • Have tokenholders migrate to the new one

  • To upgrade-in-place a proxy contract:

    • Use initializers instead of constructors for key params at deployment

    • Check the storage slots carefully to avoid corrupting state

  1. Emergency measures:

The oracle-based calculator has failsafes in case the oracle misbehaves or goes offline:

  • If the oracle misbehaves by posting incorrect scores, a `PauseGuardian` can pause the system, reverting it to flat earning power.

  • If the oracle goes offline, the calculator also automatically reverts to using flat earning power.

  • The oracle can be replaced by Staker's admin.

Resource Usage and Gas Optimization

  • Deposit: ~100,000-150,000 gas

  • Claiming rewards: ~60,000-100,000 gas

  • Withdrawal: ~80,000-120,000 gas

For optimal performance:

  • Distribute rewards at reasonable intervals, e.g., weekly or monthly

  • The earning power calculator should wait between updates, e.g. daily

  • The earning power calculator shouldn’t make lots of small updates, especially networks with high gas costs

  • Anyone can update earning power as it changes, but someone needs to do it. Staker provides “tips” as incentive for bots to do updates. If MEV bots do not know about the incentive, consider running the staker bots script directly.

  • These incentives don’t work testnets or for tokens with no market value.

The staking contracts have modules for , hooking up , and . Protocol teams can assemble a staking system from these audited pieces.

Staker is built on. Unistaker is based on Synthetix's.

UniStaker and Staker have been audited several times. The audit reports are.

The backup is a configurable strategy for keeping voting power active in governance. For example, see the , which only votes on proposals that have lots of consensus.

Access the open-source .

: Simple 1:1 mapping where earning power equals staked amount.

: More advanced calculator where earning power depends on the delegate's activity score. Here’s how it works:

ERC20 mint() -Newly minted tokens from an inflationary schedule

holds rewards directly and distributes them by calling transfer()

relies on an approve(), so that it can call transferFrom() on the reward source

calls mint() on a token contract.

calculating earning power
sources of rewards
extensions
UniStaker
StakingRewards
available here
OverwhelmingSupportAutoDelegate
stGOV repo
Staker
LST
IdentityEarningPowerCalculator
BinaryEligibilityOracleEarningPowerCalculator
TransferRewardNotifier.sol
TransferFromRewardNotifier.sol
MintRewardNotifier.sol
Staker