Fatskills
Practice. Master. Repeat.
Study Guide: Blockchain and Web3 Development: DeFi and Tokenomics - Tokenomics, Supply Distribution, Vesting, Governance Tokens
Source: https://www.fatskills.com/cryptocurrency-bitcoin-blockchain-and-more/chapter/blockchain-and-web3-development-blockchain-and-web3-development-defi-and-tokenomics-tokenomics-supply-distribution-vesting-governance-tokens

Blockchain and Web3 Development: DeFi and Tokenomics - Tokenomics, Supply Distribution, Vesting, Governance Tokens

By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.

⏱️ ~5 min read

What This Is

Tokenomics is the economic design behind a blockchain token—how many tokens exist, who gets them, when they become spendable, and how holders influence the protocol. By encoding supply rules, distribution schedules, and governance rights directly into smart contracts, projects can align incentives, fund development, and let the community run the system without a central authority. Real?world example: The UNI token that powers Uniswap’s DAO; holders receive a share of protocol fees and can vote on fee?structure changes, while a portion of UNI was locked in a 4?year vesting curve for the team and early contributors.


Key Terms & Code Snippets

  • Total Supply (uint256 public constant MAX_SUPPLY) – The hard cap of tokens that can ever exist.
    solidity uint256 public constant MAX_SUPPLY = 1_000_000 * 1e18; // 1?M tokens with 18 decimals

  • Initial Mint (_mint(msg.sender, amount)) – Tokens created at deployment for founders, treasury, or a liquidity bootstrap.
    solidity constructor() ERC20("MyToken", "MTK") { _mint(msg.sender, 200_000 * 1e18); // 20% to deployer }

  • Vesting Schedule (LinearVesting) – A contract that releases tokens over time to prevent dump?and?burn attacks.
    ```solidity contract LinearVesting { IERC20 public immutable token; uint256 public immutable start; uint256 public immutable cliff; // earliest unlock uint256 public immutable duration; uint256 public totalAllocated; mapping(address => uint256) public released;

    function claim(address beneficiary) external { uint256 vested = _vestedAmount(beneficiary); uint256 claimable = vested - released[beneficiary]; released[beneficiary] = vested; token.transfer(beneficiary, claimable); } // _vestedAmount() calculates linear proportion based on block.timestamp } ```

  • Distribution Model – The blueprint for who gets what (e.g., 40?% community, 20?% team, 15?% investors, 25?% ecosystem). Usually encoded as a series of grant calls in the deployment script.

  • Governance Token (ERC20Votes) – An ERC?20 that tracks voting power via snapshots, enabling on?chain proposals.
    solidity contract GovToken is ERC20, ERC20Permit, ERC20Votes { constructor() ERC20("GovToken", "GOV") ERC20Permit("GovToken") {} function _afterTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) { super._afterTokenTransfer(from, to, amount); } }

  • Snapshot (_snapshot()) – Takes a block?level picture of token balances so votes are based on holdings at proposal creation, not on?the?fly transfers.

  • Emission Rate (uint256 public rewardPerBlock) – For tokens that are minted as block rewards (e.g., staking or liquidity mining).

  • Burn Mechanism (_burn(address from, uint256 amount)) – Reduces circulating supply, often used to create deflationary pressure.

  • Treasury Wallet (address public treasury) – Holds a pool of tokens for future grants, community incentives, or protocol upgrades.

  • Delegation (delegate(address delegatee)) – Allows a token holder to assign voting power to another address without transferring tokens.

  • Anti?Whale Transfer Limit (require(amount <= maxTx, "Too big")) – Caps single?transaction size to curb market manipulation.


Step?by?Step / Process Flow

  1. Design the tokenomics sheet – Define total supply, allocation percentages, vesting cliffs, and governance rights in a spreadsheet.
  2. Write the ERC?20 contract – Use OpenZeppelin’s ERC20, ERC20Votes, and a custom Vesting contract.
    bash npx hardhat init npm install @openzeppelin/contracts
  3. Compile & test – Run npx hardhat compile and write unit tests (Mocha/Chai) for minting, vesting, and voting snapshots.
  4. Deploy to a testnet
    bash npx hardhat run scripts/deploy.js --network goerli The script should:
  5. Deploy GovToken
  6. Deploy LinearVesting with the team’s address and schedule
  7. Transfer allocated amounts to the vesting contract.
  8. Verify distribution – Use Ethers.js to query balances and the vesting contract’s vestedAmount for each beneficiary.
  9. Launch governance – Create a simple DAO proposal (e.g., change rewardPerBlock) via the Governor contract and let token holders vote using delegate/castVote.

