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

# Governance Setup

> Configure on-chain governance for your Folio with voting, timelocks, and role-based permissions

## Overview

Folio Protocol supports sophisticated governance structures with:

* **Role-based access control** for different operations
* **On-chain governance** with voting and timelocks
* **Dual governance** (owner governance + trading governance)
* **Vote delegation** and staking mechanisms

<Info>
  Folios can be governed by multisigs, DAOs, or fully on-chain governance contracts. You can also mix approaches for different roles.
</Info>

## Governance Roles

Folios use three primary roles:

<CardGroup cols={3}>
  <Card title="DEFAULT_ADMIN_ROLE" icon="crown">
    * Set fees and fee recipients
    * Configure auction parameters
    * Add/remove basket assets
    * Deprecate the Folio
    * Manage role assignments
  </Card>

  <Card title="REBALANCE_MANAGER" icon="scale-balanced">
    * Start new rebalances
    * End ongoing rebalances
    * Close individual auctions
  </Card>

  <Card title="AUCTION_LAUNCHER" icon="rocket">
    * Open restricted auctions
    * Narrow price/weight ranges
    * Control auction timing
    * Close auctions
  </Card>
</CardGroup>

<Note>
  There's also a `BRAND_MANAGER` role for off-chain use (no on-chain permissions).
</Note>

## Deployment Options

### Option 1: Manual Role Assignment

Deploy a raw Folio and assign roles directly:

```solidity theme={null}
// Deploy Folio
(Folio folio, address proxyAdmin) = folioDeployer.deployFolio(
    basicDetails,
    additionalDetails,
    flags,
    multisigAddress,           // DEFAULT_ADMIN_ROLE
    [tradingMultisig],         // REBALANCE_MANAGER
    [auctionBotEOA],           // AUCTION_LAUNCHER
    [],                        // BRAND_MANAGER
    deploymentNonce
);

// Roles are assigned during deployment
```

**Use cases:**

* Multisig-controlled Folios
* Testing and development
* Simple governance structures
* EOA-operated auction bots

### Option 2: Full On-Chain Governance

Deploy with complete governance infrastructure:

```solidity theme={null}
(Folio folio, address proxyAdmin) = folioDeployer.deployGovernedFolio(
    IVotes(address(0)),     // Self-governed (creates vote-locked token)
    basicDetails,
    additionalDetails,
    flags,
    ownerGovParams,         // Parameters for owner governance
    tradingGovParams,       // Parameters for trading governance
    govRoles,
    deploymentNonce
);
```

**Use cases:**

* Community-governed Folios
* Transparent decision-making
* Token-holder voting
* Decentralized management

## Configuring Owner Governance

Owner governance controls admin functions (fees, roles, deprecation).

<Steps>
  <Step title="Set Voting Parameters">
    ```solidity theme={null}
    IGovernanceDeployer.GovParams memory ownerGovParams = IGovernanceDeployer.GovParams({
        votingDelay: 1 days,           // Time before voting starts
        votingPeriod: 7 days,          // How long voting lasts
        proposalThreshold: 10_000e18,  // Min tokens to create proposal
        quorumThreshold: 10,           // Required quorum (10%)
        timelockDelay: 2 days,         // Delay before execution
        guardians: [guardianAddress]   // Can cancel malicious proposals
    });
    ```

    **Parameter Guidance:**

    * **votingDelay**: Prevents surprise proposals, allows token acquisition
    * **votingPeriod**: Balance between speed and participation
    * **proposalThreshold**: Prevents spam, should be achievable
    * **quorumThreshold**: Percentage of total supply (not circulating)
    * **timelockDelay**: Allows users to exit before changes take effect
    * **guardians**: Trusted addresses for emergency cancellation
  </Step>

  <Step title="Choose Voting Token">
    **Option A: Self-Governance** (Folio shares = voting power)

    ```solidity theme={null}
    IVotes stToken = IVotes(address(0)); // Deploy new vote-locked token
    ```

    This creates a `StakingVault` where users stake Folio shares to get voting power.

    **Option B: Existing Token**

    ```solidity theme={null}
    IVotes stToken = IVotes(existingGovernanceToken);
    ```

    Use an existing ERC20Votes token for governance.
  </Step>

  <Step title="Deploy Governance">
    ```solidity theme={null}
    (address governor, address timelock) = governanceDeployer.deployGovernanceWithTimelock(
        ownerGovParams,
        stToken,
        deploymentSalt
    );

    // Grant admin role to timelock
    folio.grantRole(folio.DEFAULT_ADMIN_ROLE(), timelock);
    ```

    Deployed components:

    * **Governor**: Handles proposals and voting
    * **Timelock**: Queues and executes approved actions
  </Step>
