Skip to content

Commit

Permalink
Try fix stack-too-deep
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized committed May 13, 2024
1 parent c78d1a3 commit 19d3ddd
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 49 deletions.
4 changes: 2 additions & 2 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ DN404MirrorTest:testSetAndGetApproved() (gas: 326724)
DN404MirrorTest:testSupportsInterface() (gas: 7544)
DN404MirrorTest:testTokenURI(string,uint256) (runs: 258, μ: 261388, ~: 270720)
DN404MirrorTest:testTransferFrom(uint32) (runs: 258, μ: 378530, ~: 378470)
DN404MirrorTest:testTransferFromMixed(uint256) (runs: 258, μ: 732929, ~: 688889)
DN404MirrorTest:testTransferFromMixed(uint256) (runs: 258, μ: 732415, ~: 688889)
DN404MirrorTest:test__codesize() (gas: 59865)
DN404OnlyERC20Test:testApprove() (gas: 35803)
DN404OnlyERC20Test:testApprove(address,uint256) (runs: 258, μ: 31276, ~: 31354)
Expand Down Expand Up @@ -125,7 +125,7 @@ DN404Test:testInitialize(uint32,address) (runs: 258, μ: 111548, ~: 113120)
DN404Test:testMintAndBurn() (gas: 346232)
DN404Test:testMintAndBurn2() (gas: 282747)
DN404Test:testMintNext() (gas: 704841)
DN404Test:testMintNextContiguous(uint256) (runs: 258, μ: 571319, ~: 503944)
DN404Test:testMintNextContiguous(uint256) (runs: 258, μ: 571188, ~: 503944)
DN404Test:testMintOnTransfer(uint32,address) (runs: 258, μ: 289489, ~: 289489)
DN404Test:testMixed(bytes32) (runs: 258, μ: 556282, ~: 506117)
DN404Test:testNameAndSymbol(string,string) (runs: 258, μ: 205704, ~: 206217)
Expand Down
105 changes: 58 additions & 47 deletions test/invariants/handlers/DN404Handler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ contract DN404Handler is SoladyTest {
uint256 n;
uint256[] burnedIds;
bool success;
uint256 id;
}