Common Mistakes

  • Mistake: Hard?coding the total supply in multiple places (e.g., both in the contract and the deployment script).
    Correction: Keep a single source of truth (a constant in the Solidity file) and reference it everywhere; mismatched caps cause supply bugs and audit red flags.

  • Mistake: Forgetting to call _snapshot() after each token transfer when using ERC20Votes.
    Correction: Inherit ERC20Votes and let OpenZeppelin’s _afterTokenTransfer hook handle snapshots automatically.

  • Mistake: Using block.timestamp for vesting cliffs without a safety buffer.
    Correction: Add a small “grace period” (e.g., + 1 days) to avoid edge?case failures caused by miners manipulating timestamps.

  • Mistake: Allowing the treasury to transfer tokens without a timelock.
    Correction: Wrap treasury actions in a TimelockController so any large move must be announced and can be vetoed by governance.

  • Mistake: Setting the vesting duration to 0 (instant unlock) for team allocations.
    Correction: Enforce a minimum multi?year duration (2?years) to align incentives and satisfy investors.


Blockchain Developer Interview / Practical Insights

  • Vesting vs. Lock?up: Interviewers ask you to differentiate—vesting releases tokens gradually, while lock?up simply prevents any transfer until a date.
  • delegatecall danger: A governance contract that uses delegatecall to execute proposals can be hijacked; auditors look for the “proxy?pattern” safety checks (require(msg.sender == admin)).
  • ERC?20 vs. ERC?777: Know that ERC?777 adds hooks (tokensReceived) that can trigger re?entrancy; most tokenomics stay on ERC?20 for simplicity and auditability.
  • Rollup choice impact: Optimistic rollups (e.g., Arbitrum) have ~7?day challenge periods affecting token distribution timing; ZK rollups (e.g., zkSync) settle instantly, which matters for vesting claim UX.

Quick Check Questions

  1. Scenario: A token contract mints new tokens each block based on rewardPerBlock. If the block time halves after a network upgrade, what happens to the annual inflation rate?
    Answer: It doubles, because the same per?block reward is emitted twice as often.

  2. Scenario: A DAO proposal tries to change the treasury address, but the call is made through a delegatecall from a malicious contract. Why is this risky?
    Answer: delegatecall runs the malicious code in the context of the DAO, allowing it to overwrite storage (e.g., treasury address) without proper permission checks.

  3. Scenario: A vesting contract uses require(block.timestamp >= start + cliff) but the cliff is set to 0. What problem arises?
    Answer: The cliff is effectively disabled, letting beneficiaries claim immediately and defeating the purpose of a delayed release.


Last?Minute Cram Sheet (10 one?liners)

  1. Never use tx.origin for auth – it can be hijacked via phishing contracts.
  2. ERC?20 = 20 (basic token), ERC?777 = 777 (hooks & operators), ERC?4626 = 4626 (tokenized vaults).
  3. Gas tip: Use unchecked {} for simple i++ loops in Solidity?0.8+ to save ~15?gas per iteration.
  4. Vesting formula: vested = totalAllocated * (now - start) / duration (clamp to [0,totalAllocated]).
  5. Snapshot block: blockNumber = block.number at proposal creation; voting power is read from that block.
  6. Timelock minimum: 48?hours is the de?facto standard for DAO treasury actions.
  7. Compiler version: Most production contracts target pragma solidity ^0.8.20 (latest stable as of 2024).
  8. Re?entrancy guard: Add nonReentrant modifier from OpenZeppelin to any external token transfer function.
  9. Distribution pattern: Allocate <?10?% to the team after a 1?year cliff, then linear vest over 3?years.
  10. Rollup latency: Optimistic 7?days-delay vesting claims; ZK seconds-immediate UX.