Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Retire on Removal.sol for direct retirement #733

Merged
merged 6 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 80 additions & 80 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,36 @@ 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)
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_callSummary() (runs: 400, calls: 6000, reverts: 4267)
MarketInvariantTest:invariant_sumOfPurchaseAmounts() (runs: 400, calls: 6000, reverts: 4261)
MarketSupplierSelectionNotUsingUpSuppliersLastRemoval:test() (gas: 923731)
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: 799239)
Market_USDC_swap_withholds_restricted_nori:test() (gas: 974402)
Market__addActiveRemoval:test() (gas: 183344)
Market__addActiveRemoval:test__lis2VintagesFor1SupplierFor2SubIdentifiers() (gas: 242901)
Market__addActiveRemoval:test__list1VintageFor1Supplier() (gas: 188309)
Expand All @@ -73,48 +73,48 @@ Market__validateSupply:test_reverts_OutOfSupply() (gas: 3194)
Market_calculates_prices_using_decimal:test() (gas: 66492)
Market_convertPurchasingTokenDecimalsToRemovalDecimals:test() (gas: 26029)
Market_convertRemovalDecimalsToPurchasingTokenDecimals:test() (gas: 29773)
Market_getActiveSuppliers:test_1_supplier() (gas: 610132)
Market_getActiveSuppliers:test_3_suppliers() (gas: 1262512)
Market_getActiveSuppliers:test_1_supplier() (gas: 610143)
Market_getActiveSuppliers:test_3_suppliers() (gas: 1262545)
Market_getActiveSuppliers:test_no_suppliers() (gas: 20837)
Market_getPriceMultiple:test() (gas: 14873)
Market_getRemovalIdsForSupplier:test_1_removal() (gas: 610557)
Market_getRemovalIdsForSupplier:test_3_removals() (gas: 993990)
Market_getRemovalIdsForSupplier:test_3_removals_different_vintages() (gas: 1040099)
Market_getRemovalIdsForSupplier:test_1_removal() (gas: 610568)
Market_getRemovalIdsForSupplier:test_3_removals() (gas: 994023)
Market_getRemovalIdsForSupplier:test_3_removals_different_vintages() (gas: 1040132)
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: 355477)
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: 345188)
Market_replace_reverts_CertificateNotYetMinted:test() (gas: 49559)
Market_replace_reverts_ReplacementAmountExceedsNrtDeficit:test() (gas: 52590)
Market_replace_reverts_ReplacementAmountMismatch:test() (gas: 86353)
Market_setNoriFeePercentage_revertsInvalidPercentage:test() (gas: 20254)
Market_setPriorityRestrictedThreshold:test() (gas: 157403)
Market_setPriorityRestrictedThreshold:test_zeroAvailable() (gas: 152378)
Market_setPriorityRestrictedThreshold:test() (gas: 157359)
Market_setPriorityRestrictedThreshold:test_zeroAvailable() (gas: 152334)
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_supplierSelectionUsingUpSuppliersLastRemoval:test() (gas: 920440)
Market_swapWithoutFeeSpecialOrder_emits_and_skips_transfer_when_transferring_wrong_erc20_to_rNori:test() (gas: 421170)
Market_swap_emits_and_skips_transfer_when_transferring_wrong_erc20_to_rNori:test() (gas: 521772)
Market_swap_emits_event_and_skips_mint_when_minting_rNori_to_nonERC1155Receiver:test() (gas: 599145)
Market_swap_revertsWhenUnsafeERC20TransferFails:test() (gas: 218819)
Market_validates_certificate_amount:test() (gas: 596888)
Market_withdraw_1x3_center:test() (gas: 340858)
Market_withdraw_2x1_back:test() (gas: 345518)
Market_withdraw_2x1_front:test() (gas: 333875)
Market_withdraw_2x1_front_relist:test() (gas: 381810)
Market_withdraw_as_DEFAULT_ADMIN_ROLE:test() (gas: 276568)
Market_withdraw_as_operator:test() (gas: 285735)
Market_withdraw_as_supplier:test() (gas: 274709)
Market_withdraw_reverts:test() (gas: 138753)
Market_withdraw_1x3_center:test() (gas: 340825)
Market_withdraw_2x1_back:test() (gas: 345485)
Market_withdraw_2x1_front:test() (gas: 333842)
Market_withdraw_2x1_front_relist:test() (gas: 381777)
Market_withdraw_as_DEFAULT_ADMIN_ROLE:test() (gas: 276535)
Market_withdraw_as_operator:test() (gas: 285702)
Market_withdraw_as_supplier:test() (gas: 274676)
Market_withdraw_reverts:test() (gas: 138709)
NORI_name:test() (gas: 17205)
NORI_permit:test() (gas: 92382)
NoriUSDC_permit:test() (gas: 122061)
RemovalQueue_getTotalBalanceFromRemovalQueue:test() (gas: 23899)
RemovalQueue_getTotalBalanceFromRemovalQueue:test_100xRemovalsOfTheDifferentVintages() (gas: 895786)
RemovalQueue_getTotalBalanceFromRemovalQueue:test_100xRemovalsOfTheSameVintage() (gas: 620299)
RemovalQueue_getTotalBalanceFromRemovalQueue:test() (gas: 23877)
RemovalQueue_getTotalBalanceFromRemovalQueue:test_100xRemovalsOfTheDifferentVintages() (gas: 895764)
RemovalQueue_getTotalBalanceFromRemovalQueue:test_100xRemovalsOfTheSameVintage() (gas: 620277)
RemovalQueue_insertRemovalByVintage:test_insertRemovalOnce() (gas: 119613)
RemovalQueue_insertRemovalByVintage:test_insertRemovalTwice() (gas: 121125)
Removal__beforeTokenTransfer:test() (gas: 18010)
Expand All @@ -124,68 +124,68 @@ 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__isValidTransferAmount:testFuzz_ReturnTrue_MultiplesOf1e14(uint256) (runs: 256, μ: 14369, ~: 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_AmountIsZeroAndToIsTheCertificate() (gas: 4705)
Removal__isValidTransferAmount:test_ReturnFalse_AmountIsZeroAndToIsTheCertificate() (gas: 4683)
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_addBalance:test() (gas: 60280)
Removal_addBalance_reverts_RemovalNotYetMinted:test() (gas: 31115)
Removal_addBalance:test() (gas: 60269)
Removal_addBalance_reverts_RemovalNotYetMinted:test() (gas: 31093)
Removal_batchGetHoldbackPercentages_multipleIds:test() (gas: 11098)
Removal_batchGetHoldbackPercentages_singleId:test() (gas: 10346)
Removal_consign_revertsForSoldRemovals:test() (gas: 1172740)
Removal_getMarketBalance:test() (gas: 1185770)
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_migrate:test() (gas: 989116)
Removal_migrate_gasLimit:test() (gas: 15359829)
Removal_migrate_revertsIfRemovalBalanceSumDifferentFromCertificateAmount:test() (gas: 1002846)
Removal_mintBatch:test() (gas: 348611)
Removal_mintBatch_list:test() (gas: 557922)
Removal_mintBatch_list_sequential:test() (gas: 749158)
Removal_mintBatch_multiple:test_16() (gas: 3083542)
Removal_mintBatch_multiple:test_2() (gas: 726249)
Removal_mintBatch_multiple:test_32() (gas: 5778699)
Removal_mintBatch_multiple:test_4() (gas: 1062966)
Removal_mintBatch_multiple:test_8() (gas: 1736405)
Removal_consign_revertsForSoldRemovals:test() (gas: 1172950)
Removal_getMarketBalance:test() (gas: 1185991)
Removal_getOwnedTokenIds:test_multiple_tokens_with_transfer() (gas: 1079154)
Removal_getOwnedTokenIds:test_no_tokens() (gas: 18772)
Removal_getProjectId:test() (gas: 19395)
Removal_grantRole:test_reverts_when_paused() (gas: 26250)
Removal_mintBatch:test() (gas: 348622)
Removal_mintBatch_list:test() (gas: 557933)
Removal_mintBatch_list_sequential:test() (gas: 749180)
Removal_mintBatch_multiple:test_16() (gas: 3083718)
Removal_mintBatch_multiple:test_2() (gas: 726271)
Removal_mintBatch_multiple:test_32() (gas: 5779051)
Removal_mintBatch_multiple:test_4() (gas: 1063010)
Removal_mintBatch_multiple:test_8() (gas: 1736493)
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:test() (gas: 311196)
Removal_mintBatch_zero_amount_removal_to_market_reverts:test() (gas: 85435)
Removal_multicall:test_balanceOfBatch() (gas: 492005)
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_burned:testDecrementsCertificateDiscrepancy() (gas: 88947)
Removal_release_retired_oneHundredCertificates:test() (gas: 89535)
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_multicall:test_balanceOfBatch() (gas: 491983)
Removal_release_listed:test() (gas: 486522)
Removal_release_listed_isRemovedFromMarket:test() (gas: 486876)
Removal_release_partial_listed:test() (gas: 79615)
Removal_release_retired:test() (gas: 92381)
Removal_release_retired_2x:test() (gas: 98467)
Removal_release_retired_burned:test() (gas: 94861)
Removal_release_retired_burned:testDecrementsCertificateDiscrepancy() (gas: 88925)
Removal_release_retired_oneHundredCertificates:test() (gas: 89491)
Removal_release_reverts_AccessControl:test() (gas: 48735)
Removal_release_unlisted:test() (gas: 48600)
Removal_release_unlisted_listed_and_retired:test() (gas: 237533)
Removal_renounceRole:test_reverts_when_paused() (gas: 19666)
Removal_retire:test() (gas: 989180)
Removal_retire_gasLimit:test() (gas: 15361939)
Removal_retire_revertsIfRemovalBalanceSumDifferentFromCertificateAmount:test() (gas: 1002910)
Removal_revokeRole:test_reverts_when_paused() (gas: 26840)
Removal_safeBatchTransferFrom_reverts_ForbiddenTransfer:test() (gas: 32073)
Removal_safeBatchTransferFrom_reverts_ForbiddenTransfer:test() (gas: 32162)
Removal_safeTransferFrom_reverts_ForbiddenTransfer:test() (gas: 27738)
Removal_setHoldbackPercentage:test() (gas: 37877)
Removal_setHoldbackPercentage:test_reverts_InvalidHoldbackPercentage() (gas: 29163)
RestrictedNORI__validateSchedule:test_startTimeNotZero() (gas: 269)
RestrictedNORI__validateSchedule_reverts:test_restrictionDurationZero() (gas: 3362)
RestrictedNORI__validateSchedule_reverts:test_startTimeZero() (gas: 3384)
RestrictedNORI_createSchedule:test_RevertWhen_MethodologyVersionHasNoDurationSet() (gas: 26650)
RestrictedNORI_createSchedule:test_RevertWhen_ScheduleExists() (gas: 43800)
RestrictedNORI_createSchedule:test_RevertWhen_ScheduleExists() (gas: 43888)
RestrictedNORI_getUnderlyingTokenAddress:test() (gas: 17124)
RestrictedNORI_initialize:test() (gas: 21827)
RestrictedNORI_linearReleaseAmountAvailable:test() (gas: 11920)
RestrictedNORI_revokeUnreleasedTokens:test() (gas: 246318)
RestrictedNORI_revokeUnreleasedTokens:test() (gas: 246406)
RestrictedNORI_scheduleExists:test() (gas: 15177)
RestrictedNORI_scheduleExists:test_doesntExist() (gas: 15156)
RestrictedNORI_transfers_revert:testSafeBatchTransferFromReverts() (gas: 29158)
Expand Down
31 changes: 23 additions & 8 deletions contracts/Removal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,22 @@ contract Removal is
uint256[] removalAmounts
);