</Steps>

## Configuring Trading Governance

Trading governance controls rebalancing operations.

<Steps>
  <Step title="Set Rebalancing Parameters">
    ```solidity theme={null}
    IGovernanceDeployer.GovParams memory tradingGovParams = IGovernanceDeployer.GovParams({
        votingDelay: 6 hours,        // Faster for trading decisions
        votingPeriod: 3 days,        // Shorter voting period
        proposalThreshold: 5_000e18, // Lower threshold
        quorumThreshold: 5,          // 5% quorum
        timelockDelay: 1 days,       // Shorter delay for market responsiveness
        guardians: [guardianAddress]
    });
    ```

    <Tip>
      Trading governance typically has shorter timelines than owner governance to respond to market conditions.
    </Tip>
  </Step>

  <Step title="Configure Role Assignment">
    ```solidity theme={null}
    IFolioDeployer.GovRoles memory govRoles = IFolioDeployer.GovRoles({
        existingBasketManagers: new address[](0), // Empty = deploy trading gov
        auctionLaunchers: [botAddress],           // EOA or automation contract
        brandManagers: []
    });
    ```

    **Two approaches:**

    1. **Governance-controlled**: Leave `existingBasketManagers` empty to deploy a separate trading governor
    2. **Direct control**: Provide addresses to skip trading governance deployment
  </Step>

  <Step title="Grant Rebalance Role">
    If using governance:

    ```solidity theme={null}
    // Automatically done by deployGovernedFolio
    folio.grantRole(REBALANCE_MANAGER, tradingTimelock);
    ```

    If using direct control:

    ```solidity theme={null}
    folio.grantRole(REBALANCE_MANAGER, tradingMultisig);
    ```
  </Step>
</Steps>

## Managing Staking Vaults

When self-governing, a `StakingVault` is deployed for vote locking.

### Staking Folio Shares

```solidity theme={null}
// Users stake Folio shares to get voting power
folio.approve(address(stakingVault), amount);
stakingVault.stake(amount, recipient);

// Staking returns vote-locked shares (stFolio)
// stFolio balance = voting power
```

### Unstaking

```solidity theme={null}
// Initiate unstaking (starts cooldown period)
stakingVault.unstake(amount);

// Wait for unstaking delay (default: 1 week)
// Then withdraw
stakingVault.withdraw();
```

### Delegation

```solidity theme={null}
// Delegate voting power without transferring tokens
stakingVault.delegate(delegateAddress);

// Check delegation
uint256 delegatedVotes = stakingVault.getVotes(delegateAddress);
```

<Info>
  The `StakingVault` has:

  * **Reward period**: 3.5 days (for reward distribution)
  * **Unstaking delay**: 1 week (security cooldown)
</Info>

## Creating Governance Proposals

<Steps>
  <Step title="Prepare Proposal Actions">
    ```solidity theme={null}
    // Example: Change mint fee to 0.5%
    address[] memory targets = new address[](1);
    targets[0] = address(folio);

    uint256[] memory values = new uint256[](1);
    values[0] = 0; // No ETH transfer

    bytes[] memory calldatas = new bytes[](1);
    calldatas[0] = abi.encodeWithSelector(
        folio.setMintFee.selector,
        0.005e18 // 0.5%
    );

    string memory description = "Lower mint fee to 0.5% to encourage adoption";
    ```
  </Step>

  <Step title="Submit Proposal">
    ```solidity theme={null}
    uint256 proposalId = governor.propose(
        targets,
        values,
        calldatas,
        description
    );
    ```

    <Check>
      Ensure the proposer has at least `proposalThreshold` tokens.
    </Check>
  </Step>

  <Step title="Vote on Proposal">
    After the voting delay:

    ```solidity theme={null}
    // 0 = Against, 1 = For, 2 = Abstain
    governor.castVote(proposalId, 1);

    // Or with reason
    governor.castVoteWithReason(proposalId, 1, "I support this change");
    ```
  </Step>

  <Step title="Queue and Execute">
    After voting period ends and proposal succeeds:

    ```solidity theme={null}
    // Queue in timelock
    governor.queue(
        targets,
        values,
        calldatas,
        keccak256(bytes(description))
    );

    // Wait for timelock delay
    // Then execute
    governor.execute(
        targets,
        values,
        calldatas,
        keccak256(bytes(description))
    );
    ```
  </Step>
