Skip to content

Commit

Permalink
Add mirror tests (Vectorized#7)
Browse files Browse the repository at this point in the history
* Save

* Add DN404 mirror tests

* Update snapshot

* Add tests for log transfer
  • Loading branch information
cygaar authored Feb 11, 2024
1 parent 9cc4bb5 commit ff8f960
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 27 deletions.
25 changes: 16 additions & 9 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
DN404Test:testBurnOnTransfer(uint32,address,address) (runs: 256, μ: 283824, ~: 285145)
DN404Test:testInitialize(uint32,address) (runs: 256, μ: 98991, ~: 112455)
DN404Test:testMintOnTransfer(uint32,address,address) (runs: 256, μ: 259217, ~: 260694)
DN404Test:testNameAndSymbol(string,string) (runs: 256, μ: 206555, ~: 206896)
DN404Test:testRegisterAndResolveAlias(address,address) (runs: 256, μ: 120364, ~: 120442)
DN404MirrorTest:testLinkMirrorContract() (gas: 46306)
DN404MirrorTest:testNameAndSymbol(string,string) (runs: 256, μ: 206555, ~: 206896)
DN404MirrorTest:testNotLinked() (gas: 12471)
DN404MirrorTest:testRootERC20() (gas: 114159)
DN404MirrorTest:testSafeTransferFrom(uint32) (runs: 256, μ: 463461, ~: 464742)
DN404MirrorTest:testSupportsInterface() (gas: 7768)
DN404MirrorTest:testTokenURI(string,uint256) (runs: 256, μ: 157342, ~: 135043)
DN404MirrorTest:testTransferFrom(uint32) (runs: 256, μ: 334768, ~: 336173)
DN404MirrorTest:test__codesize() (gas: 21824)
DN404Test:testBurnOnTransfer(uint32,address,address) (runs: 256, μ: 281799, ~: 283587)
DN404Test:testInitialize(uint32,address) (runs: 256, μ: 100575, ~: 112455)
DN404Test:testMintOnTransfer(uint32,address,address) (runs: 256, μ: 256890, ~: 258678)
DN404Test:testRegisterAndResolveAlias(address,address) (runs: 256, μ: 120186, ~: 120420)
DN404Test:testSetAndGetOperatorApprovals(address,address,bool) (runs: 256, μ: 129168, ~: 120233)
DN404Test:testTokenURI(string,uint256) (runs: 256, μ: 157342, ~: 135043)
DN404Test:testWrapAround(uint32,uint256) (runs: 256, μ: 405129, ~: 410915)
DN404Test:test__codesize() (gas: 23884)
DN404Test:test_batch_nft_log() (gas: 363131)
DN404Test:testWrapAround(uint32,uint256) (runs: 256, μ: 400750, ~: 405824)
DN404Test:test__codesize() (gas: 22196)
DN404Test:test_batch_nft_log() (gas: 328093)
SoladyTest:test__codesize() (gas: 1075)
TestPlus:test__codesize() (gas: 398)
4 changes: 2 additions & 2 deletions src/DN404.sol
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,8 @@ abstract contract DN404 {
return true;
}

function _logNftTransfer(address mirror, uint256[] memory p) private {
require(DN404Mirror(payable(mirror)).logTransfer(p));
function _logNftTransfer(address mirror, uint256[] memory packedLogs) private {
require(DN404Mirror(payable(mirror)).logTransfer(packedLogs));
}

function _ownerAt(uint256 id) internal view virtual returns (address result) {
Expand Down
6 changes: 3 additions & 3 deletions src/DN404Mirror.sol
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,12 @@ contract DN404Mirror {
_;
}

function logTransfer(uint256[] calldata p) external returns (bool) {
function logTransfer(uint256[] calldata packedLogs) external returns (bool) {
DN404NFTStorage storage $ = _getDN404NFTStorage();
if (msg.sender != $.rootERC20) revert Unauthorized();

for (uint256 i; i < p.length; ++i) {
uint256 data = p[i];
for (uint256 i; i < packedLogs.length; ++i) {
uint256 data = packedLogs[i];

address addr = address(uint160(data >> 96));
uint256 id = (data & type(uint96).max) >> 8;
Expand Down
13 changes: 0 additions & 13 deletions test/DN404.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,6 @@ contract DN404Test is SoladyTest {
mirror = new DN404Mirror();
}

function testNameAndSymbol(string memory name, string memory symbol) public {
dn.initializeDN404(1000, address(this), address(mirror));
dn.setNameAndSymbol(name, symbol);
assertEq(mirror.name(), name);
assertEq(mirror.symbol(), symbol);
}

function testTokenURI(string memory baseURI, uint256 id) public {
dn.initializeDN404(1000, address(this), address(mirror));
dn.setBaseURI(baseURI);
assertEq(mirror.tokenURI(id), string(abi.encodePacked(baseURI, id)));
}

function testRegisterAndResolveAlias(address a0, address a1) public {
assertEq(dn.registerAndResolveAlias(a0), 1);
if (a1 == a0) {
Expand Down
121 changes: 121 additions & 0 deletions test/DN404Mirror.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "./utils/SoladyTest.sol";
import {DN404, MockDN404} from "./utils/mocks/MockDN404.sol";
import {DN404Mirror} from "../src/DN404Mirror.sol";

contract Invalid721Receiver {}

contract DN404MirrorTest is SoladyTest {
uint256 private constant _WAD = 1000000000000000000;

MockDN404 dn;
DN404Mirror mirror;

function setUp() public {
dn = new MockDN404();
mirror = new DN404Mirror();
}

function testNotLinked() public {
vm.expectRevert(DN404Mirror.NotLinked.selector);
mirror.name();
}

function testNameAndSymbol(string memory name, string memory symbol) public {
dn.initializeDN404(1000, address(this), address(mirror));
dn.setNameAndSymbol(name, symbol);
assertEq(mirror.name(), name);
assertEq(mirror.symbol(), symbol);
}

function testTokenURI(string memory baseURI, uint256 id) public {
dn.initializeDN404(1000, address(this), address(mirror));
dn.setBaseURI(baseURI);
assertEq(mirror.tokenURI(id), string(abi.encodePacked(baseURI, id)));
}

function testSupportsInterface() public {
assertEq(mirror.supportsInterface(0x01ffc9a7), true);
assertEq(mirror.supportsInterface(0x80ac58cd), true);
assertEq(mirror.supportsInterface(0x5b5e139f), true);
}

function testRootERC20() public {
vm.expectRevert(DN404Mirror.NotLinked.selector);
mirror.rootERC20();

dn.initializeDN404(1000, address(this), address(mirror));
assertEq(mirror.rootERC20(), address(dn));
}

function testTransferFrom(uint32 totalNFTSupply) public {
totalNFTSupply = uint32(_bound(totalNFTSupply, 5, 1000000));
address alice = address(111);
address bob = address(222);

dn.initializeDN404(totalNFTSupply, address(this), address(mirror));
dn.transfer(alice, _WAD * uint256(5));
assertEq(mirror.balanceOf(alice), 5);
assertEq(mirror.balanceOf(bob), 0);

vm.prank(alice);
mirror.transferFrom(alice, bob, 1);
assertEq(mirror.balanceOf(alice), 4);
assertEq(mirror.balanceOf(bob), 1);
}

function testSafeTransferFrom(uint32 totalNFTSupply) public {
totalNFTSupply = uint32(_bound(totalNFTSupply, 5, 1000000));
address alice = address(111);
address bob = address(222);
address invalid = address(new Invalid721Receiver());

dn.initializeDN404(totalNFTSupply, address(this), address(mirror));
dn.transfer(alice, _WAD * uint256(5));
assertEq(mirror.balanceOf(alice), 5);
assertEq(mirror.balanceOf(bob), 0);

vm.prank(alice);
vm.expectRevert(DN404Mirror.TransferToNonERC721ReceiverImplementer.selector);
mirror.safeTransferFrom(alice, invalid, 1);

vm.prank(alice);
mirror.safeTransferFrom(alice, bob, 1);
assertEq(mirror.balanceOf(alice), 4);
assertEq(mirror.balanceOf(bob), 1);
}

function testLinkMirrorContract() public {
(bool success, bytes memory data) =
address(mirror).call(abi.encodeWithSignature("linkMirrorContract(address)", address(1)));
assertEq(data, abi.encodePacked(DN404Mirror.Unauthorized.selector));

vm.prank(address(dn));
(success, data) = address(mirror).call(
abi.encodeWithSignature("linkMirrorContract(address)", address(this))
);
assertEq(success, true);
assertEq(data, abi.encode(0x1));
}

function testLogTransfer() public {
dn.initializeDN404(1000, address(this), address(mirror));

uint256[] memory packedLogs = new uint256[](2);

address to = address(111);
address from = address(222);
uint32 id = 88;
packedLogs[0] = (uint256(uint160(to)) << 96) | (id << 8);
packedLogs[1] = (uint256(uint160(from)) << 96) | (id << 8) | 1;

vm.prank(address(dn));
vm.expectEmit(true, true, true, true);
emit DN404Mirror.Transfer(address(0), to, id);
vm.expectEmit(true, true, true, true);
emit DN404Mirror.Transfer(from, address(0), id);
mirror.logTransfer(packedLogs);
}
}

0 comments on commit ff8f960

Please sign in to comment.