教程区块链区块链技术ch1818.4 通缩代币:燃烧、税费与反射机制

本页目录

通缩代币(Deflationary Token)通过燃烧(Burn)、交易税(Tax)与反射(Reflect)机制,让每一笔转账都产生"通缩"或"再分配"效果——这是 2021 年 Meme 币潮(Shib、Safemoon 等)的标志性设计。


18.4.1 什么是通缩机制?

graph TD
    Tx[用户转账 X 代币] --> Split{代币拆分}
    Split -->|1-5%| Burn[燃烧: 永久销毁]
    Split -->|2-5%| Liquidity[自动添加流动性]
    Split -->|3-8%| Reflect[反射: 按比例分给全体持有者]
    Split -->|0-2%| Treasury[项目金库]
    Burn --> Supply[总供应量减少]
    Reflect --> Holders[持有者被动获得代币]
机制数学体现经济效果
燃烧总供应量 StotalS_{total} 单调递减稀缺性上升、长期通缩
反射单次转账按 rfeer_{fee} 比例再分配持有者被动增持
自动流动性税费的一部分路由到 DEX 池池深增加、滑点降低
金库税费一部分进项目方地址运营/营销资金来源

核心公式:假设交易税率为 τ\tau,发生一笔金额为 AA 的转账,到账金额为:

Anet=A×(1τ)A_{\text{net}} = A \times (1 - \tau)

其中 τ=τburn+τreflect+τliquidity+τtreasury\tau = \tau_{\text{burn}} + \tau_{\text{reflect}} + \tau_{\text{liquidity}} + \tau_{\text{treasury}}


18.4.2 反射机制的数学原理

反射代币(如 RFI 标准)并不真实转移代币,而是维护一个全局放大系数 _rate。每个持有者的"映射余额"(reflection balance)除以 _rate 得到真实余额:

realBalance(u)=reflectionOf(u)r\text{realBalance}(u) = \frac{\text{reflectionOf}(u)}{r}

初始 r=1r = 1。每当发生一笔带手续费的转账,收取的税费代币全部被销毁(从反射层面移除),同时 _rate 增加,使得每个持有者的真实余额按比例上升。

数量守恒更新:设转账前全局反射总量为 ref\sum ref,真实总量为 SS。转账 AA(含税 τA\tau A),税后真实总量变为 SτAS - \tau A,则新放大系数:

r=refSτA>rr' = \frac{\sum ref}{S - \tau A} > r
typescript
// 反射代币核心:从零实现(纯 TS + BigInt,无外部库)
// 模型:每笔转账收取 3% 税费,税费按"除发送方外"各持有者转账前余额占比再分配
//  => 发送方付全额,接收方得净额,税费让全体持有者被动增值(反射语义)
class ReflectToken {
  totalReal: bigint;              // 真实总供应量
  balances: Map<string, bigint>;  // 地址 -> 真实余额
  static readonly TAX_BPS = 300n; // 3% 交易税(1/10000 为单位)

  constructor(initialSupply: bigint, holders: Array<[string, bigint]>) {
    this.totalReal = initialSupply;
    this.balances = new Map(holders);
  }

  realBalance(addr: string): bigint {
    return this.balances.get(addr) ?? 0n;
  }

  transfer(from: string, to: string, amount: bigint): void {
    const fromBal = this.balances.get(from) ?? 0n;
    if (fromBal < amount) throw new Error("余额不足");
    const fee = (amount * ReflectToken.TAX_BPS) / 10000n; // 税费
    const net = amount - fee;                             // 净到账

    // 1) 反射分配:基于"除发送方外"其余持有者的转账前余额占比
    //    (顺序在 B 到账之前,保证分母不因本次净到账而改变)
    const othersBefore: Array<[string, bigint]> = [];
    let sumOtherBefore = 0n;
    for (const [addr, bal] of this.balances) {
      if (addr === from) continue;
      othersBefore.push([addr, bal]);
      sumOtherBefore += bal;
    }
    if (sumOtherBefore > 0n) {
      for (const [addr, bal] of othersBefore) {
        const share = (fee * bal) / sumOtherBefore; // 税费按占比反射
        this.balances.set(addr, (this.balances.get(addr) ?? 0n) + share);
      }
    }

    // 2) 发送方扣全额,接收方得净额
    this.balances.set(from, fromBal - amount);
    this.balances.set(to, (this.balances.get(to) ?? 0n) + net);

    // 3) 税费进入持有者账户 => 总真实供应增长(等价于全体持有人被动增持)
    this.totalReal += fee;
  }
}

