-
Notifications
You must be signed in to change notification settings - Fork 7
Add m013 Value-Based Fee Routing mechanism spec #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
CShear
wants to merge
2
commits into
regen-network:main
Choose a base branch
from
CShear:feat/m013-fee-routing
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # m013 — Value-Based Fee Routing (v0) | ||
|
|
||
| m013 replaces flat gas fees with **value-proportional fees** on ecological credit transactions, routing fee revenue to four purpose-specific pools: Burn, Validator, Community, and Agent Infrastructure. | ||
|
|
||
| ## What it outputs | ||
| - A **fee amount** (in uregen) computed as `max(value * rate, min_fee)` for each credit transaction. | ||
| - A **distribution breakdown** splitting the fee across four pools according to governance-set shares. | ||
| - KPI metrics: total fees collected, fees by transaction type, distribution by pool, average fee rate. | ||
|
|
||
| ## What it does not do (v0) | ||
| - No on-chain module deployment; v0 is a spec + reference implementation for validation. | ||
| - Non-credit transactions remain on flat gas — unaffected by this mechanism. | ||
| - Fee denomination questions (OQ-M013-3) are deferred to WG resolution. | ||
|
|
||
| ## How to reference | ||
| - Canonical spec: `mechanisms/m013-value-based-fee-routing/SPEC.md` | ||
| - Fee calculation: SPEC.md sections 3-4 (schedule + formula) | ||
| - Distribution model: SPEC.md section 5 (Model A default) | ||
| - Security invariants: SPEC.md section 9 | ||
|
|
||
| ## Replay datasets | ||
| See `datasets/` for deterministic fixtures used to generate non-zero KPI outputs without MCP. | ||
| - `v0_sample.json` — fee events from diverse transaction types | ||
|
|
||
| ## Schemas | ||
| Canonical JSON schemas for m013 outputs live in `schemas/`. | ||
| - `m013_fee_event.schema.json` — fee collection event (tx_type, value, fee_amount, distribution) | ||
| - `m013_fee_config.schema.json` — fee configuration (rates by tx type, distribution shares) | ||
| - `m013_kpi.schema.json` — KPI output with `mechanism_id: "m013"` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,230 @@ | ||
| # m013 — Value-Based Fee Routing (SPEC) | ||
|
|
||
| ## 0. Header | ||
| - **ID:** m013 | ||
| - **Name:** Value-Based Fee Routing | ||
| - **Status:** draft (v0) | ||
| - **Owner:** (unset) | ||
| - **Last updated:** 2026-02-18 | ||
| - **Scope:** Replace flat gas fees with value-proportional fees on ecological credit transactions, routing fee revenue to four purpose-specific pools. | ||
|
|
||
| ## 1. Problem | ||
| A $10 credit and a $10,000 credit pay the same gas fee — this disconnects protocol revenue from the value it facilitates. The current flat gas model produces negligible revenue from high-value credit transactions and fails to fund network operations (validators, community governance, agent infrastructure, supply management) without relying on inflationary token emission. | ||
|
|
||
| ## 2. Target actor and action | ||
| - **Actors:** Fee Payer (user initiating credit transaction), Burn Pool, Validator Fund, Community Pool, Agent Infrastructure Fund. | ||
| - **Action being evaluated:** a **credit transaction** (issuance, transfer, retirement, marketplace trade) that generates a value-proportional fee. | ||
| - **Event source:** `x/ecocredit` message handlers intercepted by `x/feerouter` module. | ||
|
|
||
| ## 3. Fee Schedule | ||
|
|
||
| | Transaction Type | Message | Current Fee | Proposed Fee | Rationale | | ||
| |---|---|---|---|---| | ||
| | Credit Issuance | `MsgCreateBatch` | Flat gas (~0.01 REGEN) | 1-3% of credit value | Highest value event; primary revenue source | | ||
| | Credit Transfer | `MsgSend` | Flat gas | 0.1% of credit value | Minimal friction for transfers | | ||
| | Credit Retirement | `MsgRetire` | Flat gas | 0.5% of credit value | Exit fee; captures value at point of impact | | ||
| | Marketplace Trade | `MsgBuySellOrder` | Flat gas | 1% of trade value | Standard marketplace fee | | ||
| | Non-credit transactions | (various) | Flat gas | Flat gas (unchanged) | Standard Cosmos SDK transactions unaffected | | ||
|
|
||
| Default v0 fee rates (reference implementation): | ||
| - `CreditIssuance`: 0.02 (2%) | ||
| - `CreditTransfer`: 0.001 (0.1%) | ||
| - `CreditRetirement`: 0.005 (0.5%) | ||
| - `MarketplaceTrade`: 0.01 (1%) | ||
|
|
||
| ## 4. Fee Calculation | ||
|
|
||
| ``` | ||
| fee_amount = max(transaction_value * fee_rate[tx_type], min_fee) | ||
| ``` | ||
|
|
||
| Where: | ||
| - `transaction_value` is denominated in uregen (1 REGEN = 1,000,000 uregen). | ||
| - `fee_rate[tx_type]` is the rate from the fee schedule (section 3). | ||
| - `min_fee` = 1,000,000 uregen (1 REGEN) — prevents zero-fee transactions on low-value credits. | ||
|
|
||
| ### Value estimation by transaction type | ||
|
|
||
| ```yaml | ||
| fee_calculation: | ||
| # For marketplace trades, value is explicit (sell order price x quantity) | ||
| marketplace_value: sell_order.price * quantity | ||
|
|
||
| # For issuance, value must be estimated | ||
| # Option A: Use most recent marketplace price for credit class | ||
| # Option B: Use governance-set reference price per credit type | ||
| # Option C: Use KOI-sourced external market price | ||
| issuance_value_method: "marketplace_reference" # OQ-M013-2 | ||
|
|
||
| # For transfers, value uses same estimation as issuance | ||
| transfer_value_method: "marketplace_reference" | ||
|
|
||
| # For retirements, value at point of retirement | ||
| retirement_value_method: "marketplace_reference" | ||
|
|
||
| # Minimum fee floor | ||
| min_fee: 1 REGEN # = 1,000,000 uregen | ||
| ``` | ||
|
|
||
| ## 5. Fee Distribution | ||
|
|
||
| ``` | ||
| For each fee-generating transaction: | ||
|
|
||
| fee_amount = max(transaction_value * fee_rate[transaction_type], min_fee) | ||
|
|
||
| burn_pool += fee_amount * burn_share | ||
| validator_fund += fee_amount * validator_share | ||
| community_pool += fee_amount * community_share | ||
| agent_infra += fee_amount * agent_share | ||
|
|
||
| where burn_share + validator_share + community_share + agent_share = 1.0 | ||
| ``` | ||
|
|
||
| ### Distribution Parameters | ||
|
|
||
| **Model A** (default for v0): | ||
|
|
||
| | Pool | Share | Purpose | | ||
| |---|---|---| | ||
| | Burn Pool | 30% | Supply reduction via M012 | | ||
| | Validator Fund | 40% | Fixed compensation for authority validators | | ||
| | Community Pool | 25% | Governance-directed spending | | ||
| | Agent Infrastructure | 5% | AI agent operational costs | | ||
|
|
||
| **Model B** (from Network Coordination Architecture, for WG discussion): | ||
|
|
||
| | Pool | Share | Purpose | | ||
| |---|---|---| | ||
| | Burn Pool | 25-35% | Supply reduction via M012 | | ||
| | Validator Fund | 15-25% | Authority validator compensation | | ||
| | Community Pool | 50-60% | Contributor distribution via M015 | | ||
| | Agent Infrastructure | (included in Community Pool) | Not separated | | ||
|
|
||
| > **OQ-M013-1**: Which distribution model should be adopted? Model A provides a dedicated Agent Infrastructure fund; Model B routes a larger share through governance. | ||
|
|
||
| > **OQ-M013-5**: Should the Burn Pool exist at all, and if so, at what share? See source material for full pro/con analysis. | ||
|
|
||
| ## 6. Token Flows | ||
|
|
||
| ``` | ||
| +--------------+ | ||
| | Credit | fee = max(value * rate, min_fee) | ||
| | Transaction | -------------------------------------------+ | ||
| +--------------+ | | ||
| v | ||
| +------------------+ | ||
| | Fee Collector | | ||
| | Module | | ||
| +------------------+ | ||
| | | ||
| +---------------+----------------+------+----------+ | ||
| | | | | | ||
| v v v v | ||
| +-----------+ +-----------+ +-----------+ +-----------+ | ||
| | Burn Pool | | Validator | | Community | | Agent | | ||
| | (-> M012 | | Fund | | Pool | | Infra | | ||
| | burn) | | (-> M014 | | (-> M015 | | Fund | | ||
| | | | validators) | rewards) | | (-> ops) | | ||
| +-----------+ +-----------+ +-----------+ +-----------+ | ||
| ``` | ||
|
|
||
| ## 7. Participants | ||
|
|
||
| | Role | Description | Token Interaction | | ||
| |---|---|---| | ||
| | Fee Payer | User initiating credit transaction | Pays % fee in REGEN (or allowed denom) | | ||
| | Burn Pool | Protocol supply reduction | Receives `burn_share` of fees -> permanent burn | | ||
| | Validator Fund | Authority validator compensation | Receives `validator_share` of fees -> fixed distribution | | ||
| | Community Pool | Governance-directed spending | Receives `community_share` of fees -> proposal-based allocation | | ||
| | Agent Infra Fund | AI agent operations | Receives `agent_share` of fees -> operational budget | | ||
|
|
||
| ## 8. State Transitions | ||
|
|
||
| ``` | ||
| States: {FLAT_GAS, TRANSITION, VALUE_BASED} | ||
|
|
||
| FLAT_GAS -> TRANSITION | ||
| trigger: governance.approve(m013_fee_proposal) | ||
| guard: fee_collector_module deployed, pool addresses configured | ||
| action: enable dual-fee mode (flat gas + value fees) | ||
| note: transition period allows UI/tooling to adapt | ||
|
|
||
| TRANSITION -> VALUE_BASED | ||
| trigger: transition_period_expired(90 days) OR governance.accelerate() | ||
| guard: fee_revenue > 0 for 30 consecutive days | ||
| action: disable legacy flat gas for credit transactions, full value-based fees | ||
| ``` | ||
|
|
||
| ## 9. Security Invariants | ||
|
|
||
| 1. **Fee Conservation**: `fee_collected = sum(pool_distributions)` — no fee revenue lost or created. | ||
| 2. **Share Sum Unity**: `burn_share + validator_share + community_share + agent_share = 1.0` | ||
| 3. **Non-Negative Fees**: All fee rates >= 0; fee amounts >= `min_fee`. | ||
| 4. **Rate Bound Safety**: Individual fee rates bounded `[0, 0.10]` (max 10%) to prevent governance attack. | ||
| 5. **Pool Isolation**: Each pool's balance is independent; no pool can draw from another without governance. | ||
|
|
||
| ## 10. Governance Parameters | ||
|
|
||
| The following parameters are governance-controlled: | ||
|
|
||
| | Parameter | Default (v0) | Range | Description | | ||
| |---|---|---|---| | ||
| | `fee_rate.CreditIssuance` | 0.02 | [0, 0.10] | Fee rate for credit issuance | | ||
| | `fee_rate.CreditTransfer` | 0.001 | [0, 0.10] | Fee rate for credit transfers | | ||
| | `fee_rate.CreditRetirement` | 0.005 | [0, 0.10] | Fee rate for credit retirements | | ||
| | `fee_rate.MarketplaceTrade` | 0.01 | [0, 0.10] | Fee rate for marketplace trades | | ||
| | `distribution.burn_share` | 0.30 | [0, 1.0] | Share routed to burn pool | | ||
| | `distribution.validator_share` | 0.40 | [0, 1.0] | Share routed to validator fund | | ||
| | `distribution.community_share` | 0.25 | [0, 1.0] | Share routed to community pool | | ||
| | `distribution.agent_share` | 0.05 | [0, 1.0] | Share routed to agent infra fund | | ||
| | `min_fee` | 1,000,000 uregen | [0, inf) | Minimum fee floor (1 REGEN) | | ||
|
|
||
| Constraint: `burn_share + validator_share + community_share + agent_share = 1.0` (Share Sum Unity). | ||
|
|
||
| ## 11. Open Questions (for WG Resolution) | ||
|
|
||
| > **OQ-M013-2**: How is credit value determined for non-marketplace transactions (issuance, transfer, retirement)? Options: (A) most recent marketplace price for that credit class, (B) governance-set reference price per credit type, (C) external oracle via KOI. This is critical for fee calculation accuracy. | ||
|
|
||
| > **OQ-M013-3**: In what denomination should fees be collected and distributed? See source material for full analysis of REGEN-only, native denom, and hybrid approaches, as well as distribution-side considerations. | ||
|
|
||
| > **OQ-M013-4**: How should the Agent Infrastructure fund be governed? As a separate module account with its own spending authority, or as a tagged allocation within the Community Pool subject to governance proposals? | ||
|
|
||
| ## 12. Implementation Notes | ||
|
|
||
| - **Module**: New `x/feerouter` module intercepting credit transaction messages. | ||
| - **Storage**: `FeeConfig` (rates, shares, min_fee), `PoolBalance` per pool, `FeeRecord` per transaction. | ||
| - **Events**: `EventFeeCollected`, `EventFeeDistributed`, `EventRateUpdated`. | ||
| - **Integration**: Hooks into `x/ecocredit` message handlers for credit transactions. | ||
| - **Migration**: Backward compatible; flat gas remains for non-credit transactions. | ||
| - **Dependencies**: M012 (burn pool feeds mint/burn algorithm), M014 (validator fund feeds PoA compensation). | ||
|
|
||
| ## 13. Acceptance Tests | ||
|
|
||
| **Fee calculation:** | ||
| 1. Credit issuance of 5,000,000,000 uregen at 2% rate produces fee of 100,000,000 uregen. | ||
| 2. Credit transfer of 100,000,000 uregen at 0.1% rate computes 100,000 uregen; clamped to `min_fee` = 1,000,000 uregen. | ||
| 3. Credit retirement of 1,000,000,000 uregen at 0.5% rate produces fee of 5,000,000 uregen. | ||
| 4. Marketplace trade of 2,500,000,000 uregen at 1% rate produces fee of 25,000,000 uregen. | ||
| 5. Low-value transfer (500,000 uregen) computes 500 uregen; clamped to `min_fee` = 1,000,000 uregen. | ||
|
|
||
| **Fee distribution:** | ||
| 6. A 100,000,000 uregen fee distributes: burn 30,000,000, validator 40,000,000, community 25,000,000, agent 5,000,000. | ||
| 7. Sum of all pool distributions equals `fee_amount` (fee conservation). | ||
| 8. Share Sum Unity: shares always sum to 1.0. | ||
|
|
||
| **Invariant enforcement:** | ||
| 9. Fee rate above 0.10 (10%) is rejected by governance parameter validation. | ||
| 10. Distribution shares that do not sum to 1.0 are rejected. | ||
| 11. Negative fee rates are rejected. | ||
| 12. Pool balances are isolated; no cross-pool withdrawals without governance. | ||
|
|
||
| **State transitions:** | ||
| 13. System starts in FLAT_GAS; transition to TRANSITION requires governance approval + module deployment. | ||
| 14. TRANSITION -> VALUE_BASED requires 30 consecutive days of fee_revenue > 0 and either 90-day expiry or governance acceleration. | ||
|
|
||
| --- | ||
|
|
||
| ## Appendix A — Source anchors | ||
| - `phase-2/2.6-economic-reboot-mechanisms.md` lines 182-367 | ||
| - "PROTOCOL SPECIFICATION: M013" — full specification including fee schedule, distribution models, state transitions, security invariants, and implementation notes. | ||
20 changes: 20 additions & 0 deletions
20
mechanisms/m013-value-based-fee-routing/datasets/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # m013 datasets (replay fixtures) | ||
|
|
||
| These fixtures are **deterministic inputs** for generating non-zero m013 KPI outputs **without MCP**. | ||
|
|
||
| ## Files | ||
| - `schema.json` — JSON schema for replay datasets | ||
| - `fixtures/v0_sample.json` — fee events from diverse transaction types (issuance, transfer, retirement, marketplace) including low-value events that trigger the min_fee floor | ||
|
|
||
| ## How they are used | ||
| A replay runner (e.g., in `regen-heartbeat`) can read a fixture file and compute: | ||
| - `total_fees_uregen` — sum of all computed fees | ||
| - `fee_events_count` — number of fee events | ||
| - `fees_by_type` — fee totals broken down by transaction type | ||
| - `distribution_by_pool` — fee distribution totals by pool (burn, validator, community, agent) | ||
| - `avg_fee_rate` — average effective fee rate (total_fees / total_value) | ||
| - `min_fee_applied_count` — count of events where the min_fee floor was applied | ||
|
|
||
| All monetary values are in **uregen** (1 REGEN = 1,000,000 uregen). | ||
|
|
||
| These datasets are for validation and digest reporting only; they do not imply on-chain enforcement. |
78 changes: 78 additions & 0 deletions
78
mechanisms/m013-value-based-fee-routing/datasets/fixtures/v0_sample.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| { | ||
| "mechanism_id": "m013", | ||
| "scope": "v0_replay", | ||
| "as_of": "2026-02-18T12:00:00Z", | ||
| "fee_config": { | ||
| "fee_rates": { | ||
| "CreditIssuance": 0.02, | ||
| "CreditTransfer": 0.001, | ||
| "CreditRetirement": 0.005, | ||
| "MarketplaceTrade": 0.01 | ||
| }, | ||
| "distribution_shares": { | ||
| "burn": 0.30, | ||
| "validator": 0.40, | ||
| "community": 0.25, | ||
| "agent": 0.05 | ||
| }, | ||
| "min_fee_uregen": 1000000 | ||
| }, | ||
| "fee_events": [ | ||
| { | ||
| "tx_hash": "tx_issuance_001", | ||
| "tx_type": "CreditIssuance", | ||
| "timestamp": "2026-02-18T08:00:00Z", | ||
| "value_uregen": 5000000000, | ||
| "payer": "regen1issuer001" | ||
| }, | ||
| { | ||
| "tx_hash": "tx_transfer_001", | ||
| "tx_type": "CreditTransfer", | ||
| "timestamp": "2026-02-18T09:00:00Z", | ||
| "value_uregen": 100000000, | ||
| "payer": "regen1sender001" | ||
| }, | ||
| { | ||
| "tx_hash": "tx_retire_001", | ||
| "tx_type": "CreditRetirement", | ||
| "timestamp": "2026-02-18T10:00:00Z", | ||
| "value_uregen": 1000000000, | ||
| "payer": "regen1retiree001" | ||
| }, | ||
| { | ||
| "tx_hash": "tx_market_001", | ||
| "tx_type": "MarketplaceTrade", | ||
| "timestamp": "2026-02-18T10:30:00Z", | ||
| "value_uregen": 2500000000, | ||
| "payer": "regen1buyer001" | ||
| }, | ||
| { | ||
| "tx_hash": "tx_transfer_002", | ||
| "tx_type": "CreditTransfer", | ||
| "timestamp": "2026-02-18T11:00:00Z", | ||
| "value_uregen": 500000, | ||
| "payer": "regen1sender002" | ||
| }, | ||
| { | ||
| "tx_hash": "tx_issuance_002", | ||
| "tx_type": "CreditIssuance", | ||
| "timestamp": "2026-02-18T11:15:00Z", | ||
| "value_uregen": 750000000, | ||
| "payer": "regen1issuer002" | ||
| }, | ||
| { | ||
| "tx_hash": "tx_retire_002", | ||
| "tx_type": "CreditRetirement", | ||
| "timestamp": "2026-02-18T11:30:00Z", | ||
| "value_uregen": 200000000, | ||
| "payer": "regen1retiree002" | ||
| }, | ||
| { | ||
| "tx_hash": "tx_market_002", | ||
| "tx_type": "MarketplaceTrade", | ||
| "timestamp": "2026-02-18T11:45:00Z", | ||
| "value_uregen": 50000000, | ||
| "payer": "regen1buyer002" | ||
| } | ||
| ] | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pseudo-code for fee distribution is ambiguous about how to handle rounding with integer-based amounts. This can lead to implementations that violate the Fee Conservation invariant (
fee_collected = sum(pool_distributions)), as flooring each share's calculation can result in lost "dust".The specification should be explicit about a deterministic rounding strategy to ensure no funds are lost. For example, you could specify that N-1 shares are calculated with flooring, and the remainder is assigned to the last (or largest) share to ensure the sum is always correct.
References
max()) and the state-based conditions (phase-gating) that govern the transition to prevent implementation ambiguity.