dexorder
This commit is contained in:
441
lib_forge_std/test/mocks/MockERC20.t.sol
Normal file
441
lib_forge_std/test/mocks/MockERC20.t.sol
Normal file
@@ -0,0 +1,441 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.7.0 <0.9.0;
|
||||
|
||||
import {MockERC20} from "../../src/mocks/MockERC20.sol";
|
||||
import {StdCheats} from "../../src/StdCheats.sol";
|
||||
import {Test} from "../../src/Test.sol";
|
||||
|
||||
contract Token_ERC20 is MockERC20 {
|
||||
constructor(string memory name, string memory symbol, uint8 decimals) {
|
||||
initialize(name, symbol, decimals);
|
||||
}
|
||||
|
||||
function mint(address to, uint256 value) public virtual {
|
||||
_mint(to, value);
|
||||
}
|
||||
|
||||
function burn(address from, uint256 value) public virtual {
|
||||
_burn(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
contract MockERC20Test is StdCheats, Test {
|
||||
Token_ERC20 token;
|
||||
|
||||
bytes32 constant PERMIT_TYPEHASH =
|
||||
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
|
||||
|
||||
function setUp() public {
|
||||
token = new Token_ERC20("Token", "TKN", 18);
|
||||
}
|
||||
|
||||
function invariantMetadata() public view {
|
||||
assertEq(token.name(), "Token");
|
||||
assertEq(token.symbol(), "TKN");
|
||||
assertEq(token.decimals(), 18);
|
||||
}
|
||||
|
||||
function testMint() public {
|
||||
token.mint(address(0xBEEF), 1e18);
|
||||
|
||||
assertEq(token.totalSupply(), 1e18);
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
|
||||
}
|
||||
|
||||
function testBurn() public {
|
||||
token.mint(address(0xBEEF), 1e18);
|
||||
token.burn(address(0xBEEF), 0.9e18);
|
||||
|
||||
assertEq(token.totalSupply(), 1e18 - 0.9e18);
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 0.1e18);
|
||||
}
|
||||
|
||||
function testApprove() public {
|
||||
assertTrue(token.approve(address(0xBEEF), 1e18));
|
||||
|
||||
assertEq(token.allowance(address(this), address(0xBEEF)), 1e18);
|
||||
}
|
||||
|
||||
function testTransfer() public {
|
||||
token.mint(address(this), 1e18);
|
||||
|
||||
assertTrue(token.transfer(address(0xBEEF), 1e18));
|
||||
assertEq(token.totalSupply(), 1e18);
|
||||
|
||||
assertEq(token.balanceOf(address(this)), 0);
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
|
||||
}
|
||||
|
||||
function testTransferFrom() public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, 1e18);
|
||||
|
||||
vm.prank(from);
|
||||
token.approve(address(this), 1e18);
|
||||
|
||||
assertTrue(token.transferFrom(from, address(0xBEEF), 1e18));
|
||||
assertEq(token.totalSupply(), 1e18);
|
||||
|
||||
assertEq(token.allowance(from, address(this)), 0);
|
||||
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
|
||||
}
|
||||
|
||||
function testInfiniteApproveTransferFrom() public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, 1e18);
|
||||
|
||||
vm.prank(from);
|
||||
token.approve(address(this), type(uint256).max);
|
||||
|
||||
assertTrue(token.transferFrom(from, address(0xBEEF), 1e18));
|
||||
assertEq(token.totalSupply(), 1e18);
|
||||
|
||||
assertEq(token.allowance(from, address(this)), type(uint256).max);
|
||||
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
|
||||
}
|
||||
|
||||
function testPermit() public {
|
||||
uint256 privateKey = 0xBEEF;
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
|
||||
|
||||
assertEq(token.allowance(owner, address(0xCAFE)), 1e18);
|
||||
assertEq(token.nonces(owner), 1);
|
||||
}
|
||||
|
||||
function testFailTransferInsufficientBalance() public {
|
||||
token.mint(address(this), 0.9e18);
|
||||
token.transfer(address(0xBEEF), 1e18);
|
||||
}
|
||||
|
||||
function testFailTransferFromInsufficientAllowance() public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, 1e18);
|
||||
|
||||
vm.prank(from);
|
||||
token.approve(address(this), 0.9e18);
|
||||
|
||||
token.transferFrom(from, address(0xBEEF), 1e18);
|
||||
}
|
||||
|
||||
function testFailTransferFromInsufficientBalance() public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, 0.9e18);
|
||||
|
||||
vm.prank(from);
|
||||
token.approve(address(this), 1e18);
|
||||
|
||||
token.transferFrom(from, address(0xBEEF), 1e18);
|
||||
}
|
||||
|
||||
function testFailPermitBadNonce() public {
|
||||
uint256 privateKey = 0xBEEF;
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 1, block.timestamp))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
|
||||
}
|
||||
|
||||
function testFailPermitBadDeadline() public {
|
||||
uint256 privateKey = 0xBEEF;
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
token.permit(owner, address(0xCAFE), 1e18, block.timestamp + 1, v, r, s);
|
||||
}
|
||||
|
||||
function testFailPermitPastDeadline() public {
|
||||
uint256 oldTimestamp = block.timestamp;
|
||||
uint256 privateKey = 0xBEEF;
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, oldTimestamp))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
vm.warp(block.timestamp + 1);
|
||||
token.permit(owner, address(0xCAFE), 1e18, oldTimestamp, v, r, s);
|
||||
}
|
||||
|
||||
function testFailPermitReplay() public {
|
||||
uint256 privateKey = 0xBEEF;
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
|
||||
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
|
||||
}
|
||||
|
||||
function testMetadata(string calldata name, string calldata symbol, uint8 decimals) public {
|
||||
Token_ERC20 tkn = new Token_ERC20(name, symbol, decimals);
|
||||
assertEq(tkn.name(), name);
|
||||
assertEq(tkn.symbol(), symbol);
|
||||
assertEq(tkn.decimals(), decimals);
|
||||
}
|
||||
|
||||
function testMint(address from, uint256 amount) public {
|
||||
token.mint(from, amount);
|
||||
|
||||
assertEq(token.totalSupply(), amount);
|
||||
assertEq(token.balanceOf(from), amount);
|
||||
}
|
||||
|
||||
function testBurn(address from, uint256 mintAmount, uint256 burnAmount) public {
|
||||
burnAmount = bound(burnAmount, 0, mintAmount);
|
||||
|
||||
token.mint(from, mintAmount);
|
||||
token.burn(from, burnAmount);
|
||||
|
||||
assertEq(token.totalSupply(), mintAmount - burnAmount);
|
||||
assertEq(token.balanceOf(from), mintAmount - burnAmount);
|
||||
}
|
||||
|
||||
function testApprove(address to, uint256 amount) public {
|
||||
assertTrue(token.approve(to, amount));
|
||||
|
||||
assertEq(token.allowance(address(this), to), amount);
|
||||
}
|
||||
|
||||
function testTransfer(address from, uint256 amount) public {
|
||||
token.mint(address(this), amount);
|
||||
|
||||
assertTrue(token.transfer(from, amount));
|
||||
assertEq(token.totalSupply(), amount);
|
||||
|
||||
if (address(this) == from) {
|
||||
assertEq(token.balanceOf(address(this)), amount);
|
||||
} else {
|
||||
assertEq(token.balanceOf(address(this)), 0);
|
||||
assertEq(token.balanceOf(from), amount);
|
||||
}
|
||||
}
|
||||
|
||||
function testTransferFrom(address to, uint256 approval, uint256 amount) public {
|
||||
amount = bound(amount, 0, approval);
|
||||
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, amount);
|
||||
|
||||
vm.prank(from);
|
||||
token.approve(address(this), approval);
|
||||
|
||||
assertTrue(token.transferFrom(from, to, amount));
|
||||
assertEq(token.totalSupply(), amount);
|
||||
|
||||
uint256 app = from == address(this) || approval == type(uint256).max ? approval : approval - amount;
|
||||
assertEq(token.allowance(from, address(this)), app);
|
||||
|
||||
if (from == to) {
|
||||
assertEq(token.balanceOf(from), amount);
|
||||
} else {
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
assertEq(token.balanceOf(to), amount);
|
||||
}
|
||||
}
|
||||
|
||||
function testPermit(uint248 privKey, address to, uint256 amount, uint256 deadline) public {
|
||||
uint256 privateKey = privKey;
|
||||
if (deadline < block.timestamp) deadline = block.timestamp;
|
||||
if (privateKey == 0) privateKey = 1;
|
||||
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
token.permit(owner, to, amount, deadline, v, r, s);
|
||||
|
||||
assertEq(token.allowance(owner, to), amount);
|
||||
assertEq(token.nonces(owner), 1);
|
||||
}
|
||||
|
||||
function testFailBurnInsufficientBalance(address to, uint256 mintAmount, uint256 burnAmount) public {
|
||||
burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max);
|
||||
|
||||
token.mint(to, mintAmount);
|
||||
token.burn(to, burnAmount);
|
||||
}
|
||||
|
||||
function testFailTransferInsufficientBalance(address to, uint256 mintAmount, uint256 sendAmount) public {
|
||||
sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max);
|
||||
|
||||
token.mint(address(this), mintAmount);
|
||||
token.transfer(to, sendAmount);
|
||||
}
|
||||
|
||||
function testFailTransferFromInsufficientAllowance(address to, uint256 approval, uint256 amount) public {
|
||||
amount = bound(amount, approval + 1, type(uint256).max);
|
||||
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, amount);
|
||||
|
||||
vm.prank(from);
|
||||
token.approve(address(this), approval);
|
||||
|
||||
token.transferFrom(from, to, amount);
|
||||
}
|
||||
|
||||
function testFailTransferFromInsufficientBalance(address to, uint256 mintAmount, uint256 sendAmount) public {
|
||||
sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max);
|
||||
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, mintAmount);
|
||||
|
||||
vm.prank(from);
|
||||
token.approve(address(this), sendAmount);
|
||||
|
||||
token.transferFrom(from, to, sendAmount);
|
||||
}
|
||||
|
||||
function testFailPermitBadNonce(uint256 privateKey, address to, uint256 amount, uint256 deadline, uint256 nonce)
|
||||
public
|
||||
{
|
||||
if (deadline < block.timestamp) deadline = block.timestamp;
|
||||
if (privateKey == 0) privateKey = 1;
|
||||
if (nonce == 0) nonce = 1;
|
||||
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, nonce, deadline))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
token.permit(owner, to, amount, deadline, v, r, s);
|
||||
}
|
||||
|
||||
function testFailPermitBadDeadline(uint256 privateKey, address to, uint256 amount, uint256 deadline) public {
|
||||
if (deadline < block.timestamp) deadline = block.timestamp;
|
||||
if (privateKey == 0) privateKey = 1;
|
||||
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
token.permit(owner, to, amount, deadline + 1, v, r, s);
|
||||
}
|
||||
|
||||
function testFailPermitPastDeadline(uint256 privateKey, address to, uint256 amount, uint256 deadline) public {
|
||||
deadline = bound(deadline, 0, block.timestamp - 1);
|
||||
if (privateKey == 0) privateKey = 1;
|
||||
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
token.permit(owner, to, amount, deadline, v, r, s);
|
||||
}
|
||||
|
||||
function testFailPermitReplay(uint256 privateKey, address to, uint256 amount, uint256 deadline) public {
|
||||
if (deadline < block.timestamp) deadline = block.timestamp;
|
||||
if (privateKey == 0) privateKey = 1;
|
||||
|
||||
address owner = vm.addr(privateKey);
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
|
||||
privateKey,
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
token.DOMAIN_SEPARATOR(),
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
token.permit(owner, to, amount, deadline, v, r, s);
|
||||
token.permit(owner, to, amount, deadline, v, r, s);
|
||||
}
|
||||
}
|
||||
721
lib_forge_std/test/mocks/MockERC721.t.sol
Normal file
721
lib_forge_std/test/mocks/MockERC721.t.sol
Normal file
@@ -0,0 +1,721 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.7.0 <0.9.0;
|
||||
|
||||
import {MockERC721, IERC721TokenReceiver} from "../../src/mocks/MockERC721.sol";
|
||||
import {StdCheats} from "../../src/StdCheats.sol";
|
||||
import {Test} from "../../src/Test.sol";
|
||||
|
||||
contract ERC721Recipient is IERC721TokenReceiver {
|
||||
address public operator;
|
||||
address public from;
|
||||
uint256 public id;
|
||||
bytes public data;
|
||||
|
||||
function onERC721Received(address _operator, address _from, uint256 _id, bytes calldata _data)
|
||||
public
|
||||
virtual
|
||||
override
|
||||
returns (bytes4)
|
||||
{
|
||||
operator = _operator;
|
||||
from = _from;
|
||||
id = _id;
|
||||
data = _data;
|
||||
|
||||
return IERC721TokenReceiver.onERC721Received.selector;
|
||||
}
|
||||
}
|
||||
|
||||
contract RevertingERC721Recipient is IERC721TokenReceiver {
|
||||
function onERC721Received(address, address, uint256, bytes calldata) public virtual override returns (bytes4) {
|
||||
revert(string(abi.encodePacked(IERC721TokenReceiver.onERC721Received.selector)));
|
||||
}
|
||||
}
|
||||
|
||||
contract WrongReturnDataERC721Recipient is IERC721TokenReceiver {
|
||||
function onERC721Received(address, address, uint256, bytes calldata) public virtual override returns (bytes4) {
|
||||
return 0xCAFEBEEF;
|
||||
}
|
||||
}
|
||||
|
||||
contract NonERC721Recipient {}
|
||||
|
||||
contract Token_ERC721 is MockERC721 {
|
||||
constructor(string memory _name, string memory _symbol) {
|
||||
initialize(_name, _symbol);
|
||||
}
|
||||
|
||||
function tokenURI(uint256) public pure virtual override returns (string memory) {}
|
||||
|
||||
function mint(address to, uint256 tokenId) public virtual {
|
||||
_mint(to, tokenId);
|
||||
}
|
||||
|
||||
function burn(uint256 tokenId) public virtual {
|
||||
_burn(tokenId);
|
||||
}
|
||||
|
||||
function safeMint(address to, uint256 tokenId) public virtual {
|
||||
_safeMint(to, tokenId);
|
||||
}
|
||||
|
||||
function safeMint(address to, uint256 tokenId, bytes memory data) public virtual {
|
||||
_safeMint(to, tokenId, data);
|
||||
}
|
||||
}
|
||||
|
||||
contract MockERC721Test is StdCheats, Test {
|
||||
Token_ERC721 token;
|
||||
|
||||
function setUp() public {
|
||||
token = new Token_ERC721("Token", "TKN");
|
||||
}
|
||||
|
||||
function invariantMetadata() public view {
|
||||
assertEq(token.name(), "Token");
|
||||
assertEq(token.symbol(), "TKN");
|
||||
}
|
||||
|
||||
function testMint() public {
|
||||
token.mint(address(0xBEEF), 1337);
|
||||
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 1);
|
||||
assertEq(token.ownerOf(1337), address(0xBEEF));
|
||||
}
|
||||
|
||||
function testBurn() public {
|
||||
token.mint(address(0xBEEF), 1337);
|
||||
token.burn(1337);
|
||||
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 0);
|
||||
|
||||
vm.expectRevert("NOT_MINTED");
|
||||
token.ownerOf(1337);
|
||||
}
|
||||
|
||||
function testApprove() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.approve(address(0xBEEF), 1337);
|
||||
|
||||
assertEq(token.getApproved(1337), address(0xBEEF));
|
||||
}
|
||||
|
||||
function testApproveBurn() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.approve(address(0xBEEF), 1337);
|
||||
|
||||
token.burn(1337);
|
||||
|
||||
assertEq(token.balanceOf(address(this)), 0);
|
||||
assertEq(token.getApproved(1337), address(0));
|
||||
|
||||
vm.expectRevert("NOT_MINTED");
|
||||
token.ownerOf(1337);
|
||||
}
|
||||
|
||||
function testApproveAll() public {
|
||||
token.setApprovalForAll(address(0xBEEF), true);
|
||||
|
||||
assertTrue(token.isApprovedForAll(address(this), address(0xBEEF)));
|
||||
}
|
||||
|
||||
function testTransferFrom() public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, 1337);
|
||||
|
||||
vm.prank(from);
|
||||
token.approve(address(this), 1337);
|
||||
|
||||
token.transferFrom(from, address(0xBEEF), 1337);
|
||||
|
||||
assertEq(token.getApproved(1337), address(0));
|
||||
assertEq(token.ownerOf(1337), address(0xBEEF));
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
}
|
||||
|
||||
function testTransferFromSelf() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.transferFrom(address(this), address(0xBEEF), 1337);
|
||||
|
||||
assertEq(token.getApproved(1337), address(0));
|
||||
assertEq(token.ownerOf(1337), address(0xBEEF));
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 1);
|
||||
assertEq(token.balanceOf(address(this)), 0);
|
||||
}
|
||||
|
||||
function testTransferFromApproveAll() public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, 1337);
|
||||
|
||||
vm.prank(from);
|
||||
token.setApprovalForAll(address(this), true);
|
||||
|
||||
token.transferFrom(from, address(0xBEEF), 1337);
|
||||
|
||||
assertEq(token.getApproved(1337), address(0));
|
||||
assertEq(token.ownerOf(1337), address(0xBEEF));
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
}
|
||||
|
||||
function testSafeTransferFromToEOA() public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
token.mint(from, 1337);
|
||||
|
||||
vm.prank(from);
|
||||
token.setApprovalForAll(address(this), true);
|
||||
|
||||
token.safeTransferFrom(from, address(0xBEEF), 1337);
|
||||
|
||||
assertEq(token.getApproved(1337), address(0));
|
||||
assertEq(token.ownerOf(1337), address(0xBEEF));
|
||||
assertEq(token.balanceOf(address(0xBEEF)), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
}
|
||||
|
||||
function testSafeTransferFromToERC721Recipient() public {
|
||||
address from = address(0xABCD);
|
||||
ERC721Recipient recipient = new ERC721Recipient();
|
||||
|
||||
token.mint(from, 1337);
|
||||
|
||||
vm.prank(from);
|
||||
token.setApprovalForAll(address(this), true);
|
||||
|
||||
token.safeTransferFrom(from, address(recipient), 1337);
|
||||
|
||||
assertEq(token.getApproved(1337), address(0));
|
||||
assertEq(token.ownerOf(1337), address(recipient));
|
||||
assertEq(token.balanceOf(address(recipient)), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
|
||||
assertEq(recipient.operator(), address(this));
|
||||
assertEq(recipient.from(), from);
|
||||
assertEq(recipient.id(), 1337);
|
||||
assertEq(recipient.data(), "");
|
||||
}
|
||||
|
||||
function testSafeTransferFromToERC721RecipientWithData() public {
|
||||
address from = address(0xABCD);
|
||||
ERC721Recipient recipient = new ERC721Recipient();
|
||||
|
||||
token.mint(from, 1337);
|
||||
|
||||
vm.prank(from);
|
||||
token.setApprovalForAll(address(this), true);
|
||||
|
||||
token.safeTransferFrom(from, address(recipient), 1337, "testing 123");
|
||||
|
||||
assertEq(token.getApproved(1337), address(0));
|
||||
assertEq(token.ownerOf(1337), address(recipient));
|
||||
assertEq(token.balanceOf(address(recipient)), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
|
||||
assertEq(recipient.operator(), address(this));
|
||||
assertEq(recipient.from(), from);
|
||||
assertEq(recipient.id(), 1337);
|
||||
assertEq(recipient.data(), "testing 123");
|
||||
}
|
||||
|
||||
function testSafeMintToEOA() public {
|
||||
token.safeMint(address(0xBEEF), 1337);
|
||||
|
||||
assertEq(token.ownerOf(1337), address(address(0xBEEF)));
|
||||
assertEq(token.balanceOf(address(address(0xBEEF))), 1);
|
||||
}
|
||||
|
||||
function testSafeMintToERC721Recipient() public {
|
||||
ERC721Recipient to = new ERC721Recipient();
|
||||
|
||||
token.safeMint(address(to), 1337);
|
||||
|
||||
assertEq(token.ownerOf(1337), address(to));
|
||||
assertEq(token.balanceOf(address(to)), 1);
|
||||
|
||||
assertEq(to.operator(), address(this));
|
||||
assertEq(to.from(), address(0));
|
||||
assertEq(to.id(), 1337);
|
||||
assertEq(to.data(), "");
|
||||
}
|
||||
|
||||
function testSafeMintToERC721RecipientWithData() public {
|
||||
ERC721Recipient to = new ERC721Recipient();
|
||||
|
||||
token.safeMint(address(to), 1337, "testing 123");
|
||||
|
||||
assertEq(token.ownerOf(1337), address(to));
|
||||
assertEq(token.balanceOf(address(to)), 1);
|
||||
|
||||
assertEq(to.operator(), address(this));
|
||||
assertEq(to.from(), address(0));
|
||||
assertEq(to.id(), 1337);
|
||||
assertEq(to.data(), "testing 123");
|
||||
}
|
||||
|
||||
function testFailMintToZero() public {
|
||||
token.mint(address(0), 1337);
|
||||
}
|
||||
|
||||
function testFailDoubleMint() public {
|
||||
token.mint(address(0xBEEF), 1337);
|
||||
token.mint(address(0xBEEF), 1337);
|
||||
}
|
||||
|
||||
function testFailBurnUnMinted() public {
|
||||
token.burn(1337);
|
||||
}
|
||||
|
||||
function testFailDoubleBurn() public {
|
||||
token.mint(address(0xBEEF), 1337);
|
||||
|
||||
token.burn(1337);
|
||||
token.burn(1337);
|
||||
}
|
||||
|
||||
function testFailApproveUnMinted() public {
|
||||
token.approve(address(0xBEEF), 1337);
|
||||
}
|
||||
|
||||
function testFailApproveUnAuthorized() public {
|
||||
token.mint(address(0xCAFE), 1337);
|
||||
|
||||
token.approve(address(0xBEEF), 1337);
|
||||
}
|
||||
|
||||
function testFailTransferFromUnOwned() public {
|
||||
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
|
||||
}
|
||||
|
||||
function testFailTransferFromWrongFrom() public {
|
||||
token.mint(address(0xCAFE), 1337);
|
||||
|
||||
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
|
||||
}
|
||||
|
||||
function testFailTransferFromToZero() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.transferFrom(address(this), address(0), 1337);
|
||||
}
|
||||
|
||||
function testFailTransferFromNotOwner() public {
|
||||
token.mint(address(0xFEED), 1337);
|
||||
|
||||
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToNonERC721Recipient() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToNonERC721RecipientWithData() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337, "testing 123");
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToRevertingERC721Recipient() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToRevertingERC721RecipientWithData() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337, "testing 123");
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToERC721RecipientWithWrongReturnData() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() public {
|
||||
token.mint(address(this), 1337);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337, "testing 123");
|
||||
}
|
||||
|
||||
function testFailSafeMintToNonERC721Recipient() public {
|
||||
token.safeMint(address(new NonERC721Recipient()), 1337);
|
||||
}
|
||||
|
||||
function testFailSafeMintToNonERC721RecipientWithData() public {
|
||||
token.safeMint(address(new NonERC721Recipient()), 1337, "testing 123");
|
||||
}
|
||||
|
||||
function testFailSafeMintToRevertingERC721Recipient() public {
|
||||
token.safeMint(address(new RevertingERC721Recipient()), 1337);
|
||||
}
|
||||
|
||||
function testFailSafeMintToRevertingERC721RecipientWithData() public {
|
||||
token.safeMint(address(new RevertingERC721Recipient()), 1337, "testing 123");
|
||||
}
|
||||
|
||||
function testFailSafeMintToERC721RecipientWithWrongReturnData() public {
|
||||
token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337);
|
||||
}
|
||||
|
||||
function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() public {
|
||||
token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337, "testing 123");
|
||||
}
|
||||
|
||||
function testFailBalanceOfZeroAddress() public view {
|
||||
token.balanceOf(address(0));
|
||||
}
|
||||
|
||||
function testFailOwnerOfUnminted() public view {
|
||||
token.ownerOf(1337);
|
||||
}
|
||||
|
||||
function testMetadata(string memory name, string memory symbol) public {
|
||||
MockERC721 tkn = new Token_ERC721(name, symbol);
|
||||
|
||||
assertEq(tkn.name(), name);
|
||||
assertEq(tkn.symbol(), symbol);
|
||||
}
|
||||
|
||||
function testMint(address to, uint256 id) public {
|
||||
if (to == address(0)) to = address(0xBEEF);
|
||||
|
||||
token.mint(to, id);
|
||||
|
||||
assertEq(token.balanceOf(to), 1);
|
||||
assertEq(token.ownerOf(id), to);
|
||||
}
|
||||
|
||||
function testBurn(address to, uint256 id) public {
|
||||
if (to == address(0)) to = address(0xBEEF);
|
||||
|
||||
token.mint(to, id);
|
||||
token.burn(id);
|
||||
|
||||
assertEq(token.balanceOf(to), 0);
|
||||
|
||||
vm.expectRevert("NOT_MINTED");
|
||||
token.ownerOf(id);
|
||||
}
|
||||
|
||||
function testApprove(address to, uint256 id) public {
|
||||
if (to == address(0)) to = address(0xBEEF);
|
||||
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.approve(to, id);
|
||||
|
||||
assertEq(token.getApproved(id), to);
|
||||
}
|
||||
|
||||
function testApproveBurn(address to, uint256 id) public {
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.approve(address(to), id);
|
||||
|
||||
token.burn(id);
|
||||
|
||||
assertEq(token.balanceOf(address(this)), 0);
|
||||
assertEq(token.getApproved(id), address(0));
|
||||
|
||||
vm.expectRevert("NOT_MINTED");
|
||||
token.ownerOf(id);
|
||||
}
|
||||
|
||||
function testApproveAll(address to, bool approved) public {
|
||||
token.setApprovalForAll(to, approved);
|
||||
|
||||
assertEq(token.isApprovedForAll(address(this), to), approved);
|
||||
}
|
||||
|
||||
function testTransferFrom(uint256 id, address to) public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
if (to == address(0) || to == from) to = address(0xBEEF);
|
||||
|
||||
token.mint(from, id);
|
||||
|
||||
vm.prank(from);
|
||||
token.approve(address(this), id);
|
||||
|
||||
token.transferFrom(from, to, id);
|
||||
|
||||
assertEq(token.getApproved(id), address(0));
|
||||
assertEq(token.ownerOf(id), to);
|
||||
assertEq(token.balanceOf(to), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
}
|
||||
|
||||
function testTransferFromSelf(uint256 id, address to) public {
|
||||
if (to == address(0) || to == address(this)) to = address(0xBEEF);
|
||||
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.transferFrom(address(this), to, id);
|
||||
|
||||
assertEq(token.getApproved(id), address(0));
|
||||
assertEq(token.ownerOf(id), to);
|
||||
assertEq(token.balanceOf(to), 1);
|
||||
assertEq(token.balanceOf(address(this)), 0);
|
||||
}
|
||||
|
||||
function testTransferFromApproveAll(uint256 id, address to) public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
if (to == address(0) || to == from) to = address(0xBEEF);
|
||||
|
||||
token.mint(from, id);
|
||||
|
||||
vm.prank(from);
|
||||
token.setApprovalForAll(address(this), true);
|
||||
|
||||
token.transferFrom(from, to, id);
|
||||
|
||||
assertEq(token.getApproved(id), address(0));
|
||||
assertEq(token.ownerOf(id), to);
|
||||
assertEq(token.balanceOf(to), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
}
|
||||
|
||||
function testSafeTransferFromToEOA(uint256 id, address to) public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
if (to == address(0) || to == from) to = address(0xBEEF);
|
||||
|
||||
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
|
||||
|
||||
token.mint(from, id);
|
||||
|
||||
vm.prank(from);
|
||||
token.setApprovalForAll(address(this), true);
|
||||
|
||||
token.safeTransferFrom(from, to, id);
|
||||
|
||||
assertEq(token.getApproved(id), address(0));
|
||||
assertEq(token.ownerOf(id), to);
|
||||
assertEq(token.balanceOf(to), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
}
|
||||
|
||||
function testSafeTransferFromToERC721Recipient(uint256 id) public {
|
||||
address from = address(0xABCD);
|
||||
|
||||
ERC721Recipient recipient = new ERC721Recipient();
|
||||
|
||||
token.mint(from, id);
|
||||
|
||||
vm.prank(from);
|
||||
token.setApprovalForAll(address(this), true);
|
||||
|
||||
token.safeTransferFrom(from, address(recipient), id);
|
||||
|
||||
assertEq(token.getApproved(id), address(0));
|
||||
assertEq(token.ownerOf(id), address(recipient));
|
||||
assertEq(token.balanceOf(address(recipient)), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
|
||||
assertEq(recipient.operator(), address(this));
|
||||
assertEq(recipient.from(), from);
|
||||
assertEq(recipient.id(), id);
|
||||
assertEq(recipient.data(), "");
|
||||
}
|
||||
|
||||
function testSafeTransferFromToERC721RecipientWithData(uint256 id, bytes calldata data) public {
|
||||
address from = address(0xABCD);
|
||||
ERC721Recipient recipient = new ERC721Recipient();
|
||||
|
||||
token.mint(from, id);
|
||||
|
||||
vm.prank(from);
|
||||
token.setApprovalForAll(address(this), true);
|
||||
|
||||
token.safeTransferFrom(from, address(recipient), id, data);
|
||||
|
||||
assertEq(token.getApproved(id), address(0));
|
||||
assertEq(token.ownerOf(id), address(recipient));
|
||||
assertEq(token.balanceOf(address(recipient)), 1);
|
||||
assertEq(token.balanceOf(from), 0);
|
||||
|
||||
assertEq(recipient.operator(), address(this));
|
||||
assertEq(recipient.from(), from);
|
||||
assertEq(recipient.id(), id);
|
||||
assertEq(recipient.data(), data);
|
||||
}
|
||||
|
||||
function testSafeMintToEOA(uint256 id, address to) public {
|
||||
if (to == address(0)) to = address(0xBEEF);
|
||||
|
||||
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
|
||||
|
||||
token.safeMint(to, id);
|
||||
|
||||
assertEq(token.ownerOf(id), address(to));
|
||||
assertEq(token.balanceOf(address(to)), 1);
|
||||
}
|
||||
|
||||
function testSafeMintToERC721Recipient(uint256 id) public {
|
||||
ERC721Recipient to = new ERC721Recipient();
|
||||
|
||||
token.safeMint(address(to), id);
|
||||
|
||||
assertEq(token.ownerOf(id), address(to));
|
||||
assertEq(token.balanceOf(address(to)), 1);
|
||||
|
||||
assertEq(to.operator(), address(this));
|
||||
assertEq(to.from(), address(0));
|
||||
assertEq(to.id(), id);
|
||||
assertEq(to.data(), "");
|
||||
}
|
||||
|
||||
function testSafeMintToERC721RecipientWithData(uint256 id, bytes calldata data) public {
|
||||
ERC721Recipient to = new ERC721Recipient();
|
||||
|
||||
token.safeMint(address(to), id, data);
|
||||
|
||||
assertEq(token.ownerOf(id), address(to));
|
||||
assertEq(token.balanceOf(address(to)), 1);
|
||||
|
||||
assertEq(to.operator(), address(this));
|
||||
assertEq(to.from(), address(0));
|
||||
assertEq(to.id(), id);
|
||||
assertEq(to.data(), data);
|
||||
}
|
||||
|
||||
function testFailMintToZero(uint256 id) public {
|
||||
token.mint(address(0), id);
|
||||
}
|
||||
|
||||
function testFailDoubleMint(uint256 id, address to) public {
|
||||
if (to == address(0)) to = address(0xBEEF);
|
||||
|
||||
token.mint(to, id);
|
||||
token.mint(to, id);
|
||||
}
|
||||
|
||||
function testFailBurnUnMinted(uint256 id) public {
|
||||
token.burn(id);
|
||||
}
|
||||
|
||||
function testFailDoubleBurn(uint256 id, address to) public {
|
||||
if (to == address(0)) to = address(0xBEEF);
|
||||
|
||||
token.mint(to, id);
|
||||
|
||||
token.burn(id);
|
||||
token.burn(id);
|
||||
}
|
||||
|
||||
function testFailApproveUnMinted(uint256 id, address to) public {
|
||||
token.approve(to, id);
|
||||
}
|
||||
|
||||
function testFailApproveUnAuthorized(address owner, uint256 id, address to) public {
|
||||
if (owner == address(0) || owner == address(this)) owner = address(0xBEEF);
|
||||
|
||||
token.mint(owner, id);
|
||||
|
||||
token.approve(to, id);
|
||||
}
|
||||
|
||||
function testFailTransferFromUnOwned(address from, address to, uint256 id) public {
|
||||
token.transferFrom(from, to, id);
|
||||
}
|
||||
|
||||
function testFailTransferFromWrongFrom(address owner, address from, address to, uint256 id) public {
|
||||
if (owner == address(0)) to = address(0xBEEF);
|
||||
if (from == owner) revert();
|
||||
|
||||
token.mint(owner, id);
|
||||
|
||||
token.transferFrom(from, to, id);
|
||||
}
|
||||
|
||||
function testFailTransferFromToZero(uint256 id) public {
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.transferFrom(address(this), address(0), id);
|
||||
}
|
||||
|
||||
function testFailTransferFromNotOwner(address from, address to, uint256 id) public {
|
||||
if (from == address(this)) from = address(0xBEEF);
|
||||
|
||||
token.mint(from, id);
|
||||
|
||||
token.transferFrom(from, to, id);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToNonERC721Recipient(uint256 id) public {
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToNonERC721RecipientWithData(uint256 id, bytes calldata data) public {
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id, data);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToRevertingERC721Recipient(uint256 id) public {
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public {
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id, data);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToERC721RecipientWithWrongReturnData(uint256 id) public {
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id);
|
||||
}
|
||||
|
||||
function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data)
|
||||
public
|
||||
{
|
||||
token.mint(address(this), id);
|
||||
|
||||
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id, data);
|
||||
}
|
||||
|
||||
function testFailSafeMintToNonERC721Recipient(uint256 id) public {
|
||||
token.safeMint(address(new NonERC721Recipient()), id);
|
||||
}
|
||||
|
||||
function testFailSafeMintToNonERC721RecipientWithData(uint256 id, bytes calldata data) public {
|
||||
token.safeMint(address(new NonERC721Recipient()), id, data);
|
||||
}
|
||||
|
||||
function testFailSafeMintToRevertingERC721Recipient(uint256 id) public {
|
||||
token.safeMint(address(new RevertingERC721Recipient()), id);
|
||||
}
|
||||
|
||||
function testFailSafeMintToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public {
|
||||
token.safeMint(address(new RevertingERC721Recipient()), id, data);
|
||||
}
|
||||
|
||||
function testFailSafeMintToERC721RecipientWithWrongReturnData(uint256 id) public {
|
||||
token.safeMint(address(new WrongReturnDataERC721Recipient()), id);
|
||||
}
|
||||
|
||||
function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) public {
|
||||
token.safeMint(address(new WrongReturnDataERC721Recipient()), id, data);
|
||||
}
|
||||
|
||||
function testFailOwnerOfUnminted(uint256 id) public view {
|
||||
token.ownerOf(id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user