OnChain DAO

BSC

Documentation

Complete reference for the OnChain DAO protocol — a fully autonomous, on-chain governance system deployed on BNB Smart Chain. This guide covers smart contracts, deployment, governance workflows, tokenomics, and staking.

Overview

OnChain DAO is a decentralized autonomous organization built on BNB Smart Chain (BSC). It features a two-token economic model and fully on-chain governance where every parameter change must pass through a proposal-vote-timelock lifecycle.

Key Properties

  • Two-token system — DAOToken (governance) + TaxToken (revenue)
  • Fully autonomous — deployer renounces all admin roles after setup
  • On-chain governance — proposals, voting, and execution happen entirely on-chain via OpenZeppelin Governor
  • Revenue sharing — TaxToken trading fees are split between stakers, burn, and development
  • Anti-whale protection — configurable max transaction and max wallet limits on TaxToken

The protocol is composed of six smart contracts that interact to provide governance, trading with taxes, revenue distribution, and staking rewards.

Architecture

The system has two main flows: a governance flow (proposals controlling protocol parameters) and a revenue flow (trading taxes distributed to stakeholders).

Governance Flow
DAOToken Holders
      |
      | delegate voting power
      v
DAOGovernor  ──propose──>  Proposal
      |                        |
      | vote (For/Against/     | passes quorum
      |       Abstain)         |
      v                        v
   Voting Period          Queue in DAOTimelock
                               |
                               | 1 hour delay
                               v
                          Execute on-chain
                          (TaxToken / RevenueSplitter / StakingVault)
Revenue Flow
TaxToken DEX Trade
      |
      | buy/sell tax (5% default)
      v
RevenueSplitter
      |
      |── 50% ──> StakingVault.addRewards()
      |               (distributed to DAOToken stakers)
      |
      |── 20% ──> 0x000...dEaD (burned)
      |
      └── 30% ──> Dev Wallet
Contract Ownership Map
DAOTimelock (autonomous - no admin)
   ├── owns TaxToken     → setBuyTax, setSellTax, setTradingEnabled, ...
   ├── owns RevenueSplitter → setShares, setDevWallet, ...
   └── owns StakingVault  → setMinLockPeriod

Smart Contracts

All contracts are written in Solidity ^0.8.20 and built on OpenZeppelin v5. They are compiled with the Paris EVM target and optimizer enabled at 200 runs.

DAOToken

ERC20 governance token with ERC20Votes and ERC20Permit extensions. Holders must delegate voting power (to themselves or another address) before it counts toward proposals and quorum.

ParameterValue
NameDAOToken
SymbolDAO
Initial Supply1,000,000 DAO
Decimals18
MintingConstructor only (fixed supply)
InheritsERC20, ERC20Permit, ERC20Votes

No admin functions exist on this contract. The entire supply is minted to the deployer at construction and can only change hands via standard ERC20 transfers. Vote checkpoints are automatically maintained on every transfer through the _update override.

DAOTimelock

Thin wrapper around OpenZeppelin's TimelockController. Enforces a mandatory delay between a proposal passing and its on-chain execution, giving the community time to react.

ParameterValue
Min Delay3,600 seconds (1 hour)
ProposerDAOGovernor (set in setup)
Executoraddress(0) (anyone can execute)
CancellerDAOGovernor
AdminRenounced after setup

After governance setup, the deployer's DEFAULT_ADMIN_ROLE is renounced, making the DAO fully autonomous. No single address can bypass the timelock.

DAOGovernor

Core governance contract using OpenZeppelin Governor with counting, quorum fraction, and timelock control extensions. Manages the full proposal lifecycle.

ParameterValue
Voting Delay1 block
Voting Period300 blocks (~15 min on BSC)
Proposal Threshold0 (any holder can propose)
Quorum4% of total supply
Vote Types0 = Against, 1 = For, 2 = Abstain

Proposals target functions on contracts owned by the DAOTimelock. When a proposal passes quorum, it is queued in the timelock and becomes executable after the 1-hour delay.

TaxToken

ERC20 token with configurable buy/sell taxes on DEX trades, anti-whale limits, and a trading toggle. After setup, all parameters are controlled by DAO governance.

ParameterDefaultRange
Buy Tax500 (5%)0 - 2,500 bps (25% max)
Sell Tax500 (5%)0 - 2,500 bps (25% max)
Max Transaction1% of supplyConfigurable
Max Wallet2% of supplyConfigurable
TradingDisabledEnabled via governance
Tax RecipientRevenueSplitterConfigurable

