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

# Minting Governance (GovMasterMinter and GovMinter)

## Purpose and Scope

StableNet implements a two-layer governance system for minting and burning of the native stablecoin.\
This architecture clearly separates **authorization** (who is allowed to be a minter) from **execution** (who can actually perform mint/burn operations):

* **GovMasterMinter**: Approves and manages minter entities
* **GovMinter**: Executes mint and burn operations through collective voting

This document explains the architecture, responsibilities, storage interactions, and execution flows between the two governance contracts.\
For the operational protocol followed by minters when performing mint/burn operations, see [Mint and Burn Protocol](/en/governance-system/5.6-mint-and-burn-protocol).\
For how minted tokens are represented on-chain, see [NativeCoinAdapter Contract](/en/governance-system/5.2-nativecoinadapter-contract).\
For an overview of all system contracts, see [System Contracts Overview](/en/governance-system/5.1-system-contracts-overview).

## Two-Layer Minting Architecture

Minting governance uses a **hierarchical authorization model** to balance flexibility and security.\
This architecture is implemented through two fixed-address system contracts and storage slots in `NativeCoinAdapter`.

**Key design principles**:

| Layer         | Contract Address | Members               | Operations                                    |
| ------------- | ---------------- | --------------------- | --------------------------------------------- |
| Authorization | `0x0000...1002`  | Master minter members | `configureMinter()`, `removeMinter()`         |
| Execution     | `0x0000...1003`  | Minter members        | `mint()`, `burn()` (quorum approval required) |

This separation is enforced by access control modifiers in the `NativeCoinAdapter` contract:

* `onlyMasterMinter`: checks `msg.sender == masterMinter` (slot 0x0)
* `onlyMinters`: checks `_minters[msg.sender] == true` (slot 0x1)
* Allowance check: `_minterAllowed[msg.sender] >= amount` (slot 0x2)

## GovMasterMinter Contract

### Contract Identification and Deployment

GovMasterMinter is deployed as a system contract at genesis:

* **Address**: `0x0000000000000000000000000000000000001002`
* **Deployment method**: Direct injection into the genesis block (no owner)
* **Upgrade mechanism**: Replacement only via hard fork
* **Version**: Specified in the genesis configuration (e.g. `"v1"`)

### Responsibilities

GovMasterMinter acts as the **authorization layer** for minting operations:

1. **Minter registration**: Approves specific addresses as minters
2. **Minter removal**: Revokes existing minter permissions
3. **Allowance management**: Sets per-minter mint/burn limits
4. **Extensibility**: Enables approval of various minter types such as bridge-based or system minters

This structure generalizes the `masterMinter` concept used in Circle’s FiatToken contracts into an on-chain governance model.

### Genesis Parameters

GovMasterMinter is initialized at genesis via `params.ChainConfig.Anzeon.SystemContracts.GovMasterMinter`:

| Parameter            | Type         | Purpose                            | Example Value                     | Genesis Location                                      |
| -------------------- | ------------ | ---------------------------------- | --------------------------------- | ----------------------------------------------------- |
| `members`            | address list | Master minter governance members   | `"0xaa5f...4697"`                 | `params.GovMasterMinter.Params["members"]`            |
| `quorum`             | uint         | Minimum approvals required         | `"1"`                             | `params.GovMasterMinter.Params["quorum"]`             |
| `expiry`             | uint         | Proposal expiration time (seconds) | `"604800"`                        | `params.GovMasterMinter.Params["expiry"]`             |
| `memberVersion`      | uint         | Membership version                 | `"1"`                             | `params.GovMasterMinter.Params["memberVersion"]`      |
| `fiatToken`          | address      | NativeCoinAdapter address          | `"0x0000...1000"`                 | `params.GovMasterMinter.Params["fiatToken"]`          |
| `minters`            | address list | Initially approved minters         | `"0x0000...1003"`                 | `params.GovMasterMinter.Params["minters"]`            |
| `maxMinterAllowance` | uint256      | Maximum allowance per minter       | `"10000000000000000000000000000"` | `params.GovMasterMinter.Params["maxMinterAllowance"]` |
| `maxProposals`       | uint         | Maximum concurrent proposals       | `"3"`                             | `params.GovMasterMinter.Params["maxProposals"]`       |

