# ERC721R，RugPull的N种方式？

By [0xMask](https://paragraph.com/@codermy) · 2022-04-12

---

最近这几天[ERC721R](https://erc721r.org/)着实的刷了一波波屏。 不止一个群里友群沸腾起来了，以后可以顺利的冲土狗了，甚至想找第一个用721R合约的冲冲，其实事实证明的这样吗？

Web3的世界，代码就是法律，一切都得从代码出发。首先我们打开官网可以看到有这样的话。

![](https://storage.googleapis.com/papyrus_images/f60fd7428d836516e8b5b18c5733e693ec5cb1665bba214fcf7cebe0ce17d004.png)

就是漏洞的方法伏笔，在代码中也可以找到这个的

    function refund(uint256[] calldata tokenIds) external {
            require(refundGuaranteeActive(), "Refund expired");
    
            for (uint256 i = 0; i < tokenIds.length; i++) {
                uint256 tokenId = tokenIds[i];
                require(msg.sender == ownerOf(tokenId), "Not token owner");
                transferFrom(msg.sender, refundAddress, tokenId);
            }
    
            uint256 refundAmount = tokenIds.length * mintPrice;
            Address.sendValue(payable(msg.sender), refundAmount);
        }
    

我们可以看到退还的NFT是退往refundAddress地址的，而这是一个变量，合约持有人可以通过下面的方法来设置退还的地址。

    function setRefundAddress(address _refundAddress) external onlyOwner {
            refundAddress = _refundAddress;
        }
    

下面来实操一下，复制官方给样例（改一下价格），在网上测试部署一下

![](https://storage.googleapis.com/papyrus_images/11ddab54a580a4d0a77851fec3acb0f1028aa7640f6adbf608ef793a3bc786e7.png)

部署成功之后，打开公共铸币开关，铸造3个NFT

![](https://storage.googleapis.com/papyrus_images/1156fb349171f2ef1fa06638be51120ebff3059811118802ace2e2b72c281afa.png)

也能看到已经签约了，已经卖掉了三个nft的

![](https://storage.googleapis.com/papyrus_images/760b7a7fe8f0de490830e988142d2ec1429bc5936593ce4723c62a8bdba9063d.png)

我就是准备地毯拉的项目方交付，我准备把RefundAddress设置成自己的地址

![](https://storage.googleapis.com/papyrus_images/7535ae721bf7300e10dc1720d9d79e3450c46fb3b89204ae1ea9ec650c972066.png)

然后有普通玩家，觉得现在不行了，或者破发了，想要一个，调用rufud

![](https://storage.googleapis.com/papyrus_images/0bb84c3d3f2b8ad7aa4e93838b7099f659c5c9ce0e8aa78b5b401e2077e2b22f.png)

![退款后钱包余额，退款前忘记截图了，是1.26](https://storage.googleapis.com/papyrus_images/35400590828d5d89e8f1939e9d4973edd529c397a240aa2b037b421db87cd231.png)

退款后钱包余额，退款前忘记截图了，是1.26

看到这不是心想，这不是都成功设置了吗？

![](https://storage.googleapis.com/papyrus_images/9375b0d2702b98cbad9611ef52c315410aa688b46142bfbe3be516990a5e39db.png)

现在我只需要换这个钱包，一直退还这个钱包，契约里的钞票被我掏空

![](https://storage.googleapis.com/papyrus_images/aa79d57dd897c59be88f7ea1e2f22b8d9ce60a1416f1ff70f0a0c2ed158b92db.png)

在钱包里进行两次追踪之后，就可以看到合约了。合约里有一个业主薄荷的方法，项目方是免费的。只要项目方有一个令牌，就可以拉扯空合约的所有币种。

你急着以为结束了吗？

是要拉格拉的方子，这样操作，大花啊啊我加气，我不执行，于是我在约定中的一个方法，而且薄荷价格的做法我很用心

![](https://storage.googleapis.com/papyrus_images/bbf66afdcaac725e5c9de6ae30203476dc2268a7dbae318ae5218b644b52383c.png)

设置Mint价格看起来不是很合理，不仔细阅读代码不会注意这个方法。

我们照着上面的再模特，并且薄荷三个。

（（（）（（（））看就无效了，退还的eth为0，nft还会被转移。

![](https://storage.googleapis.com/papyrus_images/fe58fb24ce0ea9916343e5604f189565d404172caa7b43d4e1065b672832c70a.png)

可以看到nft是有转移，但并没有退还

![](https://storage.googleapis.com/papyrus_images/fb0fdf2004a570f1347181f32ccac3aadcd9695f292546190ae292a2531cb51d.png)

对比正常的方法

![](https://storage.googleapis.com/papyrus_images/1100cc881e3993e53865e8017a033efddfd6dbfa3142142ae4603c1ff5d8e263.png)

而我现在结束的时间只需要等待设置的滋味了。

**故：不要轻易使用 721R 契约修改的土狗，要冲的话需要检查是否薄荷的价格，并且是否可以转移的 nft 需要是黑洞**

---

*Originally published on [0xMask](https://paragraph.com/@codermy/erc721r-rugpull-n)*
