Flap Vault 规范文档

基于 Flap 官方文档整理 · 当前规范 v2.2(可选 v2.3 扩展)

1. 概览

Flap 的 Vault 体系允许任何人构建智能合约来管理和分配 Tax Token 产生的 BNB 收入。 Vault 可根据不同场景自定义 —— 多方分账、社交证明路由、游戏国库、LP 分红 等等, 通过 VaultPortal 与代币生命周期挂钩。

Vault 创建是无许可的:任何工厂只要实现 VaultFactoryBaseV2,就能被 VaultPortal 用来发币,不需要注册。

    当前接口
    VaultBaseV2 + VaultFactoryBaseV2
    默认 Spec
    factorySpecVersion() = "v2.2"
    可选扩展
    v2.3 计算型 dividend token
    向后兼容
    VaultBase / v2.1 仍可用(Legacy)

2. VaultBase / VaultBaseV2

所有 Vault 必须继承 VaultBaseV2。它扩展了 VaultBase, 增加了链上 UI Schema 发现能力 vaultUISchema()

abstract contract VaultBase {
    error UnsupportedChain(uint256 chainId);

    function _getPortal()   internal view returns (address);
    function _getGuardian() internal view returns (address);

    /// 必须实现:返回反映当前状态的动态字符串
    function description() public view virtual returns (string memory);
}

abstract contract VaultBaseV2 is VaultBase {
    /// 必须实现:返回 UI 应该渲染的方法清单
    function vaultUISchema() public pure virtual
        returns (VaultUISchema memory);
}

3. 实现要求

  1. 实现 description() —— 返回一个反映 Vault 当前状态(余额、流式状态等)的动态字符串,UI 会周期性轮询显示。
  2. 实现 receive() —— 接收 Tax Token 转入的 BNB,并按 Vault 逻辑分配处理。
  3. 实现 vaultUISchema() —— 声明所有面向用户的方法,让 UI 无需定制页面即可自动渲染交互界面。
  4. Guardian 强制授权 —— 任何需要权限的函数(如可能被三明治攻击的 buyback),必须同时把 Guardian 地址加入允许调用者名单,且该权限不可被除 Guardian 自身以外的任何账户撤销。

4. Flap Guardian

Flap Guardian 是一个由 Flap 管理的可升级合约地址,在所有实现规范的 Vault 中拥有永久权限。 它平时不做任何事(仅返回 version),仅在需要保护用户资金的紧急场景下介入。

如果你用 OpenZeppelin 的 AccessControl,必须重写 revokeRole() 拒绝对 Guardian 撤权:

function revokeRole(bytes32 role, address account)
    public override onlyRole(getRoleAdmin(role))
{
    if (account == _getGuardian()) revert CannotRevokeGuardianRole();
    super.revokeRole(role, account);
}

5. Beacon Proxy 模式

对于会部署多个实例的 Vault Factory,官方推荐使用 UpgradeableBeacon + BeaconProxy ,升级权限交给 Flap Guardian。理由:

  • 先发币后审计:发现 bug 后可通过 beacon 升级实现,无需迁移已发行的代币。
  • 兜底运行时问题:静态审计无法覆盖所有边界场景(mempool 攻击、gas griefing 等),beacon 提供修复通道。

如果你的 Vault 是"一代币一实例、终身不可变"的设计,可以直接继承 VaultBaseV2 而不走 proxy。

6. VaultFactoryBaseV2

Vault Factory 负责在用户发币时通过 VaultPortal 调用 newVault() 为新代币创建 Vault 实例。

方法说明
newVault(taxToken, quoteToken, creator, vaultData)Portal 调用创建 Vault(taxToken 尚未部署,是预测地址)
isQuoteTokenSupported(quoteToken)声明本工厂支持的报价代币(address(0) = 原生 BNB)
vaultDataSchema()声明 vaultData 字节结构,让 UI 自动渲染表单
factorySpecVersion()返回 "v2.2"(默认)或 "v2.3";控制 Portal 校验路径
onBeforeLaunch(bytes)v2.2+ 通用发币前校验钩子(staticcall,只读)
tokenCreationPolicies()机器可读的 UI 提示,不做链上强制
resolveDividendToken(...)v2.3 可选:为未部署代币解析 LP / 子代币地址

校验逻辑应放在 _validateBeforeLaunch(LaunchValidationDataV1), 可访问 tokenVersion / quoteToken / buyTaxRate / sellTaxRate / vaultBps / deflationBps / dividendBps / lpBps / dividendToken / minimumShareBalance

7. VaultUISchema(IVaultSchemasV1)

前端根据 vaultUISchema() 声明动态渲染,不需要为每个 Vault 定制页面。核心结构:

struct FieldDescriptor {
    string  name;         // 字段名,如 "amount"
    string  fieldType;    // Solidity ABI 类型:"uint256" / "address" / "string" / "bool" / "bytes" / "time" / "msg.value"
    string  description;  // UI 提示
    uint8   decimals;     // 数值精度提示(输入 × 10^decimals;输出 ÷ 10^decimals)
}

struct VaultMethodSchema {
    string             name;           // Solidity 方法名
    string             description;
    FieldDescriptor[]  inputs;
    FieldDescriptor[]  outputs;
    ApproveAction[]    approvals;      // 写入前需先执行的 ERC20 approve
    bool               isInputArray;
    bool               isOutputArray;
    bool               isWriteMethod;  // true = 发交易;false = view 查询
}

struct VaultUISchema {
    string              vaultType;     // 例如 "FlapXVault"
    string              description;
    VaultMethodSchema[] methods;
}

特殊类型:"time"(uint256 秒级时间戳,UI 渲染日期选择器)、"msg.value"(原生 BNB 金额,不进 calldata,每方法至多一个)。

8. 推荐佣金结构

工厂可从 Tax 收入中收取佣金,必须在 description() 中明确披露。官方推荐:

  • taxRate ≤ 1%(≤ 100 bps),佣金 = msg.value × 6%
  • taxRate > 1%,佣金 = msg.value × 6 / taxRateBps

示例:2% → 3%,3% → 2%,10% → 0.6%。

9. 支持链与官方地址

Chain IDPortalGuardian
BNB Chain560xe2cE6ab8…5C9De00x9e270980…B8a4b
BNB Testnet970x5bEacaF7…6510e90x76Fa8C52…dbE46950

地址来自 Flap 官方 VaultBase.sol,STOCK AI 只支持 BNB Chain,合约生成时会自动嵌入 BNB 主网/测试网的 _getPortal() / _getGuardian() 分支。

10. 官方资源