### Initialization Sequence

1. `core.SetupGenesisBlock()` calls `core.InjectContracts()`
2. `InjectContracts()` calls `systemcontracts.InjectGovMasterMinter()`
3. `InjectGovMasterMinter()` directly initializes `NativeCoinAdapter` storage:
   * Slot 0x0: `masterMinter = 0x0000...1002`
   * Slot 0x1: `_minters[address] = true` for each approved minter
   * Slot 0x2: `_minterAllowed[address] = maxMinterAllowance` for each minter

### Storage Layout

GovMasterMinter does not maintain its own storage.\
Instead, it manages state via storage slots in `NativeCoinAdapter`, defined as constants in `systemcontracts/coin_adapter.go`:

```
SLOT_COIN_ADAPTER_MASTER_MINTER = "0x0" // address masterMinter
SLOT_COIN_ADAPTER_MINTERS = "0x1" // mapping(address => bool) _minters
SLOT_COIN_ADAPTER_MINTER_ALLOWED = "0x2" // mapping(address => uint256) _minterAllowed
```

**Storage access patterns**:

| Operation          | Slot | Key Derivation      | Value Type |         |           |
| ------------------ | ---- | ------------------- | ---------- | ------- | --------- |
| Read master minter | 0x0  | Direct slot access  | `address`  |         |           |
| Check minter       | 0x1  | \`keccak256(address |            | slot)\` | `bool`    |
| Read allowance     | 0x2  | \`keccak256(address |            | slot)\` | `uint256` |

Mapping slot calculation follows standard Solidity storage layout rules.

### Interaction with NativeCoinAdapter

GovMasterMinter can only call **permission management functions** on `NativeCoinAdapter`, protected by the `onlyMasterMinter` modifier.

**Function signatures**:

* `configureMinter(address minter, uint256 minterAllowedAmount) external onlyMasterMinter`
* `removeMinter(address minter) external onlyMasterMinter`

**Access control flow**:

1. A governance proposal reaches quorum and enters execution
2. The transaction is sent from the GovMasterMinter contract
3. `NativeCoinAdapter` compares `msg.sender` with `masterMinter` in slot 0x0
4. On match, slots 0x1 and 0x2 are updated and events are emitted

## GovMinter Contract

### Contract Identification and Deployment

GovMinter is deployed as a system contract at genesis:

* **Address**: `0x0000000000000000000000000000000000001003`
* **Deployment method**: Direct injection into the genesis block
* **Upgrade mechanism**: Hard fork only
* **Version**: Specified in the genesis configuration

### Responsibilities

GovMinter acts as the **execution layer** for minting operations:

1. **Mint execution**: Issues native stablecoins
2. **Burn execution**: Burns native stablecoins
3. **Oracle role**: Verifies off-chain fiat deposits and withdrawals
4. **Member governance**: Manages its own member set
5. **Multi-approval coordination**: Collects quorum approvals for mint/burn proposals

No single member can ever mint or burn unilaterally.

### Genesis Parameters

GovMinter is configured at genesis via `params.ChainConfig.Anzeon.SystemContracts.GovMinter`:

| Parameter       | Type         | Purpose                         | Example Value     | Genesis Location                           |
| --------------- | ------------ | ------------------------------- | ----------------- | ------------------------------------------ |
| `members`       | address list | Minter operator members         | `"0xaa5f...4697"` | `params.GovMinter.Params["members"]`       |
| `quorum`        | uint         | Minimum approvals for mint/burn | `"1"`             | `params.GovMinter.Params["quorum"]`        |
| `expiry`        | uint         | Proposal expiration time        | `"604800"`        | `params.GovMinter.Params["expiry"]`        |
| `memberVersion` | uint         | Member version                  | `"1"`             | `params.GovMinter.Params["memberVersion"]` |
| `fiatToken`     | address      | NativeCoinAdapter address       | `"0x0000...1000"` | `params.GovMinter.Params["fiatToken"]`     |
| `maxProposals`  | uint         | Maximum concurrent proposals    | `"3"`             | `params.GovMinter.Params["maxProposals"]`  |

### Initialization Prerequisites

GovMinter must be **approved as a minter** before it can operate:

1. GovMinter address must be included in GovMasterMinter’s `minters` list
2. GovMasterMinter must assign an allowance to GovMinter
3. During genesis, `InjectGovMasterMinter()` writes this into NativeCoinAdapter slots 0x1 and 0x2

If these conditions are not met, all `mint()` / `burn()` calls will be rejected at the `onlyMinters` check.

### Mint and Burn Workflow

Before any balance change, mint and burn operations must pass the following validation chain:

**Access control validation chain**:

1. **Minter approval check**: `_minters[msg.sender] == true`
2. **Allowance check**: `_minterAllowed[msg.sender] >= amount`
3. **Balance update**: Direct native balance modification via StateDB
4. **Allowance deduction**: `_minterAllowed[msg.sender] -= amount`

**Function signatures**:

* `mint(address to, uint256 amount) external onlyMinters`
* `burn(uint256 amount) external onlyMinters`

### Self-Governance of Members

GovMinter can manage its own membership.\
However, if GovMasterMinter revokes GovMinter’s minter approval, GovMinter’s entire execution authority is immediately disabled.

## Governance Mechanism

GovMasterMinter and GovMinter share a common GovBase pattern.

### Voting Process

**Proposal lifecycle**:

1. **Creation**: A member creates a proposal
2. **Voting**: Members vote to approve or reject
3. **Quorum reached**: Approvals meet or exceed `quorum`
4. **Execution**: Executed before expiry
5. **Expiration**: Automatically discarded if quorum is not reached

### Quorum Requirements

| Network Size | Recommended Quorum | Rationale               |
| ------------ | ------------------ | ----------------------- |
| 1 member     | 1                  | Development and testing |
| 2–4 members  | 2                  | Simple majority         |
| 5+ members   | ⌈(n/2) + 1⌉        | BFT-oriented safety     |

In production environments, a majority or ≥2/3 quorum is recommended.

### Member Versioning

`memberVersion` is incremented on membership changes and prevents execution of proposals created under older versions, mitigating replay attacks.

### Proposal Limits

`maxProposals` limits the number of concurrent proposals to prevent governance-level DoS attacks.

## Integration with System Contracts

| Relationship                   | Storage/Code Location        | Purpose                    |
| ------------------------------ | ---------------------------- | -------------------------- |
| GovMasterMinter → Slot 0x0     | `statedb.GetState(nca, 0x0)` | Master minter verification |
| GovMinter → Slot 0x1           | `_minters[address]`          | Minter approval check      |
| GovMinter → Slot 0x2           | `_minterAllowed[address]`    | Allowance check            |
| NativeCoinAdapter → Precompile | Native balance update        | Balance modification       |
| Genesis → Storage              | `InjectGovMasterMinter()`    | Initial state setup        |

## Summary

The two-layer minting governance architecture guarantees:

| Feature                                   | Benefit                         |
| ----------------------------------------- | ------------------------------- |
| Separation of authorization and execution | Prevents concentration of power |
| Multi-approval                            | Blocks unilateral abuse         |
| Extensibility                             | Supports diverse minter types   |
| Transparency                              | All actions recorded on-chain   |
| Security                                  | Allowance-based issuance limits |

This design enables StableNet to maintain a **1:1 fiat peg** while achieving protocol-level decentralization and strong operational control.
