聚焦ERC404协议创新,Beosin为ERC404协议提供安全审计服务
2月2日,一个名为Pandora的NFT碎片化项目上线,其核心技术为ERC404协议,一种结合了ERC20和ERC721的代币标准,具有原生流动性和NFT碎片化等特点。作为新推出的协议,ERC404引发了广泛的社区讨论,其首个项目Pandora的日交易量也突破5000万美元,更多基于ERC404或类似协议的项目也陆续上线。
ERC404由于未经以太坊改进提案(EIP)和以太坊请求意见(ERC)的讨论和审查,直接向社区开源进行实验,其协议本身存在许多需要改进和修改的地方。Beosin安全团队今天将对ERC404的设计机制和合约代码进行详细分析,帮助用户了解ERC404协议。
ERC404协议是什么?
ERC404是“融合”了ERC20与ERC721两种代币标准的新型实验性协议。简单来讲,ERC404 可以让NFT像ERC20代币一样进行拆分交易,ERC404代币既是币,也是图,即1枚ERC404 代币可以看成是1枚ERC20代币,也可以看成是1个NFT。
当用户购买1个ERC404代币时,用户的钱包将自动获得一个Replicant NFT。而当用户卖出该代币时,对应的NFT将被自动销毁。
以ERC404协议的首个项目Pandora为例,该项目的ERC404代币是 PANDORA,它对应的 Replicant NFT 是 Pandora Replicants。PANDORA代币的总供应量为10000,所以其对应的 Pandora NFT总量也是10000。
当用户在Uniswap上购买PANDORA代币后,此时你持有1个 PANDORA 代币就相当于同时也持有了 1 个 Pandora NFT,后续可以选择卖出PANDORA代币或是去OpenSea等NFT交易市场卖出Pandora NFT。用户先购买Pandora NFT,再选择去DEX卖出 PANDORA 代币也是同样可以的。
由于ERC404涉及“图币”两种特性,以下是ERC404的设计特点,也是普通用户需要留意的地方:
1. ERC404如果以代币交易会涉及小数,ERC404规定代币数量向下取整为对应的NFT数量,比如用户持有2.9个 PANDORA 代币,那么从NFT视角看,用户只持有2个Pandora NFT。
2. ERC404 v1以代币交易,会销毁对应的NFT,生成新的NFT,即每次生成新的NFT都是在原来NFT的最高id号上增加,这样就会出现原来NFT销毁后再也无法铸造回来(ERC404 v2改变了这一点,会在后文解析)。由于Pandora NFT设置有稀有属性,这会出现用户通过交易Pandora代币刷Pandora NFT稀有度进行套利,刷出更稀有的Pandora NFT替换原先的NFT。
3. 在ERC404 v1的情况下,如果用户持有2.9个 PANDORA 代币,卖出1个 PANDORA 代币,代币无稀有度,但对应的NFT有不同稀有度,在卖出1个代币时用户收到的最后1个Pandora NFT会先被销毁,因此用户需留意代币对应的NFT的稀有度。建议1个钱包地址只存放1个 PANDORA 代币,对应1个Pandora NFT,或是直接进行NFT交易。
ERC404协议代码解析
ERC404 v1协议是由 Coinbase 前软件工程师Acme在Github上发布的,有许多需要改进的地方。借助社区的力量,ERC404团队目前在构建和完善ERC404协议,于2月15日推出了ERC404 v2,v2大大减少了ERC404的gas消耗和优化了买卖ERC404代币的机制。其最新的代码仓库为https://github.com/Pandora-Labs-Org/erc404。
本次我们将通过Beosin VaaS工具扫描ERC404 v2的合约,结合Beosin安全专家的分析,对v2的合约代码进行解读,为ERC404协议相关的项目方提供安全建议:
ERC404 v2的合约主要有ERC404.sol,ERC721Receiver.sol和DoubleEndedQueue.sol,其中DoubleEndedQueue(双端队列)是ERC404团队为改变交易代币燃烧NFT的逻辑而引入的新数据结构。
ERC404 v2 与 v1 类似,是 ERC721 和 ERC20 的混合实现,允许将 ERC721 代币表示为可分割的 ERC20 代币。其中,每个 ERC721 代币对应固定数量的 ERC20 代币(由“units”这个参数确定),在转移 ERC721 代币时,对应的ERC20代币以units的数量进行转移。
但相比v1,ERC404有以下改进:
1. EIP-2612 支持
ERC404 已支持 EIP-2612,允许通过签名消息(许可)进行无 Gas 交易。 “DOMAIN_SEPARATOR”是在构造函数中计算,如果链 ID 发生变化,则可以重新计算,这是提高了其合约的兼容性。
constructor(string memory name_, string memory symbol_, uint8 decimals_) {
name = name_;
symbol = symbol_;
if (decimals_ < 18) {
revert DecimalsTooLow();
}
decimals = decimals_;
units = 10 ** decimals;
// EIP-2612 initialization
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = _computeDomainSeparator();
}
2. 安全转账检查
其合约中的safeTransferFrom函数遵循了 ERC721 标准的 onERC721Received,会对接收者进行检查,以确保接收者可以处理 ERC721 代币(比如接收者是合约)。
function safeTransferFrom(
address from_,
address to_,
uint256 id_,
bytes memory data_
) public virtual {
if (id_ > _minted || id_ == 0) {
revert InvalidId();
}
transferFrom(from_, to_, id_);
if (
to_.code.length != 0 &&
ERC721Receiver(to_).onERC721Received(msg.sender, from_, id_, data_) !=
ERC721Receiver.onERC721Received.selector
) {
revert UnsafeRecipient();
}
}
3. 改良的铸造和销毁逻辑
和v1不同,在交易ERC404 v2代币时,其对应的NFT并不会被销毁,而是所有的NFT的id都存储在双端队列中重复使用,这样ERC404对应的NFT就与典型的ERC721代币一样。这种做法不仅减少了gas消耗,也简化了ERC404的转移逻辑。
ERC404 v2的改进让ERC404协议更加具有拓展性和可持续性,但其中仍有一些安全风险值得关注:
1. 白名单功能
ERC404允许某些白名单地址内部转账 ERC721 代币,这可用于优化特定合约或地址的gas使用。然而,这也可能会带来中心化问题或滥用的可能性。
abstract contract ERC404 is IERC404 {
.......
mapping(address => bool) public erc721TransferExempt;
......
// Handles ERC-721 exemptions.
function _transferERC20WithERC721(
//白名单可内部转账节省gas
}
}
2. 转账函数问题
transferFrom函数处理 ERC20 和 ERC721 转账,并根据valueOrId_参数区分两者的逻辑。开发者或用户在调用该函数时可能出错,因为该函数有一个前提假设,如果转移的值大于铸造计数的值,则该笔转账是 ERC20 代币的转账。
function transferFrom(
address from_,
address to_,
uint256 valueOrId_
) public virtual returns (bool) {
......
if (valueOrId_ <= _minted) {
// Intention is to transfer as ERC-721 token (id).
uint256 id = valueOrId_;
......
}
3. gas优化
虽然ERC404 v2相比v1已经大幅降低了用户交互时所需的gas费,但还有许多提升空间。如,ERC404 v2合约使用自定义错误revert NotFound(),而不是solidity支持的带有错误消息的require语句,这增加了一部分gas消耗。
4. 缺少紧急暂停功能
所有的智能合约都可能存在漏洞,ERC404作为新诞生的协议,合约漏洞问题不可忽视。因此,在团队开发合约时,应在合约中设置紧急暂停功能并制定风险应对方案,以便在风险出现时快速反应,修复漏洞。
此前,Beosin在完成对基于ERC404的创新资产协议Avatar ERC404的审计时也向项目团队提到了以上安全建议,帮助Avatar团队提高了智能合约的安全性,保障Avatar项目的安全运行。本次审计包含形式化验证和安全专家的人工审计,以确保代码没有逻辑漏洞,符合预期运行流程和结果:
audit report:
https://www.beosin.com/audits/Avatar_202402092300.pdf总结
ERC404从新的角度去尝试解决NFT不可分割、流动性不足的问题,相比原先的NFT碎片化项目,它从协议底层入手,实现起来更为更加简单有效,为交易NFT提供了新的途径。但ERC404在代币合约中属于复杂度较高的合约,项目团队在开发时需注意 ERC20 和 ERC721 的特点和添加新功能可能会引入的风险。安全团队在审计需仔细检查 ERC20 和 ERC721 功能之间的相互作用,以及合约中各种gas优化和中心化风险的影响。
Beosin作为一家全球领先的区块链安全公司,在全球10多个国家和地区设立了分部,业务涵盖项目上线前的智能合约安全审计、项目运行时的安全风险监控、预警与阻断、安全合规KYT/AML等“一站式”区块链安全产品+服务,目前已为全球3,000多个区块链企业提供安全技术服务,审计智能合约超过3,000份,欢迎ERC404项目团队前来咨询。