> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usmewe.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Governance Contract

> Smart contract for decentralized protocol governance

# Governance Contract

The Governance contract enables token holders to propose and vote on protocol changes.

## Contract Overview

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";

contract UsmeweGovernor is
    Governor,
    GovernorSettings,
    GovernorCountingSimple,
    GovernorVotes,
    GovernorTimelockControl
{
    // Voting power multipliers for levels
    mapping(address => uint256) public levelMultipliers;

    // Proposal types
    enum ProposalType {
        ParameterChange,
        ContractUpgrade,
        TreasurySpend,
        EmergencyAction
    }

    struct ProposalMetadata {
        ProposalType proposalType;
        string ipfsHash;
        address proposer;
    }

    mapping(uint256 => ProposalMetadata) public proposalMetadata;
}
```

## Key Functions

### Create Proposal

```solidity theme={null}
function propose(
    address[] memory targets,
    uint256[] memory values,
    bytes[] memory calldatas,
    string memory description,
    ProposalType proposalType,
    string memory ipfsHash
) public returns (uint256 proposalId) {
    require(
        getVotes(msg.sender, block.number - 1) >= proposalThreshold(),
        "Below proposal threshold"
    );

    proposalId = super.propose(targets, values, calldatas, description);

    proposalMetadata[proposalId] = ProposalMetadata({
        proposalType: proposalType,
        ipfsHash: ipfsHash,
        proposer: msg.sender
    });

    emit ProposalCreatedWithMetadata(proposalId, proposalType, ipfsHash);

    return proposalId;
}
```

### Cast Vote

```solidity theme={null}
function castVote(
    uint256 proposalId,
    uint8 support
) public override returns (uint256 weight) {
    address voter = msg.sender;

    // Get base voting power
    uint256 baseWeight = getVotes(voter, proposalSnapshot(proposalId));

    // Apply level multiplier (Platinum: 1.5x, Diamond: 2x)
    uint256 multiplier = levelMultipliers[voter];
    if (multiplier == 0) multiplier = 100; // 1x default

    weight = (baseWeight * multiplier) / 100;

    _countVote(proposalId, voter, support, weight, "");

    emit VoteCastWithWeight(voter, proposalId, support, weight, baseWeight);

    return weight;
}
```

### Execute Proposal

```solidity theme={null}
function execute(
    address[] memory targets,
    uint256[] memory values,
    bytes[] memory calldatas,
    bytes32 descriptionHash
) public payable override returns (uint256) {
    uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);

    require(
        state(proposalId) == ProposalState.Succeeded,
        "Proposal not successful"
    );

    // Emergency proposals skip timelock
    if (proposalMetadata[proposalId].proposalType == ProposalType.EmergencyAction) {
        _executeOperations(proposalId, targets, values, calldatas, descriptionHash);
    } else {
        super.execute(targets, values, calldatas, descriptionHash);
    }

    emit ProposalExecuted(proposalId);

    return proposalId;
}
```

### Update Level Multiplier

```solidity theme={null}
function updateLevelMultiplier(
    address user,
    uint256 multiplier
) external onlyRole(LEVEL_MANAGER_ROLE) {
    require(multiplier >= 100 && multiplier <= 200, "Invalid multiplier");

    levelMultipliers[user] = multiplier;

    emit LevelMultiplierUpdated(user, multiplier);
}
```

## View Functions

### Get Proposal Details

```solidity theme={null}
function getProposalDetails(uint256 proposalId) external view returns (
    ProposalState currentState,
    uint256 forVotes,
    uint256 againstVotes,
    uint256 abstainVotes,
    uint256 startBlock,
    uint256 endBlock,
    ProposalType proposalType,
    string memory ipfsHash
) {
    (forVotes, againstVotes, abstainVotes) = proposalVotes(proposalId);

    return (
        state(proposalId),
        forVotes,
        againstVotes,
        abstainVotes,
        proposalSnapshot(proposalId),
        proposalDeadline(proposalId),
        proposalMetadata[proposalId].proposalType,
        proposalMetadata[proposalId].ipfsHash
    );
}
```

### Get Voting Power

```solidity theme={null}
function getVotingPower(address account) external view returns (
    uint256 baseVotes,
    uint256 multiplier,
    uint256 effectiveVotes
) {
    baseVotes = getVotes(account, block.number - 1);
    multiplier = levelMultipliers[account];
    if (multiplier == 0) multiplier = 100;
    effectiveVotes = (baseVotes * multiplier) / 100;

    return (baseVotes, multiplier, effectiveVotes);
}
```

## Events

```solidity theme={null}
event ProposalCreatedWithMetadata(
    uint256 indexed proposalId,
    ProposalType proposalType,
    string ipfsHash
);