function transfer(uint256 fromIndexSeed, uint256 toIndexSeed, uint256 amount) public {
Expand Down Expand Up @@ -157,27 +158,26 @@ contract DN404Handler is SoladyTest {
// POST-CONDITIONS
if (t.success) {
Vm.Log[] memory logs = vm.getRecordedLogs();
uint256 id;
for (uint256 i = 0; i < logs.length; i++) {
if (
i < logs.length
&& logs[i].topics[0] == keccak256("Transfer(address,address,uint256)")
) {
// Grab minted ID from logs.
if (logs[i].topics.length > 3) id = uint256(logs[i].topics[3]);
if (logs[i].topics.length > 3) t.id = uint256(logs[i].topics[3]);
if (t.n > 0 && t.from != t.to) {
for (uint256 j = 0; j < t.burnedIds.length; j++) {
// Assert direct transfers do not overlap with burned pool.
if (dn404.useDirectTransfersIfPossible() && i < t.n) {
assertNotEq(
t.burnedIds[j], id, "transfer direct went over burned ids"
t.burnedIds[j], t.id, "transfer direct went over burned ids"
);
}
}
}
// Assert approval for id has been reset during transfer.
if (mirror.ownerAt(id) != address(0)) {
assertEq(mirror.getApproved(id), address(0));
if (mirror.ownerAt(t.id) != address(0)) {
assertEq(mirror.getApproved(t.id), address(0));
}
}
}
Expand Down Expand Up @@ -237,6 +237,7 @@ contract DN404Handler is SoladyTest {
uint256 n;
uint256[] burnedIds;
bool success;
uint256 id;
}

function transferFrom(
Expand Down Expand Up @@ -282,27 +283,26 @@ contract DN404Handler is SoladyTest {
// POST-CONDITIONS
if (t.success) {
Vm.Log[] memory logs = vm.getRecordedLogs();
uint256 id;
for (uint256 i = 0; i < logs.length; i++) {
if (
i < logs.length
&& logs[i].topics[0] == keccak256("Transfer(address,address,uint256)")
) {
// Grab minted ID from logs.
if (logs[i].topics.length > 3) id = uint256(logs[i].topics[3]);
if (logs[i].topics.length > 3) t.id = uint256(logs[i].topics[3]);
if (t.n > 0 && t.from != t.to) {
for (uint256 j = 0; j < t.burnedIds.length; j++) {
// Assert direct transfers not overlap with burned pool.
if (dn404.useDirectTransfersIfPossible() && i < t.n) {
assertNotEq(
t.burnedIds[j], id, "transfer direct went over burned ids"
t.burnedIds[j], t.id, "transfer direct went over burned ids"
);
}
}
}
// Assert approval for id has been reset during transfer.
if (mirror.ownerAt(id) != address(0)) {
assertEq(mirror.getApproved(id), address(0));
if (mirror.ownerAt(t.id) != address(0)) {
assertEq(mirror.getApproved(t.id), address(0));
}
}
}
Expand Down Expand Up @@ -353,66 +353,71 @@ contract DN404Handler is SoladyTest {
}
}

struct MintTemps {
address to;
bool success;
uint256 transferCounter;
}

function mint(uint256 toIndexSeed, uint256 amount) public {
MintTemps memory t;
// PRE-CONDITIONS
address to = randomAddress(toIndexSeed);
t.to = randomAddress(toIndexSeed);
amount = _bound(amount, 0, 100e18);

BeforeAfter memory beforeAfter;
beforeAfter.toBalanceBefore = dn404.balanceOf(to);
beforeAfter.toBalanceBefore = dn404.balanceOf(t.to);
beforeAfter.totalSupplyBefore = dn404.totalSupply();
beforeAfter.totalNFTSupplyBefore = mirror.totalSupply();
beforeAfter.toNFTBalanceBefore = dn404.balanceOfNFT(to);
beforeAfter.toAuxBefore = dn404.getAux(to);
beforeAfter.toNFTBalanceBefore = dn404.balanceOfNFT(t.to);
beforeAfter.toAuxBefore = dn404.getAux(t.to);

// ACTION
vm.recordLogs();
(bool success,) =
address(dn404).call(abi.encodeWithSelector(MockDN404.mint.selector, to, amount)); // mint(to, amount);
(t.success,) =
address(dn404).call(abi.encodeWithSelector(MockDN404.mint.selector, t.to, amount)); // mint(to, amount);

// POST-CONDITIONS
if (success) {
beforeAfter.toBalanceAfter = dn404.balanceOf(to);
if (t.success) {
beforeAfter.toBalanceAfter = dn404.balanceOf(t.to);
beforeAfter.totalSupplyAfter = dn404.totalSupply();
beforeAfter.totalNFTSupplyAfter = mirror.totalSupply();
beforeAfter.toAuxAfter = dn404.getAux(to);
beforeAfter.toAuxAfter = dn404.getAux(t.to);

Vm.Log[] memory logs = vm.getRecordedLogs();
uint256 transferCounter;
for (uint256 i = 0; i < logs.length; i++) {
if (
i < logs.length
&& logs[i].topics[0] == keccak256("Transfer(address,address,uint256)")
) {
transferCounter += 1;
t.transferCounter += 1;
assertEq(
address(uint160(uint256(logs[i].topics[1]))),
address(0),
"from address does not match event"
);
assertEq(
address(uint160(uint256(logs[i].topics[2]))),
to,
t.to,
"to address does not match event"
);
if (logs[i].topics.length > 3) {
assertEq(
mirror.ownerAt(uint256(logs[i].topics[3])),
to,
t.to,
"to address does not own minted id"
);
}
}
}

if (!dn404.getSkipNFT(to)) {
nftsOwned[to] = (beforeAfter.toBalanceBefore + amount) / dn404.unit();
uint256[] memory tokensAfter = dn404.tokensOf(to);
assertEq(tokensAfter.length, nftsOwned[to], "owned != len(tokensOf)");
if (!dn404.getSkipNFT(t.to)) {
nftsOwned[t.to] = (beforeAfter.toBalanceBefore + amount) / dn404.unit();
assertEq(dn404.tokensOf(t.to).length, nftsOwned[t.to], "owned != len(tokensOf)");
// Assert that number of (Transfer events - 1) should match the loop iterations to mint an NFT in `mint`.
// Subtract by 1 because one of the Transfer events is for the ERC20 transfer.
assertEq(
transferCounter - 1,
t.transferCounter - 1,
_zeroFloorSub(
(beforeAfter.toBalanceAfter / dn404.unit()), beforeAfter.toNFTBalanceBefore
),
Expand Down Expand Up @@ -443,69 +448,75 @@ contract DN404Handler is SoladyTest {
}
}

struct MintNextTemps {
address to;
uint256 transferCounter;
uint256 head;
uint256 tail;
}

function mintNext(uint256 toIndexSeed, uint256 amount) public {
MintNextTemps memory t;
// PRE-CONDITIONS
address to = randomAddress(toIndexSeed);
t.to = randomAddress(toIndexSeed);
amount = _bound(amount, 0, 100e18);

BeforeAfter memory beforeAfter;
beforeAfter.toBalanceBefore = dn404.balanceOf(to);
beforeAfter.toBalanceBefore = dn404.balanceOf(t.to);
beforeAfter.totalSupplyBefore = dn404.totalSupply();
beforeAfter.totalNFTSupplyBefore = mirror.totalSupply();
beforeAfter.toNFTBalanceBefore = dn404.balanceOfNFT(to);
beforeAfter.toAuxBefore = dn404.getAux(to);
beforeAfter.toNFTBalanceBefore = dn404.balanceOfNFT(t.to);
beforeAfter.toAuxBefore = dn404.getAux(t.to);

// ACTION
vm.recordLogs();
dn404.mintNext(to, amount);
dn404.mintNext(t.to, amount);

// POST-CONDITIONS
Vm.Log[] memory logs = vm.getRecordedLogs();
uint256 transferCounter;
for (uint256 i = 0; i < logs.length; i++) {
if (logs[i].topics[0] == keccak256("Transfer(address,address,uint256)")) {
transferCounter += 1;
t.transferCounter += 1;
assertEq(
address(uint160(uint256(logs[i].topics[1]))),
address(0),
"from address does not match event"
);
assertEq(
address(uint160(uint256(logs[i].topics[2]))),
to,
t.to,
"to address does not match event"
);
if (logs[i].topics.length > 3) {
assertEq(
mirror.ownerAt(uint256(logs[i].topics[3])),
to,
t.to,
"to address does not own minted id"
);
}
}
}

beforeAfter.toBalanceAfter = dn404.balanceOf(to);
beforeAfter.toBalanceAfter = dn404.balanceOf(t.to);
beforeAfter.totalSupplyAfter = dn404.totalSupply();
beforeAfter.totalNFTSupplyAfter = mirror.totalSupply();
beforeAfter.toAuxAfter = dn404.getAux(to);
beforeAfter.toAuxAfter = dn404.getAux(t.to);

if (!dn404.getSkipNFT(to)) {
nftsOwned[to] = (beforeAfter.toBalanceBefore + amount) / dn404.unit();
uint256[] memory tokensAfter = dn404.tokensOf(to);
assertEq(tokensAfter.length, nftsOwned[to], "owned != len(tokensOf)");
if (!dn404.getSkipNFT(t.to)) {
nftsOwned[t.to] = (beforeAfter.toBalanceBefore + amount) / dn404.unit();
assertEq(dn404.tokensOf(t.to).length, nftsOwned[t.to], "owned != len(tokensOf)");
assertEq(
transferCounter - 1,
t.transferCounter - 1,
_zeroFloorSub(
(beforeAfter.toBalanceAfter / dn404.unit()), beforeAfter.toNFTBalanceBefore
),
"# of times transfer emitted != mint loop iterations"
);
}
// If NFT was minted, ensure burned pool head and tail are 0.
if (transferCounter > 1) {
(uint256 head, uint256 tail) = dn404.burnedPoolHeadTail();
assertTrue(head == 0 && tail == 0, "Head or Tail != 0");
if (t.transferCounter > 1) {
(t.head, t.tail) = dn404.burnedPoolHeadTail();
assertTrue(t.head == 0 && t.tail == 0, "Head or Tail != 0");
}

// Assert user balance increased by minted amount.
Expand Down

0 comments on commit 19d3ddd

Please sign in to comment.