xyyme.eth

Posted on Apr 11, 2022Read on Mirror.xyz

ERC721R ,一个可以退款的 ERC721 标准

今天在推特上看到好多人都在说一个新的标准叫 ERC721R,可以给用户退款,防止 rug。抽了点时间看了看,其实代码也很简单,简单写篇文章介绍一下(官网GitHub)。

概述

现在有好多项目方,发完图捞一笔之后就跑路了,而参与 mint 的用户都成了接盘侠。ERC721R 的目的就是让用户可以在 mint 之后的一段时间内,有后悔药吃,可以用 mint 到的 NFT 以原价换回自己的币。这对于用户来说是一个很好的规则。来看看官方文档对于自己的优点说明:

对于买家来说:

  • 购买风险低(最差的情况也可以换回自己的币)
  • 防止 rug pull
  • 强迫项目方能够好好做事

对于项目方来说:

  • 能够在消费者心中建立对自己的信心

对于两者都有的有点:

  • 当处于退款期间时,项目的地板价不会低于 mint 的价格(因为可以反向刚兑)
  • 短期炒作者会早早离开项目,便于项目长期发展

代码

数据结构:

// 退款时间区间
uint256 public constant refundPeriod;
// 退款结束时间
uint256 public refundEndTime;
// 退款接收地址
address public refundAddress;

合约函数:

当用户在退款期内想要退款时,可以调用 refund 函数,传入想要退款的 tokenId 列表,就可以将 NFT 换成币。

管理员在退款期内,不能转出币(以实现用户可以刚兑)。到期后可以转出。

总结

ERC721R 的代码还是很简单的,只是加了几个字段和对应的函数。虽然我个人觉得可能没啥用处,但是毕竟也是一个技术创新,值得支持。

bug

这个合约有一个 bug,就是 refundAddress 可以用一个 tokenId 无限次退款,把钱都给套出来。这个 bug 我开始写文章的时候没有注意,后面看到了崔棉大师的推特,发现确实是这样。

目前我想到的解决方法有两种:

  • 退款的时候直接将对应的 tokenId burn 掉
  • 建立一个 mapping(tokenId => 是否退款 bool),来限制一个 tokenId 只能退款一次

这两种方法的目的都是限制一个 tokenId 只能退款一次。

不过当你看到这篇文章的时候,可能 bug 已经被修复了~

参考

https://erc721r.org/

https://github.com/exo-digital-labs/ERC721R