# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.treem.io/treem-dao/governance/smart-contracts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