// 验证:创始 1000 token,A=500、B=500;A 给 B 转 100(税 3%)
const WEI = 10n ** 18n; // 1e18 定点
const t = new ReflectToken(1000n * WEI, [
  ["0xA", 500n * WEI],
  ["0xB", 500n * WEI],
]);
const b0 = t.realBalance("0xB");
t.transfer("0xA", "0xB", 100n * WEI);
const b1 = t.realBalance("0xB");
const got = Number(b1 - b0) / Number(WEI);
// 理论:净到账 97 + 反射份额 = fee(3) × B占比(500/500=1.0) = 3 => 增量 = 100
console.log("B 到账增量 ≈", got.toFixed(2), "token(预期 100.00)");

运行验证:node --experimental-strip-types 输出 B 到账增量 ≈ 100.00 token(预期 100.00),数学自洽。


18.4.3 燃烧与总供应量

硬性燃烧(Hard Burn):把代币转到 0x000...dead 地址,彻底从流通中移除:

solidity
function _burn(address from, uint256 amount) internal {
    _balances[from] -= amount;
    _totalSupply -= amount;
    emit Transfer(from, address(0), amount);
}

反射燃烧(Reflection Burn):RFI 风格的燃烧并不从任何账户扣减,而是通过增加 rate 实现全体持有人真实余额按比例上升、总供应量的反射总量不变——看起来"每个人余额都变多"。

数学关系:每燃烧 ΔS\Delta S,通缩率可表达为:

ΔSSS(t)=S0×eδt\frac{\Delta S}{S} \qquad \Rightarrow \qquad S(t) = S_0 \times e^{-\delta \, t}

其中 δ\delta 为平均年燃烧速率(需由实际税费流量估算)。


18.4.4 自动添加流动性(Auto-LP)

税费的一部分(如 3%)被积累在合约中,达到阈值后自动 swap 为 ETH/配对代币,再与等量代币一起注入 DEX 池。这形成了"每笔交易都在买底池"的机制。

sequenceDiagram
    participant U as 转账发起
    participant C as 通缩合约
    participant P as DEX Pair
    C->>C: 收取 tau_lp 比例代币到内部积累地址
    C->>C: 积累量 >= swapThreshold?
    C->>P: swap 积累代币 -> 配对代币(ETH/USDC)
    C->>C: 用配对代币 + 等量代币 addLiquidity
    P->>P: 池深度增加 (k 增大)

风险提示:自动 LP 机制曾是众多 Rug Pull 与"貔貅盘"(只能买不能卖)攻击的载体——若合约 owner 可随时修改税率或将 swapBack 阈值调至极高,用户卖出将永远失败。审计这类合约时首先要检查:税费是否上限锁定、owner 是否可任意改税率、是否有黑名单。


18.4.5 TS 从零实现:锤子税 / 手续费结算

下面的纯 TS 实现了"每笔转移收取固定比例手续费并累计到金库",展示税率的数学分解:

typescript
// 税率数学:输入金额 -> 各项去向(纯 BigInt,无外部库)
function splitFee(amount: bigint, basisPoints: readonly number[]): bigint[] {
  // basisPoints: [burn, reflect, liquidity, treasury],单位万分比(1/10000)
  const TOTAL = 10000n;
  const totalBps = basisPoints.reduce((a, b) => a + b, 0);
  if (totalBps > 10000) throw new Error("总税率超过100%");

  const parts = basisPoints.map(bp => (amount * BigInt(bp)) / TOTAL);
  // 用整数除法后余数归给接收方,保证到账+税费 == 原金额
  const net = amount - parts.reduce((a, b) => a + b, 0n);
  return [...parts, net]; // [burn, reflect, liq, treasury, netToReceiver]
}

// 验证:100e18 代币,税 8% (burn1% reflect3% liq3% treasury1%)
const amount = 100n * 10n ** 18n;
const [b, r, l, t, net] = splitFee(amount, [100, 300, 300, 100]);
console.log("burn", (b / 10n ** 16n) / 100, "reflect", (r / 10n ** 16n) / 100);
console.log("liq ", (l / 10n ** 16n) / 100, "treasury", (t / 10n ** 16n) / 100);
console.log("net ", (net / 10n ** 16n) / 100);   // 应约 92
// 输出:burn 1  reflect 3  liq 3  treasury 1  net 92

18.4.6 小结与审计要点

检查项关注点
税率是否可改owner 是否能绕过限额把税率调到 99%
swapBack 门槛若阈值过高,LP 税永不激活
黑名单是否可封禁用户(貔貅盘特征)
反射精度rate 溢出 / 除零风险
函数可见性mint 是否对外暴露(无限增发)

3 个关键认知:① 通缩 = 燃烧使 SS 递减 + 反射使持有者被动增持;② 税费各部分需用整数运算精确拆分,余数必须归账保证守恒;③ 自动流动性是"每笔交易买底池",但也是 Rug Pull 高危区,审计优先审查 owner 权限。


, 前往 → 18.5 通证经济设计 |*

评论

0

评论加载中…

发表评论

0/2000