</Steps>

## Example Governance Actions

### Update Fees

```solidity theme={null}
// Proposal to change TVL fee
calldatas[0] = abi.encodeWithSelector(
    folio.setTVLFee.selector,
    634195839675290 // ~2% annual
);
```

### Add Fee Recipient

```solidity theme={null}
IFolio.FeeRecipient[] memory newRecipients = new IFolio.FeeRecipient[](2);
newRecipients[0] = IFolio.FeeRecipient(treasury, 0.7e18);
newRecipients[1] = IFolio.FeeRecipient(devFund, 0.3e18);

calldatas[0] = abi.encodeWithSelector(
    folio.setFeeRecipients.selector,
    newRecipients
);
```

### Start Rebalance

```solidity theme={null}
// Proposal to rebalance basket
IFolio.TokenRebalanceParams[] memory tokens = ...;
IFolio.RebalanceLimits memory limits = ...;

calldatas[0] = abi.encodeWithSelector(
    folio.startRebalance.selector,
    tokens,
    limits,
    3 days,  // Auction launcher window
    7 days   // TTL
);
```

### Grant Role

```solidity theme={null}
// Add new auction launcher
calldatas[0] = abi.encodeWithSelector(
    folio.grantRole.selector,
    AUCTION_LAUNCHER,
    newBotAddress
);
```

## Guardian Emergency Powers

Guardians can cancel malicious or erroneous proposals:

```solidity theme={null}
// Guardian cancels proposal via timelock
timelock.cancel(proposalId);
```

<Warning>
  Guardians have significant power. Choose trusted, security-conscious addresses. Consider using a multi-guardian setup.
</Warning>

## Best Practices

<AccordionGroup>
  <Accordion title="Separation of Concerns">
    Use different governance structures for different roles:

    * **Owner governance**: Long timelock, high quorum (protocol safety)
    * **Trading governance**: Shorter timelock, lower quorum (market responsiveness)
    * **Auction launcher**: Automated EOA or bot (execution efficiency)
  </Accordion>

  <Accordion title="Progressive Decentralization">
    Start with multisig control, then gradually transition to on-chain governance as the community matures:

    1. Launch: Multisig for all roles
    2. Growth: On-chain trading governance, multisig owner governance
    3. Maturity: Full on-chain governance with guardians
  </Accordion>

  <Accordion title="Timelock Configuration">
    * **2+ days for owner governance**: Allows users to exit before major changes
    * **1 day for trading governance**: Balance between security and responsiveness
    * **Never 0**: Always have some delay for transparency
  </Accordion>

  <Accordion title="Quorum Calculation">
    Calculate based on:

    * Expected participation rates (typically 5-20%)
    * Token distribution (whale concentration vs broad distribution)
    * Proposal importance (higher quorum for critical changes)
  </Accordion>
</AccordionGroup>

## Monitoring Governance

### Check Current Configuration

```solidity theme={null}
// View role holders
uint256 adminCount = folio.getRoleMemberCount(folio.DEFAULT_ADMIN_ROLE());
address admin = folio.getRoleMember(folio.DEFAULT_ADMIN_ROLE(), 0);

// View governance parameters
uint256 votingDelay = governor.votingDelay();
uint256 votingPeriod = governor.votingPeriod();
uint256 proposalThreshold = governor.proposalThreshold();
uint256 quorum = governor.quorum(block.number - 1);
```

### Track Proposals

```solidity theme={null}
// Get proposal state
IGovernor.ProposalState state = governor.state(proposalId);
// States: Pending, Active, Canceled, Defeated, Succeeded, Queued, Expired, Executed

// Check votes
(uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) = governor.proposalVotes(proposalId);
```

## Code Reference

* Governance deployer: `contracts/deployer/GovernanceDeployer.sol:40-109`
* Governor implementation: `contracts/governance/FolioGovernor.sol`
* Staking vault: `contracts/staking/StakingVault.sol`
* Role constants: `contracts/utils/Constants.sol`

## Next Steps

<CardGroup cols={2}>
  <Card title="Managing Rebalances" icon="scale-balanced" href="/guides/managing-rebalances">
    Use governance to start and manage rebalances
  </Card>

  <Card title="Deploying Folio" icon="rocket" href="/guides/deploying-folio">
    Review deployment options with governance
  </Card>
</CardGroup>
