摘要
Stable 是一个使用 USDT0 作为原生 Gas 代币的 EVM 兼容区块链。USDT0 同时作为 Gas 支付和价值转移的原生资产,以及支持approve、transfer、transferFrom 和 permit 的 ERC20 代币。
这种设计让交易成本可预测并以美元计价,简化了用户体验。然而,它引入了与以太坊不同的行为差异,影响余额语义、授权安全性和某些操作码假设。
本文档指定了 Stable 的 USDT0 Gas 机制,描述了由此产生的行为差异,并定义了在 Stable 上部署的智能合约所需和推荐的开发模式。
版本说明
随着 Stable v1.2.0,USDT0 成为 Stable 上的原生 Gas 代币,取代了 gUSDT。作为此过渡的一部分:- gUSDT 即将下线。
- 现有的 gUSDT 余额会自动转换为 USDT0。
- 用户和应用程序不再需要封包和解包代币来支付费用或转移价值。
- 网络费用资产(gas),以及
- 具有
approve、permit、transfer和transferFrom的标准 ERC20 代币。
网络地址
USDT0 代币合约地址:术语
- Stable:一个 EVM 兼容的区块链,其中 USDT0 是原生 Gas 代币。
- USDT0:USDT 的原生跨链版本,同时作为:
- 用于 Gas 和价值转移的原生资产,以及
- 具有授权和许可语义的 ERC20 代币。
- 原生余额:由
address(x).balance返回的余额,以 USDT0 计价。 - Gas 费:在 EIP-1559 式费用市场下计算的以 USDT0 支付的交易费用。
什么是 USDT0?
USDT0 是使用 LayerZero 的全链可替代代币 (OFT) 标准的 USDT 的原生跨链版本。USDT0 与 USDT 1:1 锚定,旨在跨多个区块链移动,而无需传统的桥接工作流程或封包表示。 在跨链转移 USDT0 时,代币在某些源链上被锁定(取决于链的原生 USDT 支持)或销毁,然后通过 LayerZero 的跨链消息在目标链上铸造。这保持了 1:1 锚定,同时将流动性整合到单个可互操作的资产中,而不是分散的链本地池。 对于用户,这可以实现更快的入门、降低的操作复杂性和改进的流动性流动性。USDT0 和 Stable
USDT0 是支撑 Stable 链上经济和日常使用的核心资产。由于同一资产用于支付费用和转移价值,Stable 减少了以下方面的摩擦:- 普通用户:更简单的入门和更少的代币概念
- 开发人员:更简单的费用和价值流
- 企业:简化的会计和财务运营
假设和先决条件
对于以下内容,读者应该理解:- Solidity 执行语义和原生价值转移
- ERC20 授权机制和许可流程
- 标准智能合约安全模式,包括 Checks-Effects-Interactions
1. Gas 和费用模型
1.1 概述
Stable 以 USDT0 计价所有交易费用。Gas 定价遵循 EIP-1559 式模型,具有动态调整的基础费用。 交易费用定义为:maxFeePerGas。
注意:Stable 不支持优先小费。不要设置 maxPriorityFeePerGas,否则小费金额将丢失。
1.2 交易提交
客户端应从最近的区块获取最新的基础费用,并在计算maxFeePerGas 时包含安全边际。
示例(说明性):
1.3 获取 USDT0
账户通过以下方式获取 USDT0:- 从其他支持的链桥接 USDT0
- 从 Stable 上的其他账户接收转账
2. Stable 如何启用 USDT0 作为 Gas 代币
Stable 使用预扣费和退款结算模型在 USDT0 中收取 Gas 费。示例交易
Alice 向 Bob 发送 100 USDT0。2.1 Ante-handler 阶段
在MonoEVMAnteHandler 中的交易验证期间:
- 读取 Alice 的 USDT0 余额。
- 协议验证 Alice 可以覆盖:
- 交易价值(100 USDT0),以及
- 最大可能的 Gas 费(
gasWanted × fee)。
- 预先转移最大 Gas 费:
alice → fee_collector以 USDT0。
2.2 执行阶段
在ApplyTransaction 期间:
- EVM 执行交易。
- 记录实际 Gas 消耗。
- 应用价值转移:
alice → bob转移 100 USDT0。
2.3 结算阶段
执行后:- 协议计算预扣费的未使用部分:
- 退还未使用的费用:
fee_collector → alice以 USDT0。
3. 余额语义和行为差异
3.1 原生余额可变性
在以太坊上,合约的原生余额通常仅因合约执行而改变。 在 Stable 上,合约的原生 USDT0 余额也可能由于基于 ERC20 授权的操作而改变,包括transferFrom 和 permit。这些操作可以在不调用任何合约代码的情况下减少合约的原生余额。
因此,以下假设在 Stable 上无效:
- 合约的原生余额只能在合约被调用时减少。
4. 合约设计要求
4.1 禁止模式:镜像余额会计
合约不得依赖内部变量来镜像原生余额。 不安全模式的示例:4.2 必需模式:实际余额偿付能力检查
所有原生价值转移必须在转移之前立即使用address(this).balance 验证偿付能力。
示例:
4.3 状态进展必须独立于余额
依赖进展、里程碑或完成条件的协议逻辑必须使用非余额状态变量(如计数器或纪元)显式跟踪这些内容。 原生余额只能在支付时用于偿付能力验证。4.4 授权暴露
托管用户资金的合约不应向外部地址授予 USDT0 授权。 如果无法避免授权,合约应:- 仅批准确切金额
- 使用后立即重置授权
- 将余额排空风险视为已知限制
5. 地址状态假设
5.1 EXTCODEHASH
合约不得依赖EXTCODEHASH(addr) == 0x0 来推断地址从未被使用过。
任何地址使用的概念都必须在合约状态中显式跟踪。
示例:
6. 零地址处理
在 Stable 上:- 向
address(0)的原生 USDT0 转移会回滚。 - 向
address(0)的 ERC20 USDT0 转移也会回滚。
- 明确拒绝
address(0)作为接收者 - 重新设计任何假设零地址销毁的逻辑
- 如果需要不可逆丢失语义,请使用显式接收合约
7. 测试要求
Stable 部署的测试套件应包括:- 基于授权的排空场景(
approve+transferFrom) - 使用实际原生余额的偿付能力执行
- 不依赖
EXTCODEHASH的地址使用逻辑 - 零地址转移的显式失败情况
8. 迁移检查清单
将合约从以太坊移植到 Stable 时:- 删除内部原生余额镜像
- 用
address(this).balance替换所有偿付能力检查 - 删除所有到
address(0)的原生或 ERC20 转移 - 审计所有 USDT0 批准
- 添加涵盖许可和基于授权流程的测试
9. 总结
Stable 使用 USDT0 作为 Gas 代币提供了可预测的费用和统一的价值会计,同时改变了关于原生余额行为的核心假设。 Stable 上的正确合约设计需要:- 将 USDT0 视为双重角色资产
- 针对实际余额执行偿付能力
- 避免基于授权的余额排空
- 消除对以太坊特有的余额及地址假设的依赖
常见问题
我们现在使用 USDT0 作为封包的原生代币。升级后,哪个代币应该被视为封包的原生代币? 升级后,USDT0 既是原生代币又是 ERC-20 代币。您应该直接使用 USDT0,不再需要封包或解包。 原始的 USDT0 合约地址(0x779Ded0c9e1022225f8E0630b35a9b54bE713736)会发生什么变化?
没有任何变化。相同的地址仍然有效并继续代表 USDT0。
升级后,原生代币地址是 0x779Ded0c9e1022225f8E0630b35a9b54bE713736(而不是 0x0000000000000000000000000000000000001000)吗?
是的。升级后,原生代币标识符/地址是 0x779Ded0c9e1022225f8E0630b35a9b54bE713736。
那么 0x0000000000000000000000000000000000001000 呢?它还会作为 gUSDT 的代币地址使用吗,我们应该保留它吗?
不会。您可以删除它。升级后将不再使用它。
对于 DEX calldata,协议是否会停止使用 0x0000000000000000000000000000000000001000 作为”原生代币”标识符,而改用 0x779Ded0c9e1022225f8E0630b35a9b54bE713736?
正确。升级后,DEX 应使用 0x779Ded0c9e1022225f8E0630b35a9b54bE713736 作为原生代币标识符。