/**
* @notice Emitted when removals are directly retired into a certificate by Nori.
* @param certificateRecipient The recipient of the certificate.
* @param certificateAmount The total amount of the certificate to mint (denominated in RTs).
* @param certificateId The ID of the certificate being minted.
* @param removalIds The removal IDs to use to mint the certificate.
* @param removalAmounts The amounts to retire from each corresponding removal ID.
*/
event Retire(
address indexed certificateRecipient,
uint256 indexed certificateAmount,
uint256 indexed certificateId,
uint256[] removalIds,
uint256[] removalAmounts
);

/**
* @notice Locks the contract, preventing any future re-initialization.
* @dev See more [here](https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--).
Expand Down Expand Up @@ -381,19 +397,18 @@ contract Removal is

/**
* @notice Transfers the provided `amounts` (denominated in NRTs) of the specified removal `ids` directly to the
* Certificate contract to mint a legacy certificate. This function provides Nori the ability to execute a one-off
* migration of legacy certificates and removals (legacy certificates and removals are those which existed prior to
* our deployment to Polygon and covers all historic issuances and purchases up until the date that we start using the
* Market contract).
* Certificate contract to mint a certificate. This function provides Nori the ability to retire removals directly
* into the Certificate contract and to specify exactly which removals will be retired.
* @dev The Certificate contract implements `onERC1155BatchReceived`, which is invoked upon receipt of a batch of
* removals (triggered via `_safeBatchTransferFrom`). This function circumvents the market contract's lifecycle by
* removals (triggered via `_safeBatchTransferFrom`). This function circumvents the market contract by
* transferring the removals from an account with the `CONSIGNOR_ROLE` role.
* Emits a `Retire` event.
*
* It is necessary that the consignor holds the removals because of the following:
* - `ids` can be composed of a list of removal IDs that belong to one or more suppliers.
* - `_safeBatchTransferFrom` only accepts one `from` address.
* - `Certificate.onERC1155BatchReceived` will mint a *new* certificate every time an additional batch is received, so
* we must ensure that all the removals comprising the certificate to be migrated come from a single batch.
* we must ensure that all the removals comprising the certificate come from a single batch.
*
* ##### Requirements:
* - The caller must have the `CONSIGNOR_ROLE` role.
Expand All @@ -407,13 +422,13 @@ contract Removal is
* @param certificateRecipient The recipient of the certificate to be minted.
* @param certificateAmount The total amount of the certificate.
*/
function migrate(
function retire(
uint256[] calldata ids,
uint256[] calldata amounts,
address certificateRecipient,
uint256 certificateAmount
) external onlyRole(CONSIGNOR_ROLE) {
emit Migrate({
emit Retire({
certificateRecipient: certificateRecipient,
certificateAmount: certificateAmount,
certificateId: _certificate.totalMinted(),
Expand Down
Loading
Loading