2月3日上午(+8时区),我们的系统报告了一笔针对 HypeBears NFT合约的攻击交易 0xfa97c3476aa8aeac662dae0cc3f0d3da48472ff4e7c55d0e305901ec37a2f704。经过调查,我们发现这是由ERC721的_safeMint函数引起的一次重入攻击。
根本原因
该项目对一个账户可以铸造的NFT数量有限制。基本上,它有一个addressMinted映射,用于记录一个账户是否已经铸造了NFT。
在铸造NFT时,代码使用了OZ参考实现的_safeMint函数。这个函数是“安全”的,因为它会检查接收方是否能够接收ERC721代币。这可以防止NFT被铸造到无法处理ERC721代币的合约中。根据文档:
如果to指向一个智能合约,它必须实现IERC721Receiver.onERC721Received,该函数在安全转账时会被调用。以下代码显示了OZ实现
_safeMint函数的代码。

然而,这个外部函数调用会产生一个安全漏洞。具体来说,攻击者可以在onERC721Received回调函数中执行重入调用。例如,在易受攻击的HypeBears合约中,攻击者可以在onERC721Received回调函数中再次调用mintNFT函数(因为addressMinted尚未更新)。

攻击
下图显示了攻击交易。

教训
安全研究人员已经讨论过SafeMint带来的风险链接1 链接2。然而,我们仍然可以看到易受攻击的代码和现实中的攻击。正如在QBridge安全事件中的safeTransfer所示,使用一个**安全的函数并不保证一个安全**的合约 😃。



