diff --git a/.gas-snapshot b/.gas-snapshot index 07cfb81..a97cb52 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -67,19 +67,19 @@ BenchTest:testMintPandora_13() (gas: 967982) BenchTest:testMintPandora_14() (gas: 1037484) BenchTest:testMintPandora_15() (gas: 1106989) BenchTest:testMintPandora_16() (gas: 1176450) -BenchTest:test__codesize() (gas: 26594) +BenchTest:test__codesize() (gas: 26608) DN404CustomUnitTest:testInitializeCorrectUnitSuccess() (gas: 129962) DN404CustomUnitTest:testInitializeWithUnitTooLargeReverts() (gas: 33824) DN404CustomUnitTest:testInitializeWithZeroUnitReverts() (gas: 13897) DN404CustomUnitTest:testMint() (gas: 162923) -DN404CustomUnitTest:testMintWithoutNFTs(uint256,uint256,uint256) (runs: 258, μ: 154791, ~: 163018) +DN404CustomUnitTest:testMintWithoutNFTs(uint256,uint256,uint256) (runs: 258, μ: 156444, ~: 163189) DN404CustomUnitTest:testNFTMint() (gas: 57526664) -DN404CustomUnitTest:testNFTMintAndBurn(uint256,uint256,uint256) (runs: 258, μ: 208113, ~: 161918) -DN404CustomUnitTest:testNFTMintViaTransfer(uint256,uint256,uint256) (runs: 258, μ: 215338, ~: 241451) -DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256) (runs: 258, μ: 613, ~: 669) -DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256,uint256) (runs: 258, μ: 781, ~: 746) +DN404CustomUnitTest:testNFTMintAndBurn(uint256,uint256,uint256) (runs: 258, μ: 210784, ~: 161918) +DN404CustomUnitTest:testNFTMintViaTransfer(uint256,uint256,uint256) (runs: 258, μ: 216136, ~: 239915) +DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256) (runs: 258, μ: 612, ~: 669) +DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256,uint256) (runs: 258, μ: 784, ~: 746) DN404CustomUnitTest:testUnitInvalidCheckTrick(uint256) (runs: 258, μ: 525, ~: 527) -DN404CustomUnitTest:test__codesize() (gas: 27194) +DN404CustomUnitTest:test__codesize() (gas: 27208) DN404MirrorTest:testBaseERC20() (gas: 114633) DN404MirrorTest:testFnSelectorNotRecognized() (gas: 6236) DN404MirrorTest:testLinkMirrorContract() (gas: 39444) @@ -88,88 +88,88 @@ DN404MirrorTest:testLogTransfer() (gas: 120710) DN404MirrorTest:testNameAndSymbol(string,string) (runs: 258, μ: 206468, ~: 206981) DN404MirrorTest:testNotLinked() (gas: 12777) DN404MirrorTest:testPullOwner() (gas: 112613) -DN404MirrorTest:testPullOwnerWithOwnable() (gas: 3289101) -DN404MirrorTest:testSafeTransferFrom(uint32) (runs: 258, μ: 465944, ~: 465938) +DN404MirrorTest:testPullOwnerWithOwnable() (gas: 3291917) +DN404MirrorTest:testSafeTransferFrom(uint32) (runs: 258, μ: 465943, ~: 465938) DN404MirrorTest:testSetAndGetApprovalForAll() (gas: 325486) DN404MirrorTest:testSetAndGetApproved() (gas: 322728) DN404MirrorTest:testSupportsInterface() (gas: 7544) -DN404MirrorTest:testTokenURI(string,uint256) (runs: 258, μ: 157416, ~: 135217) -DN404MirrorTest:testTransferFrom(uint32) (runs: 258, μ: 366988, ~: 366980) -DN404MirrorTest:testTransferFromMixed(uint256) (runs: 258, μ: 684731, ~: 643712) -DN404MirrorTest:test__codesize() (gas: 55040) +DN404MirrorTest:testTokenURI(string,uint256) (runs: 258, μ: 157449, ~: 135250) +DN404MirrorTest:testTransferFrom(uint32) (runs: 258, μ: 366985, ~: 366980) +DN404MirrorTest:testTransferFromMixed(uint256) (runs: 258, μ: 675722, ~: 624768) +DN404MirrorTest:test__codesize() (gas: 55068) DN404OnlyERC20Test:testApprove() (gas: 35803) DN404OnlyERC20Test:testApprove(address,uint256) (runs: 258, μ: 30505, ~: 31354) DN404OnlyERC20Test:testBurn() (gas: 51508) -DN404OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 258, μ: 52572, ~: 52687) -DN404OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 45640, ~: 45780) +DN404OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 258, μ: 52458, ~: 52687) +DN404OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 45700, ~: 45763) DN404OnlyERC20Test:testInfiniteApproveTransferFrom() (gas: 104368) DN404OnlyERC20Test:testMaxSupplyTrick(uint256) (runs: 258, μ: 541, ~: 541) DN404OnlyERC20Test:testMetadata() (gas: 9014) DN404OnlyERC20Test:testMint() (gas: 47556) DN404OnlyERC20Test:testMintOverMaxLimitReverts() (gas: 43535) -DN404OnlyERC20Test:testMintz(address,uint256) (runs: 258, μ: 48009, ~: 47978) +DN404OnlyERC20Test:testMintz(address,uint256) (runs: 258, μ: 47918, ~: 47978) DN404OnlyERC20Test:testTransfer() (gas: 77020) -DN404OnlyERC20Test:testTransfer(address,uint256) (runs: 258, μ: 77762, ~: 77543) +DN404OnlyERC20Test:testTransfer(address,uint256) (runs: 258, μ: 77483, ~: 77543) DN404OnlyERC20Test:testTransferFrom() (gas: 86826) -DN404OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 258, μ: 107794, ~: 109795) +DN404OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 258, μ: 108008, ~: 109795) DN404OnlyERC20Test:testTransferFromInsufficientAllowanceReverts() (gas: 70283) -DN404OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 258, μ: 70546, ~: 71362) +DN404OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 258, μ: 70443, ~: 71345) DN404OnlyERC20Test:testTransferFromInsufficientBalanceReverts() (gas: 76697) -DN404OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 77600, ~: 77818) +DN404OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 77751, ~: 77801) DN404OnlyERC20Test:testTransferInsufficientBalanceReverts() (gas: 68196) -DN404OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 69270, ~: 69305) -DN404OnlyERC20Test:test__codesize() (gas: 28926) +DN404OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 69238, ~: 69288) +DN404OnlyERC20Test:test__codesize() (gas: 28940) DN404Test:testBatchNFTLog() (gas: 291443) DN404Test:testBurnOnTransfer(uint32,address) (runs: 258, μ: 269823, ~: 269823) DN404Test:testFnSelectorNotRecognized() (gas: 6223) -DN404Test:testInitialize(uint32,address) (runs: 258, μ: 112203, ~: 116293) +DN404Test:testInitialize(uint32,address) (runs: 258, μ: 113542, ~: 116293) DN404Test:testMintAndBurn() (gas: 328471) DN404Test:testMintAndBurn2() (gas: 275156) DN404Test:testMintNext() (gas: 627787) -DN404Test:testMintNextMixed(uint256) (runs: 258, μ: 627443, ~: 558448) +DN404Test:testMintNextMixed(uint256) (runs: 258, μ: 633278, ~: 558448) DN404Test:testMintOnTransfer(uint32,address) (runs: 258, μ: 287429, ~: 287429) -DN404Test:testMixed(uint256) (runs: 258, μ: 801569, ~: 616467) +DN404Test:testMixed(uint256) (runs: 258, μ: 798158, ~: 623782) DN404Test:testNameAndSymbol(string,string) (runs: 258, μ: 206119, ~: 206632) DN404Test:testNumAliasesOverflowReverts() (gas: 57310) DN404Test:testOwnedIds() (gas: 350446) -DN404Test:testOwnedIds(uint256) (runs: 258, μ: 271031, ~: 279536) +DN404Test:testOwnedIds(uint256) (runs: 258, μ: 270501, ~: 279565) DN404Test:testPermit2() (gas: 437997) -DN404Test:testRegisterAndResolveAlias(address,address) (runs: 258, μ: 126385, ~: 126549) -DN404Test:testSetAndGetAux(address,uint88) (runs: 258, μ: 21989, ~: 22360) +DN404Test:testRegisterAndResolveAlias(address,address) (runs: 258, μ: 126519, ~: 126549) +DN404Test:testSetAndGetAux(address,uint88) (runs: 258, μ: 22024, ~: 22362) DN404Test:testSetAndGetOperatorApprovals(address,address,bool) (runs: 258, μ: 130828, ~: 140316) DN404Test:testSetAndGetSkipNFT() (gas: 716729) -DN404Test:testTokenURI(string,uint256) (runs: 258, μ: 157282, ~: 135083) +DN404Test:testTokenURI(string,uint256) (runs: 258, μ: 161113, ~: 138629) DN404Test:testTransferWithMirrorEvent() (gas: 396680) DN404Test:testTransfersAndBurns() (gas: 461487) -DN404Test:testWrapAround(uint32,uint256) (runs: 258, μ: 348536, ~: 343694) +DN404Test:testWrapAround(uint32,uint256) (runs: 258, μ: 347593, ~: 343378) DN404Test:test__codesize() (gas: 54539) MappingsTest:testAddressPairMapSetAndGet(address[2],address[2],uint256,uint256) (runs: 258, μ: 45433, ~: 47053) -MappingsTest:testBitmapSetAndGet(uint256) (runs: 258, μ: 463772, ~: 436038) -MappingsTest:testBitmapSetAndGet(uint256,uint256,bool,bool) (runs: 258, μ: 25609, ~: 26331) +MappingsTest:testBitmapSetAndGet(uint256) (runs: 258, μ: 453622, ~: 393780) +MappingsTest:testBitmapSetAndGet(uint256,uint256,bool,bool) (runs: 258, μ: 25583, ~: 26218) MappingsTest:testFindFirstUnset() (gas: 79749) -MappingsTest:testFindFirstUnset(uint256) (runs: 258, μ: 315483, ~: 221885) +MappingsTest:testFindFirstUnset(uint256) (runs: 258, μ: 329451, ~: 221885) MappingsTest:testRestrictNFTId(uint256) (runs: 258, μ: 340, ~: 340) -MappingsTest:testSetOwnerAliasAndOwnedIndex(uint256,uint32,uint32) (runs: 258, μ: 23430, ~: 23538) -MappingsTest:testStorageSlotsNoCollision(uint256,uint256,uint256,uint256) (runs: 258, μ: 26882, ~: 26732) -MappingsTest:testUint32MapSetAndGet(uint256) (runs: 258, μ: 1365129, ~: 1478509) -MappingsTest:testUint32MapSetAndGet(uint256,uint256,uint32,uint32) (runs: 258, μ: 42427, ~: 46177) +MappingsTest:testSetOwnerAliasAndOwnedIndex(uint256,uint32,uint32) (runs: 258, μ: 23408, ~: 23410) +MappingsTest:testStorageSlotsNoCollision(uint256,uint256,uint256,uint256) (runs: 258, μ: 26858, ~: 26734) +MappingsTest:testUint32MapSetAndGet(uint256) (runs: 258, μ: 1383328, ~: 1624683) +MappingsTest:testUint32MapSetAndGet(uint256,uint256,uint32,uint32) (runs: 258, μ: 43782, ~: 46049) MappingsTest:testWrapNFTIdWithOverflowCheck(uint256,uint256,uint256) (runs: 258, μ: 828, ~: 852) MappingsTest:test__codesize() (gas: 6840) -MintTests:test_WhenAmountIsGreaterThan_MAX_SUPPLYOrMintMakesNFTTotalSupplyExceed_MAX_SUPPLY(uint256) (runs: 258, μ: 64547, ~: 64684) -MintTests:test_WhenRecipientAddressHasSkipNFTEnabled(uint256) (runs: 258, μ: 85840, ~: 85832) -MintTests:test_WhenRecipientIsAddress0(uint256) (runs: 258, μ: 31085, ~: 31147) -MintTests:test_WhenRecipientsBalanceDifferenceIsNotUpTo1e18(uint256) (runs: 258, μ: 82803, ~: 82908) -MintTests:test_WhenRecipientsBalanceDifferenceIsUpTo1e18OrAbove(uint256) (runs: 258, μ: 89369, ~: 89438) -MintTests:test__codesize() (gas: 25718) +MintTests:test_WhenAmountIsGreaterThan_MAX_SUPPLYOrMintMakesNFTTotalSupplyExceed_MAX_SUPPLY(uint256) (runs: 258, μ: 64531, ~: 64683) +MintTests:test_WhenRecipientAddressHasSkipNFTEnabled(uint256) (runs: 258, μ: 85833, ~: 85832) +MintTests:test_WhenRecipientIsAddress0(uint256) (runs: 258, μ: 31087, ~: 31147) +MintTests:test_WhenRecipientsBalanceDifferenceIsNotUpTo1e18(uint256) (runs: 258, μ: 82819, ~: 82909) +MintTests:test_WhenRecipientsBalanceDifferenceIsUpTo1e18OrAbove(uint256) (runs: 258, μ: 89345, ~: 89438) +MintTests:test__codesize() (gas: 25732) NFTMintDN404Test:testAllowlistMint() (gas: 259166) NFTMintDN404Test:testMint() (gas: 231745) NFTMintDN404Test:testTotalSupplyReached() (gas: 629656918) -NFTMintDN404Test:test__codesize() (gas: 22634) +NFTMintDN404Test:test__codesize() (gas: 22648) SimpleDN404Test:testMint() (gas: 47571) SimpleDN404Test:testName() (gas: 9155) -SimpleDN404Test:testSetBaseURI() (gas: 46489) +SimpleDN404Test:testSetBaseURI() (gas: 46522) SimpleDN404Test:testSymbol() (gas: 9153) SimpleDN404Test:testWithdraw() (gas: 18232) -SimpleDN404Test:test__codesize() (gas: 19240) +SimpleDN404Test:test__codesize() (gas: 19254) SoladyTest:test__codesize() (gas: 840) TestPlus:test__codesize() (gas: 406) \ No newline at end of file diff --git a/src/DN404.sol b/src/DN404.sol index 44402e7..d236e43 100644 --- a/src/DN404.sol +++ b/src/DN404.sol @@ -1178,9 +1178,11 @@ abstract contract DN404 { /// @solidity memory-safe-assembly assembly { // Memory safe, as we've advanced the free memory pointer by a word. - let o := sub(uri, 0x20) + let o := sub(uri, 0x20) // Start of the returndata. + let z := add(mload(uri), 0x40) // Unpadded length of returndata. + mstore(add(o, z), 0) // Zeroize the word after the end of the string. mstore(o, 0x20) // Store the offset of `uri`. - return(o, add(0x60, mload(uri))) + return(o, and(not(0x1f), add(0x1f, z))) } } // `implementsDN404()`. diff --git a/test/DN404.t.sol b/test/DN404.t.sol index 4b1603e..1782cef 100644 --- a/test/DN404.t.sol +++ b/test/DN404.t.sol @@ -40,7 +40,9 @@ contract DN404Test is SoladyTest { function testTokenURI(string memory baseURI, uint256 id) public { dn.initializeDN404(1000 * _WAD, address(this), address(mirror)); dn.setBaseURI(baseURI); - assertEq(mirror.tokenURI(id), string(abi.encodePacked(baseURI, id))); + string memory expected = string(abi.encodePacked(baseURI, id)); + assertEq(DN404Mirror(mirror).tokenURI(id), expected); + assertEq(mirror.tokenURI(id), expected); } function testRegisterAndResolveAlias(address a0, address a1) public {