diff --git a/.gas-snapshot b/.gas-snapshot index 8bf28f5..1146bfe 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -67,7 +67,7 @@ BenchTest:testMintDN420_13() (gas: 111640) BenchTest:testMintDN420_14() (gas: 113114) BenchTest:testMintDN420_15() (gas: 114496) BenchTest:testMintDN420_16() (gas: 115948) -BenchTest:test__codesize() (gas: 28712) +BenchTest:test__codesize() (gas: 28700) DN404CustomUnitTest:testInitializeCorrectUnitSuccess() (gas: 129992) DN404CustomUnitTest:testInitializeWithUnitTooLargeReverts() (gas: 33824) DN404CustomUnitTest:testInitializeWithZeroUnitReverts() (gas: 13897) @@ -145,38 +145,38 @@ DN404Test:test__codesize() (gas: 57359) DN420OnlyERC20Test:testApprove() (gas: 35770) DN420OnlyERC20Test:testApprove(address,uint256) (runs: 258, μ: 30086, ~: 31321) DN420OnlyERC20Test:testBurn() (gas: 50438) -DN420OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 258, μ: 51549, ~: 51639) -DN420OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 44627, ~: 44709) +DN420OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 258, μ: 51564, ~: 51639) +DN420OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 44631, ~: 44709) DN420OnlyERC20Test:testInfiniteApproveTransferFrom() (gas: 102630) DN420OnlyERC20Test:testMaxSupplyTrick(uint256) (runs: 258, μ: 541, ~: 541) DN420OnlyERC20Test:testMetadata() (gas: 10112) DN420OnlyERC20Test:testMint() (gas: 45958) DN420OnlyERC20Test:testMintOverMaxLimitReverts() (gas: 41962) -DN420OnlyERC20Test:testMintz(address,uint256) (runs: 258, μ: 46265, ~: 46380) +DN420OnlyERC20Test:testMintz(address,uint256) (runs: 258, μ: 46262, ~: 46380) DN420OnlyERC20Test:testTransfer() (gas: 75434) -DN420OnlyERC20Test:testTransfer(address,uint256) (runs: 258, μ: 75770, ~: 75891) +DN420OnlyERC20Test:testTransfer(address,uint256) (runs: 258, μ: 75795, ~: 75891) DN420OnlyERC20Test:testTransferFrom() (gas: 85088) -DN420OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 258, μ: 105802, ~: 108058) +DN420OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 258, μ: 105778, ~: 108058) DN420OnlyERC20Test:testTransferFromInsufficientAllowanceReverts() (gas: 68658) -DN420OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 258, μ: 69189, ~: 69768) +DN420OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 258, μ: 69181, ~: 69768) DN420OnlyERC20Test:testTransferFromInsufficientBalanceReverts() (gas: 75577) -DN420OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 76640, ~: 76702) +DN420OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 76635, ~: 76698) DN420OnlyERC20Test:testTransferInsufficientBalanceReverts() (gas: 67140) -DN420OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 68173, ~: 68227) -DN420OnlyERC20Test:test__codesize() (gas: 26885) -DN420Test:testERC1155Methods(uint256) (runs: 258, μ: 4346596, ~: 4601179) -DN420Test:testERC1155MethodsSelfTransfers(uint256) (runs: 258, μ: 2546320, ~: 2685708) -DN420Test:testFindOwnedIds() (gas: 2651260) -DN420Test:testMintNext() (gas: 2126914) -DN420Test:testMintToNonERC155RecipientReverts(uint256) (runs: 258, μ: 899013, ~: 798557) -DN420Test:testMintToRevertingERC155RecipientReverts(uint256) (runs: 258, μ: 1453715, ~: 982568) -DN420Test:testMintToZeroReverts(uint256) (runs: 258, μ: 742100, ~: 665294) -DN420Test:testMixed(uint256) (runs: 258, μ: 10547010, ~: 6465435) -DN420Test:testSafeBatchTransferFromToERC1155Recipient(uint256) (runs: 258, μ: 2238368, ~: 2182182) -DN420Test:testSafeTransferFromToERC1155Recipient(uint256) (runs: 258, μ: 1784409, ~: 1475200) -DN420Test:testTransferFromToERC1155Recipient(uint256) (runs: 258, μ: 2881452, ~: 2868451) -DN420Test:testTransferMixedReverts(uint256) (runs: 258, μ: 4214140, ~: 3287831) -DN420Test:test__codesize() (gas: 66295) +DN420OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 68267, ~: 68231) +DN420OnlyERC20Test:test__codesize() (gas: 26873) +DN420Test:testERC1155Methods(uint256) (runs: 258, μ: 4370769, ~: 4604805) +DN420Test:testERC1155MethodsSelfTransfers(uint256) (runs: 258, μ: 2527117, ~: 2684325) +DN420Test:testFindOwnedIds() (gas: 2647505) +DN420Test:testMintNext() (gas: 2124073) +DN420Test:testMintToNonERC155RecipientReverts(uint256) (runs: 258, μ: 981585, ~: 799362) +DN420Test:testMintToRevertingERC155RecipientReverts(uint256) (runs: 258, μ: 1447973, ~: 981555) +DN420Test:testMintToZeroReverts(uint256) (runs: 258, μ: 711313, ~: 664263) +DN420Test:testMixed(uint256) (runs: 258, μ: 10721971, ~: 6383788) +DN420Test:testSafeBatchTransferFromToERC1155Recipient(uint256) (runs: 258, μ: 2219189, ~: 2180542) +DN420Test:testSafeTransferFromToERC1155Recipient(uint256) (runs: 258, μ: 1748321, ~: 1474285) +DN420Test:testTransferFromToERC1155Recipient(uint256) (runs: 258, μ: 2880183, ~: 2866558) +DN420Test:testTransferMixedReverts(uint256) (runs: 258, μ: 3915640, ~: 3302456) +DN420Test:test__codesize() (gas: 66288) MappingsTest:testAddressPairMapSetAndGet(address[2],address[2],uint256,uint256) (runs: 258, μ: 45763, ~: 47075) MappingsTest:testBitmapSetAndGet(uint256) (runs: 258, μ: 453208, ~: 413769) MappingsTest:testBitmapSetAndGet(uint256,uint256,bool,bool) (runs: 258, μ: 25592, ~: 26270) diff --git a/src/DN420.sol b/src/DN420.sol index c8150d0..341d8b8 100644 --- a/src/DN420.sol +++ b/src/DN420.sol @@ -761,12 +761,10 @@ abstract contract DN420 { if (!isApprovedForAll(from, by)) revert NotOwnerNorApproved(); } - { - Bitmap storage fromOwned = $.owned[from]; - if (!_owns(fromOwned, id)) revert TransferFromIncorrectOwner(); - _set(fromOwned, id, false); - _set($.owned[to], id, true); - } + Bitmap storage fromOwned = $.owned[from]; + if (!_owns(fromOwned, id)) revert TransferFromIncorrectOwner(); + _set(fromOwned, id, false); + _set($.owned[to], id, true); uint256 unit = _unit(); AddressData storage fromAddressData = $.addressData[from]; @@ -1130,14 +1128,15 @@ abstract contract DN420 { } // `balanceOfBatch(address[],uint256[])`. if (fnSelector == 0x4e1273f4) { - address[] memory owners = _toAddressArray(_calldataUint256Array(0x04)); + uint256[] memory owners = _calldataUint256Array(0x04); uint256[] memory ids = _calldataUint256Array(0x24); unchecked { uint256 n = ids.length; if (owners.length != n) revert ArrayLengthsMismatch(); uint256[] memory result = _idsMalloc(n); while (n-- != 0) { - _set(result, n, _toUint(owns(_get(owners, n), _get(ids, n)))); + address owner = address(uint160(_get(owners, n))); + _set(result, n, _toUint(owns(owner, _get(ids, n)))); } /// @solidity memory-safe-assembly assembly { @@ -1519,15 +1518,6 @@ abstract contract DN420 { } } - /// @dev Casts `a` to `address[]`. - /// This function does not check if elements in `a` have their upper 96 bits cleaned. - function _toAddressArray(uint256[] memory a) private pure returns (address[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - /// @dev Returns a `uint256[] calldata` at `offset` in calldata as `uint256[] memory`. function _calldataUint256Array(uint256 offset) private pure returns (uint256[] memory result) { /// @solidity memory-safe-assembly @@ -1537,7 +1527,7 @@ abstract contract DN420 { let n := calldataload(o) mstore(result, n) calldatacopy(add(0x20, result), add(o, 0x20), shl(5, n)) - mstore(0x40, add(add(result, 0x20), shl(5, n))) + mstore(0x40, add(add(0x20, result), shl(5, n))) } } @@ -1550,20 +1540,12 @@ abstract contract DN420 { let n := calldataload(o) mstore(result, n) calldatacopy(add(0x20, result), add(o, 0x20), n) - o := add(add(result, 0x20), n) + o := add(add(0x20, result), n) mstore(o, 0) // Zeroize the slot after the last word. mstore(0x40, add(0x20, o)) } } - /// @dev Returns `a[i]` without bounds check. - function _get(address[] memory a, uint256 i) private pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(0x20, a), shl(5, i))) - } - } - /// @dev Returns `a[i]` without bounds check. function _get(uint256[] memory a, uint256 i) private pure returns (uint256 result) { /// @solidity memory-safe-assembly