> For the complete documentation index, see [llms.txt](https://docs.treem.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.treem.io/treem-dao/governance/smart-contracts.md).

# Smart Contracts

This section provides comprehensive documentation for the smart contracts powering Treem DAO governance.

### Contract Architecture

#### Overview

The Treem DAO governance system consists of four main smart contracts working together to provide secure, transparent, and efficient governance:

```mermaid
graph TD
    A[TreemGovernanceToken] --> B[TreemGovernor]
    A --> C[TreemStaking]
    B --> D[TimelockController]
    C --> A
    C --> B
```

#### Contract Relationships

* **TreemGovernanceToken**: Provides voting power and token transfers
* **TreemStaking**: Manages token locks and voting eligibility
* **TreemGovernor**: Handles proposal creation and voting
* **TimelockController**: Enforces execution delays for security

### TreemGovernanceToken Contract

#### Contract Overview

**Purpose**: ERC-20 governance token with voting capabilities

**Standard**: ERC-20, ERC-20Permit, ERC-20Votes

**Features**: Voting power delegation, permit signatures, governance integration

#### Token Specifications

```solidity
contract TreemGovernanceToken is ERC20, ERC20Permit, ERC20Votes, Ownable {
    uint256 public constant TOTAL_SUPPLY = 1_000_000_000 * 10**18; // 1B tokens
    string public constant AGREEMENT_IPFS = "bafybeiatjzzgloq7dfmytaeuxwnktquinjdxzasw555lfwey6mpnihbpta";
}
```

#### Distribution Allocation

| Recipient           | Amount            | Percentage | Purpose                  |
| ------------------- | ----------------- | ---------- | ------------------------ |
| Foundation Treasury | 400,000,000 TREEM | 40%        | Operations & Development |
| Community Grants    | 300,000,000 TREEM | 30%        | Community Funding        |
| Reserve Future      | 150,000,000 TREEM | 15%        | Strategic Reserves       |
| Founders & Team     | 150,000,000 TREEM | 15%        | Team Allocation          |

#### Key Functions

**Token Information**

```solidity
function name() external pure returns (string memory) {
    return "Treem Governance Token";
}

function symbol() external pure returns (string memory) {
    return "TREEM";
}

function decimals() external pure returns (uint8) {
    return 18;
}

function totalSupply() external pure returns (uint256) {
    return TOTAL_SUPPLY;
}
```

**Voting Functions**

```solidity
function delegate(address delegatee) external {
    // Delegate voting power to another address
}

function getVotes(address account) external view returns (uint256) {
    // Get current voting power of account
}

function getPastVotes(address account, uint256 blockNumber) external view returns (uint256) {
    // Get historical voting power at specific block
}
```

**Agreement Access**

```solidity
function getAgreementIPFS() external pure returns (string memory) {
    return AGREEMENT_IPFS;
}

function getAgreementURL() external pure returns (string memory) {
    return "https://ipfs.io/ipfs/bafybeiatjzzgloq7dfmytaeuxwnktquinjdxzasw555lfwey6mpnihbpta";
}
```

#### Events

```solidity
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);
```

### TreemStaking Contract

#### Contract Overview

**Purpose**: Manage token staking with lock periods and voting eligibility

**Features**: Tiered staking, voting rewards, grant proposal permissions

#### Staking Tiers

```solidity
enum StakeTier { 
    NONE,           // No active stake
    SIX_MONTHS,     // 6-month lock period
    TWELVE_MONTHS   // 12-month lock period
}

struct StakeInfo {
    uint256 amount;      // Staked token amount
    uint256 startTime;   // Stake creation timestamp
    StakeTier tier;      // Staking tier
}
```

#### Constructor

```solidity
constructor(
    address _treemToken,    // TREEM token address
    address _votesToken,    // Same as TREEM token (IVotes interface)
    address _treasury       // Treasury for bonus payments
) {
    treemToken = IERC20(_treemToken);
    votesToken = IVotes(_votesToken);
    treasury = _treasury;
    bonusPerVote = 100 * 1e18; // 100 TREEM per vote
}
```

#### Core Functions

**Staking Operations**

```solidity
function stake(uint256 amount, StakeTier tier) external {
    require(tier == StakeTier.SIX_MONTHS || tier == StakeTier.TWELVE_MONTHS, "Invalid tier");
    require(amount > 0, "Amount must be > 0");
    require(stakes[msg.sender].amount == 0, "Already staked");

    treemToken.transferFrom(msg.sender, address(this), amount);
    stakes[msg.sender] = StakeInfo(amount, block.timestamp, tier);
    votesToken.delegate(msg.sender); // Auto-delegate to self

    emit Staked(msg.sender, amount, tier);
}

function unstake() external {
    StakeInfo storage info = stakes[msg.sender];
    require(info.amount > 0, "Nothing to unstake");

    uint256 requiredTime = info.tier == StakeTier.SIX_MONTHS ? 180 days : 365 days;
    require(block.timestamp >= info.startTime + requiredTime, "Lock period not over");

    uint256 amount = info.amount;
    delete stakes[msg.sender];
    treemToken.transfer(msg.sender, amount);

    emit Unstaked(msg.sender, amount);
}
```

**Reward Management**

```solidity
function recordVoteParticipation(address voter) external onlyOwner {
    votesParticipated[voter] += 1;
}

function claimBonus() external {
    uint256 participation = votesParticipated[msg.sender];
    require(participation > 0, "No participation recorded");
    require(stakes[msg.sender].amount > 0, "Must be staked");

    uint256 bonus = bonusPerVote * participation;
    votesParticipated[msg.sender] = 0;
    treemToken.transferFrom(treasury, msg.sender, bonus);

    emit BonusClaimed(msg.sender, bonus);
}
```

**Permission Checks**

```solidity
function canProposeGrants(address user) external view returns (bool) {
    return stakes[user].tier == StakeTier.TWELVE_MONTHS;
}

function canVoteOnGrants(address user) external view returns (bool) {
    return stakes[user].tier == StakeTier.TWELVE_MONTHS;
}

function canVoteOnGeneral(address user) external view returns (bool) {
    return stakes[user].tier != StakeTier.NONE;
}
```

#### Administrative Functions

```solidity
function setBonusPerVote(uint256 newBonus) external onlyOwner {
    bonusPerVote = newBonus;
}

function setTreasury(address newTreasury) external onlyOwner {
    require(newTreasury != address(0), "Zero address");
    treasury = newTreasury;
}
```

#### Events

```solidity
event Staked(address indexed user, uint256 amount, StakeTier tier);
event Unstaked(address indexed user, uint256 amount);
event BonusClaimed(address indexed user, uint256 bonusAmount);
```

### TreemGovernor Contract

#### Contract Overview

**Purpose**: Main governance contract for proposals and voting

**Standard**: OpenZeppelin Governor with extensions

**Features**: Proposal creation, voting, execution with timelock

#### Governance Parameters

```solidity
constructor(IVotes _token, TimelockController _timelock)
    Governor("TreemGovernor")
    GovernorSettings(
        7200,         // 1 day voting delay
        50400,        // 7 days voting period  
        5_000_000e18  // 0.5% proposal threshold
    )
    GovernorVotes(_token)
    GovernorVotesQuorumFraction(4) // 4% quorum
    GovernorTimelockControl(_timelock)
{}
```

#### Core Functions

**Proposal Creation**

```solidity
function propose(
    address[] memory targets,
    uint256[] memory values,
    bytes[] memory calldatas,
    string memory description
) public override returns (uint256) {
    require(getVotes(msg.sender, block.number - 1) >= proposalThreshold(), "Below threshold");
    return super.propose(targets, values, calldatas, description);
}
```

**Voting Functions**

```solidity
function castVote(uint256 proposalId, uint8 support) public override returns (uint256) {
    return super.castVote(proposalId, support);
}

function castVoteWithReason(
    uint256 proposalId, 
    uint8 support, 
    string memory reason
) public override returns (uint256) {
    return super.castVoteWithReason(proposalId, support, reason);
}
```

**State Management**

```solidity
enum ProposalState {
    Pending,   // Proposal created, voting not started
    Active,    // Voting in progress
    Canceled,  // Proposal cancelled
    Defeated,  // Voting failed (no majority or quorum)
    Succeeded, // Voting succeeded
    Queued,    // Successful proposal queued for execution
    Expired,   // Execution window expired
    Executed   // Proposal executed
}

function state(uint256 proposalId) public view override returns (ProposalState) {
    return super.state(proposalId);
}
```

#### Proposal Execution

```solidity
function execute(
    address[] memory targets,
    uint256[] memory values,
    bytes[] memory calldatas,
    bytes32 descriptionHash
) public payable override returns (uint256) {
    return super.execute(targets, values, calldatas, descriptionHash);
}
```

#### Events

```solidity
event ProposalCreated(
    uint256 proposalId,
    address proposer,
    address[] targets,
    uint256[] values,
    string[] signatures,
    bytes[] calldatas,
    uint256 startBlock,
    uint256 endBlock,
    string description
);

event VoteCast(
    address indexed voter,
    uint256 proposalId,
    uint8 support,
    uint256 weight,
    string reason
);

event ProposalExecuted(uint256 proposalId);
```

### TimelockController Contract

#### Overview

**Purpose**: Add execution delay for security

**Standard**: OpenZeppelin TimelockController

**Features**: Multi-signature support, role-based access

#### Configuration

```solidity
constructor(
    uint256 minDelay,     // 2 days minimum delay
    address[] proposers,  // Governor contract
    address[] executors   // Governor contract + admin
) TimelockController(minDelay, proposers, executors) {}
```

#### Key Functions

```solidity
function schedule(
    address target,
    uint256 value,
    bytes calldata data,
    bytes32 predecessor,
    bytes32 salt,
    uint256 delay
) external onlyRole(PROPOSER_ROLE);

function execute(
    address target,
    uint256 value,
    bytes calldata data,
    bytes32 predecessor,
    bytes32 salt
) external payable onlyRoleOrOpenRole(EXECUTOR_ROLE);
```

### Deployment Guide

#### Prerequisites

* Hardhat development environment
* Ethereum wallet with ETH for deployment
* Access to Ethereum node (Infura, Alchemy, etc.)

#### Deployment Sequence

**1. Deploy TreemGovernanceToken**

```typescript
const TreemGovernanceToken = await ethers.getContractFactory("TreemGovernanceToken");
const token = await TreemGovernanceToken.deploy(
    foundationTreasury,   // Foundation treasury address
    foundersTeam,         // Founders team address  
    communityGrants,      // Community grants address
    reserveFuture,        // Reserve future address
    initialOwner          // Initial owner (deployer)
);
await token.deployed();
```

**2. Deploy TimelockController**

```typescript
const TimelockController = await ethers.getContractFactory("TimelockController");
const timelock = await TimelockController.deploy(
    172800,              // 2 days in seconds
    [],                  // Proposers (will be set to governor)
    []                   // Executors (will be set to governor + admin)
);
await timelock.deployed();
```

**3. Deploy TreemStaking**

```typescript
const TreemStaking = await ethers.getContractFactory("TreemStaking");
const staking = await TreemStaking.deploy(
    token.address,       // TREEM token address
    token.address,       // Votes token (same as TREEM)
    treasury            // Treasury address for rewards
);
await staking.deployed();
```

**4. Deploy TreemGovernor**

```typescript
const TreemGovernor = await ethers.getContractFactory("TreemGovernor");
const governor = await TreemGovernor.deploy(
    token.address,       // Votes token
    timelock.address     // Timelock controller
);
await governor.deployed();
```

**5. Configure Contracts**

```typescript
// Grant governor roles in timelock
await timelock.grantRole(await timelock.PROPOSER_ROLE(), governor.address);
await timelock.grantRole(await timelock.EXECUTOR_ROLE(), governor.address);

// Renounce admin role from deployer
await timelock.revokeRole(await timelock.TIMELOCK_ADMIN_ROLE(), deployer.address);
```

#### Gas Estimates

| Contract             | Deployment Gas  | Mainnet Cost (50 gwei) |
| -------------------- | --------------- | ---------------------- |
| TreemGovernanceToken | \~2,500,000     | \~0.125 ETH            |
| TreemStaking         | \~1,200,000     | \~0.060 ETH            |
| TreemGovernor        | \~3,000,000     | \~0.150 ETH            |
| TimelockController   | \~1,500,000     | \~0.075 ETH            |
| **Total**            | **\~8,200,000** | **\~0.410 ETH**        |

### Security Considerations

#### Access Controls

**Critical Functions Protected**:

* Contract ownership transfer
* Parameter updates
* Emergency functions
* Treasury management

**Role-Based Security**:

```solidity
modifier onlyOwner() {
    require(msg.sender == owner(), "Not the owner");
    _;
}

modifier onlyRole(bytes32 role) {
    require(hasRole(role, msg.sender), "Access denied");
    _;
}
```

#### Reentrancy Protection

```solidity
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract TreemStaking is ReentrancyGuard {
    function stake(uint256 amount, StakeTier tier) external nonReentrant {
        // Protected against reentrancy
    }
}
```

#### Time-Based Security

**Block Timestamp Usage**:

* Lock period calculations use `block.timestamp`
* Resistant to minor manipulation
* Suitable for periods measured in days

**Snapshot Mechanism**:

* Voting power calculated at proposal creation
* Prevents vote manipulation
* Historical data preserved

### Integration Examples

#### Frontend Integration

**Contract Instance Creation**

```typescript
import { ethers } from 'ethers';

// Contract addresses
const CONTRACTS = {
  TREEM_TOKEN: '0x...',
  STAKING: '0x...',
  GOVERNOR: '0x...',
  TIMELOCK: '0x...'
};

// Create contract instances
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();

const treemToken = new ethers.Contract(
  CONTRACTS.TREEM_TOKEN,
  TreemTokenABI,
  signer
);

const stakingContract = new ethers.Contract(
  CONTRACTS.STAKING,
  TreemStakingABI,
  signer
);
```

**Common Operations**

```typescript
// Stake tokens
async function stakeTokens(amount: string, tier: number) {
  const tx = await stakingContract.stake(
    ethers.utils.parseEther(amount),
    tier // 1 for SIX_MONTHS, 2 for TWELVE_MONTHS
  );
  await tx.wait();
}

// Check staking status
async function getStakeInfo(address: string) {
  const stakeInfo = await stakingContract.stakes(address);
  return {
    amount: ethers.utils.formatEther(stakeInfo.amount),
    startTime: new Date(stakeInfo.startTime.toNumber() * 1000),
    tier: stakeInfo.tier
  };
}

// Create proposal
async function createProposal(description: string) {
  const tx = await governorContract.propose(
    [], // targets
    [], // values
    [], // calldatas
    description
  );
  await tx.wait();
}
```

#### Event Listening

```typescript
// Listen for staking events
stakingContract.on('Staked', (user, amount, tier, event) => {
  console.log(`User ${user} staked ${ethers.utils.formatEther(amount)} TREEM`);
});

// Listen for voting events
governorContract.on('VoteCast', (voter, proposalId, support, weight, reason, event) => {
  console.log(`Vote cast: ${voter} voted ${support} with weight ${weight}`);
});
```

### Troubleshooting

#### Common Deployment Issues

**Insufficient Gas**:

```
Error: Transaction ran out of gas
Solution: Increase gas limit to 3,000,000+
```

**Constructor Arguments**:

```
Error: Invalid constructor arguments
Solution: Verify all addresses are valid and checksummed
```

**Network Configuration**:

```
Error: Network mismatch
Solution: Ensure correct network configuration in hardhat.config.js
```

#### Runtime Issues

**Staking Failures**:

* Check token approval
* Verify sufficient balance
* Ensure not already staked

**Voting Issues**:

* Confirm tokens are staked
* Check proposal is in active state
* Verify voting power > 0

**Proposal Creation**:

* Meet proposal threshold
* Provide valid description
* Check governor contract state

This comprehensive smart contracts documentation provides all necessary information for understanding, deploying, and interacting with the Treem DAO governance contracts.
