diff --git a/.gas-snapshot b/.gas-snapshot index 5b70304f..e84e8316 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -20,23 +20,23 @@ Certificate_supportsInterface:test() (gas: 5159) Certificate_transferFrom:test() (gas: 48618) Certificate_transferFrom:test_reverts_when_paused() (gas: 38088) Certificate_transferFrom_reverts_ForbiddenTransferAfterMinting:test() (gas: 18960) -Checkout_buyingFromOneRemoval:test() (gas: 652994) -Checkout_buyingFromOneRemoval_byApproval:test() (gas: 589052) -Checkout_buyingFromTenRemovals:test() (gas: 1976346) -Checkout_buyingFromTenRemovals_singleSupplier:test() (gas: 1711916) -Checkout_buyingFromTenRemovals_singleSupplier_withoutFee:test() (gas: 1707116) -Checkout_buyingFromTenRemovals_withoutFee:test() (gas: 1719822) -Checkout_buyingFromTenSuppliers:test() (gas: 2854632) -Checkout_buyingWithAlternateERC20:test() (gas: 546928) -Checkout_buyingWithAlternateERC20_floatingPointPriceMultiple:test() (gas: 512982) +Checkout_buyingFromOneRemoval:test() (gas: 653182) +Checkout_buyingFromOneRemoval_byApproval:test() (gas: 589240) +Checkout_buyingFromTenRemovals:test() (gas: 1978293) +Checkout_buyingFromTenRemovals_singleSupplier:test() (gas: 1713863) +Checkout_buyingFromTenRemovals_singleSupplier_withoutFee:test() (gas: 1709063) +Checkout_buyingFromTenRemovals_withoutFee:test() (gas: 1721769) +Checkout_buyingFromTenSuppliers:test() (gas: 2856579) +Checkout_buyingWithAlternateERC20:test() (gas: 547028) +Checkout_buyingWithAlternateERC20_floatingPointPriceMultiple:test() (gas: 513082) Checkout_swapRevertsWhenBuyerIsMissingSANCTION_ALLOWLIST_ROLE:test() (gas: 168598) Checkout_swapRevertsWithDifferentPermitSignerAndMsgSender:test() (gas: 168610) -Checkout_swapWithoutFeeSpecialOrder:test() (gas: 569131) -Checkout_swapWithoutFeeSpecialOrder_specificSupplier:test() (gas: 563830) +Checkout_swapWithoutFeeSpecialOrder:test() (gas: 569319) +Checkout_swapWithoutFeeSpecialOrder_specificSupplier:test() (gas: 564018) Checkout_swapWithoutFeeSpecialOrder_specificSupplier:test_revertsWhenSupplierDoesNotExistInMarket() (gas: 57731) -Checkout_swapWithoutFeeSpecialOrder_specificVintages:test_basicFulfillment() (gas: 965410) +Checkout_swapWithoutFeeSpecialOrder_specificVintages:test_basicFulfillment() (gas: 965796) Checkout_swapWithoutFeeSpecialOrder_specificVintages:test_revertsWhenNoRemovalsFromSpecifiedVintages() (gas: 91000) -Checkout_swapWithoutFeeSpecialOrder_specificVintagesSpecificSupplier:test_basicFulfillment() (gas: 701767) +Checkout_swapWithoutFeeSpecialOrder_specificVintagesSpecificSupplier:test_basicFulfillment() (gas: 702054) LockedNORILib_availableAmount:test() (gas: 12371) LockedNORITest:testBatchGrantCreation() (gas: 705179) LockedNORITest:testNormalWithdrawal() (gas: 1102743) @@ -44,12 +44,12 @@ LockedNORITest:testReentryTokensReceived() (gas: 1102887) LockedNORITest:testReentryTokensToSend() (gas: 1104432) LockedNORITest:testTokensReceivedReverts() (gas: 69026) MarketInvariantTest:invariant_callSummary() (runs: 400, calls: 6000, reverts: 4269) -MarketInvariantTest:invariant_sumOfPurchaseAmounts() (runs: 400, calls: 6000, reverts: 4292) -MarketSupplierSelectionNotUsingUpSuppliersLastRemoval:test() (gas: 923444) +MarketInvariantTest:invariant_sumOfPurchaseAmounts() (runs: 400, calls: 6000, reverts: 4266) +MarketSupplierSelectionNotUsingUpSuppliersLastRemoval:test() (gas: 923378) Market_ALLOWLIST_ROLE:test() (gas: 12799) Market_SANCTION_ALLOWLIST_ROLE:test() (gas: 12897) -Market_USDC_swap_respects_decimal_mismatch:test() (gas: 799139) -Market_USDC_swap_withholds_restricted_nori:test() (gas: 974214) +Market_USDC_swap_respects_decimal_mismatch:test() (gas: 799095) +Market_USDC_swap_withholds_restricted_nori:test() (gas: 974170) Market__addActiveRemoval:test() (gas: 183344) Market__addActiveRemoval:test__lis2VintagesFor1SupplierFor2SubIdentifiers() (gas: 242901) Market__addActiveRemoval:test__list1VintageFor1Supplier() (gas: 188309) @@ -82,24 +82,24 @@ Market_getRemovalIdsForSupplier:test_3_removals() (gas: 993990) Market_getRemovalIdsForSupplier:test_3_removals_different_vintages() (gas: 1040099) Market_getRemovalIdsForSupplier:test_no_removals() (gas: 26044) Market_onERC1155BatchReceived:test() (gas: 208168) -Market_onERC1155BatchReceived_reverts_SenderNotRemovalContract:test() (gas: 355367) +Market_onERC1155BatchReceived_reverts_SenderNotRemovalContract:test() (gas: 355389) Market_onERC1155Received:test() (gas: 206036) Market_onERC1155Received_reverts_SenderNotRemovalContract:test() (gas: 159000) Market_purchasingTokenAddress:test() (gas: 17191) -Market_replace:test() (gas: 345000) +Market_replace:test() (gas: 344956) Market_replace_reverts_CertificateNotYetMinted:test() (gas: 49559) Market_replace_reverts_ReplacementAmountExceedsNrtDeficit:test() (gas: 52590) -Market_replace_reverts_ReplacementAmountMismatch:test() (gas: 86353) +Market_replace_reverts_ReplacementAmountMismatch:test() (gas: 86331) Market_setNoriFeePercentage_revertsInvalidPercentage:test() (gas: 20254) Market_setPriorityRestrictedThreshold:test() (gas: 157403) Market_setPriorityRestrictedThreshold:test_zeroAvailable() (gas: 152378) Market_setPurchasingTokenAndPriceMultiple:test() (gas: 1026588) Market_setPurchasingTokenAndPriceMultiple_revertsIfNotAdmin:test() (gas: 50791) -Market_supplierSelectionUsingUpSuppliersLastRemoval:test() (gas: 920153) -Market_swapWithoutFeeSpecialOrder_emits_and_skips_transfer_when_transferring_wrong_erc20_to_rNori:test() (gas: 421070) -Market_swap_emits_and_skips_transfer_when_transferring_wrong_erc20_to_rNori:test() (gas: 521672) -Market_swap_emits_event_and_skips_mint_when_minting_rNori_to_nonERC1155Receiver:test() (gas: 598957) -Market_swap_revertsWhenUnsafeERC20TransferFails:test() (gas: 218819) +Market_supplierSelectionUsingUpSuppliersLastRemoval:test() (gas: 920087) +Market_swapWithoutFeeSpecialOrder_emits_and_skips_transfer_when_transferring_wrong_erc20_to_rNori:test() (gas: 421026) +Market_swap_emits_and_skips_transfer_when_transferring_wrong_erc20_to_rNori:test() (gas: 521628) +Market_swap_emits_event_and_skips_mint_when_minting_rNori_to_nonERC1155Receiver:test() (gas: 598913) +Market_swap_revertsWhenUnsafeERC20TransferFails:test() (gas: 218775) Market_validates_certificate_amount:test() (gas: 596888) Market_withdraw_1x3_center:test() (gas: 340858) Market_withdraw_2x1_back:test() (gas: 345518) @@ -120,30 +120,33 @@ RemovalQueue_insertRemovalByVintage:test_insertRemovalTwice() (gas: 121125) Removal__beforeTokenTransfer:test() (gas: 18010) Removal__beforeTokenTransfer:test_paused_reverts_Paused() (gas: 29432) Removal__createRemovalData:test() (gas: 22593) -Removal__createRemovalData:test_reverts_InvalidData() (gas: 25711) -Removal__createRemovalDataBatch:test() (gas: 29572) -Removal__createRemovalDataBatch:test_reverts_InvalidData2() (gas: 36714) -Removal__isValidTransferAmount:testFuzz_ReturnFalse_NonMultiplesOf1e14(uint256) (runs: 256, μ: 13891, ~: 13847) -Removal__isValidTransferAmount:testFuzz_ReturnTrue_MultiplesOf1e14(uint256) (runs: 256, μ: 14380, ~: 14497) +Removal__createRemovalData:test_reverts_InvalidData() (gas: 25689) +Removal__createRemovalDataBatch:test() (gas: 29550) +Removal__createRemovalDataBatch:test_reverts_InvalidData2() (gas: 36648) +Removal__isValidTransferAmount:testFuzz_ReturnFalse_NonMultiplesOf1e14(uint256) (runs: 256, μ: 13914, ~: 13870) +Removal__isValidTransferAmount:testFuzz_ReturnTrue_MultiplesOf1e14(uint256) (runs: 256, μ: 14375, ~: 14497) Removal__isValidTransferAmount:testFuzz_ReturnTrue_SmallestGranularity() (gas: 6832) Removal__isValidTransferAmount:test_ReturnFalse_AmountIsTooGranular() (gas: 6898) -Removal__isValidTransferAmount:test_ReturnFalse_AmountIsTooGranularAndToIsTheCertificate() (gas: 4745) -Removal__isValidTransferAmount:test_ReturnFalse_AmountIsTooGranularAndToIsTheMarket() (gas: 2608) +Removal__isValidTransferAmount:test_ReturnFalse_AmountIsTooGranularAndToIsTheCertificate() (gas: 4723) +Removal__isValidTransferAmount:test_ReturnFalse_AmountIsTooGranularAndToIsTheMarket() (gas: 2631) Removal__isValidTransferAmount:test_ReturnFalse_AmountIsZeroAndToIsTheCertificate() (gas: 4705) Removal__isValidTransferAmount:test_ReturnFalse_AmountIsZeroAndToIsTheMarket() (gas: 2521) Removal__isValidTransferAmount:test_ReturnTrue_AmountIsZeroAndToIsNeitherTheMarketNorCertificate() (gas: 6852) Removal__validateRemoval:test() (gas: 2491) -Removal__validateRemoval:test_reverts_InvalidData() (gas: 5373) +Removal__validateRemoval:test_reverts_InvalidData() (gas: 5351) Removal_addBalance:test() (gas: 60280) Removal_addBalance_reverts_RemovalNotYetMinted:test() (gas: 31115) Removal_batchGetHoldbackPercentages_multipleIds:test() (gas: 11098) Removal_batchGetHoldbackPercentages_singleId:test() (gas: 10346) -Removal_consign_revertsForSoldRemovals:test() (gas: 1172740) -Removal_getMarketBalance:test() (gas: 1185770) +Removal_consign_revertsForSoldRemovals:test() (gas: 1172630) +Removal_consignorBatchTransfer:test() (gas: 297281) +Removal_consignorBatchTransfer:test_reverts_whenReceiverIsNotConsignor() (gas: 128747) +Removal_consignorBatchTransfer:test_reverts_whenSenderIsNotConsignor() (gas: 65602) +Removal_getMarketBalance:test() (gas: 1185638) Removal_getOwnedTokenIds:test_multiple_tokens_with_transfer() (gas: 1078643) Removal_getOwnedTokenIds:test_no_tokens() (gas: 18683) Removal_getProjectId:test() (gas: 19307) -Removal_grantRole:test_reverts_when_paused() (gas: 26272) +Removal_grantRole:test_reverts_when_paused() (gas: 26250) Removal_migrate:test() (gas: 989116) Removal_migrate_gasLimit:test() (gas: 15359829) Removal_migrate_revertsIfRemovalBalanceSumDifferentFromCertificateAmount:test() (gas: 1002846) @@ -159,24 +162,23 @@ Removal_mintBatch_revertsInvalidHoldbackPercentage:test() (gas: 56204) Removal_mintBatch_reverts_mint_to_wrong_address:test() (gas: 89002) Removal_mintBatch_zero_amount_removal:test() (gas: 311185) Removal_mintBatch_zero_amount_removal_to_market_reverts:test() (gas: 85435) -Removal_multicall:test_balanceOfBatch() (gas: 492005) +Removal_multicall:test_balanceOfBatch() (gas: 491983) Removal_release_listed:test() (gas: 486531) Removal_release_listed_isRemovedFromMarket:test() (gas: 486885) Removal_release_partial_listed:test() (gas: 79637) -Removal_release_retired:test() (gas: 92425) -Removal_release_retired_2x:test() (gas: 98489) -Removal_release_retired_burned:test() (gas: 94905) +Removal_release_retired:test() (gas: 92513) +Removal_release_retired_2x:test() (gas: 98577) +Removal_release_retired_burned:test() (gas: 94993) Removal_release_retired_burned:testDecrementsCertificateDiscrepancy() (gas: 88947) -Removal_release_retired_oneHundredCertificates:test() (gas: 89535) +Removal_release_retired_oneHundredCertificates:test() (gas: 89623) Removal_release_reverts_AccessControl:test() (gas: 48757) Removal_release_unlisted:test() (gas: 48617) Removal_release_unlisted_listed_and_retired:test() (gas: 237568) -Removal_renounceRole:test_reverts_when_paused() (gas: 19688) +Removal_renounceRole:test_reverts_when_paused() (gas: 19666) Removal_revokeRole:test_reverts_when_paused() (gas: 26840) -Removal_safeBatchTransferFrom_reverts_ForbiddenTransfer:test() (gas: 32073) -Removal_safeTransferFrom_reverts_ForbiddenTransfer:test() (gas: 27738) -Removal_setHoldbackPercentage:test() (gas: 37877) -Removal_setHoldbackPercentage:test_reverts_InvalidHoldbackPercentage() (gas: 29163) +Removal_safeBatchTransferFrom:test_reverts_ForbiddenTransfer() (gas: 32007) +Removal_setHoldbackPercentage:test() (gas: 37811) +Removal_setHoldbackPercentage:test_reverts_InvalidHoldbackPercentage() (gas: 29119) RestrictedNORI__validateSchedule:test_startTimeNotZero() (gas: 269) RestrictedNORI__validateSchedule_reverts:test_restrictionDurationZero() (gas: 3362) RestrictedNORI__validateSchedule_reverts:test_startTimeZero() (gas: 3384) diff --git a/contracts/Removal.sol b/contracts/Removal.sol index 202da518..9ddcce96 100644 --- a/contracts/Removal.sol +++ b/contracts/Removal.sol @@ -649,12 +649,13 @@ contract Removal is } /** - * @notice Permissioned version of `safeTransferFrom`. + * @notice Allows an address with the `CONSIGNOR_ROLE` to transfer tokens. * @dev Emits a `TransferBatch` event. * * ##### Requirements: * * - Can only be called by an address with the `CONSIGNOR_ROLE`. + * - Respects the rules of `Removal._beforeTokenTransfer`. * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. diff --git a/docs/Removal.md b/docs/Removal.md index 28e4ec52..f980ff70 100644 --- a/docs/Removal.md +++ b/docs/Removal.md @@ -575,6 +575,32 @@ acceptance magic value. | data | bytes | The data to pass to the receiver contract. | +### consignorBatchTransfer + +```solidity +function consignorBatchTransfer(address from, address to, uint256[] ids, uint256[] amounts) public +``` + +Allows an address with the `CONSIGNOR_ROLE` to transfer tokens. + +Emits a `TransferBatch` event. + +##### Requirements: + +- Can only be called by an address with the `CONSIGNOR_ROLE`. +- Respects the rules of `Removal._beforeTokenTransfer`. +- `ids` and `amounts` must have the same length. +- If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the +acceptance magic value. + +| Name | Type | Description | +| ---- | ---- | ----------- | +| from | address | The address to transfer from. | +| to | address | The address to transfer to. | +| ids | uint256[] | The removal IDs to transfer. | +| amounts | uint256[] | The amounts of removals to transfer. | + + ### setApprovalForAll ```solidity