Governance-Controlled Functions

FunctionDescription
setBuyTax(uint256)Update buy tax (0-2500 bps)
setSellTax(uint256)Update sell tax (0-2500 bps)
setTaxRecipient(address)Change where taxes are sent
setMaxTransactionAmount(uint256)Update per-tx limit
setMaxWalletAmount(uint256)Update per-wallet limit
setTradingEnabled(bool)Enable/disable public trading
setAmmPair(address, bool)Register DEX pair addresses
setTaxExempt(address, bool)Grant/revoke tax exemption
setLimitExempt(address, bool)Grant/revoke limit exemption

RevenueSplitter

Receives TaxToken proceeds from trades and distributes them across three streams. Thedistribute() function is permissionless — anyone can trigger it.

StreamDefault ShareDestination
Staking Rewards50%StakingVault.addRewards()
Burn20%0x000...dEaD
Development30%Dev wallet

Governance-Controlled Functions

FunctionDescription
setShares(uint256, uint256, uint256)Update staking/burn/dev split (sum <= 10000 bps)
setDevWallet(address)Change dev wallet address
setStakingVault(address)Change staking vault address

StakingVault

Allows DAOToken holders to stake and earn TaxToken rewards. Uses the SynthetixrewardPerToken accumulator pattern for gas-efficient pro-rata distribution.

ParameterValue
Staking TokenDAOToken
Reward TokenTaxToken
Min Lock Period7 days (default)
Reward ModelSynthetix rewardPerToken accumulator
FunctionDescription
stake(uint256)Deposit DAOTokens into the vault
withdraw(uint256)Withdraw after lock period expires
claimRewards()Claim accrued TaxToken rewards
addRewards(uint256)Called by RevenueSplitter to fund rewards
setMinLockPeriod(uint256)Governance-controlled lock duration

Deployment Guide

Prerequisites

  • Node.js v18+ and npm
  • A funded deployer wallet (BNB for gas)
  • BscScan API key (for contract verification)

1. Install Dependencies

Terminal
npm install

2. Configure Environment

Copy the example env file and fill in your values:

.env
PRIVATE_KEY=your_deployer_private_key
BSCSCAN_API_KEY=your_bscscan_api_key

3. Compile Contracts

Terminal
npx hardhat compile

4. Deploy Contracts

The deploy script deploys all six contracts in dependency order and configures initial TaxToken exemptions.

Terminal
npx hardhat run scripts/deploy.ts --network bscTestnet

The script outputs contract addresses as environment variables. Copy them into your.env file:

Deploy output
DAO_TOKEN_ADDRESS=0x...
DAO_TIMELOCK_ADDRESS=0x...
DAO_GOVERNOR_ADDRESS=0x...
TAX_TOKEN_ADDRESS=0x...
STAKING_VAULT_ADDRESS=0x...
REVENUE_SPLITTER_ADDRESS=0x...

5. Setup Governance

This script grants timelock roles to the Governor, transfers contract ownership to the Timelock, and renounces the deployer's admin role. This is irreversible — after this step, all parameter changes require a governance proposal.

Terminal
npx hardhat run scripts/setup-governance.ts --network bscTestnet

Warning: The setup-governance script renounces the deployer's admin role. Ensure all initial configuration is correct before running this step.

6. Verify Contracts

Terminal
npx hardhat verify --network bscTestnet <CONTRACT_ADDRESS> <CONSTRUCTOR_ARGS>

Deployment Order Summary

StepContractDependencies
1DAOTokenNone
2DAOTimelockNone
3DAOGovernorDAOToken, DAOTimelock
4TaxTokenNone
5StakingVaultDAOToken, TaxToken
6RevenueSplitterTaxToken, StakingVault

Frontend Setup

The frontend is a Next.js 15 app with React 19, Tailwind CSS v4, wagmi v2 for wallet interactions, and Reown AppKit for the wallet connection modal.

1. Get a Reown Project ID

Sign up at cloud.reown.com and create a project to get your Project ID.

2. Configure Environment

frontend/.env.local
NEXT_PUBLIC_REOWN_PROJECT_ID=your_project_id

NEXT_PUBLIC_DAO_TOKEN_ADDRESS=0x...
NEXT_PUBLIC_DAO_TIMELOCK_ADDRESS=0x...
NEXT_PUBLIC_DAO_GOVERNOR_ADDRESS=0x...
NEXT_PUBLIC_TAX_TOKEN_ADDRESS=0x...
NEXT_PUBLIC_REVENUE_SPLITTER_ADDRESS=0x...
NEXT_PUBLIC_STAKING_VAULT_ADDRESS=0x...

