Skip to main content

Purpose and Scope

This document describes the end-to-end protocol for minting and burning the native stablecoin on StableNet.
It covers off-chain coordination between minter members and financial institutions, the proof structures used to verify fiat movements, and the GovMinter governance contract with quorum-based approval procedures.
For detailed information on the governance contracts implementing this protocol, see Minting Governance (GovMasterMinter and GovMinter).
For the token layer where minting and burning are actually executed, see the NativeCoinAdapter Contract.
The overall governance architecture is described in System Contracts Overview.

Protocol Overview

The mint and burn protocol aims to issue stablecoins backed by verifiable fiat deposits and withdrawals.
The protocol follows three core principles:
  1. No unilateral execution without quorum: Mint and burn operations are executed only after a GovMinter proposal and quorum-based approval.
  2. Proof-based verification: Every mint and burn is proposed together with a proof referencing an off-chain fiat movement.
  3. Quorum-based consensus: Operations are executed only when the minter quorum defined at GovMinter genesis is reached.
The protocol assumes cooperation among the following participants:
  • Minter members: Governance participants who verify proofs and vote on mint/burn proposals
  • Collateral accounts: Bank accounts where fiat deposits and withdrawals actually occur
  • GovMinter contract: On-chain governance contract managing mint/burn proposals and voting
    (0x0000000000000000000000000000000000001003)
  • NativeCoinAdapter contract: System contract that executes approved mint/burn operations by modifying native balances
    (0x0000000000000000000000000000000000001000)

System Architecture

The mint and burn protocol consists of three layers: off-chain verification + on-chain consensus + native balance modification.
The off-chain layer verifies fiat movements, the on-chain layer validates them via collective consensus, and the execution layer updates balances and total supply consistently through the NativeCoinAdapter.

Minting Protocol

Minting Workflow

The minting protocol follows the four-step flow below:
  1. Deposit detection: A fiat deposit into a collateral account is detected
  2. Proof construction: A mint proof containing deposit information is created
  3. Proposal and verification: A proposal is submitted to GovMinter and independently verified by minters
  4. On-chain execution: Once quorum is reached, minting is executed via the NativeCoinAdapter

Mint Proof Structure

A mint proof is a data structure that binds a token issuance request to a specific fiat deposit.
On-chain, it is represented by the MintProof struct in GovMinter.
FieldTypeDescription
beneficiaryaddressAddress that will receive the minted tokens
amountuint256Amount of tokens to mint (in smallest units)
timestampuint256Unix timestamp when the deposit occurred
depositIdstringUnique identifier of the deposit in the banking system
bankReferencestringBank transaction reference (1:1 with deposit record)
memostringOptional memo for internal accounting and auditing
This structure, together with GovMinter state (usedProofHashes, depositIdToProposalId, executedDepositIds), ensures:
  • Uniqueness: Each depositId can be used only once, preventing double minting
  • Traceability: On-chain issuance is linked to a specific off-chain deposit
  • Timeliness: Old proofs can be rejected based on timestamps

Minter Responsibilities During Minting

Minter members have the following responsibilities during minting:
  1. Collateral account association: Minters must be associated with predefined collateral accounts, managed via GovMasterMinter
  2. Deposit monitoring: Continuously monitor fiat deposits in collateral accounts off-chain
  3. Proof creation: Generate a mint proof when a deposit is detected
  4. Proposal submission: One minter submits a mint proposal to GovMinter
    Duplicate proposals for the same depositId are rejected
  5. Independent verification: Other minters independently verify the proof:
    • Whether the deposit occurred
    • Whether the amount matches
    • Whether the beneficiary address is correct
    • Whether the deposit has already been used
  6. Approval voting: Approve after successful verification; otherwise reject or abstain

On-Chain Execution

