Skip to content

Commit

Permalink
Optimize and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized committed Mar 19, 2024
1 parent 8738322 commit 45db083
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 112 deletions.
148 changes: 74 additions & 74 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -67,134 +67,134 @@ BenchTest:testMintDN420_13() (gas: 111640)
BenchTest:testMintDN420_14() (gas: 113114)
BenchTest:testMintDN420_15() (gas: 114496)
BenchTest:testMintDN420_16() (gas: 115948)
BenchTest:test__codesize() (gas: 29036)
BenchTest:test__codesize() (gas: 28725)
DN404CustomUnitTest:testInitializeCorrectUnitSuccess() (gas: 129992)
DN404CustomUnitTest:testInitializeWithUnitTooLargeReverts() (gas: 33824)
DN404CustomUnitTest:testInitializeWithZeroUnitReverts() (gas: 13897)
DN404CustomUnitTest:testMint() (gas: 764779)
DN404CustomUnitTest:testMintWithoutNFTs(uint256,uint256,uint256) (runs: 256, μ: 676621, ~: 764104)
DN404CustomUnitTest:testMintWithoutNFTs(uint256,uint256,uint256) (runs: 258, μ: 685149, ~: 764102)
DN404CustomUnitTest:testNFTMint() (gas: 59220902)
DN404CustomUnitTest:testNFTMintAndBurn(uint256,uint256,uint256) (runs: 256, μ: 1128824, ~: 763469)
DN404CustomUnitTest:testNFTMintViaTransfer(uint256,uint256,uint256) (runs: 256, μ: 730513, ~: 840230)
DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256) (runs: 256, μ: 638, ~: 692)
DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256,uint256) (runs: 256, μ: 780, ~: 746)
DN404CustomUnitTest:testUnitInvalidCheckTrick(uint256) (runs: 256, μ: 548, ~: 550)
DN404CustomUnitTest:testNFTMintAndBurn(uint256,uint256,uint256) (runs: 258, μ: 1144481, ~: 763505)
DN404CustomUnitTest:testNFTMintViaTransfer(uint256,uint256,uint256) (runs: 258, μ: 735928, ~: 842344)
DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256) (runs: 258, μ: 638, ~: 692)
DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256,uint256) (runs: 258, μ: 780, ~: 746)
DN404CustomUnitTest:testUnitInvalidCheckTrick(uint256) (runs: 258, μ: 548, ~: 550)
DN404CustomUnitTest:test__codesize() (gas: 28387)
DN404MirrorTest:testBaseERC20() (gas: 114608)
DN404MirrorTest:testFnSelectorNotRecognized() (gas: 7032)
DN404MirrorTest:testLinkMirrorContract() (gas: 45864)
DN404MirrorTest:testLogDirectTransfers() (gas: 1610907)
DN404MirrorTest:testLogTransfer() (gas: 120685)
DN404MirrorTest:testNameAndSymbol(string,string) (runs: 256, μ: 207776, ~: 208117)
DN404MirrorTest:testNameAndSymbol(string,string) (runs: 258, μ: 207604, ~: 208117)
DN404MirrorTest:testNotLinked() (gas: 12767)
DN404MirrorTest:testPullOwner() (gas: 112643)
DN404MirrorTest:testPullOwnerWithOwnable() (gas: 3289528)
DN404MirrorTest:testSafeTransferFrom(uint32) (runs: 256, μ: 2315509, ~: 2315489)
DN404MirrorTest:testSafeTransferFrom(uint32) (runs: 258, μ: 2315506, ~: 2315489)
DN404MirrorTest:testSetAndGetApprovalForAll() (gas: 2170983)
DN404MirrorTest:testSetAndGetApproved() (gas: 2167717)
DN404MirrorTest:testSupportsInterface() (gas: 7544)
DN404MirrorTest:testTokenURI(string,uint256) (runs: 256, μ: 158083, ~: 135821)
DN404MirrorTest:testTransferFrom(uint32) (runs: 256, μ: 2219121, ~: 2219076)
DN404MirrorTest:testTransferFromMixed(uint256) (runs: 256, μ: 11009388, ~: 8629376)
DN404MirrorTest:testTokenURI(string,uint256) (runs: 258, μ: 158086, ~: 135821)
DN404MirrorTest:testTransferFrom(uint32) (runs: 258, μ: 2219126, ~: 2219076)
DN404MirrorTest:testTransferFromMixed(uint256) (runs: 258, μ: 10844442, ~: 8629376)
DN404MirrorTest:test__codesize() (gas: 57325)
DN404OnlyERC20Test:testApprove() (gas: 35803)
DN404OnlyERC20Test:testApprove(address,uint256) (runs: 256, μ: 30110, ~: 31354)
DN404OnlyERC20Test:testApprove(address,uint256) (runs: 258, μ: 30119, ~: 31354)
DN404OnlyERC20Test:testBurn() (gas: 52009)
DN404OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 256, μ: 53072, ~: 53210)
DN404OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 256, μ: 46248, ~: 46312)
DN404OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 258, μ: 53070, ~: 53210)
DN404OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 46324, ~: 46312)
DN404OnlyERC20Test:testInfiniteApproveTransferFrom() (gas: 104918)
DN404OnlyERC20Test:testMaxSupplyTrick(uint256) (runs: 256, μ: 541, ~: 541)
DN404OnlyERC20Test:testMaxSupplyTrick(uint256) (runs: 258, μ: 541, ~: 541)
DN404OnlyERC20Test:testMetadata() (gas: 10044)
DN404OnlyERC20Test:testMint() (gas: 47577)
DN404OnlyERC20Test:testMintOverMaxLimitReverts() (gas: 43571)
DN404OnlyERC20Test:testMintz(address,uint256) (runs: 256, μ: 47986, ~: 47999)
DN404OnlyERC20Test:testMintz(address,uint256) (runs: 258, μ: 47891, ~: 47999)
DN404OnlyERC20Test:testTransfer() (gas: 77636)
DN404OnlyERC20Test:testTransfer(address,uint256) (runs: 256, μ: 77973, ~: 78093)
DN404OnlyERC20Test:testTransfer(address,uint256) (runs: 258, μ: 77963, ~: 78093)
DN404OnlyERC20Test:testTransferFrom() (gas: 87376)
DN404OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 256, μ: 108327, ~: 110345)
DN404OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 258, μ: 107960, ~: 110345)
DN404OnlyERC20Test:testTransferFromInsufficientAllowanceReverts() (gas: 70282)
DN404OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 256, μ: 70820, ~: 71447)
DN404OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 258, μ: 70985, ~: 71392)
DN404OnlyERC20Test:testTransferFromInsufficientBalanceReverts() (gas: 77235)
DN404OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 256, μ: 78307, ~: 78365)
DN404OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 78305, ~: 78356)
DN404OnlyERC20Test:testTransferInsufficientBalanceReverts() (gas: 68734)
DN404OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 256, μ: 69774, ~: 69825)
DN404OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 69868, ~: 69830)
DN404OnlyERC20Test:test__codesize() (gas: 30292)
DN404Test:testBatchNFTLog() (gas: 3670932)
DN404Test:testBurnOnTransfer(uint32,address) (runs: 256, μ: 1664410, ~: 1501059)
DN404Test:testBurnOnTransfer(uint32,address) (runs: 258, μ: 1623223, ~: 1501073)
DN404Test:testFnSelectorNotRecognized() (gas: 6974)
DN404Test:testInitialize(uint32,address) (runs: 256, μ: 112581, ~: 116323)
DN404Test:testInitialize(uint32,address) (runs: 258, μ: 112911, ~: 116323)
DN404Test:testMintAndBurn() (gas: 2792646)
DN404Test:testMintAndBurn2() (gas: 3355751)
DN404Test:testMintNext() (gas: 2476800)
DN404Test:testMintNextMixed(uint256) (runs: 256, μ: 11160005, ~: 6715659)
DN404Test:testMintOnTransfer(uint32,address) (runs: 256, μ: 984523, ~: 903178)
DN404Test:testMixed(uint256) (runs: 256, μ: 9757449, ~: 6321003)
DN404Test:testNameAndSymbol(string,string) (runs: 256, μ: 207494, ~: 207835)
DN404Test:testMintNextMixed(uint256) (runs: 258, μ: 11771867, ~: 7727499)
DN404Test:testMintOnTransfer(uint32,address) (runs: 258, μ: 954371, ~: 903145)
DN404Test:testMixed(uint256) (runs: 258, μ: 9727013, ~: 6321003)
DN404Test:testNameAndSymbol(string,string) (runs: 258, μ: 207322, ~: 207835)
DN404Test:testNumAliasesOverflowReverts() (gas: 57369)
DN404Test:testOwnedIds() (gas: 15735632)
DN404Test:testOwnedIds(uint256) (runs: 256, μ: 1722808, ~: 1513621)
DN404Test:testOwnedIds(uint256) (runs: 258, μ: 1682288, ~: 1514215)
DN404Test:testPermit2() (gas: 2899852)
DN404Test:testRegisterAndResolveAlias(address,address) (runs: 256, μ: 126443, ~: 126677)
DN404Test:testSetAndGetAux(address,uint88) (runs: 256, μ: 22073, ~: 22344)
DN404Test:testSetAndGetOperatorApprovals(address,address,bool) (runs: 256, μ: 129281, ~: 120342)
DN404Test:testRegisterAndResolveAlias(address,address) (runs: 258, μ: 126522, ~: 126677)
DN404Test:testSetAndGetAux(address,uint88) (runs: 258, μ: 21971, ~: 22344)
DN404Test:testSetAndGetOperatorApprovals(address,address,bool) (runs: 258, μ: 129289, ~: 120342)
DN404Test:testSetAndGetSkipNFT() (gas: 719817)
DN404Test:testTokenURI(string,uint256) (runs: 256, μ: 157949, ~: 135687)
DN404Test:testTokenURI(string,uint256) (runs: 258, μ: 157952, ~: 135687)
DN404Test:testTransfersAndBurns() (gas: 2924439)
DN404Test:testWrapAround(uint32,uint256) (runs: 256, μ: 3662972, ~: 3425561)
DN404Test:testWrapAround(uint32,uint256) (runs: 258, μ: 3689376, ~: 3425666)
DN404Test:test__codesize() (gas: 57359)
DN420OnlyERC20Test:testApprove() (gas: 35770)
DN420OnlyERC20Test:testApprove(address,uint256) (runs: 256, μ: 30077, ~: 31321)
DN420OnlyERC20Test:testApprove(address,uint256) (runs: 258, μ: 30086, ~: 31321)
DN420OnlyERC20Test:testBurn() (gas: 50438)
DN420OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 256, μ: 51542, ~: 51639)
DN420OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 256, μ: 44638, ~: 44709)
DN420OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 258, μ: 51560, ~: 51639)
DN420OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 44636, ~: 44709)
DN420OnlyERC20Test:testInfiniteApproveTransferFrom() (gas: 102630)
DN420OnlyERC20Test:testMaxSupplyTrick(uint256) (runs: 256, μ: 541, ~: 541)
DN420OnlyERC20Test:testMaxSupplyTrick(uint256) (runs: 258, μ: 541, ~: 541)
DN420OnlyERC20Test:testMetadata() (gas: 10112)
DN420OnlyERC20Test:testMint() (gas: 45958)
DN420OnlyERC20Test:testMintOverMaxLimitReverts() (gas: 41962)
DN420OnlyERC20Test:testMintz(address,uint256) (runs: 256, μ: 46279, ~: 46380)
DN420OnlyERC20Test:testMintz(address,uint256) (runs: 258, μ: 46282, ~: 46380)
DN420OnlyERC20Test:testTransfer() (gas: 75434)
DN420OnlyERC20Test:testTransfer(address,uint256) (runs: 256, μ: 75790, ~: 75891)
DN420OnlyERC20Test:testTransfer(address,uint256) (runs: 258, μ: 75770, ~: 75891)
DN420OnlyERC20Test:testTransferFrom() (gas: 85088)
DN420OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 256, μ: 105864, ~: 108058)
DN420OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 258, μ: 105874, ~: 108058)
DN420OnlyERC20Test:testTransferFromInsufficientAllowanceReverts() (gas: 68658)
DN420OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 256, μ: 69180, ~: 69759)
DN420OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 258, μ: 69184, ~: 69768)
DN420OnlyERC20Test:testTransferFromInsufficientBalanceReverts() (gas: 75577)
DN420OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 256, μ: 76731, ~: 76698)
DN420OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 76698, ~: 76702)
DN420OnlyERC20Test:testTransferInsufficientBalanceReverts() (gas: 67140)
DN420OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 256, μ: 68262, ~: 68227)
DN420OnlyERC20Test:test__codesize() (gas: 27225)
DN420Test:testERC1155Methods(uint256) (runs: 256, μ: 4274230, ~: 4513795)
DN420Test:testERC1155MethodsSelfTransfers(uint256) (runs: 256, μ: 2356698, ~: 2038371)
DN420Test:testFindOwnedIds() (gas: 2609788)
DN420Test:testMintNext() (gas: 2095753)
DN420Test:testMintToNonERC155RecipientReverts(uint256) (runs: 256, μ: 914968, ~: 788804)
DN420Test:testMintToRevertingERC155RecipientReverts(uint256) (runs: 256, μ: 1527040, ~: 972152)
DN420Test:testMintToZeroReverts(uint256) (runs: 256, μ: 752453, ~: 654981)
DN420Test:testMixed(uint256) (runs: 256, μ: 9931929, ~: 6330085)
DN420Test:testSafeBatchTransferFromToERC1155Recipient(uint256) (runs: 256, μ: 2208923, ~: 2162910)
DN420Test:testSafeTransferFromToERC1155Recipient(uint256) (runs: 256, μ: 1755913, ~: 1466043)
DN420Test:testTransferFromToERC1155Recipient(uint256) (runs: 256, μ: 2860071, ~: 2847745)
DN420Test:testTransferMixedReverts(uint256) (runs: 256, μ: 4149926, ~: 3255945)
DN420Test:test__codesize() (gas: 65215)
MappingsTest:testAddressPairMapSetAndGet(address[2],address[2],uint256,uint256) (runs: 256, μ: 45753, ~: 47075)
MappingsTest:testBitmapSetAndGet(uint256) (runs: 256, μ: 465457, ~: 442995)
MappingsTest:testBitmapSetAndGet(uint256,uint256,bool,bool) (runs: 256, μ: 25658, ~: 26270)
DN420OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 68183, ~: 68227)
DN420OnlyERC20Test:test__codesize() (gas: 26898)
DN420Test:testERC1155Methods(uint256) (runs: 258, μ: 4358116, ~: 4607174)
DN420Test:testERC1155MethodsSelfTransfers(uint256) (runs: 258, μ: 2382290, ~: 2071900)
DN420Test:testFindOwnedIds() (gas: 2656474)
DN420Test:testMintNext() (gas: 2130909)
DN420Test:testMintToNonERC155RecipientReverts(uint256) (runs: 258, μ: 926867, ~: 801546)
DN420Test:testMintToRevertingERC155RecipientReverts(uint256) (runs: 258, μ: 1408748, ~: 982904)
DN420Test:testMintToZeroReverts(uint256) (runs: 258, μ: 784036, ~: 666420)
DN420Test:testMixed(uint256) (runs: 258, μ: 10731920, ~: 6403891)
DN420Test:testSafeBatchTransferFromToERC1155Recipient(uint256) (runs: 258, μ: 2227938, ~: 2184910)
DN420Test:testSafeTransferFromToERC1155Recipient(uint256) (runs: 258, μ: 1755423, ~: 1476488)
DN420Test:testTransferFromToERC1155Recipient(uint256) (runs: 258, μ: 2885047, ~: 2871091)
DN420Test:testTransferMixedReverts(uint256) (runs: 258, μ: 4048827, ~: 3337559)
DN420Test:test__codesize() (gas: 65539)
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)
MappingsTest:testFindFirstUnset() (gas: 80034)
MappingsTest:testFindFirstUnset(uint256) (runs: 256, μ: 322311, ~: 222151)
MappingsTest:testFindLastSet(uint256) (runs: 256, μ: 713641, ~: 441299)
MappingsTest:testRestrictNFTId(uint256) (runs: 256, μ: 340, ~: 340)
MappingsTest:testSetOwnerAliasAndOwnedIndex(uint256,uint32,uint32) (runs: 256, μ: 23444, ~: 23561)
MappingsTest:testStorageSlotsNoCollision(uint256,uint256,uint256,uint256) (runs: 256, μ: 26826, ~: 26692)
MappingsTest:testUint32MapSetAndGet(uint256) (runs: 256, μ: 1312545, ~: 1260981)
MappingsTest:testUint32MapSetAndGet(uint256,uint256,uint32,uint32) (runs: 256, μ: 42884, ~: 46200)
MappingsTest:testWrapNFTIdWithOverflowCheck(uint256,uint256,uint256) (runs: 256, μ: 826, ~: 852)
MappingsTest:testFindFirstUnset(uint256) (runs: 258, μ: 331337, ~: 223263)
MappingsTest:testFindLastSet(uint256) (runs: 258, μ: 701484, ~: 424151)
MappingsTest:testRestrictNFTId(uint256) (runs: 258, μ: 340, ~: 340)
MappingsTest:testSetOwnerAliasAndOwnedIndex(uint256,uint32,uint32) (runs: 258, μ: 23449, ~: 23561)
MappingsTest:testStorageSlotsNoCollision(uint256,uint256,uint256,uint256) (runs: 258, μ: 26841, ~: 26694)
MappingsTest:testUint32MapSetAndGet(uint256) (runs: 258, μ: 1322218, ~: 1465647)
MappingsTest:testUint32MapSetAndGet(uint256,uint256,uint32,uint32) (runs: 258, μ: 43149, ~: 46200)
MappingsTest:testWrapNFTIdWithOverflowCheck(uint256,uint256,uint256) (runs: 258, μ: 826, ~: 852)
MappingsTest:test__codesize() (gas: 9063)
MintTests:test_WhenAmountIsGreaterThan_MAX_SUPPLYOrMintMakesNFTTotalSupplyExceed_MAX_SUPPLY(uint256) (runs: 256, μ: 793573, ~: 680063)
MintTests:test_WhenRecipientAddressHasSkipNFTEnabled(uint256) (runs: 256, μ: 768317, ~: 701676)
MintTests:test_WhenRecipientIsAddress0(uint256) (runs: 256, μ: 731664, ~: 646359)
MintTests:test_WhenRecipientsBalanceDifferenceIsNotUpTo1e18(uint256) (runs: 256, μ: 1099842, ~: 698543)
MintTests:test_WhenRecipientsBalanceDifferenceIsUpTo1e18OrAbove(uint256) (runs: 256, μ: 779659, ~: 705081)
MintTests:test_WhenAmountIsGreaterThan_MAX_SUPPLYOrMintMakesNFTTotalSupplyExceed_MAX_SUPPLY(uint256) (runs: 258, μ: 777538, ~: 680342)
MintTests:test_WhenRecipientAddressHasSkipNFTEnabled(uint256) (runs: 258, μ: 793418, ~: 701518)
MintTests:test_WhenRecipientIsAddress0(uint256) (runs: 258, μ: 694980, ~: 646331)
MintTests:test_WhenRecipientsBalanceDifferenceIsNotUpTo1e18(uint256) (runs: 258, μ: 1029051, ~: 698516)
MintTests:test_WhenRecipientsBalanceDifferenceIsUpTo1e18OrAbove(uint256) (runs: 258, μ: 781120, ~: 705038)
MintTests:test__codesize() (gas: 26743)
NFTMintDN404Test:testAllowlistMint() (gas: 257485)
NFTMintDN404Test:testMint() (gas: 231816)
Expand Down
68 changes: 32 additions & 36 deletions src/DN420.sol
Original file line number Diff line number Diff line change
Expand Up @@ -769,19 +769,17 @@ abstract contract DN420 {
}