3. Install and Run

Terminal
cd frontend
npm install
npm run dev

The dev server starts at http://localhost:3000. The app connects to BSC Testnet by default.

4. Production Build

Terminal
npm run build
npm run start

Tech Stack

TechnologyVersionPurpose
Next.js15React framework (App Router)
React19UI library
Tailwind CSS4Utility-first styling
wagmi2React hooks for Ethereum
viem2Low-level Ethereum client
Reown AppKit1.6Wallet connection modal
TanStack Query5Async data fetching/caching

Governance Guide

Governance follows the standard OpenZeppelin Governor lifecycle. Any DAOToken holder with delegated voting power can participate.

Step 1: Delegate Voting Power

Before you can vote or propose, you must delegate your voting power. You can delegate to yourself or to another address. Go to the /delegate page in the app.

// Self-delegate to activate your own voting power
DAOToken.delegate(yourAddress)

Step 2: Create a Proposal

Navigate to /proposals/create. A proposal specifies one or more on-chain actions (target contract, function call, and parameters) plus a description.

The proposal threshold is currently 0, so any token holder with delegated power can propose.

Step 3: Vote

After the 1-block voting delay, the proposal enters the Active state for 300 blocks (~15 minutes on BSC). Token holders can vote For, Against, or Abstain. Voting power is based on your delegated balance at the block the proposal was created.

Step 4: Queue

If the proposal passes (more For than Against votes, and at least 4% quorum), it moves to the Succeeded state. Anyone can then queue it in the DAOTimelock, which starts the 1-hour delay.

Step 5: Execute

After the timelock delay elapses, anyone can execute the proposal. The on-chain actions are carried out through the Timelock contract.

Proposal Lifecycle

StateDescription
PendingCreated, waiting for voting delay
ActiveVoting is open
DefeatedDid not reach quorum or more Against votes
SucceededPassed, ready to queue
QueuedIn timelock, waiting for delay
ExecutedActions performed on-chain
CanceledCanceled by the proposer or Governor
ExpiredQueued but not executed before grace period

Tokenomics

The protocol uses a two-token model: DAOToken for governance and staking, and TaxToken for revenue generation through trading taxes.

DAOToken (DAO)

PropertyValue
TypeERC20 + Votes + Permit
Total Supply1,000,000 DAO (fixed)
MintingDisabled (constructor-only mint)
Use CasesGovernance voting, staking for rewards

TaxToken (TAX)

PropertyValue
TypeERC20 + Ownable
Total Supply1,000,000 TAX (fixed)
Buy Tax5% (configurable, max 25%)
Sell Tax5% (configurable, max 25%)
Max Transaction1% of supply
Max Wallet2% of supply

Revenue Distribution

Taxes collected from TaxToken DEX trades are sent to the RevenueSplitter contract, which distributes them across three streams:

50%

Staking Rewards

20%

Burned (Deflationary)

30%

Development

All tax rates and revenue splits are governance-controlled. The DAO can vote to adjust these parameters at any time through proposals.

Staking

DAOToken holders can stake their tokens in the StakingVault to earn TaxToken rewards from trading fees. Rewards are distributed proportionally to each staker's share of the total staked pool.

How to Stake

  • Navigate to the /staking page
  • Enter the amount of DAOTokens to stake
  • Approve the StakingVault to spend your DAOTokens (first time only)
  • Confirm the stake transaction

Lock Period

Staked tokens are subject to a minimum lock period of 7 days (default). You cannot withdraw before this period expires. The lock resets each time you add more stake. The lock period is governance-controlled and can be adjusted via proposal.

Rewards

Rewards accumulate continuously as trading fees flow through the RevenueSplitter. The StakingVault uses a rewardPerToken accumulator (Synthetix pattern) to efficiently calculate each staker's pro-rata share without iterating over all stakers.

Claiming Rewards

  • View your pending rewards on the /staking page
  • Click "Claim Rewards" to receive your accrued TaxToken rewards
  • Claiming does not affect your staked balance or lock period

Withdrawing

  • After the lock period expires, enter the amount to withdraw
  • Any unclaimed rewards are automatically claimed on withdrawal
  • Partial withdrawals are supported

Staking Parameters

ParameterValueControlled By
Staking TokenDAOTokenImmutable
Reward TokenTaxTokenImmutable
Min Lock Period7 daysGovernance
Reward Source50% of trading taxesGovernance (RevenueSplitter shares)