Fee Burn Module
The Fee Burn module implements a deflationary mechanism by permanently burning 50% of all transaction fees.
Overview
┌─────────────────────────────────────────────────────────────┐
│ Fee Distribution │
│ │
│ Transaction Fee: 1000 RP1 │
│ │ │
│ ├──────────────────────────────────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 50% Burned │ │ 50% Distributed│ │
│ │ 500 RP1 │ │ 500 RP1 │ │
│ │ (Permanent) │ │ │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ Supply Reduced Validators & Stakers │
│ Deflationary Block Rewards │
│ │
└─────────────────────────────────────────────────────────────┘
Burn Mechanics
Every transaction on RP1:
- User pays transaction fee
- Fee collected by network
- 50% permanently burned (sent to burn address)
- 50% distributed to validators/stakers
Burn Address
rp1000000000000000000000000000000000000burn
Tokens sent here are permanently removed from circulation.
Query Statistics
Total Burned
rp1d query feeburn total-burned
Output:
{
"total_burned": "1234567890000urp1",
"burn_rate": "0.50",
"last_block_burned": "500000urp1"
}
Burn History
rp1d query feeburn history --limit 100
Supply Statistics
rp1d query feeburn supply-stats
Output:
{
"initial_supply": "1000000000000000urp1",
"current_supply": "998765432100000urp1",
"total_burned": "1234567900000urp1",
"burn_percentage": "0.123%"
}
TypeScript SDK
import { FeeBurnModule } from '@rp1/sdk';
const feeburn = new FeeBurnModule(client);
// Get total burned
const stats = await feeburn.getTotalBurned();
console.log(`Total Burned: ${stats.totalBurned} RP1`);
// Get supply stats
const supply = await feeburn.getSupplyStats();
console.log(`Initial Supply: ${supply.initial}`);
console.log(`Current Supply: ${supply.current}`);
console.log(`Burn Rate: ${supply.burnPercentage}%`);
// Get burn history
const history = await feeburn.getBurnHistory({ limit: 10 });
history.forEach(h => {
console.log(`Block ${h.height}: ${h.burned} RP1 burned`);
});
Impact Calculator
Calculate the deflationary impact:
// Estimate yearly burn based on current volume
const dailyTxs = 1000000;
const avgFee = 1000; // urp1
const burnRate = 0.5;
const dailyBurn = dailyTxs * avgFee * burnRate;
const yearlyBurn = dailyBurn * 365;
const yearlyBurnPercent = yearlyBurn / totalSupply * 100;
console.log(`Estimated yearly burn: ${yearlyBurn} urp1 (${yearlyBurnPercent}%)`);
Governance
The burn percentage can be adjusted via governance:
# Submit proposal to change burn rate
rp1d tx gov submit-proposal param-change burn-proposal.json \
--from validator
Example burn-proposal.json:
{
"title": "Adjust Burn Rate",
"description": "Increase burn rate from 50% to 60%",
"changes": [
{
"subspace": "feeburn",
"key": "BurnPercentage",
"value": "0.60"
}
],
"deposit": "1000000urp1"
}
Parameters
| Parameter | Default | Description |
|---|---|---|
burn_percentage | 0.50 | Percentage of fees burned |
burn_enabled | true | Enable/disable burning |
min_burn_amount | 1 | Minimum amount to trigger burn |
Events
EventTypeBurn = "fee_burn"
AttributeKeyAmount = "amount"
AttributeKeyTotalBurned = "total_burned"
AttributeKeyBlockHeight = "height"
Economic Impact
Supply Reduction Over Time
| Year | Estimated Burn | Supply Reduction |
|---|---|---|
| 1 | 50M RP1 | 5% |
| 2 | 45M RP1 | 9.5% |
| 3 | 40M RP1 | 13.5% |
| 5 | 35M RP1 | 20% |
Estimates based on projected transaction volume
Comparison with Other Mechanisms
| Protocol | Mechanism | Rate |
|---|---|---|
| RP1 | Fee Burn | 50% of fees |
| Ethereum (EIP-1559) | Base Fee Burn | Variable |
| BNB | Quarterly Burn | Until 100M |
| LUNA (Classic) | Mint/Burn | Variable |
Implementation
// BeginBlocker burns accumulated fees
func (k Keeper) BeginBlocker(ctx sdk.Context) {
// Get accumulated fees
fees := k.bankKeeper.GetAllBalances(ctx, k.feeCollectorAddr)
// Calculate burn amount
burnAmount := fees.MulInt(k.GetBurnPercentage(ctx))
// Burn tokens
if err := k.bankKeeper.BurnCoins(ctx, types.ModuleName, burnAmount); err != nil {
k.Logger(ctx).Error("failed to burn fees", "error", err)
return
}
// Update statistics
k.AddToBurnTotal(ctx, burnAmount)
// Emit event
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeBurn,
sdk.NewAttribute(types.AttributeKeyAmount, burnAmount.String()),
),
)
}