event VoteCastWithWeight(
    address indexed voter,
    uint256 indexed proposalId,
    uint8 support,
    uint256 effectiveWeight,
    uint256 baseWeight
);

event ProposalExecuted(uint256 indexed proposalId);

event LevelMultiplierUpdated(
    address indexed user,
    uint256 multiplier
);
```

## Governance Parameters

| Parameter           | Value       | Description               |
| ------------------- | ----------- | ------------------------- |
| `votingDelay`       | 1 day       | Time before voting starts |
| `votingPeriod`      | 7 days      | Duration of voting        |
| `proposalThreshold` | 1000 tmUSDC | Minimum to propose        |
| `quorumNumerator`   | 4%          | Minimum participation     |

## Proposal Types

<CardGroup cols={2}>
  <Card title="Parameter Change" icon="sliders">
    Modify protocol parameters (interest rates, limits, fees)
  </Card>

  <Card title="Contract Upgrade" icon="arrow-up">
    Upgrade proxy implementations
  </Card>

  <Card title="Treasury Spend" icon="wallet">
    Allocate treasury funds
  </Card>

  <Card title="Emergency Action" icon="bolt">
    Critical fixes (bypasses timelock)
  </Card>
</CardGroup>

## Voting Power by Level

| Level    | Base Multiplier | Effective Vote         |
| -------- | --------------- | ---------------------- |
| Bronze   | 1.0x            | 100 tmUSDC = 100 votes |
| Silver   | 1.0x            | 100 tmUSDC = 100 votes |
| Gold     | 1.0x            | 100 tmUSDC = 100 votes |
| Platinum | 1.5x            | 100 tmUSDC = 150 votes |
| Diamond  | 2.0x            | 100 tmUSDC = 200 votes |

## Proposal Lifecycle

```
┌─────────────────────────────────────────────────────────────────┐
│  PROPOSAL LIFECYCLE                                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Created → Pending → Active → Succeeded → Queued → Executed    │
│              │          │         │                             │
│              │          │         └──→ Defeated                 │
│              │          │                                       │
│              │          └──→ Defeated (quorum not met)          │
│              │                                                  │
│              └──→ Cancelled (by proposer)                       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

| State       | Description                |
| ----------- | -------------------------- |
| `Pending`   | Waiting for voting delay   |
| `Active`    | Voting in progress         |
| `Succeeded` | Passed, awaiting execution |
| `Defeated`  | Failed (votes or quorum)   |
| `Queued`    | In timelock queue          |
| `Executed`  | Successfully executed      |
| `Cancelled` | Cancelled by proposer      |

## Integration Example

```typescript theme={null}
import { ethers } from 'ethers';

// Check voting power
const power = await governor.getVotingPower(myAddress);
console.log(`Effective votes: ${power.effectiveVotes}`);

// Create proposal
const targets = [trustVaultAddress];
const values = [0];
const calldatas = [
  trustVault.interface.encodeFunctionData('updateInterestRate', [500])
];
const description = "Proposal #1: Reduce base interest rate to 5%";

const proposalId = await governor.propose(
  targets,
  values,
  calldatas,
  description,
  0, // ParameterChange
  "QmXxx..." // IPFS hash with details
);

// Vote
await governor.castVote(proposalId, 1); // 1 = For

// Execute after voting period
await governor.execute(targets, values, calldatas, ethers.id(description));
```

## Security Measures

<Warning>
  Critical governance security features:
</Warning>

* **Timelock**: 48-hour delay on non-emergency actions
* **Quorum**: 4% minimum participation required
* **Proposal Threshold**: Prevents spam proposals
* **Emergency Guardian**: Multi-sig can pause in emergencies

## Related Documentation

<CardGroup cols={2}>
  <Card title="Voting Power" icon="vote-yea" href="/governance/voting-power">
    How voting power works
  </Card>

  <Card title="Proposals" icon="file" href="/governance/proposals">
    Creating and managing proposals
  </Card>
</CardGroup>
