Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
LABS
Guides

How to Set Up Emission Schedules

A technical guide for developers implementing token emission and vesting schedules in smart contracts. Covers common models, security considerations, and Solidity code examples.
Chainscore © 2026
introduction
IMPLEMENTATION GUIDE

How to Set Up Emission Schedules

A technical guide to designing and deploying token emission schedules for staking rewards, liquidity mining, and protocol incentives.

An emission schedule is a smart contract that controls the rate and distribution of token rewards over time. It is a core mechanism for managing protocol inflation, aligning long-term incentives, and ensuring sustainable growth. Common use cases include distributing governance tokens to liquidity providers (liquidity mining), rewarding validators or stakers in a Proof-of-Stake network, and vesting tokens for team members or investors. A well-designed schedule prevents token dumping, controls supply inflation, and programmatically enforces commitment from participants.

The most common schedule is a linear vesting contract, which releases tokens at a constant rate. For example, a 1-year linear vesting contract for 365 tokens would release 1 token per day. More complex schedules use cliff periods (no tokens released for an initial duration) or non-linear curves (logarithmic, exponential) to tailor the incentive structure. When implementing, you must decide key parameters: the total reward pool, the emission duration, the start timestamp, and the recipient addresses. These are typically stored as immutable variables upon contract deployment.

Here is a simplified Solidity example for a linear emission schedule using a vesting wallet pattern. This contract releases tokens linearly over a duration starting from a startTime.

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract LinearVesting {
    IERC20 public immutable token;
    uint256 public immutable startTime;
    uint256 public immutable duration;
    uint256 public immutable totalAmount;
    address public immutable beneficiary;
    uint256 public released;

    constructor(
        IERC20 _token,
        address _beneficiary,
        uint256 _startTime,
        uint256 _duration,
        uint256 _totalAmount
    ) {
        token = _token;
        beneficiary = _beneficiary;
        startTime = _startTime;
        duration = _duration;
        totalAmount = _totalAmount;
    }

    function release() public {
        uint256 releasable = vestedAmount(block.timestamp) - released;
        require(releasable > 0, "No tokens to release");
        released += releasable;
        token.transfer(beneficiary, releasable);
    }

    function vestedAmount(uint256 timestamp) public view returns (uint256) {
        if (timestamp < startTime) {
            return 0;
        } else if (timestamp > startTime + duration) {
            return totalAmount;
        } else {
            return (totalAmount * (timestamp - startTime)) / duration;
        }
    }
}

The vestedAmount function calculates the claimable amount at any given time based on elapsed time, ensuring a predictable, on-chain schedule.

For production use, consider using audited libraries like OpenZeppelin's VestingWallet contract, which provides a secure, reusable implementation of linear vesting. When setting up a schedule for a public protocol (e.g., a liquidity mining program), you must also integrate it with your staking or farming contract. The farming contract would hold the reward tokens and call a function to mint or transfer the scheduled amount to users based on their share. Always ensure the contract holding the tokens has a sufficient balance and that the emission math is checked for overflow and precision errors, typically by using a rate = totalAmount / duration pattern.

Key security and design considerations include: - Immutable parameters: Fix schedule details at deployment to prevent manipulation. - Access control: Restrict functions like release to authorized parties or the beneficiary. - Timestamp dependence: Be aware of minor blockchain timestamp manipulation; designs using block numbers for duration are more predictable in some cases. - Gas efficiency: For programs with thousands of participants, consider merkle drop distributions or layer-2 solutions to batch claims. - Transparency: Clearly communicate the schedule's start time, duration, and total amount to users, as these values are permanently visible on-chain.

To deploy and test your schedule, use a framework like Hardhat or Foundry. Write comprehensive tests that simulate the passage of time using evm_increaseTime in Hardhat or warp in Foundry to verify the vested amount at different points. After testing, verify the contract source code on a block explorer like Etherscan. A properly implemented emission schedule is a trustless, transparent foundation for managing tokenomics, crucial for the long-term health of DeFi protocols and DAOs.

prerequisites
PREREQUISITES

How to Set Up Emission Schedules

Before creating an emission schedule, you need a foundational understanding of token standards, smart contract development, and the specific blockchain environment you'll be deploying on.