uint256 unit = _unit();

AddressData storage fromAddressData = $.addressData[from];
AddressData storage toAddressData = $.addressData[to];

unchecked {
uint256 fromBalance = fromAddressData.balance;
if (unit > fromBalance) revert InsufficientBalance();
fromAddressData.balance = uint96(fromBalance - unit);
toAddressData.balance += uint96(unit);

--fromAddressData.ownedCount;
++toAddressData.ownedCount;
toAddressData.ownedCheckpoint = uint32(_max(toAddressData.ownedCheckpoint, id));
/// @solidity memory-safe-assembly
assembly {
let diff := or(shl(160, unit), shl(128, 1))
sstore(fromAddressData.slot, sub(sload(fromAddressData.slot), diff))
let toPacked := sload(toAddressData.slot)
let toCheckpoint := and(0xffffffff, shr(96, toPacked))
// forgefmt: disable-next-item
sstore(toAddressData.slot, add(diff,
xor(toPacked, shl(96, mul(gt(id, toCheckpoint), xor(id, toCheckpoint))))))
}
_afterNFTTransfer(from, to, id);
/// @solidity memory-safe-assembly
Expand Down Expand Up @@ -827,35 +825,33 @@ abstract contract DN420 {
if (!isApprovedForAll(from, by)) revert NotOwnerNorApproved();
}

uint256 upTo;
uint256 amount;
uint256 n = ids.length;
AddressData storage fromAddressData = $.addressData[from];
AddressData storage toAddressData = $.addressData[to];
unchecked {
uint256 n = ids.length;
amount = n * _unit();

AddressData storage fromAddressData = $.addressData[from];
AddressData storage toAddressData = $.addressData[to];
{
uint256 fromBalance = fromAddressData.balance;
if (amount > fromBalance) revert InsufficientBalance();
fromAddressData.balance = uint96(fromBalance - amount);
toAddressData.balance += uint96(amount);
}
{
Bitmap storage fromOwned = $.owned[from];
Bitmap storage toOwned = $.owned[to];
uint256 upTo = toAddressData.ownedCheckpoint;
for (uint256 i; i != n; ++i) {
uint256 id = _get(ids, i);
if (!_owns(fromOwned, id)) revert TransferFromIncorrectOwner();
_set(fromOwned, id, false);
_set(toOwned, id, true);
upTo = uint32(_max(upTo, id));
_afterNFTTransfer(from, to, id);
}
toAddressData.ownedCheckpoint = uint32(upTo);
Bitmap storage fromOwned = $.owned[from];
Bitmap storage toOwned = $.owned[to];
for (uint256 i; i != n; ++i) {
uint256 id = _get(ids, i);
if (!_owns(fromOwned, id)) revert TransferFromIncorrectOwner();
_set(fromOwned, id, false);
_set(toOwned, id, true);
upTo = uint32(_max(upTo, id));
_afterNFTTransfer(from, to, id);
}
fromAddressData.ownedCount -= uint32(n);
toAddressData.ownedCount += uint32(n);
}
/// @solidity memory-safe-assembly
assembly {
let diff := or(shl(160, amount), shl(128, n))
sstore(fromAddressData.slot, sub(sload(fromAddressData.slot), diff))
let toPacked := sload(toAddressData.slot)
let toCheckpoint := and(0xffffffff, shr(96, toPacked))
// forgefmt: disable-next-item
sstore(toAddressData.slot, add(diff,
xor(toPacked, shl(96, mul(gt(upTo, toCheckpoint), xor(upTo, toCheckpoint))))))
}
_batchTransferEmit(from, to, ids);
/// @solidity memory-safe-assembly
Expand Down
Loading

0 comments on commit 45db083

Please sign in to comment.