Once a mint proposal reaches quorum, GovBase.executeProposal() calls GovMinter’s _executeMint(), which internally issues tokens via fiatToken.mint(beneficiary, amount).
In typical networks, this fiatToken is the NativeCoinAdapter.
Execution steps:
  1. Quorum check: GovBase verifies that sufficient approvals have been collected
  2. Allowance verification: Confirms that fiatToken.minterAllowance(GovMinter) is sufficient
  3. Mint execution: Calls fiatToken.mint(beneficiary, amount)
    For NativeCoinAdapter, native balances are increased via the internal ICoinManager.mint()
  4. Proof consumption: Records executedDepositIds[depositId] = true to prevent reuse
  5. Total supply update: Increases the fiat token total supply
  6. Event emission: Emits Mint and Transfer(address(0), beneficiary, amount) events

Burn Protocol

Burn Workflow

The burn protocol operates as the reverse of minting.
After tokens are burned on-chain, an equivalent amount of fiat is returned off-chain.

Burn Proof Structure

A burn proof represents a valid withdrawal request corresponding to a token burn.
On-chain, it is represented by the BurnProof struct in GovMinter.
FieldTypeDescription
fromaddressAddress holding the tokens to be burned
amountuint256Amount of tokens to burn
timestampuint256Time when the withdrawal request was received
withdrawalIdstringUnique identifier of the withdrawal request
referenceIdstringExternal settlement system reference ID
memostringOptional memo for internal accounting and auditing
GovMinter uses withdrawalIdToProposalId, executedWithdrawalIds, and usedProofHashes to ensure:
  • ID uniqueness: Each withdrawalId can be used only once
  • User specificity: Burns are executed for a specific from address
  • Idempotency: Duplicate burns for the same withdrawal request are prevented

Minter Responsibilities During Burning

  1. Receive withdrawal request
  2. Generate withdrawal ID
  3. Share off-chain
  4. Create burn proof
  5. Submit proposal and escrow: Call proposeBurn{value: amount} to escrow the same amount of native coin
  6. Independent verification
  7. Approval voting
  8. Fiat return

On-Chain Burn Execution

When quorum is reached, GovBase.executeProposal() calls GovMinter’s _safeBurn(). Execution steps:
  1. Quorum verification
  2. Emergency pause check
  3. Escrow balance deduction
  4. Burn execution: fiatToken.burn(amount)
  5. Withdrawal ID consumption
  6. Event emission

Quorum Requirements and Governance

Quorum Configuration

The quorum required for mint and burn operations is set via GovMinter genesis parameters.
systemContracts.govMinter.params:
- members: "comma-separated list of minter addresses"
- quorum: "minimum approvals required"
- expiry: "proposal expiration time in seconds"
- memberVersion: "version identifier"
- fiatToken: "0x0000000000000000000000000000000000001000"
Recommended guidelines:
  • Minimum: 1
  • Maximum: Number of minters
  • Typical: ceil((members.length * 2) / 3)

Proposal Lifecycle

  1. Proposed
  2. Voting
  3. Quorum reached
  4. Executed
  5. Expired

Security Considerations

Byzantine Fault Tolerance

With quorum set to ceil((N * 2) / 3), up to floor((N - 1) / 3) malicious minters can be tolerated.

Off-Chain Dependencies

Failures in off-chain coordination may cause delays or rejections, but are mitigated by the multi-minter structure and on-chain event auditing.

Proposal Expiry

The expiry mechanism prevents execution of stale proofs, governance griefing, and unbounded proposal accumulation.

Integration with NativeCoinAdapter

Mint Execution Path

GovBase.executeProposal()
→ GovMinter._executeMint(...)
→ fiatToken.mint(...)
→ CoinManager.mint(...) precompile
→ Transfer(0x0, beneficiary, amount)

Burn Execution Path

GovBase.executeProposal()
→ GovMinter._safeBurn(...)
→ fiatToken.burn(...)
→ CoinManager.burn(...) precompile
→ Transfer(from, 0x0, amount)
Through these execution paths, native balances, fiat tokens, and event logs remain consistent, enabling both on-chain and off-chain auditing.