An emission schedule is a smart contract logic that controls the release of tokens over time, commonly used for vesting, staking rewards, or token unlocks. To implement one, you must first be comfortable with writing and deploying smart contracts. This requires proficiency in a language like Solidity for Ethereum Virtual Machine (EVM) chains (Ethereum, Polygon, Arbitrum) or Rust for Solana or CosmWasm chains. You'll also need a development environment set up, such as Hardhat, Foundry, or Anchor, and a basic wallet like MetaMask for testing.

Your contract must interact with a token standard. For EVM chains, this is almost always the ERC-20 standard. You need to understand how to interface with an existing token contract using the IERC20 interface to transfer tokens programmatically. For the schedule itself, you'll define key parameters: the totalAmount to distribute, the startTime and duration (or endTime), and the beneficiary address(es). More complex schedules may involve cliff periods (a delay before any tokens are released) or a non-linear release curve (e.g., exponential decay for incentives).

Security is paramount. Your schedule must safely hold the allocated tokens and prevent common vulnerabilities. This includes using pull-over-push patterns for withdrawals to avoid reentrancy attacks, implementing access control (e.g., OpenZeppelin's Ownable or role-based systems) so only authorized parties can fund the schedule, and ensuring proper input validation for all parameters. Always write and run comprehensive tests using frameworks like Hardhat or Foundry's Forge to simulate the passage of time and verify the token release amounts are correct at any given block.

Finally, you must consider the deployment and maintenance lifecycle. You'll need testnet tokens (like Goerli ETH or SOL) to deploy and verify your contract. For mainnet deployment, use a multisig wallet or a timelock controller for the owner role to add a layer of security. After deployment, you should create a simple front-end or script for beneficiaries to claim their tokens, and consider implementing events for transparency (e.g., TokensReleased). Resources like the OpenZeppelin Contracts Wizard can help generate a basic vesting contract template to build upon.

key-concepts
EMISSION SCHEDULES

Key Concepts

Emission schedules are the foundational logic that controls how tokens are distributed over time. This section covers the core components and strategies for designing them.

01

What is an Emission Schedule?

An emission schedule is a smart contract function that defines the rate at which new tokens are minted and distributed. It is the core mechanism for managing token supply inflation, incentivizing user behavior, and funding protocol operations. Key parameters include:

  • Total Emission: The maximum number of tokens to be released.
  • Emission Curve: The mathematical function (e.g., linear, exponential decay, step-function) governing the release rate.
  • Distribution Targets: The recipients of the emissions, such as liquidity providers, stakers, or a treasury.

Poorly designed schedules can lead to hyperinflation or insufficient incentives.

02

Linear vs. Exponential Decay

The choice of emission curve is critical for long-term protocol health.

Linear Emission releases a fixed number of tokens per block or per epoch. This is predictable and simple to implement but can lead to a constant, high inflation rate that devalues the token over time if not paired with strong utility.

Exponential Decay (or halving) reduces the emission rate over time, similar to Bitcoin's model. This creates scarcity and can support token price appreciation, but requires careful calibration to ensure incentives remain attractive during the later stages of the schedule.

03

Vesting Schedules for Teams & Investors

Vesting schedules are a specialized type of emission used to lock allocated tokens for founders, team members, and investors. They prevent immediate dumping and align long-term interests.

A typical cliff-and-vest schedule includes:

  • Cliff Period: A duration (e.g., 1 year) where no tokens are released.
  • Vesting Period: After the cliff, tokens are released linearly over a set period (e.g., 2-3 years).

These are often implemented using vesting wallet contracts (like OpenZeppelin's VestingWallet) that allow beneficiaries to claim tokens as they unlock.

04

Implementing with Solidity

Emission logic is typically coded directly into a protocol's staking or mining contract. A basic structure involves:

  1. A state variable for tokensPerSecond or tokensPerBlock.
  2. A function (often called updateEmissionRate) that can be called by governance to adjust the rate.
  3. A time-based calculation in the reward distribution function.

Example snippet for a linear emitter:

solidity
uint256 public emissionPerSecond = 1e18; // 1 token per second
uint256 public lastUpdateTime;

function _updateRewards() internal {
    uint256 timePassed = block.timestamp - lastUpdateTime;
    uint256 newRewards = timePassed * emissionPerSecond;
    // ... mint and distribute `newRewards`
}
05

Emission Schedule Auditing

Auditing an emission schedule contract is essential for security and economic soundness. Key checks include:

  • Math Precision: Ensuring calculations use sufficient precision (e.g., 1e18 for decimals) and avoid rounding errors that could lock funds.
  • Access Controls: Verifying that functions to change the emission rate or halt emissions are properly permissioned (e.g., timelock governance).
  • Time Manipulation: Guarding against miners/validators manipulating block.timestamp or block.number to claim extra rewards.
  • Total Supply Cap: Confirming the schedule cannot mint beyond the defined maximum supply, preventing infinite inflation bugs.

Use static analysis tools like Slither and manual review for these checks.

implementation-overview
EMISSION SCHEDULES

Implementation Overview

This guide details the technical implementation for setting up and managing token emission schedules, covering smart contract architecture and key parameters.

An emission schedule is a smart contract logic that controls the release of tokens over time, typically used for vesting, staking rewards, or liquidity mining. The core implementation involves a Schedule struct that defines key parameters: the startTime (Unix timestamp), endTime, cliffDuration, and totalAmount of tokens to be distributed. The contract must calculate the releasedAmount at any given block timestamp, ensuring tokens are unlocked linearly or according to a predefined curve. This prevents large, sudden dumps and aligns long-term incentives between projects and their communities.

The most common implementation uses a linear vesting formula: releasedAmount = totalAmount * (elapsedTime / totalDuration). For example, a 1-year schedule for 1,000,000 tokens would release approximately 2,739 tokens per day (1,000,000 / 365). Smart contracts must handle the cliff period—a duration after startTime during which no tokens are released. If a 3-month cliff is set, the first token release occurs at startTime + cliffDuration, after which the linear vesting begins. This structure is standard in ERC-20 vesting contracts and employee compensation plans.

For more complex distributions like quadratic funding or decaying emissions, the contract logic implements a custom getReleasableAmount function. A decaying emission for a liquidity mining pool might reduce rewards by 10% each month, requiring an exponential calculation. Developers often use OpenZeppelin's VestingWallet as a secure, audited base contract, extending it for custom schedules. Key security considerations include ensuring the contract holds sufficient token balance, preventing reentrancy attacks on the release function, and using onlyOwner modifiers for schedule adjustments to prevent unauthorized changes.

COMPARISON

Emission Schedule Models

Key characteristics of common token emission models used in DeFi and crypto projects.

ModelLinearExponential DecayStepwiseDynamic

Release Pattern

Constant rate over time

High initial rate, decreases over time

Fixed amounts at predefined intervals

Algorithmically adjusts based on metrics

Complexity

Low

Medium

Medium

High

Predictability

High

High

High

Low

Inflation Control

Poor

Good

Fair

Excellent

Common Use Case

Vesting schedules

Liquidity mining

Team/advisor unlocks

Rebase tokens, algorithmic stablecoins

Gas Cost (Deploy)

Low

Medium

Medium

High

Requires Oracles

Example Protocols

Standard ERC-20 vesting

Curve (CRV), SushiSwap (SUSHI)

VC/team cliff schedules

Olympus DAO (OHM), Ampleforth (AMPL)

EMISSION SCHEDULES

Step-by-Step: Linear Vesting Contract

A linear vesting contract releases tokens to beneficiaries over a defined period. This guide covers common implementation questions and troubleshooting for developers building or interacting with these schedules.

A linear vesting schedule releases tokens at a constant rate from a start time until a cliff and/or end time. The core formula calculates the vested amount based on elapsed time.

Key Calculation:

solidity
function _vestingSchedule(uint256 totalAllocation, uint64 start, uint64 cliff, uint64 end, uint256 currentTime) internal pure returns (uint256) {
    if (currentTime < cliff) {
        return 0;
    }
    if (currentTime >= end) {
        return totalAllocation;
    }
    return (totalAllocation * (currentTime - start)) / (end - start);
}

The vested amount increases linearly from the start (or cliff) timestamp. A common mistake is using block numbers instead of timestamps, which can lead to inconsistent vesting periods on chains with variable block times.

EMISSION SCHEDULES

Step-by-Step: Exponential Decay Emission

A guide to implementing and troubleshooting exponential decay emission schedules for token distribution, covering common pitfalls and developer FAQs.

An exponential decay emission schedule is a token distribution model where the rate of new token issuance decreases continuously over time, following a mathematical decay function. Unlike linear vesting, which releases a fixed amount per block, exponential decay reduces the emission rate proportionally to the remaining supply.

Key characteristics:

  • The emission rate is highest at the start (t=0) and asymptotically approaches zero.
  • It's defined by a decay constant (often lambda, λ) which controls how quickly the emission slows down.
  • The total emission over infinite time converges to a finite emission cap, preventing infinite minting.

This model is commonly used for liquidity mining incentives, protocol-owned liquidity bootstrapping, and foundation treasuries to create predictable, long-tail distribution.

security-considerations
SECURITY AND TESTING

How to Set Up Emission Schedules

A secure emission schedule is a critical component of any token distribution model, requiring careful planning and rigorous testing to prevent exploits and ensure long-term protocol health.

An emission schedule defines how and when new tokens are minted and distributed over time. This is a foundational mechanism for protocols using tokens for incentives, such as liquidity mining rewards, staking yields, or team/advisor vesting. A poorly designed schedule can lead to hyperinflation, token price instability, or security vulnerabilities where an attacker could drain the minting contract. Key parameters to define include the total emission cap, emission rate, start block/time, duration, and distribution recipients. For security, these parameters should be immutable or governed by a secure, multi-signature process after deployment.

Setting up a schedule typically involves deploying a smart contract that manages the minting logic. A common pattern is a linear vesting contract or a merkle distributor for airdrops. For ongoing emissions, a Minter or StakingRewards contract is often used. Below is a simplified example of a linear vesting schedule in Solidity, using a cliff period and linear release thereafter. This code should be thoroughly audited and tested before mainnet use.

solidity
// Simplified Linear Vesting Contract
contract TokenVester {
    IERC20 public token;
    uint256 public startTime;
    uint256 public cliffDuration;
    uint256 public vestingDuration;
    mapping(address => uint256) public vestedAmount;
    mapping(address => uint256) public claimed;

    constructor(IERC20 _token, uint256 _cliff, uint256 _duration) {
        token = _token;
        startTime = block.timestamp;
        cliffDuration = _cliff;
        vestingDuration = _duration;
    }

    function claimable(address beneficiary) public view returns (uint256) {
        if (block.timestamp < startTime + cliffDuration) return 0;
        uint256 totalVested = vestedAmount[beneficiary];
        uint256 elapsed = block.timestamp - startTime;
        if (elapsed > vestingDuration) elapsed = vestingDuration;
        uint256 claimableAmount = (totalVested * elapsed) / vestingDuration;
        return claimableAmount - claimed[beneficiary];
    }
}

Testing emission schedules is non-negotiable for security. Your test suite should verify: the total supply cap is enforced, tokens cannot be minted before the start time, the emission rate is accurate over time, and funds are only distributable to authorized addresses. Use a testing framework like Hardhat or Foundry to simulate the passage of time and test edge cases. For Foundry, you can use vm.warp() to jump forward in time and assert claimable amounts. A critical test is ensuring no tokens are accidentally locked forever due to rounding errors or logic flaws in the vesting calculation.

Beyond unit tests, consider the economic security of the schedule. Use tools like tokenomics simulators or custom scripts to model the impact of emissions on circulating supply, inflation rate, and potential sell pressure. For DeFi protocols, a common failure mode is "emission dumping," where farmers immediately sell reward tokens. Mitigations include implementing lock-up periods or curve-based emissions that reduce the reward rate as total value locked (TVL) increases. Always disclose the full emission schedule transparently to users, as hidden minting functions are a major red flag for auditors and users.

For ongoing, adjustable emissions (e.g., liquidity mining rewards controlled by governance), implement a timelock controller and rate limiter. Any function that changes the emission rate or adds new reward tokens should be behind a timelock of at least 48-72 hours, giving the community time to react to proposed changes. The contract should also include an emergency stopEmission function accessible by a multisig to pause distributions in case a critical bug is discovered. Reference secure implementations from established protocols like Compound's Comptroller or Synthetix's StakingRewards for design patterns.

Finally, integrate monitoring and alerting. Once live, track the emission contract's activity with a service like Tenderly or OpenZeppelin Defender. Set up alerts for unusual events, such as the minting of more tokens than expected in a single block or transfers to unauthorized addresses. A well-tested, transparent, and securely managed emission schedule builds long-term trust and is a hallmark of a professionally developed Web3 project.

EMISSION SCHEDULES

Common Mistakes and Pitfalls

Setting up a token emission schedule is a critical but error-prone task. This guide covers the most frequent mistakes developers make when implementing vesting, staking rewards, or airdrop distributions, and how to fix them.

This is a common error caused by incorrect total supply allocation or a flawed release calculation. The contract's token balance must be greater than or equal to the sum of all tokens scheduled for release over time.

Common causes:

  • Miscalculating the total vested amount across all beneficiaries.
  • Using a linear release formula that doesn't account for the contract's actual balance.
  • Forgetting to fund the emission contract with the allocated tokens after deployment.

How to fix:

  1. Audit the math: Before deployment, sum the totalAmount for all schedules (e.g., using a script). Ensure it matches the tokens sent to the contract.
  2. Implement safety checks: Add a require statement in your release function: require(token.balanceOf(address(this)) >= amountToRelease, "Insufficient contract balance");
  3. Test edge cases: Simulate the entire emission period in a test (e.g., using Foundry's warp to jump forward in time) to ensure the contract never reverts due to lack of funds.
EMISSION SCHEDULES

Frequently Asked Questions

Common questions and troubleshooting for setting up and managing token emission schedules using smart contracts.

An emission schedule is a smart contract mechanism that controls the rate and timing of token distribution over a predefined period. It's a core component for managing tokenomics, ensuring predictable and verifiable supply releases.

Common use cases include:

  • Vesting for team members, advisors, and investors
  • Staking rewards distributed over time
  • Liquidity mining incentives for DeFi protocols
  • Treasury management with controlled fund releases

Schedules are defined by parameters like start time, end time, cliff period, total allocated amount, and a release function (e.g., linear, exponential, stepwise). Using a schedule prevents token dumping, aligns incentives, and provides transparency for all stakeholders.

conclusion
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have configured a custom emission schedule for your token, defining how rewards are distributed over time. This guide covered the core concepts and steps.

Setting up an emission schedule is a foundational step for managing tokenomics, whether for a liquidity mining program, vesting schedule, or protocol rewards. The key components you defined include the total emission amount, start and end timestamps, and the distribution curve (e.g., linear, exponential decay). Using a smart contract library like OpenZeppelin's VestingWallet or a custom EmissionSchedule.sol contract ensures these rules are enforced transparently on-chain.

For ongoing management, consider implementing pause/unpause functionality controlled by a multi-signature wallet or DAO vote, allowing you to halt emissions in case of an emergency. You should also set up off-chain monitoring using a service like The Graph to index emission events and track real-time distribution rates. This data is crucial for providing transparency to your community and for internal reporting.

Your next steps should involve thorough testing. Deploy your emission contract to a testnet (like Sepolia or Goerli) and simulate the full schedule using a script in a framework like Hardhat or Foundry. Verify that tokens are released at the correct block.timestamp intervals and that the total distributed equals the allocated amount. Use a block explorer to confirm all transactions.

After a successful testnet deployment, plan your mainnet launch. Ensure you have sufficient token liquidity in the emission contract's wallet before the start timestamp. Publicly document the schedule parameters—total supply, duration, and contract address—in your project's documentation or announcement to build trust. Consider writing an audit report or engaging a firm like CertiK or OpenZeppelin for a security review before going live.

Finally, explore advanced patterns to build upon this foundation. You could create multi-token emission schedules that distribute several assets from one contract, or implement dynamic emission that adjusts rates based on on-chain metrics like TVL or trading volume. The Solidity by Example site and the OpenZeppelin Contracts documentation are excellent resources for these more complex implementations.

How to Set Up Token Emission Schedules: A Developer Guide | ChainScore Guides