From 059f76d2aeac36cadb90e1fe421b41872f5a5c88 Mon Sep 17 00:00:00 2001 From: Hamza Benhmani Date: Tue, 6 Jun 2023 18:47:46 -0400 Subject: [PATCH] DEPRECATE Operator filters have been proven to be easily circumvented, go against principles of ownership and decentralization, and increase gas costs for the entire network. --- .gas-snapshot | 162 --- .github/workflows/publish.yaml | 18 - .github/workflows/test.yml | 34 - .prettierrc | 5 - LICENSE | 7 - README.md | 254 +--- .../OpenSea Operator Filteer Audit Report.pdf | Bin 411261 -> 0 bytes foundry.toml | 18 - lib/ds-test | 1 - lib/forge-std | 1 - lib/openzeppelin-contracts | 1 - lib/openzeppelin-contracts-upgradeable | 1 - package.json | 18 - sample.env | 4 - script/ConfigureOwnedRegistrant.s.sol | 28 - script/ConfigureOwnedRegistry.s.sol | 45 - .../DeployAndConfigureOwnedRegistrant.s.sol | 23 - script/DeployRegistry.s.sol | 18 - script/DeployRegistryAndRegistrant.s.sol | 34 - script/ScriptBase.sol | 33 - script/cast-deploy.sh | 19 - ...eratorFilterRegistryStandardJsonInput.json | 1075 ----------------- .../OwnedRegistrantStandardJsonInput.json | 1 - script/verification/README.md | 5 - src/DefaultOperatorFilterer.sol | 17 - src/IOperatorFilterRegistry.sol | 139 --- src/OperatorFilterRegistry.sol | 560 --------- src/OperatorFilterRegistryErrorsAndEvents.sol | 76 -- src/OperatorFilterer.sol | 77 -- src/OwnedRegistrant.sol | 19 - src/RevokableDefaultOperatorFilterer.sol | 18 - src/RevokableOperatorFilterer.sol | 71 -- src/UpdatableOperatorFilterer.sol | 100 -- src/example/ExampleERC1155.sol | 58 - src/example/ExampleERC721.sol | 68 -- src/example/RevokableExampleERC1155.sol | 67 - src/example/RevokableExampleERC721.sol | 82 -- .../upgradeable/ExampleERC1155Upgradeable.sol | 78 -- .../upgradeable/ExampleERC721Upgradeable.sol | 88 -- .../RevokableExampleERC1155Upgradeable.sol | 93 -- .../RevokableExampleERC721Upgradeable.sol | 103 -- .../UpdatableExampleERC721Upgradeable.sol | 61 - src/lib/Constants.sol | 5 - .../DefaultOperatorFiltererUpgradeable.sol | 17 - .../OperatorFiltererUpgradeable.sol | 80 -- ...ableDefaultOperatorFiltererUpgradeable.sol | 19 - .../RevokableOperatorFiltererUpgradeable.sol | 88 -- .../UpdatableOperatorFiltererUpgradeable.sol | 128 -- test/BaseRegistryTest.sol | 14 - test/DefaultOperatorFilterer.t.sol | 55 - test/OperatorFilterRegistry.t.sol | 864 ------------- test/OperatorFilterer.t.sol | 93 -- test/OwnedRegistrant.t.sol | 28 - test/RevokableDefaultOperatorFilterer.t.sol | 74 -- test/RevokableOperatorFilterer.t.sol | 135 --- test/UpdatableOperatorFilterer.t.sol | 125 -- test/example/ExampleERC1155.t.sol | 107 -- test/example/ExampleERC721.t.sol | 105 -- test/example/RevokableERC1155.t.sol | 123 -- test/example/RevokableERC721.t.sol | 121 -- .../ExampleERC1155Upgradeable.t.sol | 118 -- .../ExampleERC721Upgradeable.t.sol | 116 -- .../RevokableExampleERC1155Upgradeable.t.sol | 135 --- .../RevokableExampleERC721Upgradeable.t.sol | 132 -- .../UpdatableExampleERC721Upgradeable.t.sol | 272 ----- test/helpers/DefaultFilterer.sol | 12 - test/helpers/Filterer.sol | 17 - test/helpers/OperatorFilterRegistryStub.sol | 10 - test/helpers/RevokableDefaultFilterer.sol | 20 - test/helpers/RevokableFilterer.sol | 19 - test/helpers/RevokableUpgradeableFilterer.sol | 25 - test/helpers/UpdatableFilterer.sol | 21 - test/helpers/UpgradeableFilterer.sol | 21 - ...RevokableUpgradeableOperatorFilterer.t.sol | 43 - .../UpgradeableOperatorFilterer.t.sol | 37 - .../validation/ExampleERC1155Validation.t.sol | 24 - test/validation/ExampleERC721Validation.t.sol | 24 - test/validation/Validation.t.sol | 220 ---- yarn.lock | 13 - 79 files changed, 2 insertions(+), 7038 deletions(-) delete mode 100644 .gas-snapshot delete mode 100644 .github/workflows/publish.yaml delete mode 100644 .github/workflows/test.yml delete mode 100644 .prettierrc delete mode 100644 LICENSE delete mode 100644 audit/OpenSea Operator Filteer Audit Report.pdf delete mode 100644 foundry.toml delete mode 160000 lib/ds-test delete mode 160000 lib/forge-std delete mode 160000 lib/openzeppelin-contracts delete mode 160000 lib/openzeppelin-contracts-upgradeable delete mode 100644 package.json delete mode 100644 sample.env delete mode 100644 script/ConfigureOwnedRegistrant.s.sol delete mode 100644 script/ConfigureOwnedRegistry.s.sol delete mode 100644 script/DeployAndConfigureOwnedRegistrant.s.sol delete mode 100644 script/DeployRegistry.s.sol delete mode 100644 script/DeployRegistryAndRegistrant.s.sol delete mode 100644 script/ScriptBase.sol delete mode 100644 script/cast-deploy.sh delete mode 100644 script/verification/OperatorFilterRegistryStandardJsonInput.json delete mode 100644 script/verification/OwnedRegistrantStandardJsonInput.json delete mode 100644 script/verification/README.md delete mode 100644 src/DefaultOperatorFilterer.sol delete mode 100644 src/IOperatorFilterRegistry.sol delete mode 100644 src/OperatorFilterRegistry.sol delete mode 100644 src/OperatorFilterRegistryErrorsAndEvents.sol delete mode 100644 src/OperatorFilterer.sol delete mode 100644 src/OwnedRegistrant.sol delete mode 100644 src/RevokableDefaultOperatorFilterer.sol delete mode 100644 src/RevokableOperatorFilterer.sol delete mode 100644 src/UpdatableOperatorFilterer.sol delete mode 100644 src/example/ExampleERC1155.sol delete mode 100644 src/example/ExampleERC721.sol delete mode 100644 src/example/RevokableExampleERC1155.sol delete mode 100644 src/example/RevokableExampleERC721.sol delete mode 100644 src/example/upgradeable/ExampleERC1155Upgradeable.sol delete mode 100644 src/example/upgradeable/ExampleERC721Upgradeable.sol delete mode 100644 src/example/upgradeable/RevokableExampleERC1155Upgradeable.sol delete mode 100644 src/example/upgradeable/RevokableExampleERC721Upgradeable.sol delete mode 100644 src/example/upgradeable/UpdatableExampleERC721Upgradeable.sol delete mode 100644 src/lib/Constants.sol delete mode 100644 src/upgradeable/DefaultOperatorFiltererUpgradeable.sol delete mode 100644 src/upgradeable/OperatorFiltererUpgradeable.sol delete mode 100644 src/upgradeable/RevokableDefaultOperatorFiltererUpgradeable.sol delete mode 100644 src/upgradeable/RevokableOperatorFiltererUpgradeable.sol delete mode 100644 src/upgradeable/UpdatableOperatorFiltererUpgradeable.sol delete mode 100644 test/BaseRegistryTest.sol delete mode 100644 test/DefaultOperatorFilterer.t.sol delete mode 100644 test/OperatorFilterRegistry.t.sol delete mode 100644 test/OperatorFilterer.t.sol delete mode 100644 test/OwnedRegistrant.t.sol delete mode 100644 test/RevokableDefaultOperatorFilterer.t.sol delete mode 100644 test/RevokableOperatorFilterer.t.sol delete mode 100644 test/UpdatableOperatorFilterer.t.sol delete mode 100644 test/example/ExampleERC1155.t.sol delete mode 100644 test/example/ExampleERC721.t.sol delete mode 100644 test/example/RevokableERC1155.t.sol delete mode 100644 test/example/RevokableERC721.t.sol delete mode 100644 test/example/upgradeable/ExampleERC1155Upgradeable.t.sol delete mode 100644 test/example/upgradeable/ExampleERC721Upgradeable.t.sol delete mode 100644 test/example/upgradeable/RevokableExampleERC1155Upgradeable.t.sol delete mode 100644 test/example/upgradeable/RevokableExampleERC721Upgradeable.t.sol delete mode 100644 test/example/upgradeable/UpdatableExampleERC721Upgradeable.t.sol delete mode 100644 test/helpers/DefaultFilterer.sol delete mode 100644 test/helpers/Filterer.sol delete mode 100644 test/helpers/OperatorFilterRegistryStub.sol delete mode 100644 test/helpers/RevokableDefaultFilterer.sol delete mode 100644 test/helpers/RevokableFilterer.sol delete mode 100644 test/helpers/RevokableUpgradeableFilterer.sol delete mode 100644 test/helpers/UpdatableFilterer.sol delete mode 100644 test/helpers/UpgradeableFilterer.sol delete mode 100644 test/upgradeable/RevokableUpgradeableOperatorFilterer.t.sol delete mode 100644 test/upgradeable/UpgradeableOperatorFilterer.t.sol delete mode 100644 test/validation/ExampleERC1155Validation.t.sol delete mode 100644 test/validation/ExampleERC721Validation.t.sol delete mode 100644 test/validation/Validation.t.sol delete mode 100644 yarn.lock diff --git a/.gas-snapshot b/.gas-snapshot deleted file mode 100644 index 3469cf2..0000000 --- a/.gas-snapshot +++ /dev/null @@ -1,162 +0,0 @@ -DefaultOperatorFiltererTest:testFilter() (gas: 41235) -OperatorFilterRegistryTest:testCodeHashOf() (gas: 8478) -OperatorFilterRegistryTest:testCopyEntriesOf() (gas: 562154) -OperatorFilterRegistryTest:testCopyEntriesOf_CannotUpdateWhileSubscribed() (gas: 270730) -OperatorFilterRegistryTest:testCopyEntriesOf_NotRegistered() (gas: 10834) -OperatorFilterRegistryTest:testCopyEntriesOf_NotRegistered_registrant() (gas: 35705) -OperatorFilterRegistryTest:testCopyEntriesOf_OnlyAddressOrOwner() (gas: 67577) -OperatorFilterRegistryTest:testCopyEntriesOf_cannotCopySelf() (gas: 31131) -OperatorFilterRegistryTest:testFilteredCodeHashAt_subscription() (gas: 199760) -OperatorFilterRegistryTest:testFilteredCodeHashes_subscription() (gas: 204697) -OperatorFilterRegistryTest:testFilteredOperatorAt_subscription() (gas: 199132) -OperatorFilterRegistryTest:testFilteredOperators_subscription() (gas: 204146) -OperatorFilterRegistryTest:testIsCodeHashFiltered_subscription() (gas: 203085) -OperatorFilterRegistryTest:testIsCodeHashOfFiltered() (gas: 111402) -OperatorFilterRegistryTest:testIsCodeHashOfFiltered_subscription() (gas: 207503) -OperatorFilterRegistryTest:testIsOperatorAllowed() (gas: 188726) -OperatorFilterRegistryTest:testIsOperatorAllowed_NotRegistered() (gas: 9988) -OperatorFilterRegistryTest:testIsOperatorAllowed_subscription() (gas: 284810) -OperatorFilterRegistryTest:testIsOperatorFiltered_subscription() (gas: 204184) -OperatorFilterRegistryTest:testIsRegistered() (gas: 35586) -OperatorFilterRegistryTest:testOnlyAddressOrOwner() (gas: 24488) -OperatorFilterRegistryTest:testRegisterAndCopyEntries() (gas: 337400) -OperatorFilterRegistryTest:testRegisterAndCopyEntries_AlreadyRegistered() (gas: 33298) -OperatorFilterRegistryTest:testRegisterAndCopyEntries_CannotCopyFromSelf() (gas: 31534) -OperatorFilterRegistryTest:testRegisterAndCopyEntries_NotRegistered() (gas: 14558) -OperatorFilterRegistryTest:testRegisterAndCopyEntries_OnlyAddressOrOwner() (gas: 16140) -OperatorFilterRegistryTest:testRegisterAndSubscribe() (gas: 135937) -OperatorFilterRegistryTest:testRegisterAndSubscribe_AlreadyRegistered() (gas: 33219) -OperatorFilterRegistryTest:testRegisterAndSubscribe_CannotRegisterToSelf() (gas: 9081) -OperatorFilterRegistryTest:testRegisterAndSubscribe_CannotSubscribeToRegistrantWithSubscription() (gas: 131752) -OperatorFilterRegistryTest:testRegisterAndSubscribe_NotRegistered() (gas: 14537) -OperatorFilterRegistryTest:testRegisterAndSubscribe_OnlyAddressOrOwner() (gas: 17628) -OperatorFilterRegistryTest:testRegister_alreadyRegistered() (gas: 31593) -OperatorFilterRegistryTest:testRegister_constructor() (gas: 38270) -OperatorFilterRegistryTest:testRegister_onlyAddressOrOwner() (gas: 16035) -OperatorFilterRegistryTest:testSubscribe() (gas: 136406) -OperatorFilterRegistryTest:testSubscribe_AlreadySubscribed() (gas: 128950) -OperatorFilterRegistryTest:testSubscribe_CannotSubscribeToRegistrantWithSubscription() (gas: 154402) -OperatorFilterRegistryTest:testSubscribe_CannotSubscribeToSelf() (gas: 31487) -OperatorFilterRegistryTest:testSubscribe_CannotSubscribeToZeroAddress() (gas: 31485) -OperatorFilterRegistryTest:testSubscribe_OnlyAddressOrOwner() (gas: 42598) -OperatorFilterRegistryTest:testSubscribe_SubscriptionNotRegistered() (gas: 35670) -OperatorFilterRegistryTest:testSubscribe_notRegistered() (gas: 35820) -OperatorFilterRegistryTest:testSubscribe_removeOldSubscription() (gas: 188416) -OperatorFilterRegistryTest:testSubscriptionOf_notRegistered() (gas: 9132) -OperatorFilterRegistryTest:testUnregister() (gas: 107634) -OperatorFilterRegistryTest:testUnsubscribe() (gas: 106169) -OperatorFilterRegistryTest:testUnsubscribe_NotRegistered() (gas: 9199) -OperatorFilterRegistryTest:testUnsubscribe_NotSubscribed() (gas: 31689) -OperatorFilterRegistryTest:testUnsubscribe_copyExistingEntries() (gas: 360792) -OperatorFilterRegistryTest:testUnsubscribe_notRegistered() (gas: 9047) -OperatorFilterRegistryTest:testUnsubscribe_onlyAddressOrOwner() (gas: 137734) -OperatorFilterRegistryTest:testUpdateCodeHash() (gas: 105160) -OperatorFilterRegistryTest:testUpdateCodeHash_CannotFilterEOAs() (gas: 31509) -OperatorFilterRegistryTest:testUpdateCodeHash_CannotUpdateWhileSubscribed() (gas: 127621) -OperatorFilterRegistryTest:testUpdateCodeHash_CodeHashAlreadyFiltered() (gas: 102221) -OperatorFilterRegistryTest:testUpdateCodeHash_CodeHashNotFiltered() (gas: 34307) -OperatorFilterRegistryTest:testUpdateCodeHash_NotRegistered() (gas: 9275) -OperatorFilterRegistryTest:testUpdateCodeHash_OnlyAddressOrOwner() (gas: 16062) -OperatorFilterRegistryTest:testUpdateCodeHash_unfilter() (gas: 83437) -OperatorFilterRegistryTest:testUpdateCodeHashes() (gas: 149999) -OperatorFilterRegistryTest:testUpdateCodeHashes_CannotFilterEOAs() (gas: 99404) -OperatorFilterRegistryTest:testUpdateCodeHashes_CannotUpdateWhileSubscribed() (gas: 128538) -OperatorFilterRegistryTest:testUpdateCodeHashes_CodeHashAlreadyFiltered() (gas: 151240) -OperatorFilterRegistryTest:testUpdateCodeHashes_CodeHashNotFiltered() (gas: 35306) -OperatorFilterRegistryTest:testUpdateCodeHashes_OnlyAddressOrOwner() (gas: 16804) -OperatorFilterRegistryTest:testUpdateCodeHashes_notRegistered() (gas: 10043) -OperatorFilterRegistryTest:testUpdateCodeHashes_unfilter() (gas: 127162) -OperatorFilterRegistryTest:testUpdateOperator() (gas: 111558) -OperatorFilterRegistryTest:testUpdateOperator_AddressAlreadyFiltered() (gas: 107110) -OperatorFilterRegistryTest:testUpdateOperator_AddressNotFiltered() (gas: 37525) -OperatorFilterRegistryTest:testUpdateOperator_CannotUpdateWhileSubscribed() (gas: 129249) -OperatorFilterRegistryTest:testUpdateOperator_OnlyAddressOrOwner() (gas: 17746) -OperatorFilterRegistryTest:testUpdateOperator_notRegistered() (gas: 10892) -OperatorFilterRegistryTest:testUpdateOperator_unfilter() (gas: 88638) -OperatorFilterRegistryTest:testUpdateOperators() (gas: 160186) -OperatorFilterRegistryTest:testUpdateOperators_AddressAlreadyFiltered() (gas: 159298) -OperatorFilterRegistryTest:testUpdateOperators_AddressNotFiltered() (gas: 40093) -OperatorFilterRegistryTest:testUpdateOperators_CannotUpdateWhileSubscribed() (gas: 131638) -OperatorFilterRegistryTest:testUpdateOperators_OnlyAddressOrOwner() (gas: 18329) -OperatorFilterRegistryTest:testUpdateOperators_notRegistered() (gas: 13185) -OperatorFilterRegistryTest:testUpdateOperators_unfilter() (gas: 132844) -OperatorFiltererTest:testConstructor_copy() (gas: 257763) -OperatorFiltererTest:testConstructor_subscribe() (gas: 177081) -OperatorFiltererTest:testConstructory_noSubscribeOrCopy() (gas: 326674) -OperatorFiltererTest:testFilter() (gas: 41303) -OperatorFiltererTest:testRegistryNotDeployedDoesNotRevert() (gas: 298447) -OperatorFiltererTest:testConstructor() (gas: 87006) -RevokableDefaultOperatorFiltererTest:testFilter() (gas: 44167) -RevokableDefaultOperatorFiltererTest:testRevoke() (gas: 38568) -RevokableOperatorFiltererTest:testConstructor_copy() (gas: 445192) -RevokableOperatorFiltererTest:testConstructor_revertOnZeroAddress() (gas: 43436) -RevokableOperatorFiltererTest:testConstructor_subscribe() (gas: 364511) -RevokableOperatorFiltererTest:testConstructory_noSubscribeOrCopy() (gas: 495785) -RevokableOperatorFiltererTest:testFilter() (gas: 44230) -RevokableOperatorFiltererTest:testRegistryNotDeployedDoesNotRevert() (gas: 467790) -RevokableOperatorFiltererTest:testUpdateRegistry() (gas: 17738) -RevokableOperatorFiltererTest:testUpdateRegistry_onlyOwner() (gas: 12749) -RevokableOperatorFiltererTest:testZeroAddressBypass() (gas: 38854) -UpdatableOperatorFiltererTest:testConstructor_copy() (gas: 361762) -UpdatableOperatorFiltererTest:testConstructor_subscribe() (gas: 281131) -UpdatableOperatorFiltererTest:testConstructory_noSubscribeOrCopy() (gas: 405697) -UpdatableOperatorFiltererTest:testFilter() (gas: 43767) -UpdatableOperatorFiltererTest:testRegistryNotDeployedDoesNotRevert() (gas: 377615) -UpdatableOperatorFiltererTest:testUpdateRegistry() (gas: 17623) -UpdatableOperatorFiltererTest:testUpdateRegistry_onlyOwner() (gas: 12749) -UpdatableOperatorFiltererTest:testZeroAddressBypass() (gas: 27363) -ExampleERC1155Test:testExcludeApprovals() (gas: 99392) -ExampleERC1155Test:testExclusionExceptionDoesNotApplyToOperators() (gas: 131242) -ExampleERC1155Test:testFilter() (gas: 38329) -ExampleERC1155Test:testOwnersNotExcluded() (gas: 105862) -ExampleERC1155Test:testOwnersNotExcludedBatch() (gas: 109044) -ExampleERC721Test:testExcludeApprovals() (gas: 123377) -ExampleERC721Test:testExclusionExceptionDoesNotApplyToOperators() (gas: 149528) -ExampleERC721Test:testFilter() (gas: 48826) -ExampleERC721Test:testOwnersNotExcluded() (gas: 123566) -ExampleERC721Test:testOwnersNotExcludedSafeTransfer() (gas: 161425) -RevokeExampleERC1155Test:testExcludeApprovals() (gas: 101694) -RevokeExampleERC1155Test:testExclusionExceptionDoesNotApplyToOperators() (gas: 133903) -RevokeExampleERC1155Test:testFilter() (gas: 42998) -RevokeExampleERC1155Test:testOwnersNotExcluded() (gas: 105840) -RevokeExampleERC1155Test:testOwnersNotExcludedBatch() (gas: 109089) -RevokeExampleERC1155Test:testRevoke() (gas: 139822) -RevokableExampleERC721Test:testExcludeApprovals() (gas: 127957) -RevokableExampleERC721Test:testExclusionExceptionDoesNotApplyToOperators() (gas: 152232) -RevokableExampleERC721Test:testFilter() (gas: 55752) -RevokableExampleERC721Test:testOwnersNotExcluded() (gas: 123588) -RevokableExampleERC721Test:testOwnersNotExcludedSafeTransfer() (gas: 161360) -RevokableExampleERC721Test:testRevoke() (gas: 160542) -ExampleER1155UpgradeableTest:testExcludeApprovals() (gas: 99399) -ExampleER1155UpgradeableTest:testExclusionExceptionDoesNotApplyToOperators() (gas: 131327) -ExampleER1155UpgradeableTest:testFilter() (gas: 38423) -ExampleER1155UpgradeableTest:testOwnersNotExcluded() (gas: 106035) -ExampleER1155UpgradeableTest:testOwnersNotExcludedBatch() (gas: 109258) -ExampleER1155UpgradeableTest:testUpgradeable() (gas: 2381586) -ExampleERC721UpgradeableTest:testExcludeApprovals() (gas: 123377) -ExampleERC721UpgradeableTest:testExclusionExceptionDoesNotApplyToOperators() (gas: 149610) -ExampleERC721UpgradeableTest:testFilter() (gas: 48945) -ExampleERC721UpgradeableTest:testOwnersNotExcluded() (gas: 123730) -ExampleERC721UpgradeableTest:testOwnersNotExcludedSafeTransfer() (gas: 161952) -ExampleERC721UpgradeableTest:testUpgradeable() (gas: 2482571) -RevokableExampleER1155UpgradeableTest:testExcludeApprovals() (gas: 101609) -RevokableExampleER1155UpgradeableTest:testExclusionExceptionDoesNotApplyToOperators() (gas: 133680) -RevokableExampleER1155UpgradeableTest:testFilter() (gas: 42687) -RevokableExampleER1155UpgradeableTest:testOwnersNotExcluded() (gas: 108222) -RevokableExampleER1155UpgradeableTest:testOwnersNotExcludedBatch() (gas: 111424) -RevokableExampleER1155UpgradeableTest:testRevoke() (gas: 142611) -RevokableExampleER1155UpgradeableTest:testUpgradeable() (gas: 2457993) -ExampleERC721UpgradeableTest:testExcludeApprovals() (gas: 127663) -ExampleERC721UpgradeableTest:testExclusionExceptionDoesNotApplyToOperators() (gas: 151962) -ExampleERC721UpgradeableTest:testFilter() (gas: 55397) -ExampleERC721UpgradeableTest:testOwnersNotExcluded() (gas: 125939) -ExampleERC721UpgradeableTest:testOwnersNotExcludedSafeTransfer() (gas: 164361) -ExampleERC721UpgradeableTest:testRevoke() (gas: 163227) -ExampleERC721UpgradeableTest:testUpgradeable() (gas: 2568242) -Filterer:testFilter(address):(bool) (runs: 256, μ: 2952, ~: 3004) -ExampleERC1155ValidationTest:testERC1155() (gas: 149946) -ExampleERC1155ValidationTest:testERC721() (gas: 82135) -ExampleERC721ValidationTest:testERC1155() (gas: 76558) -ExampleERC721ValidationTest:testERC721() (gas: 219006) -ValidationTest:testERC1155() (gas: 77094) -ValidationTest:testERC721() (gas: 230959) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml deleted file mode 100644 index 225f0b3..0000000 --- a/.github/workflows/publish.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: Publish Package to npmjs -on: - release: - types: [created] -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: "16.x" - registry-url: "https://registry.npmjs.org" - - run: grep -RiIln 'openzeppelin-contracts' src | xargs sed -i 's/openzeppelin\-contracts/@openzeppelin\/contracts/g' - - run: yarn - - run: npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index a7ee20c..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: test - -on: [push, pull_request] - -env: - FOUNDRY_PROFILE: ci - -jobs: - check: - strategy: - fail-fast: true - - name: Foundry project - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Run Forge build - run: | - forge --version - forge build --sizes - id: build - - - name: Run Forge tests - run: | - forge test -vvv - id: test diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 884f11c..0000000 --- a/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "tabWidth": 4, - "printWidth": 120, - "bracketSpacing": false -} diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8d4b8ca..0000000 --- a/LICENSE +++ /dev/null @@ -1,7 +0,0 @@ -Copyright 2022 Ozone Networks, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 1b74f33..3ad3995 100644 --- a/README.md +++ b/README.md @@ -1,255 +1,5 @@ # Operator Filter Registry -## Introduction +## DEPRECATED -This repository contains a number of tools to help token contracts manage the operators allowed to transfer tokens on behalf of users - including the smart contracts and delegates of marketplaces that do not respect creator earnings. - -This is not a foolproof approach - but it makes bypassing creator earnings less liquid and easy at scale. - -## How it works - -Token smart contracts may register themselves (or be registered by their "owner") with the `OperatorFilterRegistry`. Token contracts or their "owner"s may then curate lists of operators (specific account addresses) and codehashes (smart contracts deployed with the same code) that should not be allowed to transfer tokens on behalf of users. - -## Creator Earnings Enforcement - -OpenSea will enforce creator earnings for smart contracts that make best efforts to filter transfers from operators known to not respect creator earnings. - -This repository facilitates that process by providing smart contracts that interface with the registry automatically, including automatically subscribing to OpenSea's list of filtered operators. - -When filtering operators, use of this registry is not required, nor is it required for a token contract to "subscribe" to OpenSea's list within this registry. Subscriptions can be changed or removed at any time. Filtered operators and codehashes may likewise be added or removed at any time. - -Contract owners may implement their own filtering outside of this registry, or they may use this registry to curate their own lists of filtered operators. However, there are certain contracts that are filtered by the default subscription, and must be filtered in order to be eligible for creator earnings enforcement on OpenSea. - -## Note on [EIP-2981](https://eips.ethereum.org/EIPS/eip-2981) - -Implementing EIP-2981 is not sufficient for a token to be eligible for creator earnings on OpenSea. - -While sometimes described as "on-chain," EIP-2981 only provides a method to determine what the appropriate creator earnings should be for a sale. EIP-2981 does not provide any mechanism of on-chain enforcement of those earnings. - -## Filtered addresses - -Entries in this list are added according to the following criteria: - -- If the application most commonly used to interface with the contract gives buyers and sellers the ability to bypass creator earnings when a similar transaction for the same item would require creator earnings payment on OpenSea.io -- If the contract is facilitating the evasion of on-chain creator earnings enforcement measures. For example, the contract uses a wrapper contract to bypass earnings enforcement. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameAddressNetwork
LooksRare TransferManagerERC7210xf42aa99F011A1fA7CDA90E5E98b277E306BcA83eEthereum Mainnet
LooksRare TransferManagerERC11550xFED24eC7E22f573c2e08AEF55aA6797Ca2b3A051Ethereum Mainnet
SudoSwap LSSVMPairEnumerableERC200xD42638863462d2F21bb7D4275d7637eE5d5541eBEthereum Mainnet
SudoSwap LSSVMPairEnumerableETH0x08CE97807A81896E85841d74FB7E7B065ab3ef05Ethereum Mainnet
SudoSwap LSSVMPairMissingEnumerableERC200x92de3a1511EF22AbCf3526c302159882a4755B22Ethereum Mainnet
SudoSwap LSSVMPairMissingEnumerableETH0xCd80C916B1194beB48aBF007D0b79a7238436D56Ethereum Mainnet
SudoSwap LSSVMPairFactory0xb16c1342E617A5B6E4b631EB114483FDB289c0A4Ethereum Mainnet
NFTX NFTXMarketplaceZap0x0fc584529a2aefa997697fafacba5831fac0c22dEthereum Mainnet
Looksrare V2 TransferManager0x000000000060C4Ca14CfC4325359062ace33Fe3DEthereum Mainnet
- -## Deployments - -## Usage - -Token contracts that wish to manage lists of filtered operators and restrict transfers from them may integrate with the registry easily with tokens using the [`OperatorFilterer`](src/OperatorFilterer.sol) and [`DefaultOperatorFilterer`](src/DefaultOperatorFilterer.sol) contracts. These contracts provide modifiers (`onlyAllowedOperator` and `onlyAllowedOperatorApproval`) which can be used on the token's transfer methods to restrict transfers from or approvals of filtered operators. - -See the [ExampleERC721](src/example/ExampleERC721.sol) and [ExampleERC1155](src/example/ExampleERC1155.sol) contracts for basic implementations that inherit the `DefaultOperatorFilterer`. - -## Getting Started with Foundry - -This package can be installed into a [Foundry](https://github.com/foundry-rs/foundry#installation) project with the following command - -```bash -forge install ProjectOpenSea/operator-filter-registry -``` - -With default remappings provided by `forge remappings`, the default operator filterer can be imported into your project with the following statement - -```solidity -import "operator-filter-registry/DefaultOperatorFilterer.sol"; -``` - -See NPM section below for further details. - -## Getting started with NPM - -This package can be found on NPM to integrate with tools like hardhat. - -### Installing - -with npm - -```bash -npm i operator-filter-registry -``` - -with yarn - -```bash -yarn add operator-filter-registry -``` - -### Default usage - -Add to your smart contract in the import section: - -```solidity -import "operator-filter-registry/src/DefaultOperatorFilterer.sol"; -``` - -Next extend from `DefaultOperatorFilterer` - -```solidity -contract MyNft is - DefaultOperatorFilterer, - // remaining inheritance here -{ -``` - -Finally, override the ERC721 transfer and approval methods (modifiers are overridable as needed) - -```solidity - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) { - super.approve(operator, tokenId); - } - - function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.transferFrom(from, to, tokenId); - } - - function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.safeTransferFrom(from, to, tokenId); - } - - function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, data); - } -``` - -# Smart Contracts - -## `OperatorFilterRegistry` - -`OperatorFilterRegistry` lets a smart contract or its [EIP-173 `Owner`](https://eips.ethereum.org/EIPS/eip-173) register a list of addresses and code hashes to deny when `isOperatorBlocked` is called. - -It also supports "subscriptions," which allow a contract to delegate its operator filtering to another contract. This is useful for contracts that want to allow users to delegate their operator filtering to a trusted third party, who can continuously update the list of filtered operators and code hashes. Subscriptions may be cancelled at any time by the subscriber or its `Owner`. - -### updateOperator(address registrant, address operator, bool filtered) - -This method will toggle filtering for an operator for a given registrant. If `filtered` is `true`, `isOperatorAllowed` will return `false`. If `filtered` is `false`, `isOperatorAllowed` will return `true`. This can filter known addresses. - -### updateCodeHash(address registrant, bytes32 codeHash, bool filtered) - -This method will toggle filtering on code hashes of operators given registrant. If an operator's `EXTCODEHASH` matches a filtered code hash, `isOperatorAllowed` will return `true`. Otherwise, `isOperatorAllowed` will return `false`. This can filter smart contract operators with different addresses but the same code. - -## `OperatorFilterer` - -This smart contract is meant to be inherited by token contracts so they can use the following: - -- `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. -- `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. - -On construction, it takes three parameters: - -- `address registry`: the address of the `OperatorFilterRegistry` contract -- `address subscriptionOrRegistrantToCopy`: the address of the registrant the contract will either subscribe to, or do a one-time copy of that registrant's filters. If the zero address is provided, no subscription or copies will be made. -- `bool subscribe`: if true, subscribes to the previous address if it was not the zero address. If false, copies existing filtered addresses and codeHashes without subscribing to future updates. - -Please note that if your token contract does not provide an owner with [EIP-173](https://eips.ethereum.org/EIPS/eip-173), it must provide administration methods on the contract itself to interact with the registry otherwise the subscription will be locked to the options set during construction. - -### `onlyAllowedOperator(address operator)` - -This modifier will revert if the `operator` or its code hash is filtered by the `OperatorFilterRegistry` contract. - -## `DefaultOperatorFilterer` - -This smart contract extends `OperatorFilterer` and automatically configures the token contract that inherits it to subscribe to OpenSea's list of filtered operators and code hashes. This subscription can be updated at any time by the owner by calling `updateSubscription` on the `OperatorFilterRegistry` contract. - -Please note that if your token contract does not provide an owner with [EIP-173](https://eips.ethereum.org/EIPS/eip-173), it must provide administration methods on the contract itself to interact with the registry otherwise the subscription will be locked to the options set during construction. - -## `OwnedRegistrant` - -This `Ownable` smart contract is meant as a simple utility to enable subscription addresses that can easily be transferred to a new owner for administration. For example: an EOA curates a list of filtered operators and code hashes, and then transfers ownership of the `OwnedRegistrant` to a multisig wallet. - -# Validation - -When the first token is minted on an NFT smart contract, OpenSea checks if the filtered operators on that network (Ethereum Mainnet, Goerli, Polygon, etc.) are allowed to transfer the token. If they are, OpenSea will mark the collection as ineligible for creator earnings. Otherwise, OpenSea will enforce creator earnings on the collection. - -If at a later point, OpenSea detects orders being fulfilled by filtered operators, OpenSea will mark the collection as ineligible for creator earnings going forward. - -The included [validation test](test/validation/Validation.t.sol) runs the same checks that OpenSea does when first creating a collection page, and can be extended with custom setup for your token contract. - -The test can be configured to test against deployed contracts on a network fork with a `.env` file following the [sample.env](sample.env). You may need to supply a custom [`[rpc_endpoints]`](https://book.getfoundry.sh/reference/config/testing#rpc_endpoints) in the `foundry.toml` file for forking to work properly. - -To run only the validation tests, run - -```bash -forge test --match-contract ValidationTest -vvv -``` - -See the [Foundry project page](https://github.com/foundry-rs/foundry#installation) for Foundry installation instructions. - -# Audit - -The contracts in this repository have been audited by [OpenZeppelin](https://openzeppelin.com/). You may read the final audit report [here](audit/OpenSea%20Operator%20Filteer%20Audit%20Report.pdf). - -# License - -[MIT](LICENSE) Copyright 2022 Ozone Networks, Inc. +Operator filters have been proven to be easily circumvented and go against principles of ownership and decentralization. \ No newline at end of file diff --git a/audit/OpenSea Operator Filteer Audit Report.pdf b/audit/OpenSea Operator Filteer Audit Report.pdf deleted file mode 100644 index e8dfe0c19a0cef121488ceea2e4fcc3ae42f764a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 411261 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�RGf(OIKq&| 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
)#ju@OxhjOZq5li$+xqxt01mSVDaKm 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

_g3w-NQd!nx;FhRaap_1lZ~`~)SuYh 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∾j&??9S$cSd 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", - "license": "MIT", - "dependencies": { - "@openzeppelin/contracts": "^4.7.3", - "@openzeppelin/contracts-upgradeable": "^4.8.2" - }, - "files": [ - "node_modules", - "package.json", - "src", - "LICENSE", - "README.md" - ] -} diff --git a/sample.env b/sample.env deleted file mode 100644 index 86d483d..0000000 --- a/sample.env +++ /dev/null @@ -1,4 +0,0 @@ -NETWORK=mainnet -CONTRACT_ADDRESS=0xa518286d66f3699ba4f546f3addb75f2b838c307 -TOKEN_ID=4 -OWNER=0xd8fb7fb541e0bfe5863c5be4b1b41bb552933383 \ No newline at end of file diff --git a/script/ConfigureOwnedRegistrant.s.sol b/script/ConfigureOwnedRegistrant.s.sol deleted file mode 100644 index d91c2fa..0000000 --- a/script/ConfigureOwnedRegistrant.s.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OwnedRegistrant} from "../src/OwnedRegistrant.sol"; -import {IOperatorFilterRegistry} from "../src/IOperatorFilterRegistry.sol"; -import {DeployRegistry} from "./DeployRegistry.s.sol"; -import {ScriptBase, console2} from "./ScriptBase.sol"; - -contract ConfigureOwnedRegistrant is ScriptBase { - function run() public { - setUp(); - address registryAddress = vm.envAddress("REGISTRY_ADDRESS"); - IOperatorFilterRegistry registry = IOperatorFilterRegistry(registryAddress); - OwnedRegistrant registrant = OwnedRegistrant(vm.envAddress("REGISTRANT_ADDRESS")); - address[] memory add = vm.envAddress("NEW_FILTERED_ADDRESSES", ","); - address[] memory remove = vm.envAddress("REMOVE_FILTERED_ADDRESSES", ","); - - string[] memory chains = vm.envString("CHAINS", ","); - for (uint256 i = 0; i < chains.length; i++) { - string memory chain = chains[i]; - vm.createSelectFork(getChain(chain).rpcUrl); - vm.startBroadcast(deployer); - registry.updateOperators(address(registrant), add, true); - registry.updateOperators(address(registrant), remove, false); - vm.stopBroadcast(); - } - } -} diff --git a/script/ConfigureOwnedRegistry.s.sol b/script/ConfigureOwnedRegistry.s.sol deleted file mode 100644 index 1cf18f9..0000000 --- a/script/ConfigureOwnedRegistry.s.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OwnedRegistrant} from "../src/OwnedRegistrant.sol"; -import {IOperatorFilterRegistry} from "../src/IOperatorFilterRegistry.sol"; -import {DeployRegistry} from "./DeployRegistry.s.sol"; -import {ScriptBase, console2} from "./ScriptBase.sol"; - -contract DeployRegistryAndConfigureOwnedRegistrant is ScriptBase { - mapping(string => bool) selectedChains; - - function run() public { - setUp(); - - string[] memory chainNames = vm.envString("BROADCAST_CHAINS", ","); - for (uint256 i = 0; i < chainNames.length; i++) { - selectedChains[chainNames[i]] = true; - } - string[2][] memory rpcs = vm.rpcUrls(); - for (uint256 i = 0; i < rpcs.length; i++) { - if (selectedChains[rpcs[i][0]]) { - console2.log("Configuring registry on chain ", rpcs[i][0]); - vm.createSelectFork(rpcs[i][1]); - configure(); - } - } - } - - function configure() internal { - address registryAddress = vm.envAddress("REGISTRY_ADDRESS"); - IOperatorFilterRegistry registry = IOperatorFilterRegistry(registryAddress); - address[] memory addressesToAdd = vm.envAddress("NEW_FILTERED_ADDRESSES", ","); - address[] memory addressesToRemove = vm.envAddress("REMOVE_FILTERED_ADDRESSES", ","); - OwnedRegistrant registrant = OwnedRegistrant(vm.envAddress("REGISTRANT_ADDRESS")); - - vm.startBroadcast(deployer); - if (addressesToAdd.length > 0) { - registry.updateOperators(address(registrant), addressesToAdd, true); - } - if (addressesToRemove.length > 0) { - registry.updateOperators(address(registrant), addressesToRemove, false); - } - vm.stopBroadcast(); - } -} diff --git a/script/DeployAndConfigureOwnedRegistrant.s.sol b/script/DeployAndConfigureOwnedRegistrant.s.sol deleted file mode 100644 index 773afef..0000000 --- a/script/DeployAndConfigureOwnedRegistrant.s.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OwnedRegistrant} from "../src/OwnedRegistrant.sol"; -import {IOperatorFilterRegistry} from "../src/IOperatorFilterRegistry.sol"; -import {DeployRegistry} from "./DeployRegistry.s.sol"; -import {ScriptBase, console2} from "./ScriptBase.sol"; - -contract DeployRegistryAndConfigureOwnedRegistrant is ScriptBase { - function run() public { - setUp(); - address registryAddress = vm.envAddress("REGISTRY_ADDRESS"); - IOperatorFilterRegistry registry = IOperatorFilterRegistry(registryAddress); - address[] memory addressesToFilter = vm.envAddress("FILTERED_ADDRESSES", ","); - - bytes memory creationCode = abi.encodePacked(type(OwnedRegistrant).creationCode, abi.encode(deployer)); - bytes32 salt = bytes32(uint256(uint160(deployer)) << 96); - vm.startBroadcast(deployer); - OwnedRegistrant registrant = OwnedRegistrant(IMMUTABLE_CREATE2_FACTORY.safeCreate2(salt, creationCode)); - registrant.acceptOwnership(); - registry.updateOperators(address(registrant), addressesToFilter, true); - } -} diff --git a/script/DeployRegistry.s.sol b/script/DeployRegistry.s.sol deleted file mode 100644 index e268579..0000000 --- a/script/DeployRegistry.s.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFilterRegistry} from "../src/OperatorFilterRegistry.sol"; -import {ScriptBase, console2} from "./ScriptBase.sol"; - -contract DeployRegistry is ScriptBase { - function run() public { - setUp(); - bytes memory creationCode = type(OperatorFilterRegistry).creationCode; - console2.logBytes32(keccak256(creationCode)); - bytes32 salt = bytes32(0x0000000000000000000000000000000000000000d40ba0de8b5adb1cc4070000); - // bytes32 salt = bytes32(0); - - vm.broadcast(deployer); - IMMUTABLE_CREATE2_FACTORY.safeCreate2(salt, creationCode); - } -} diff --git a/script/DeployRegistryAndRegistrant.s.sol b/script/DeployRegistryAndRegistrant.s.sol deleted file mode 100644 index 12356ce..0000000 --- a/script/DeployRegistryAndRegistrant.s.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFilterRegistry} from "../src/OperatorFilterRegistry.sol"; -import {OwnedRegistrant} from "../src/OwnedRegistrant.sol"; -import {ScriptBase, console2} from "./ScriptBase.sol"; - -contract DeployRegistryAndRegistrant is ScriptBase { - function run() public { - setUp(); - bytes memory creationCode = - hex"608060405234801561001057600080fd5b50613848806100206000396000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c8063712fc00b116100e3578063b314d4141161008c578063c430880511610066578063c4308805146103d1578063c6171134146103e4578063e4aecb54146103f757600080fd5b8063b314d4141461035b578063bbd652c71461036e578063c3c5a5471461039657600080fd5b8063a14584c1116100bd578063a14584c114610314578063a2f367ab14610327578063a6529eb51461033a57600080fd5b8063712fc00b146102db5780637d3e3dbe146102ee578063a0af29031461030157600080fd5b80633f1cc5fa116101455780635745ae281161011f5780635745ae28146102855780635eae3173146102a55780636af0c315146102c857600080fd5b80633f1cc5fa1461024c5780634420e4861461025f57806355940e511461027257600080fd5b80632ec2c246116101765780632ec2c246146101ee57806334a0dc10146102015780633c5030bb1461021457600080fd5b8063063298b61461019d5780631e06b4b4146101b257806322fa2762146101c5575b600080fd5b6101b06101ab366004613484565b61040a565b005b6101b06101c03660046134eb565b610854565b6101d86101d3366004613524565b610b57565b6040516101e59190613541565b60405180910390f35b6101b06101fc366004613524565b610bec565b6101b061020f366004613585565b610eaa565b610227610222366004613524565b611168565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e5565b61022761025a3660046135ba565b61121b565b6101b061026d366004613524565b6112bc565b6102276102803660046135ba565b6114b7565b610298610293366004613524565b6114e6565b6040516101e591906135e6565b6102b86102b33660046134eb565b611517565b60405190151581526020016101e5565b6102b86102d63660046135ba565b6115be565b6101b06102e9366004613634565b61164d565b6101b06102fc3660046134eb565b6119cd565b6101b061030f3660046134eb565b611da3565b6101b0610322366004613484565b612081565b6101b0610335366004613672565b61244f565b61034d6103483660046135ba565b6127b6565b6040519081526020016101e5565b6101b06103693660046134eb565b612845565b61034d61037c366004613524565b73ffffffffffffffffffffffffffffffffffffffff163f90565b6102b86103a4366004613524565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b6102986103df366004613524565b612d63565b6102b86103f23660046134eb565b612df1565b6102b86104053660046134eb565b612f4c565b833373ffffffffffffffffffffffffffffffffffffffff821614610575578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156104ad575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526104aa918101906136b0565b60015b610524573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b606091505b50805160000361051c576040517fb2c1414000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b3373ffffffffffffffffffffffffffffffffffffffff821614610573576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80861660009081526002602052604090205416806105f1576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024015b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461066e576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260016020526040902084846107225760005b8181101561071c5760008888838181106106b8576106b86136cd565b90506020020135905060006106d68286612fdb90919063ffffffff16565b905080610712576040517f478730a8000000000000000000000000000000000000000000000000000000008152600481018390526024016105e8565b505060010161069c565b506107f7565b60005b818110156107f5576000888883818110610741576107416136cd565b9050602002013590507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081036107a3576040517ff575ead800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107af8583612fe7565b9050806107eb576040517f186bea00000000000000000000000000000000000000000000000000000000008152600481018390526024016105e8565b5050600101610725565b505b8415158873ffffffffffffffffffffffffffffffffffffffff167f34e9f70c5a16a4df2a396cf0cbc4735eb3c7fb6ae40aaa0b34be7720121d1b9689896040516108429291906136fc565b60405180910390a35050505050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614610976578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156108f7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526108f4918101906136b0565b60015b610925573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610974576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109db576040517f1acab6b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680610a52576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610acf576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680610b46576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b610b508585612ff3565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff80821660008181526002602052604090205460609216908114610bbe5773ffffffffffffffffffffffffffffffffffffffff81166000908152600160205260409020610bb79061318d565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600160205260409020610bb79061318d565b803373ffffffffffffffffffffffffffffffffffffffff821614610d0e578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610c8f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610c8c918101906136b0565b60015b610cbd573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610d0c576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020541680610d85576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016105e8565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610e305773ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260409020610de7908461319a565b5060405160009073ffffffffffffffffffffffffffffffffffffffff80841691908616907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a45b73ffffffffffffffffffffffffffffffffffffffff831660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055519091907f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59908390a3505050565b813373ffffffffffffffffffffffffffffffffffffffff821614610fcc578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610f4d575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610f4a918101906136b0565b60015b610f7b573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610fca576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680611043576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036110a8576040517f237e6c2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090206110d7908561319a565b5073ffffffffffffffffffffffffffffffffffffffff80851660008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055519092841691907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a48215611162576111628482612ff3565b50505050565b73ffffffffffffffffffffffffffffffffffffffff80821660009081526002602052604090205416806111df576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611216575060005b919050565b73ffffffffffffffffffffffffffffffffffffffff8083166000818152600260205260408120549092169081146112835773ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902061127b90846131bc565b9150506112b6565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090206112b290846131bc565b9150505b92915050565b803373ffffffffffffffffffffffffffffffffffffffff8216146113de578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561135f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261135c918101906136b0565b60015b61138d573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff8216146113dc576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff828116600090815260026020526040902054161561143d576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551600192917f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5991a35050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120610bb790836131bc565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090206060906112b69061318d565b73ffffffffffffffffffffffffffffffffffffffff82811660008181526002602052604081205490928085163f9291169081146115865773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061157d90836131c8565b925050506112b6565b73ffffffffffffffffffffffffffffffffffffffff851660009081526001602052604090206115b590836131c8565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff80831660008181526002602052604081205490921690811461161e5773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061127b90846131c8565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604090206112b290846131c8565b823373ffffffffffffffffffffffffffffffffffffffff82161461176f578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156116f0575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526116ed918101906136b0565b60015b61171e573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff82161461176d576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47083036117c8576040517ff575ead800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808516600090815260026020526040902054168061183f576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146118bc576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600160205260409020836119345760006118f28287612fdb565b90508061192e576040517f478730a8000000000000000000000000000000000000000000000000000000008152600481018790526024016105e8565b5061197e565b60006119408287612fe7565b90508061197c576040517f186bea00000000000000000000000000000000000000000000000000000000008152600481018790526024016105e8565b505b831515858773ffffffffffffffffffffffffffffffffffffffff167fb8036058bafea884aabc446ca15619fd86f5464a4ad96f64164ad6f77444354d60405160405180910390a4505050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614611aef578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a70575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611a6d918101906136b0565b60015b611a9e573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614611aed576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020526040902054168015611b4f576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611bb4576040517f347f118f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680611c2b576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611ca8576040517f768e549c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694891694851790559282526003905220611d0f90866131e0565b5060405160019073ffffffffffffffffffffffffffffffffffffffff8716907f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5990600090a360405160019073ffffffffffffffffffffffffffffffffffffffff80871691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e890600090a45050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614611ec5578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611e46575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611e43918101906136b0565b60015b611e74573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614611ec3576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611f2a576040517f1acab6b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020526040902054168015611f8a576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612001576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551600192917f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5991a3610b508585612ff3565b833373ffffffffffffffffffffffffffffffffffffffff8216146121a3578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612124575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612121918101906136b0565b60015b612152573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff8216146121a1576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff808616600090815260026020526040902054168061221a576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612297576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902084846123655760005b8181101561235f5760008888838181106122e1576122e16136cd565b90506020020160208101906122f69190613524565b90506000612304858361319a565b905080612355576040517f45525c0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b50506001016122c5565b50612404565b60005b81811015612402576000888883818110612384576123846136cd565b90506020020160208101906123999190613524565b905060006123a785836131e0565b9050806123f8576040517f0bb4423400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b5050600101612368565b505b8415158873ffffffffffffffffffffffffffffffffffffffff167f02b85afdacb82d5512c6f05566b3018677ffcbd7e5f75e498bc64081131cbd6c898960405161084292919061374e565b823373ffffffffffffffffffffffffffffffffffffffff821614612571578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156124f2575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526124ef918101906136b0565b60015b612520573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff82161461256f576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80851660009081526002602052604090205416806125e8576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612665576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85166000908152602081905260409020836126f257600061269b828761319a565b9050806126ec576040517f45525c0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b50612751565b60006126fe82876131e0565b90508061274f576040517f0bb4423400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b505b8315158573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f2738289d9deecdc30eb8ffc42876633caecca1ffa166e4efa89f408e17373a1a60405160405180910390a4505050505050565b73ffffffffffffffffffffffffffffffffffffffff8083166000818152600260205260408120549092169081146128165773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061127b90846131bc565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604090206112b290846131bc565b813373ffffffffffffffffffffffffffffffffffffffff821614612967578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128e8575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526128e5918101906136b0565b60015b612916573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614612965576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036129cc576040517f347f118f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216612a19576040517fb05574d300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612a90576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b0d576040517f73a4164900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612b84576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612c01576040517f768e549c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612cac5773ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260409020612c63908661319a565b5060405160009073ffffffffffffffffffffffffffffffffffffffff80851691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a45b73ffffffffffffffffffffffffffffffffffffffff858116600090815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694891694851790559282526003905220612d1390866131e0565b5060405160019073ffffffffffffffffffffffffffffffffffffffff80871691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e890600090a45050505050565b73ffffffffffffffffffffffffffffffffffffffff80821660008181526002602052604090205460609216908114612dc35773ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020610bb79061318d565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260409020610bb79061318d565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260408120549091168015612f425773ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260408083206001909252909120612e598286613202565b15612ea8576040517fa8cf495d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85163b15612f3f5773ffffffffffffffffffffffffffffffffffffffff85163f612ee782826131c8565b15612f3d576040517f5f3853a900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87166004820152602481018290526044016105e8565b505b50505b5060019392505050565b73ffffffffffffffffffffffffffffffffffffffff808316600081815260026020526040812054909216908114612fac5773ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902061127b9084613202565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090206112b29084613202565b6000610bb78383613231565b6000610bb78383613324565b73ffffffffffffffffffffffffffffffffffffffff811660009081526020818152604080832060019092528220909161302b83613373565b9050600061303883613373565b905060005b828110156130e057600061305186836131bc565b73ffffffffffffffffffffffffffffffffffffffff891660009081526020819052604081209192509061308490836131e0565b905080156130d65760405160019073ffffffffffffffffffffffffffffffffffffffff80851691908c16907f2738289d9deecdc30eb8ffc42876633caecca1ffa166e4efa89f408e17373a1a90600090a45b505060010161303d565b5060005b818110156131845760006130f885836131bc565b73ffffffffffffffffffffffffffffffffffffffff891660009081526001602052604081209192509061312b9083612fe7565b9050801561317a57604051600190839073ffffffffffffffffffffffffffffffffffffffff8c16907fb8036058bafea884aabc446ca15619fd86f5464a4ad96f64164ad6f77444354d90600090a45b50506001016130e4565b50505050505050565b60606000610bb78361337d565b6000610bb78373ffffffffffffffffffffffffffffffffffffffff8416613231565b6000610bb783836133d9565b60008181526001830160205260408120541515610bb7565b6000610bb78373ffffffffffffffffffffffffffffffffffffffff8416613324565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610bb7565b6000818152600183016020526040812054801561331a5760006132556001836137a9565b8554909150600090613269906001906137a9565b90508181146132ce576000866000018281548110613289576132896136cd565b90600052602060002001549050808760000184815481106132ac576132ac6136cd565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806132df576132df6137e3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112b6565b60009150506112b6565b600081815260018301602052604081205461336b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112b6565b5060006112b6565b60006112b6825490565b6060816000018054806020026020016040519081016040528092919081815260200182805480156133cd57602002820191906000526020600020905b8154815260200190600101908083116133b9575b50505050509050919050565b60008260000182815481106133f0576133f06136cd565b9060005260206000200154905092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461342557600080fd5b50565b60008083601f84011261343a57600080fd5b50813567ffffffffffffffff81111561345257600080fd5b6020830191508360208260051b850101111561346d57600080fd5b9250929050565b8035801515811461121657600080fd5b6000806000806060858703121561349a57600080fd5b84356134a581613403565b9350602085013567ffffffffffffffff8111156134c157600080fd5b6134cd87828801613428565b90945092506134e0905060408601613474565b905092959194509250565b600080604083850312156134fe57600080fd5b823561350981613403565b9150602083013561351981613403565b809150509250929050565b60006020828403121561353657600080fd5b8135610bb781613403565b6020808252825182820181905260009190848201906040850190845b818110156135795783518352928401929184019160010161355d565b50909695505050505050565b6000806040838503121561359857600080fd5b82356135a381613403565b91506135b160208401613474565b90509250929050565b600080604083850312156135cd57600080fd5b82356135d881613403565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561357957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613602565b60008060006060848603121561364957600080fd5b833561365481613403565b92506020840135915061366960408501613474565b90509250925092565b60008060006060848603121561368757600080fd5b833561369281613403565b925060208401356136a281613403565b915061366960408501613474565b6000602082840312156136c257600080fd5b8151610bb781613403565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561373557600080fd5b8260051b80856040850137919091016040019392505050565b60208082528181018390526000908460408401835b8681101561379e57823561377681613403565b73ffffffffffffffffffffffffffffffffffffffff1682529183019190830190600101613763565b509695505050505050565b818103818111156112b6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220d2eb4529f96412ccc09b0c0c04d7ff105932b0b691aea14b7aa158442949a08664736f6c63430008110033"; - console2.logBytes32(keccak256(creationCode)); - bytes32 salt = bytes32(0x0000000000000000000000000000000000000000d40ba0de8b5adb1cc4070000); - // bytes32 salt = bytes32(0); - string[] memory chains = vm.envString("CHAINS", ","); - - bytes memory registrantCreationCode = - hex"608060405234801561001057600080fd5b5060405161063b38038061063b83398101604081905261002f916101f2565b610038336100ab565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b15801561007e57600080fd5b505af1158015610092573d6000803e3d6000fd5b505050506100a5816100d260201b60201c565b50610222565b600180546001600160a01b03191690556100cf81610142602090811b61027017901c565b50565b6100da610192565b600180546001600160a01b0319166001600160a01b03831690811790915561010a6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146101f05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b565b60006020828403121561020457600080fd5b81516001600160a01b038116811461021b57600080fd5b9392505050565b61040a806102316000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80638da5cb5b116100505780638da5cb5b1461007e578063e30c3978146100c1578063f2fde38b146100df57600080fd5b8063715018a61461006c57806379ba509714610076575b600080fd5b6100746100f2565b005b610074610106565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b60015473ffffffffffffffffffffffffffffffffffffffff16610098565b6100746100ed366004610397565b6101c0565b6100fa6102e5565b6101046000610366565b565b600154339073ffffffffffffffffffffffffffffffffffffffff1681146101b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060448201527f6e6577206f776e6572000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6101bd81610366565b50565b6101c86102e5565b6001805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915561022b60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101ab565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556101bd81610270565b6000602082840312156103a957600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146103cd57600080fd5b939250505056fea26469706673582212204f2a6b671e719be38470ca6124ec766d477c6d9dbd2f313eb84f6065c70ad51b64736f6c634300081100330000000000000000000000009aac739c133074db445183a95149880a2156541a"; - bytes32 registrantSalt = 0x9aac739c133074db445183a95149880a2156541a000000000000000000000000; - - for (uint256 i; i < chains.length; i++) { - string memory chain = chains[i]; - console2.log(chain); - vm.createSelectFork(getChain(chain).rpcUrl); - vm.startBroadcast(deployer); - IMMUTABLE_CREATE2_FACTORY.safeCreate2(salt, creationCode); - OwnedRegistrant registrant = - OwnedRegistrant(IMMUTABLE_CREATE2_FACTORY.safeCreate2(registrantSalt, registrantCreationCode)); - registrant.acceptOwnership(); - vm.stopBroadcast(); - } - } -} diff --git a/script/ScriptBase.sol b/script/ScriptBase.sol deleted file mode 100644 index c0bb8a8..0000000 --- a/script/ScriptBase.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFilterRegistry} from "../src/OperatorFilterRegistry.sol"; -import {Script, console2} from "forge-std/Script.sol"; - -interface ImmutableCreate2Factory { - function findCreate2Address(bytes32 salt, bytes memory initCode) - external - view - returns (address deploymentAddress); - function findCreate2AddressViaHash(bytes32 salt, bytes32 initCodeHash) - external - view - returns (address deploymentAddress); - function hasBeenDeployed(address deploymentAddress) external view returns (bool); - function safeCreate2(bytes32 salt, bytes memory initializationCode) - external - payable - returns (address deploymentAddress); -} - -contract ScriptBase is Script { - address deployer; - - ImmutableCreate2Factory constant IMMUTABLE_CREATE2_FACTORY = - ImmutableCreate2Factory(0x0000000000FFe8B47B3e2130213B802212439497); - - function setUp() public { - bytes32 pkey = vm.envBytes32("PRIVATE_KEY"); - deployer = vm.rememberKey(uint256(pkey)); - } -} diff --git a/script/cast-deploy.sh b/script/cast-deploy.sh deleted file mode 100644 index 9979e41..0000000 --- a/script/cast-deploy.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -# As of writing, Forge scripting has issues estimating gas for some networks - for those networks, we can run this -# script instead. - -source .env -factory=0x0000000000FFe8B47B3e2130213B802212439497 -registrant=0x3cc6cdda760b79bafa08df41ecfa224f810dceb6 - -salt1=0x0000000000000000000000000000000000000000d40ba0de8b5adb1cc4070000 -salt2=0x9aac739c133074db445183a95149880a2156541a000000000000000000000000 - -code1=0x608060405234801561001057600080fd5b50613848806100206000396000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c8063712fc00b116100e3578063b314d4141161008c578063c430880511610066578063c4308805146103d1578063c6171134146103e4578063e4aecb54146103f757600080fd5b8063b314d4141461035b578063bbd652c71461036e578063c3c5a5471461039657600080fd5b8063a14584c1116100bd578063a14584c114610314578063a2f367ab14610327578063a6529eb51461033a57600080fd5b8063712fc00b146102db5780637d3e3dbe146102ee578063a0af29031461030157600080fd5b80633f1cc5fa116101455780635745ae281161011f5780635745ae28146102855780635eae3173146102a55780636af0c315146102c857600080fd5b80633f1cc5fa1461024c5780634420e4861461025f57806355940e511461027257600080fd5b80632ec2c246116101765780632ec2c246146101ee57806334a0dc10146102015780633c5030bb1461021457600080fd5b8063063298b61461019d5780631e06b4b4146101b257806322fa2762146101c5575b600080fd5b6101b06101ab366004613484565b61040a565b005b6101b06101c03660046134eb565b610854565b6101d86101d3366004613524565b610b57565b6040516101e59190613541565b60405180910390f35b6101b06101fc366004613524565b610bec565b6101b061020f366004613585565b610eaa565b610227610222366004613524565b611168565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e5565b61022761025a3660046135ba565b61121b565b6101b061026d366004613524565b6112bc565b6102276102803660046135ba565b6114b7565b610298610293366004613524565b6114e6565b6040516101e591906135e6565b6102b86102b33660046134eb565b611517565b60405190151581526020016101e5565b6102b86102d63660046135ba565b6115be565b6101b06102e9366004613634565b61164d565b6101b06102fc3660046134eb565b6119cd565b6101b061030f3660046134eb565b611da3565b6101b0610322366004613484565b612081565b6101b0610335366004613672565b61244f565b61034d6103483660046135ba565b6127b6565b6040519081526020016101e5565b6101b06103693660046134eb565b612845565b61034d61037c366004613524565b73ffffffffffffffffffffffffffffffffffffffff163f90565b6102b86103a4366004613524565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b6102986103df366004613524565b612d63565b6102b86103f23660046134eb565b612df1565b6102b86104053660046134eb565b612f4c565b833373ffffffffffffffffffffffffffffffffffffffff821614610575578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156104ad575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526104aa918101906136b0565b60015b610524573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b606091505b50805160000361051c576040517fb2c1414000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b3373ffffffffffffffffffffffffffffffffffffffff821614610573576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80861660009081526002602052604090205416806105f1576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024015b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461066e576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260016020526040902084846107225760005b8181101561071c5760008888838181106106b8576106b86136cd565b90506020020135905060006106d68286612fdb90919063ffffffff16565b905080610712576040517f478730a8000000000000000000000000000000000000000000000000000000008152600481018390526024016105e8565b505060010161069c565b506107f7565b60005b818110156107f5576000888883818110610741576107416136cd565b9050602002013590507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081036107a3576040517ff575ead800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107af8583612fe7565b9050806107eb576040517f186bea00000000000000000000000000000000000000000000000000000000008152600481018390526024016105e8565b5050600101610725565b505b8415158873ffffffffffffffffffffffffffffffffffffffff167f34e9f70c5a16a4df2a396cf0cbc4735eb3c7fb6ae40aaa0b34be7720121d1b9689896040516108429291906136fc565b60405180910390a35050505050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614610976578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156108f7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526108f4918101906136b0565b60015b610925573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610974576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109db576040517f1acab6b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680610a52576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610acf576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680610b46576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b610b508585612ff3565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff80821660008181526002602052604090205460609216908114610bbe5773ffffffffffffffffffffffffffffffffffffffff81166000908152600160205260409020610bb79061318d565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600160205260409020610bb79061318d565b803373ffffffffffffffffffffffffffffffffffffffff821614610d0e578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610c8f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610c8c918101906136b0565b60015b610cbd573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610d0c576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020541680610d85576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016105e8565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610e305773ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260409020610de7908461319a565b5060405160009073ffffffffffffffffffffffffffffffffffffffff80841691908616907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a45b73ffffffffffffffffffffffffffffffffffffffff831660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055519091907f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59908390a3505050565b813373ffffffffffffffffffffffffffffffffffffffff821614610fcc578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610f4d575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610f4a918101906136b0565b60015b610f7b573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610fca576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680611043576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036110a8576040517f237e6c2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090206110d7908561319a565b5073ffffffffffffffffffffffffffffffffffffffff80851660008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055519092841691907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a48215611162576111628482612ff3565b50505050565b73ffffffffffffffffffffffffffffffffffffffff80821660009081526002602052604090205416806111df576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611216575060005b919050565b73ffffffffffffffffffffffffffffffffffffffff8083166000818152600260205260408120549092169081146112835773ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902061127b90846131bc565b9150506112b6565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090206112b290846131bc565b9150505b92915050565b803373ffffffffffffffffffffffffffffffffffffffff8216146113de578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561135f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261135c918101906136b0565b60015b61138d573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff8216146113dc576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff828116600090815260026020526040902054161561143d576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551600192917f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5991a35050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120610bb790836131bc565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090206060906112b69061318d565b73ffffffffffffffffffffffffffffffffffffffff82811660008181526002602052604081205490928085163f9291169081146115865773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061157d90836131c8565b925050506112b6565b73ffffffffffffffffffffffffffffffffffffffff851660009081526001602052604090206115b590836131c8565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff80831660008181526002602052604081205490921690811461161e5773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061127b90846131c8565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604090206112b290846131c8565b823373ffffffffffffffffffffffffffffffffffffffff82161461176f578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156116f0575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526116ed918101906136b0565b60015b61171e573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff82161461176d576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47083036117c8576040517ff575ead800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808516600090815260026020526040902054168061183f576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146118bc576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600160205260409020836119345760006118f28287612fdb565b90508061192e576040517f478730a8000000000000000000000000000000000000000000000000000000008152600481018790526024016105e8565b5061197e565b60006119408287612fe7565b90508061197c576040517f186bea00000000000000000000000000000000000000000000000000000000008152600481018790526024016105e8565b505b831515858773ffffffffffffffffffffffffffffffffffffffff167fb8036058bafea884aabc446ca15619fd86f5464a4ad96f64164ad6f77444354d60405160405180910390a4505050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614611aef578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a70575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611a6d918101906136b0565b60015b611a9e573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614611aed576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020526040902054168015611b4f576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611bb4576040517f347f118f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680611c2b576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611ca8576040517f768e549c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694891694851790559282526003905220611d0f90866131e0565b5060405160019073ffffffffffffffffffffffffffffffffffffffff8716907f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5990600090a360405160019073ffffffffffffffffffffffffffffffffffffffff80871691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e890600090a45050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614611ec5578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611e46575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611e43918101906136b0565b60015b611e74573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614611ec3576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611f2a576040517f1acab6b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020526040902054168015611f8a576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612001576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551600192917f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5991a3610b508585612ff3565b833373ffffffffffffffffffffffffffffffffffffffff8216146121a3578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612124575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612121918101906136b0565b60015b612152573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff8216146121a1576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff808616600090815260026020526040902054168061221a576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612297576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902084846123655760005b8181101561235f5760008888838181106122e1576122e16136cd565b90506020020160208101906122f69190613524565b90506000612304858361319a565b905080612355576040517f45525c0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b50506001016122c5565b50612404565b60005b81811015612402576000888883818110612384576123846136cd565b90506020020160208101906123999190613524565b905060006123a785836131e0565b9050806123f8576040517f0bb4423400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b5050600101612368565b505b8415158873ffffffffffffffffffffffffffffffffffffffff167f02b85afdacb82d5512c6f05566b3018677ffcbd7e5f75e498bc64081131cbd6c898960405161084292919061374e565b823373ffffffffffffffffffffffffffffffffffffffff821614612571578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156124f2575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526124ef918101906136b0565b60015b612520573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff82161461256f576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80851660009081526002602052604090205416806125e8576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612665576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85166000908152602081905260409020836126f257600061269b828761319a565b9050806126ec576040517f45525c0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b50612751565b60006126fe82876131e0565b90508061274f576040517f0bb4423400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b505b8315158573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f2738289d9deecdc30eb8ffc42876633caecca1ffa166e4efa89f408e17373a1a60405160405180910390a4505050505050565b73ffffffffffffffffffffffffffffffffffffffff8083166000818152600260205260408120549092169081146128165773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061127b90846131bc565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604090206112b290846131bc565b813373ffffffffffffffffffffffffffffffffffffffff821614612967578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128e8575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526128e5918101906136b0565b60015b612916573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614612965576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036129cc576040517f347f118f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216612a19576040517fb05574d300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612a90576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b0d576040517f73a4164900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612b84576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612c01576040517f768e549c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612cac5773ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260409020612c63908661319a565b5060405160009073ffffffffffffffffffffffffffffffffffffffff80851691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a45b73ffffffffffffffffffffffffffffffffffffffff858116600090815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694891694851790559282526003905220612d1390866131e0565b5060405160019073ffffffffffffffffffffffffffffffffffffffff80871691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e890600090a45050505050565b73ffffffffffffffffffffffffffffffffffffffff80821660008181526002602052604090205460609216908114612dc35773ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020610bb79061318d565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260409020610bb79061318d565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260408120549091168015612f425773ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260408083206001909252909120612e598286613202565b15612ea8576040517fa8cf495d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85163b15612f3f5773ffffffffffffffffffffffffffffffffffffffff85163f612ee782826131c8565b15612f3d576040517f5f3853a900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87166004820152602481018290526044016105e8565b505b50505b5060019392505050565b73ffffffffffffffffffffffffffffffffffffffff808316600081815260026020526040812054909216908114612fac5773ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902061127b9084613202565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090206112b29084613202565b6000610bb78383613231565b6000610bb78383613324565b73ffffffffffffffffffffffffffffffffffffffff811660009081526020818152604080832060019092528220909161302b83613373565b9050600061303883613373565b905060005b828110156130e057600061305186836131bc565b73ffffffffffffffffffffffffffffffffffffffff891660009081526020819052604081209192509061308490836131e0565b905080156130d65760405160019073ffffffffffffffffffffffffffffffffffffffff80851691908c16907f2738289d9deecdc30eb8ffc42876633caecca1ffa166e4efa89f408e17373a1a90600090a45b505060010161303d565b5060005b818110156131845760006130f885836131bc565b73ffffffffffffffffffffffffffffffffffffffff891660009081526001602052604081209192509061312b9083612fe7565b9050801561317a57604051600190839073ffffffffffffffffffffffffffffffffffffffff8c16907fb8036058bafea884aabc446ca15619fd86f5464a4ad96f64164ad6f77444354d90600090a45b50506001016130e4565b50505050505050565b60606000610bb78361337d565b6000610bb78373ffffffffffffffffffffffffffffffffffffffff8416613231565b6000610bb783836133d9565b60008181526001830160205260408120541515610bb7565b6000610bb78373ffffffffffffffffffffffffffffffffffffffff8416613324565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610bb7565b6000818152600183016020526040812054801561331a5760006132556001836137a9565b8554909150600090613269906001906137a9565b90508181146132ce576000866000018281548110613289576132896136cd565b90600052602060002001549050808760000184815481106132ac576132ac6136cd565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806132df576132df6137e3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112b6565b60009150506112b6565b600081815260018301602052604081205461336b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112b6565b5060006112b6565b60006112b6825490565b6060816000018054806020026020016040519081016040528092919081815260200182805480156133cd57602002820191906000526020600020905b8154815260200190600101908083116133b9575b50505050509050919050565b60008260000182815481106133f0576133f06136cd565b9060005260206000200154905092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461342557600080fd5b50565b60008083601f84011261343a57600080fd5b50813567ffffffffffffffff81111561345257600080fd5b6020830191508360208260051b850101111561346d57600080fd5b9250929050565b8035801515811461121657600080fd5b6000806000806060858703121561349a57600080fd5b84356134a581613403565b9350602085013567ffffffffffffffff8111156134c157600080fd5b6134cd87828801613428565b90945092506134e0905060408601613474565b905092959194509250565b600080604083850312156134fe57600080fd5b823561350981613403565b9150602083013561351981613403565b809150509250929050565b60006020828403121561353657600080fd5b8135610bb781613403565b6020808252825182820181905260009190848201906040850190845b818110156135795783518352928401929184019160010161355d565b50909695505050505050565b6000806040838503121561359857600080fd5b82356135a381613403565b91506135b160208401613474565b90509250929050565b600080604083850312156135cd57600080fd5b82356135d881613403565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561357957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613602565b60008060006060848603121561364957600080fd5b833561365481613403565b92506020840135915061366960408501613474565b90509250925092565b60008060006060848603121561368757600080fd5b833561369281613403565b925060208401356136a281613403565b915061366960408501613474565b6000602082840312156136c257600080fd5b8151610bb781613403565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561373557600080fd5b8260051b80856040850137919091016040019392505050565b60208082528181018390526000908460408401835b8681101561379e57823561377681613403565b73ffffffffffffffffffffffffffffffffffffffff1682529183019190830190600101613763565b509695505050505050565b818103818111156112b6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220d2eb4529f96412ccc09b0c0c04d7ff105932b0b691aea14b7aa158442949a08664736f6c63430008110033 -code2=0x608060405234801561001057600080fd5b5060405161063b38038061063b83398101604081905261002f916101f2565b610038336100ab565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b15801561007e57600080fd5b505af1158015610092573d6000803e3d6000fd5b505050506100a5816100d260201b60201c565b50610222565b600180546001600160a01b03191690556100cf81610142602090811b61027017901c565b50565b6100da610192565b600180546001600160a01b0319166001600160a01b03831690811790915561010a6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146101f05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b565b60006020828403121561020457600080fd5b81516001600160a01b038116811461021b57600080fd5b9392505050565b61040a806102316000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80638da5cb5b116100505780638da5cb5b1461007e578063e30c3978146100c1578063f2fde38b146100df57600080fd5b8063715018a61461006c57806379ba509714610076575b600080fd5b6100746100f2565b005b610074610106565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b60015473ffffffffffffffffffffffffffffffffffffffff16610098565b6100746100ed366004610397565b6101c0565b6100fa6102e5565b6101046000610366565b565b600154339073ffffffffffffffffffffffffffffffffffffffff1681146101b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060448201527f6e6577206f776e6572000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6101bd81610366565b50565b6101c86102e5565b6001805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915561022b60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101ab565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556101bd81610270565b6000602082840312156103a957600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146103cd57600080fd5b939250505056fea26469706673582212204f2a6b671e719be38470ca6124ec766d477c6d9dbd2f313eb84f6065c70ad51b64736f6c634300081100330000000000000000000000009aac739c133074db445183a95149880a2156541a - - -cast send $factory "safeCreate2(bytes32,bytes)" $salt1 $code1 --rpc-url $ETH_RPC_URL --private-key $PRIVATE_KEY --gas-price 207170000 -cast send $factory "safeCreate2(bytes32,bytes)" $salt2 $code2 --rpc-url $ETH_RPC_URL --private-key $PRIVATE_KEY --gas-price 207170000 -cast send $registrant "acceptOwnership()" --rpc-url $ETH_RPC_URL --private-key $PRIVATE_KEY --gas-price 207170000 \ No newline at end of file diff --git a/script/verification/OperatorFilterRegistryStandardJsonInput.json b/script/verification/OperatorFilterRegistryStandardJsonInput.json deleted file mode 100644 index 4ce6e03..0000000 --- a/script/verification/OperatorFilterRegistryStandardJsonInput.json +++ /dev/null @@ -1,1075 +0,0 @@ -{"language":"Solidity","sources":{"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) - -pragma solidity ^0.8.0; - -import \"../utils/Context.sol\"; - -/** - * @dev Contract module which provides a basic access control mechanism, where - * there is an account (an owner) that can be granted exclusive access to - * specific functions. - * - * By default, the owner account will be the one that deploys the contract. This - * can later be changed with {transferOwnership}. - * - * This module is used through inheritance. It will make available the modifier - * `onlyOwner`, which can be applied to your functions to restrict their use to - * the owner. - */ -abstract contract Ownable is Context { - address private _owner; - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - /** - * @dev Initializes the contract setting the deployer as the initial owner. - */ - constructor() { - _transferOwnership(_msgSender()); - } - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - _checkOwner(); - _; - } - - /** - * @dev Returns the address of the current owner. - */ - function owner() public view virtual returns (address) { - return _owner; - } - - /** - * @dev Throws if the sender is not the owner. - */ - function _checkOwner() internal view virtual { - require(owner() == _msgSender(), \"Ownable: caller is not the owner\"); - } - - /** - * @dev Leaves the contract without owner. It will not be possible to call - * `onlyOwner` functions anymore. Can only be called by the current owner. - * - * NOTE: Renouncing ownership will leave the contract without an owner, - * thereby removing any functionality that is only available to the owner. - */ - function renounceOwnership() public virtual onlyOwner { - _transferOwnership(address(0)); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Can only be called by the current owner. - */ - function transferOwnership(address newOwner) public virtual onlyOwner { - require(newOwner != address(0), \"Ownable: new owner is the zero address\"); - _transferOwnership(newOwner); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Internal function without access restriction. - */ - function _transferOwnership(address newOwner) internal virtual { - address oldOwner = _owner; - _owner = newOwner; - emit OwnershipTransferred(oldOwner, newOwner); - } -} -"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/Context.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Provides information about the current execution context, including the - * sender of the transaction and its data. While these are generally available - * via msg.sender and msg.data, they should not be accessed in such a direct - * manner, since when dealing with meta-transactions the account sending and - * paying for execution may not be the actual sender (as far as an application - * is concerned). - * - * This contract is only required for intermediate, library-like contracts. - */ -abstract contract Context { - function _msgSender() internal view virtual returns (address) { - return msg.sender; - } - - function _msgData() internal view virtual returns (bytes calldata) { - return msg.data; - } -} -"},"lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol":{"content":"// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) -// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. - -pragma solidity ^0.8.0; - -/** - * @dev Library for managing - * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive - * types. - * - * Sets have the following properties: - * - * - Elements are added, removed, and checked for existence in constant time - * (O(1)). - * - Elements are enumerated in O(n). No guarantees are made on the ordering. - * - * ``` - * contract Example { - * // Add the library methods - * using EnumerableSet for EnumerableSet.AddressSet; - * - * // Declare a set state variable - * EnumerableSet.AddressSet private mySet; - * } - * ``` - * - * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) - * and `uint256` (`UintSet`) are supported. - * - * [WARNING] - * ==== - * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure - * unusable. - * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. - * - * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an - * array of EnumerableSet. - * ==== - */ -library EnumerableSet { - // To implement this library for multiple types with as little code - // repetition as possible, we write it in terms of a generic Set type with - // bytes32 values. - // The Set implementation uses private functions, and user-facing - // implementations (such as AddressSet) are just wrappers around the - // underlying Set. - // This means that we can only create new EnumerableSets for types that fit - // in bytes32. - - struct Set { - // Storage of set values - bytes32[] _values; - // Position of the value in the `values` array, plus 1 because index 0 - // means a value is not in the set. - mapping(bytes32 => uint256) _indexes; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function _add(Set storage set, bytes32 value) private returns (bool) { - if (!_contains(set, value)) { - set._values.push(value); - // The value is stored at length-1, but we add 1 to all indexes - // and use 0 as a sentinel value - set._indexes[value] = set._values.length; - return true; - } else { - return false; - } - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function _remove(Set storage set, bytes32 value) private returns (bool) { - // We read and store the value's index to prevent multiple reads from the same storage slot - uint256 valueIndex = set._indexes[value]; - - if (valueIndex != 0) { - // Equivalent to contains(set, value) - // To delete an element from the _values array in O(1), we swap the element to delete with the last one in - // the array, and then remove the last element (sometimes called as 'swap and pop'). - // This modifies the order of the array, as noted in {at}. - - uint256 toDeleteIndex = valueIndex - 1; - uint256 lastIndex = set._values.length - 1; - - if (lastIndex != toDeleteIndex) { - bytes32 lastValue = set._values[lastIndex]; - - // Move the last value to the index where the value to delete is - set._values[toDeleteIndex] = lastValue; - // Update the index for the moved value - set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex - } - - // Delete the slot where the moved value was stored - set._values.pop(); - - // Delete the index for the deleted slot - delete set._indexes[value]; - - return true; - } else { - return false; - } - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function _contains(Set storage set, bytes32 value) private view returns (bool) { - return set._indexes[value] != 0; - } - - /** - * @dev Returns the number of values on the set. O(1). - */ - function _length(Set storage set) private view returns (uint256) { - return set._values.length; - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function _at(Set storage set, uint256 index) private view returns (bytes32) { - return set._values[index]; - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function _values(Set storage set) private view returns (bytes32[] memory) { - return set._values; - } - - // Bytes32Set - - struct Bytes32Set { - Set _inner; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { - return _add(set._inner, value); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { - return _remove(set._inner, value); - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { - return _contains(set._inner, value); - } - - /** - * @dev Returns the number of values in the set. O(1). - */ - function length(Bytes32Set storage set) internal view returns (uint256) { - return _length(set._inner); - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { - return _at(set._inner, index); - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { - bytes32[] memory store = _values(set._inner); - bytes32[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // AddressSet - - struct AddressSet { - Set _inner; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function add(AddressSet storage set, address value) internal returns (bool) { - return _add(set._inner, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function remove(AddressSet storage set, address value) internal returns (bool) { - return _remove(set._inner, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function contains(AddressSet storage set, address value) internal view returns (bool) { - return _contains(set._inner, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Returns the number of values in the set. O(1). - */ - function length(AddressSet storage set) internal view returns (uint256) { - return _length(set._inner); - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(AddressSet storage set, uint256 index) internal view returns (address) { - return address(uint160(uint256(_at(set._inner, index)))); - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function values(AddressSet storage set) internal view returns (address[] memory) { - bytes32[] memory store = _values(set._inner); - address[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // UintSet - - struct UintSet { - Set _inner; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function add(UintSet storage set, uint256 value) internal returns (bool) { - return _add(set._inner, bytes32(value)); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function remove(UintSet storage set, uint256 value) internal returns (bool) { - return _remove(set._inner, bytes32(value)); - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function contains(UintSet storage set, uint256 value) internal view returns (bool) { - return _contains(set._inner, bytes32(value)); - } - - /** - * @dev Returns the number of values in the set. O(1). - */ - function length(UintSet storage set) internal view returns (uint256) { - return _length(set._inner); - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(UintSet storage set, uint256 index) internal view returns (uint256) { - return uint256(_at(set._inner, index)); - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function values(UintSet storage set) internal view returns (uint256[] memory) { - bytes32[] memory store = _values(set._inner); - uint256[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } -} -"},"src/IOperatorFilterRegistry.sol":{"content":"// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {EnumerableSet} from \"openzeppelin-contracts/utils/structs/EnumerableSet.sol\"; - -interface IOperatorFilterRegistry { - function isOperatorAllowed(address registrant, address operator) external returns (bool); - function register(address registrant) external; - function registerAndSubscribe(address registrant, address subscription) external; - function registerAndCopyEntries(address registrant, address registrantToCopy) external; - function updateOperator(address registrant, address operator, bool filtered) external; - function updateOperators(address registrant, address[] calldata operators, bool filtered) external; - function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; - function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; - function subscribe(address registrant, address registrantToSubscribe) external; - function unsubscribe(address registrant, bool copyExistingEntries) external; - function subscriptionOf(address addr) external returns (address registrant); - function subscribers(address registrant) external returns (address[] memory); - function subscriberAt(address registrant, uint256 index) external returns (address); - function copyEntriesOf(address registrant, address registrantToCopy) external; - function isOperatorFiltered(address registrant, address operator) external returns (bool); - function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); - function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); - function filteredOperators(address addr) external returns (address[] memory); - function filteredCodeHashes(address addr) external returns (bytes32[] memory); - function filteredOperatorAt(address registrant, uint256 index) external returns (address); - function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); - function isRegistered(address addr) external returns (bool); - function codeHashOf(address addr) external returns (bytes32); -} -"},"src/OperatorFilterRegistry.sol":{"content":"// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {IOperatorFilterRegistry} from \"./IOperatorFilterRegistry.sol\"; -import {Ownable} from \"openzeppelin-contracts/access/Ownable.sol\"; -import {EnumerableSet} from \"openzeppelin-contracts/utils/structs/EnumerableSet.sol\"; -import {OperatorFilterRegistryErrorsAndEvents} from \"./OperatorFilterRegistryErrorsAndEvents.sol\"; - -/** - * @title OperatorFilterRegistry - * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract: - * https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol - * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be - * * restricted according to the isOperatorAllowed function. - */ -contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents { - using EnumerableSet for EnumerableSet.AddressSet; - using EnumerableSet for EnumerableSet.Bytes32Set; - - /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052) - /// Note that this will also be a smart contract's codehash when making calls from its constructor. - bytes32 constant EOA_CODEHASH = keccak256(\"\"); - - mapping(address => EnumerableSet.AddressSet) private _filteredOperators; - mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes; - mapping(address => address) private _registrations; - mapping(address => EnumerableSet.AddressSet) private _subscribers; - - /** - * @notice restricts method caller to the address or EIP-173 \"owner()\" - */ - modifier onlyAddressOrOwner(address addr) { - if (msg.sender != addr) { - try Ownable(addr).owner() returns (address owner) { - if (msg.sender != owner) { - revert OnlyAddressOrOwner(); - } - } catch (bytes memory reason) { - if (reason.length == 0) { - revert NotOwnable(); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } - _; - } - - /** - * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns - * true if supplied registrant address is not registered. - */ - function isOperatorAllowed(address registrant, address operator) external view returns (bool) { - address registration = _registrations[registrant]; - if (registration != address(0)) { - EnumerableSet.AddressSet storage filteredOperatorsRef; - EnumerableSet.Bytes32Set storage filteredCodeHashesRef; - - filteredOperatorsRef = _filteredOperators[registration]; - filteredCodeHashesRef = _filteredCodeHashes[registration]; - - if (filteredOperatorsRef.contains(operator)) { - revert AddressFiltered(operator); - } - if (operator.code.length > 0) { - bytes32 codeHash = operator.codehash; - if (filteredCodeHashesRef.contains(codeHash)) { - revert CodeHashFiltered(operator, codeHash); - } - } - } - return true; - } - - ////////////////// - // AUTH METHODS // - ////////////////// - - /** - * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. - */ - function register(address registrant) external onlyAddressOrOwner(registrant) { - if (_registrations[registrant] != address(0)) { - revert AlreadyRegistered(); - } - _registrations[registrant] = registrant; - emit RegistrationUpdated(registrant, true); - } - - /** - * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. - * Note that this does not remove any filtered addresses or codeHashes. - * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. - */ - function unregister(address registrant) external onlyAddressOrOwner(registrant) { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - _subscribers[registration].remove(registrant); - emit SubscriptionUpdated(registrant, registration, false); - } - _registrations[registrant] = address(0); - emit RegistrationUpdated(registrant, false); - } - - /** - * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes. - */ - function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) { - address registration = _registrations[registrant]; - if (registration != address(0)) { - revert AlreadyRegistered(); - } - if (registrant == subscription) { - revert CannotSubscribeToSelf(); - } - address subscriptionRegistration = _registrations[subscription]; - if (subscriptionRegistration == address(0)) { - revert NotRegistered(subscription); - } - if (subscriptionRegistration != subscription) { - revert CannotSubscribeToRegistrantWithSubscription(subscription); - } - - _registrations[registrant] = subscription; - _subscribers[subscription].add(registrant); - emit RegistrationUpdated(registrant, true); - emit SubscriptionUpdated(registrant, subscription, true); - } - - /** - * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another - * address without subscribing. - */ - function registerAndCopyEntries(address registrant, address registrantToCopy) - external - onlyAddressOrOwner(registrant) - { - if (registrantToCopy == registrant) { - revert CannotCopyFromSelf(); - } - address registration = _registrations[registrant]; - if (registration != address(0)) { - revert AlreadyRegistered(); - } - address registrantRegistration = _registrations[registrantToCopy]; - if (registrantRegistration == address(0)) { - revert NotRegistered(registrantToCopy); - } - _registrations[registrant] = registrant; - emit RegistrationUpdated(registrant, true); - _copyEntries(registrant, registrantToCopy); - } - - /** - * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. - */ - function updateOperator(address registrant, address operator, bool filtered) - external - onlyAddressOrOwner(registrant) - { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; - - if (!filtered) { - bool removed = filteredOperatorsRef.remove(operator); - if (!removed) { - revert AddressNotFiltered(operator); - } - } else { - bool added = filteredOperatorsRef.add(operator); - if (!added) { - revert AddressAlreadyFiltered(operator); - } - } - emit OperatorUpdated(registrant, operator, filtered); - } - - /** - * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. - */ - function updateCodeHash(address registrant, bytes32 codeHash, bool filtered) - external - onlyAddressOrOwner(registrant) - { - if (codeHash == EOA_CODEHASH) { - revert CannotFilterEOAs(); - } - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; - - if (!filtered) { - bool removed = filteredCodeHashesRef.remove(codeHash); - if (!removed) { - revert CodeHashNotFiltered(codeHash); - } - } else { - bool added = filteredCodeHashesRef.add(codeHash); - if (!added) { - revert CodeHashAlreadyFiltered(codeHash); - } - } - emit CodeHashUpdated(registrant, codeHash, filtered); - } - - /** - * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. - */ - function updateOperators(address registrant, address[] calldata operators, bool filtered) - external - onlyAddressOrOwner(registrant) - { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; - uint256 operatorsLength = operators.length; - unchecked { - if (!filtered) { - for (uint256 i = 0; i < operatorsLength; ++i) { - address operator = operators[i]; - bool removed = filteredOperatorsRef.remove(operator); - if (!removed) { - revert AddressNotFiltered(operator); - } - } - } else { - for (uint256 i = 0; i < operatorsLength; ++i) { - address operator = operators[i]; - bool added = filteredOperatorsRef.add(operator); - if (!added) { - revert AddressAlreadyFiltered(operator); - } - } - } - } - emit OperatorsUpdated(registrant, operators, filtered); - } - - /** - * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. - */ - function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) - external - onlyAddressOrOwner(registrant) - { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; - uint256 codeHashesLength = codeHashes.length; - unchecked { - if (!filtered) { - for (uint256 i = 0; i < codeHashesLength; ++i) { - bytes32 codeHash = codeHashes[i]; - bool removed = filteredCodeHashesRef.remove(codeHash); - if (!removed) { - revert CodeHashNotFiltered(codeHash); - } - } - } else { - for (uint256 i = 0; i < codeHashesLength; ++i) { - bytes32 codeHash = codeHashes[i]; - if (codeHash == EOA_CODEHASH) { - revert CannotFilterEOAs(); - } - bool added = filteredCodeHashesRef.add(codeHash); - if (!added) { - revert CodeHashAlreadyFiltered(codeHash); - } - } - } - } - emit CodeHashesUpdated(registrant, codeHashes, filtered); - } - - /** - * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous - * subscription if present. - * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, - * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be - * used. - */ - function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) { - if (registrant == newSubscription) { - revert CannotSubscribeToSelf(); - } - if (newSubscription == address(0)) { - revert CannotSubscribeToZeroAddress(); - } - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration == newSubscription) { - revert AlreadySubscribed(newSubscription); - } - address newSubscriptionRegistration = _registrations[newSubscription]; - if (newSubscriptionRegistration == address(0)) { - revert NotRegistered(newSubscription); - } - if (newSubscriptionRegistration != newSubscription) { - revert CannotSubscribeToRegistrantWithSubscription(newSubscription); - } - - if (registration != registrant) { - _subscribers[registration].remove(registrant); - emit SubscriptionUpdated(registrant, registration, false); - } - _registrations[registrant] = newSubscription; - _subscribers[newSubscription].add(registrant); - emit SubscriptionUpdated(registrant, newSubscription, true); - } - - /** - * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. - */ - function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration == registrant) { - revert NotSubscribed(); - } - _subscribers[registration].remove(registrant); - _registrations[registrant] = registrant; - emit SubscriptionUpdated(registrant, registration, false); - if (copyExistingEntries) { - _copyEntries(registrant, registration); - } - } - - /** - * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. - */ - function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { - if (registrant == registrantToCopy) { - revert CannotCopyFromSelf(); - } - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - address registrantRegistration = _registrations[registrantToCopy]; - if (registrantRegistration == address(0)) { - revert NotRegistered(registrantToCopy); - } - _copyEntries(registrant, registrantToCopy); - } - - /// @dev helper to copy entries from registrantToCopy to registrant and emit events - function _copyEntries(address registrant, address registrantToCopy) private { - EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy]; - EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy]; - uint256 filteredOperatorsLength = filteredOperatorsRef.length(); - uint256 filteredCodeHashesLength = filteredCodeHashesRef.length(); - unchecked { - for (uint256 i = 0; i < filteredOperatorsLength; ++i) { - address operator = filteredOperatorsRef.at(i); - bool added = _filteredOperators[registrant].add(operator); - if (added) { - emit OperatorUpdated(registrant, operator, true); - } - } - for (uint256 i = 0; i < filteredCodeHashesLength; ++i) { - bytes32 codehash = filteredCodeHashesRef.at(i); - bool added = _filteredCodeHashes[registrant].add(codehash); - if (added) { - emit CodeHashUpdated(registrant, codehash, true); - } - } - } - } - - ////////////////// - // VIEW METHODS // - ////////////////// - - /** - * @notice Get the subscription address of a given registrant, if any. - */ - function subscriptionOf(address registrant) external view returns (address subscription) { - subscription = _registrations[registrant]; - if (subscription == address(0)) { - revert NotRegistered(registrant); - } else if (subscription == registrant) { - subscription = address(0); - } - } - - /** - * @notice Get the set of addresses subscribed to a given registrant. - * Note that order is not guaranteed as updates are made. - */ - function subscribers(address registrant) external view returns (address[] memory) { - return _subscribers[registrant].values(); - } - - /** - * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. - * Note that order is not guaranteed as updates are made. - */ - function subscriberAt(address registrant, uint256 index) external view returns (address) { - return _subscribers[registrant].at(index); - } - - /** - * @notice Returns true if operator is filtered by a given address or its subscription. - */ - function isOperatorFiltered(address registrant, address operator) external view returns (bool) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredOperators[registration].contains(operator); - } - return _filteredOperators[registrant].contains(operator); - } - - /** - * @notice Returns true if a codeHash is filtered by a given address or its subscription. - */ - function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].contains(codeHash); - } - return _filteredCodeHashes[registrant].contains(codeHash); - } - - /** - * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. - */ - function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) { - bytes32 codeHash = operatorWithCode.codehash; - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].contains(codeHash); - } - return _filteredCodeHashes[registrant].contains(codeHash); - } - - /** - * @notice Returns true if an address has registered - */ - function isRegistered(address registrant) external view returns (bool) { - return _registrations[registrant] != address(0); - } - - /** - * @notice Returns a list of filtered operators for a given address or its subscription. - */ - function filteredOperators(address registrant) external view returns (address[] memory) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredOperators[registration].values(); - } - return _filteredOperators[registrant].values(); - } - - /** - * @notice Returns the set of filtered codeHashes for a given address or its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].values(); - } - return _filteredCodeHashes[registrant].values(); - } - - /** - * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or - * its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredOperatorAt(address registrant, uint256 index) external view returns (address) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredOperators[registration].at(index); - } - return _filteredOperators[registrant].at(index); - } - - /** - * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or - * its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].at(index); - } - return _filteredCodeHashes[registrant].at(index); - } - - /// @dev Convenience method to compute the code hash of an arbitrary contract - function codeHashOf(address a) external view returns (bytes32) { - return a.codehash; - } -} -"},"src/OperatorFilterRegistryErrorsAndEvents.sol":{"content":"// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -contract OperatorFilterRegistryErrorsAndEvents { - error CannotFilterEOAs(); - error AddressAlreadyFiltered(address operator); - error AddressNotFiltered(address operator); - error CodeHashAlreadyFiltered(bytes32 codeHash); - error CodeHashNotFiltered(bytes32 codeHash); - error OnlyAddressOrOwner(); - error NotRegistered(address registrant); - error AlreadyRegistered(); - error AlreadySubscribed(address subscription); - error NotSubscribed(); - error CannotUpdateWhileSubscribed(address subscription); - error CannotSubscribeToSelf(); - error CannotSubscribeToZeroAddress(); - error NotOwnable(); - error AddressFiltered(address filtered); - error CodeHashFiltered(address account, bytes32 codeHash); - error CannotSubscribeToRegistrantWithSubscription(address registrant); - error CannotCopyFromSelf(); - - event RegistrationUpdated(address indexed registrant, bool indexed registered); - event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered); - event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered); - event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered); - event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered); - event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed); -}"}},"settings":{"remappings":["ds-test/=lib/forge-std/lib/ds-test/src/","forge-std/=lib/forge-std/src/","openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/","solmate/=lib/solmate/src/"],"optimizer":{"enabled":true,"runs":1000000},"metadata":{"bytecodeHash":"ipfs"},"outputSelection":{"*":{"":["ast"],"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"]}},"evmVersion":"london","libraries":{}}} \ No newline at end of file diff --git a/script/verification/OwnedRegistrantStandardJsonInput.json b/script/verification/OwnedRegistrantStandardJsonInput.json deleted file mode 100644 index 1f9a4a5..0000000 --- a/script/verification/OwnedRegistrantStandardJsonInput.json +++ /dev/null @@ -1 +0,0 @@ -{"language":"Solidity","sources":{"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() external {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n"},"src/IOperatorFilterRegistry.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {EnumerableSet} from \"openzeppelin-contracts/utils/structs/EnumerableSet.sol\";\n\ninterface IOperatorFilterRegistry {\n function isOperatorAllowed(address registrant, address operator) external returns (bool);\n function register(address registrant) external;\n function registerAndSubscribe(address registrant, address subscription) external;\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n function updateOperator(address registrant, address operator, bool filtered) external;\n function updateOperators(address registrant, address[] calldata operators, bool filtered) external;\n function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;\n function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;\n function subscribe(address registrant, address registrantToSubscribe) external;\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n function subscriptionOf(address addr) external returns (address registrant);\n function subscribers(address registrant) external returns (address[] memory);\n function subscriberAt(address registrant, uint256 index) external returns (address);\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n function filteredOperators(address addr) external returns (address[] memory);\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n function isRegistered(address addr) external returns (bool);\n function codeHashOf(address addr) external returns (bytes32);\n}\n"},"src/OwnedRegistrant.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {IOperatorFilterRegistry} from \"./IOperatorFilterRegistry.sol\";\nimport {Ownable2Step} from \"openzeppelin-contracts/access/Ownable2Step.sol\";\n\n/**\n * @title OwnedRegistrant\n * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries,\n * to facilitate a subscription whose ownership can be transferred.\n */\ncontract OwnedRegistrant is Ownable2Step {\n address constant registry = 0x000000000000AAeB6D7670E522A718067333cd4E;\n\n constructor(address _owner) {\n IOperatorFilterRegistry(registry).register(address(this));\n transferOwnership(_owner);\n }\n}\n"}},"settings":{"remappings":["ds-test/=lib/forge-std/lib/ds-test/src/","forge-std/=lib/forge-std/src/","openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/","solmate/=lib/solmate/src/"],"optimizer":{"enabled":true,"runs":1000000},"metadata":{"bytecodeHash":"ipfs"},"outputSelection":{"*":{"":["ast"],"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"]}},"evmVersion":"london","libraries":{}}} diff --git a/script/verification/README.md b/script/verification/README.md deleted file mode 100644 index 21dab6f..0000000 --- a/script/verification/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Verifying OperatorFilterRegistry and OwnedRegistrant - -To verify the contracts deployed by the scripts, when verifying on (e.g.) Etherscan, select "Solidity (Standard-Json-Input)" for Compiler Type, and MIT for license. - -Then, select and upload the relevant JSON file. \ No newline at end of file diff --git a/src/DefaultOperatorFilterer.sol b/src/DefaultOperatorFilterer.sol deleted file mode 100644 index 58c0df9..0000000 --- a/src/DefaultOperatorFilterer.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFilterer} from "./OperatorFilterer.sol"; -import {CANONICAL_CORI_SUBSCRIPTION} from "./lib/Constants.sol"; -/** - * @title DefaultOperatorFilterer - * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. - * @dev Please note that if your token contract does not provide an owner with EIP-173, it must provide - * administration methods on the contract itself to interact with the registry otherwise the subscription - * will be locked to the options set during construction. - */ - -abstract contract DefaultOperatorFilterer is OperatorFilterer { - /// @dev The constructor that is called when the contract is being deployed. - constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {} -} diff --git a/src/IOperatorFilterRegistry.sol b/src/IOperatorFilterRegistry.sol deleted file mode 100644 index 8cc4984..0000000 --- a/src/IOperatorFilterRegistry.sol +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -interface IOperatorFilterRegistry { - /** - * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns - * true if supplied registrant address is not registered. - */ - function isOperatorAllowed(address registrant, address operator) external view returns (bool); - - /** - * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. - */ - function register(address registrant) external; - - /** - * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. - */ - function registerAndSubscribe(address registrant, address subscription) external; - - /** - * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another - * address without subscribing. - */ - function registerAndCopyEntries(address registrant, address registrantToCopy) external; - - /** - * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. - * Note that this does not remove any filtered addresses or codeHashes. - * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. - */ - function unregister(address addr) external; - - /** - * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. - */ - function updateOperator(address registrant, address operator, bool filtered) external; - - /** - * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. - */ - function updateOperators(address registrant, address[] calldata operators, bool filtered) external; - - /** - * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. - */ - function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; - - /** - * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. - */ - function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; - - /** - * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous - * subscription if present. - * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, - * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be - * used. - */ - function subscribe(address registrant, address registrantToSubscribe) external; - - /** - * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. - */ - function unsubscribe(address registrant, bool copyExistingEntries) external; - - /** - * @notice Get the subscription address of a given registrant, if any. - */ - function subscriptionOf(address addr) external returns (address registrant); - - /** - * @notice Get the set of addresses subscribed to a given registrant. - * Note that order is not guaranteed as updates are made. - */ - function subscribers(address registrant) external returns (address[] memory); - - /** - * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. - * Note that order is not guaranteed as updates are made. - */ - function subscriberAt(address registrant, uint256 index) external returns (address); - - /** - * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. - */ - function copyEntriesOf(address registrant, address registrantToCopy) external; - - /** - * @notice Returns true if operator is filtered by a given address or its subscription. - */ - function isOperatorFiltered(address registrant, address operator) external returns (bool); - - /** - * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. - */ - function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); - - /** - * @notice Returns true if a codeHash is filtered by a given address or its subscription. - */ - function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); - - /** - * @notice Returns a list of filtered operators for a given address or its subscription. - */ - function filteredOperators(address addr) external returns (address[] memory); - - /** - * @notice Returns the set of filtered codeHashes for a given address or its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredCodeHashes(address addr) external returns (bytes32[] memory); - - /** - * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or - * its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredOperatorAt(address registrant, uint256 index) external returns (address); - - /** - * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or - * its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); - - /** - * @notice Returns true if an address has registered - */ - function isRegistered(address addr) external returns (bool); - - /** - * @dev Convenience method to compute the code hash of an arbitrary contract - */ - function codeHashOf(address addr) external returns (bytes32); -} diff --git a/src/OperatorFilterRegistry.sol b/src/OperatorFilterRegistry.sol deleted file mode 100644 index a279697..0000000 --- a/src/OperatorFilterRegistry.sol +++ /dev/null @@ -1,560 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; -import {EnumerableSet} from "openzeppelin-contracts/utils/structs/EnumerableSet.sol"; -import {OperatorFilterRegistryErrorsAndEvents} from "./OperatorFilterRegistryErrorsAndEvents.sol"; - -/** - * @title OperatorFilterRegistry - * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract: - * https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol - * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be - * * restricted according to the isOperatorAllowed function. - */ -contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents { - using EnumerableSet for EnumerableSet.AddressSet; - using EnumerableSet for EnumerableSet.Bytes32Set; - - /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052) - /// Note that this will also be a smart contract's codehash when making calls from its constructor. - bytes32 constant EOA_CODEHASH = keccak256(""); - - mapping(address => EnumerableSet.AddressSet) private _filteredOperators; - mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes; - mapping(address => address) private _registrations; - mapping(address => EnumerableSet.AddressSet) private _subscribers; - - /** - * @notice Restricts method caller to the address or EIP-173 "owner()" - */ - modifier onlyAddressOrOwner(address addr) { - if (msg.sender != addr) { - try Ownable(addr).owner() returns (address owner) { - if (msg.sender != owner) { - revert OnlyAddressOrOwner(); - } - } catch (bytes memory reason) { - if (reason.length == 0) { - revert NotOwnable(); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } - _; - } - - /** - * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns - * true if supplied registrant address is not registered. - * Note that this method will *revert* if an operator or its codehash is filtered with an error that is - * more informational than a false boolean, so smart contracts that query this method for informational - * purposes will need to wrap in a try/catch or perform a low-level staticcall in order to handle the case - * that an operator is filtered. - */ - function isOperatorAllowed(address registrant, address operator) external view returns (bool) { - address registration = _registrations[registrant]; - if (registration != address(0)) { - EnumerableSet.AddressSet storage filteredOperatorsRef; - EnumerableSet.Bytes32Set storage filteredCodeHashesRef; - - filteredOperatorsRef = _filteredOperators[registration]; - filteredCodeHashesRef = _filteredCodeHashes[registration]; - - if (filteredOperatorsRef.contains(operator)) { - revert AddressFiltered(operator); - } - if (operator.code.length > 0) { - bytes32 codeHash = operator.codehash; - if (filteredCodeHashesRef.contains(codeHash)) { - revert CodeHashFiltered(operator, codeHash); - } - } - } - return true; - } - - ////////////////// - // AUTH METHODS // - ////////////////// - - /** - * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. - */ - function register(address registrant) external onlyAddressOrOwner(registrant) { - if (_registrations[registrant] != address(0)) { - revert AlreadyRegistered(); - } - _registrations[registrant] = registrant; - emit RegistrationUpdated(registrant, true); - } - - /** - * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. - * Note that this does not remove any filtered addresses or codeHashes. - * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. - */ - function unregister(address registrant) external onlyAddressOrOwner(registrant) { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - _subscribers[registration].remove(registrant); - emit SubscriptionUpdated(registrant, registration, false); - } - _registrations[registrant] = address(0); - emit RegistrationUpdated(registrant, false); - } - - /** - * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. - */ - function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) { - address registration = _registrations[registrant]; - if (registration != address(0)) { - revert AlreadyRegistered(); - } - if (registrant == subscription) { - revert CannotSubscribeToSelf(); - } - address subscriptionRegistration = _registrations[subscription]; - if (subscriptionRegistration == address(0)) { - revert NotRegistered(subscription); - } - if (subscriptionRegistration != subscription) { - revert CannotSubscribeToRegistrantWithSubscription(subscription); - } - - _registrations[registrant] = subscription; - _subscribers[subscription].add(registrant); - emit RegistrationUpdated(registrant, true); - emit SubscriptionUpdated(registrant, subscription, true); - } - - /** - * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another - * address without subscribing. - */ - function registerAndCopyEntries(address registrant, address registrantToCopy) - external - onlyAddressOrOwner(registrant) - { - if (registrantToCopy == registrant) { - revert CannotCopyFromSelf(); - } - address registration = _registrations[registrant]; - if (registration != address(0)) { - revert AlreadyRegistered(); - } - address registrantRegistration = _registrations[registrantToCopy]; - if (registrantRegistration == address(0)) { - revert NotRegistered(registrantToCopy); - } - _registrations[registrant] = registrant; - emit RegistrationUpdated(registrant, true); - _copyEntries(registrant, registrantToCopy); - } - - /** - * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. - */ - function updateOperator(address registrant, address operator, bool filtered) - external - onlyAddressOrOwner(registrant) - { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; - - if (!filtered) { - bool removed = filteredOperatorsRef.remove(operator); - if (!removed) { - revert AddressNotFiltered(operator); - } - } else { - bool added = filteredOperatorsRef.add(operator); - if (!added) { - revert AddressAlreadyFiltered(operator); - } - } - emit OperatorUpdated(registrant, operator, filtered); - } - - /** - * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. - * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior, - * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any - * un-initialized account. Since un-initialized accounts have no code, the registry will not validate - * that an un-initalized account's codeHash is not filtered. By the time an account is able to - * act as an operator (an account is initialized or a smart contract exclusively in the context of its - * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered. - */ - function updateCodeHash(address registrant, bytes32 codeHash, bool filtered) - external - onlyAddressOrOwner(registrant) - { - if (codeHash == EOA_CODEHASH) { - revert CannotFilterEOAs(); - } - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; - - if (!filtered) { - bool removed = filteredCodeHashesRef.remove(codeHash); - if (!removed) { - revert CodeHashNotFiltered(codeHash); - } - } else { - bool added = filteredCodeHashesRef.add(codeHash); - if (!added) { - revert CodeHashAlreadyFiltered(codeHash); - } - } - emit CodeHashUpdated(registrant, codeHash, filtered); - } - - /** - * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. - */ - function updateOperators(address registrant, address[] calldata operators, bool filtered) - external - onlyAddressOrOwner(registrant) - { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; - uint256 operatorsLength = operators.length; - if (!filtered) { - for (uint256 i = 0; i < operatorsLength;) { - address operator = operators[i]; - bool removed = filteredOperatorsRef.remove(operator); - if (!removed) { - revert AddressNotFiltered(operator); - } - unchecked { - ++i; - } - } - } else { - for (uint256 i = 0; i < operatorsLength;) { - address operator = operators[i]; - bool added = filteredOperatorsRef.add(operator); - if (!added) { - revert AddressAlreadyFiltered(operator); - } - unchecked { - ++i; - } - } - } - emit OperatorsUpdated(registrant, operators, filtered); - } - - /** - * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. - * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior, - * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any - * un-initialized account. Since un-initialized accounts have no code, the registry will not validate - * that an un-initalized account's codeHash is not filtered. By the time an account is able to - * act as an operator (an account is initialized or a smart contract exclusively in the context of its - * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered. - */ - function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) - external - onlyAddressOrOwner(registrant) - { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; - uint256 codeHashesLength = codeHashes.length; - if (!filtered) { - for (uint256 i = 0; i < codeHashesLength;) { - bytes32 codeHash = codeHashes[i]; - bool removed = filteredCodeHashesRef.remove(codeHash); - if (!removed) { - revert CodeHashNotFiltered(codeHash); - } - unchecked { - ++i; - } - } - } else { - for (uint256 i = 0; i < codeHashesLength;) { - bytes32 codeHash = codeHashes[i]; - if (codeHash == EOA_CODEHASH) { - revert CannotFilterEOAs(); - } - bool added = filteredCodeHashesRef.add(codeHash); - if (!added) { - revert CodeHashAlreadyFiltered(codeHash); - } - unchecked { - ++i; - } - } - } - emit CodeHashesUpdated(registrant, codeHashes, filtered); - } - - /** - * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous - * subscription if present. - * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, - * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be - * used. - */ - function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) { - if (registrant == newSubscription) { - revert CannotSubscribeToSelf(); - } - if (newSubscription == address(0)) { - revert CannotSubscribeToZeroAddress(); - } - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration == newSubscription) { - revert AlreadySubscribed(newSubscription); - } - address newSubscriptionRegistration = _registrations[newSubscription]; - if (newSubscriptionRegistration == address(0)) { - revert NotRegistered(newSubscription); - } - if (newSubscriptionRegistration != newSubscription) { - revert CannotSubscribeToRegistrantWithSubscription(newSubscription); - } - - if (registration != registrant) { - _subscribers[registration].remove(registrant); - emit SubscriptionUpdated(registrant, registration, false); - } - _registrations[registrant] = newSubscription; - _subscribers[newSubscription].add(registrant); - emit SubscriptionUpdated(registrant, newSubscription, true); - } - - /** - * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. - */ - function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration == registrant) { - revert NotSubscribed(); - } - _subscribers[registration].remove(registrant); - _registrations[registrant] = registrant; - emit SubscriptionUpdated(registrant, registration, false); - if (copyExistingEntries) { - _copyEntries(registrant, registration); - } - } - - /** - * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. - */ - function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { - if (registrant == registrantToCopy) { - revert CannotCopyFromSelf(); - } - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - address registrantRegistration = _registrations[registrantToCopy]; - if (registrantRegistration == address(0)) { - revert NotRegistered(registrantToCopy); - } - _copyEntries(registrant, registrantToCopy); - } - - /// @dev helper to copy entries from registrantToCopy to registrant and emit events - function _copyEntries(address registrant, address registrantToCopy) private { - EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy]; - EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy]; - uint256 filteredOperatorsLength = filteredOperatorsRef.length(); - uint256 filteredCodeHashesLength = filteredCodeHashesRef.length(); - for (uint256 i = 0; i < filteredOperatorsLength;) { - address operator = filteredOperatorsRef.at(i); - bool added = _filteredOperators[registrant].add(operator); - if (added) { - emit OperatorUpdated(registrant, operator, true); - } - unchecked { - ++i; - } - } - for (uint256 i = 0; i < filteredCodeHashesLength;) { - bytes32 codehash = filteredCodeHashesRef.at(i); - bool added = _filteredCodeHashes[registrant].add(codehash); - if (added) { - emit CodeHashUpdated(registrant, codehash, true); - } - unchecked { - ++i; - } - } - } - - ////////////////// - // VIEW METHODS // - ////////////////// - - /** - * @notice Get the subscription address of a given registrant, if any. - */ - function subscriptionOf(address registrant) external view returns (address subscription) { - subscription = _registrations[registrant]; - if (subscription == address(0)) { - revert NotRegistered(registrant); - } else if (subscription == registrant) { - subscription = address(0); - } - } - - /** - * @notice Get the set of addresses subscribed to a given registrant. - * Note that order is not guaranteed as updates are made. - */ - function subscribers(address registrant) external view returns (address[] memory) { - return _subscribers[registrant].values(); - } - - /** - * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. - * Note that order is not guaranteed as updates are made. - */ - function subscriberAt(address registrant, uint256 index) external view returns (address) { - return _subscribers[registrant].at(index); - } - - /** - * @notice Returns true if operator is filtered by a given address or its subscription. - */ - function isOperatorFiltered(address registrant, address operator) external view returns (bool) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredOperators[registration].contains(operator); - } - return _filteredOperators[registrant].contains(operator); - } - - /** - * @notice Returns true if a codeHash is filtered by a given address or its subscription. - */ - function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].contains(codeHash); - } - return _filteredCodeHashes[registrant].contains(codeHash); - } - - /** - * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. - */ - function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) { - bytes32 codeHash = operatorWithCode.codehash; - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].contains(codeHash); - } - return _filteredCodeHashes[registrant].contains(codeHash); - } - - /** - * @notice Returns true if an address has registered - */ - function isRegistered(address registrant) external view returns (bool) { - return _registrations[registrant] != address(0); - } - - /** - * @notice Returns a list of filtered operators for a given address or its subscription. - */ - function filteredOperators(address registrant) external view returns (address[] memory) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredOperators[registration].values(); - } - return _filteredOperators[registrant].values(); - } - - /** - * @notice Returns the set of filtered codeHashes for a given address or its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].values(); - } - return _filteredCodeHashes[registrant].values(); - } - - /** - * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or - * its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredOperatorAt(address registrant, uint256 index) external view returns (address) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredOperators[registration].at(index); - } - return _filteredOperators[registrant].at(index); - } - - /** - * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or - * its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].at(index); - } - return _filteredCodeHashes[registrant].at(index); - } - - /** - * @dev Convenience method to compute the code hash of an arbitrary contract - */ - function codeHashOf(address a) external view returns (bytes32) { - return a.codehash; - } -} diff --git a/src/OperatorFilterRegistryErrorsAndEvents.sol b/src/OperatorFilterRegistryErrorsAndEvents.sol deleted file mode 100644 index 8321402..0000000 --- a/src/OperatorFilterRegistryErrorsAndEvents.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -contract OperatorFilterRegistryErrorsAndEvents { - /// @notice Emitted when trying to register an address that has no code. - error CannotFilterEOAs(); - - /// @notice Emitted when trying to add an address that is already filtered. - error AddressAlreadyFiltered(address operator); - - /// @notice Emitted when trying to remove an address that is not filtered. - error AddressNotFiltered(address operator); - - /// @notice Emitted when trying to add a codehash that is already filtered. - error CodeHashAlreadyFiltered(bytes32 codeHash); - - /// @notice Emitted when trying to remove a codehash that is not filtered. - error CodeHashNotFiltered(bytes32 codeHash); - - /// @notice Emitted when the caller is not the address or EIP-173 "owner()" - error OnlyAddressOrOwner(); - - /// @notice Emitted when the registrant is not registered. - error NotRegistered(address registrant); - - /// @notice Emitted when the registrant is already registered. - error AlreadyRegistered(); - - /// @notice Emitted when the registrant is already subscribed. - error AlreadySubscribed(address subscription); - - /// @notice Emitted when the registrant is not subscribed. - error NotSubscribed(); - - /// @notice Emitted when trying to update a registration where the registrant is already subscribed. - error CannotUpdateWhileSubscribed(address subscription); - - /// @notice Emitted when trying to subscribe to itself. - error CannotSubscribeToSelf(); - - /// @notice Emitted when trying to subscribe to the zero address. - error CannotSubscribeToZeroAddress(); - - /// @notice Emitted when trying to register and the contract is not ownable (EIP-173 "owner()") - error NotOwnable(); - - /// @notice Emitted when an address is filtered. - error AddressFiltered(address filtered); - - /// @notice Emitted when a codeHash is filtered. - error CodeHashFiltered(address account, bytes32 codeHash); - - /// @notice Emited when trying to register to a registrant with a subscription. - error CannotSubscribeToRegistrantWithSubscription(address registrant); - - /// @notice Emitted when trying to copy a registration from itself. - error CannotCopyFromSelf(); - - /// @notice Emitted when a registration is updated. - event RegistrationUpdated(address indexed registrant, bool indexed registered); - - /// @notice Emitted when an operator is updated. - event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered); - - /// @notice Emitted when multiple operators are updated. - event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered); - - /// @notice Emitted when a codeHash is updated. - event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered); - - /// @notice Emitted when multiple codeHashes are updated. - event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered); - - /// @notice Emitted when a subscription is updated. - event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed); -} diff --git a/src/OperatorFilterer.sol b/src/OperatorFilterer.sol deleted file mode 100644 index cea5fc5..0000000 --- a/src/OperatorFilterer.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; -import {CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS} from "./lib/Constants.sol"; -/** - * @title OperatorFilterer - * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another - * registrant's entries in the OperatorFilterRegistry. - * @dev This smart contract is meant to be inherited by token contracts so they can use the following: - * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. - * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. - * Please note that if your token contract does not provide an owner with EIP-173, it must provide - * administration methods on the contract itself to interact with the registry otherwise the subscription - * will be locked to the options set during construction. - */ - -abstract contract OperatorFilterer { - /// @dev Emitted when an operator is not allowed. - error OperatorNotAllowed(address operator); - - IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = - IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS); - - /// @dev The constructor that is called when the contract is being deployed. - constructor(address subscriptionOrRegistrantToCopy, bool subscribe) { - // If an inheriting token contract is deployed to a network without the registry deployed, the modifier - // will not revert, but the contract will need to be registered with the registry once it is deployed in - // order for the modifier to filter addresses. - if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { - if (subscribe) { - OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); - } else { - if (subscriptionOrRegistrantToCopy != address(0)) { - OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); - } else { - OPERATOR_FILTER_REGISTRY.register(address(this)); - } - } - } - } - - /** - * @dev A helper function to check if an operator is allowed. - */ - modifier onlyAllowedOperator(address from) virtual { - // Allow spending tokens from addresses with balance - // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred - // from an EOA. - if (from != msg.sender) { - _checkFilterOperator(msg.sender); - } - _; - } - - /** - * @dev A helper function to check if an operator approval is allowed. - */ - modifier onlyAllowedOperatorApproval(address operator) virtual { - _checkFilterOperator(operator); - _; - } - - /** - * @dev A helper function to check if an operator is allowed. - */ - function _checkFilterOperator(address operator) internal view virtual { - // Check registry code length to facilitate testing in environments without a deployed registry. - if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { - // under normal circumstances, this function will revert rather than return false, but inheriting contracts - // may specify their own OperatorFilterRegistry implementations, which may behave differently - if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { - revert OperatorNotAllowed(operator); - } - } - } -} diff --git a/src/OwnedRegistrant.sol b/src/OwnedRegistrant.sol deleted file mode 100644 index af2bd05..0000000 --- a/src/OwnedRegistrant.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; -import {Ownable2Step} from "openzeppelin-contracts/access/Ownable2Step.sol"; -import {CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS} from "./lib/Constants.sol"; -/** - * @title OwnedRegistrant - * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries, - * to facilitate a subscription whose ownership can be transferred. - */ - -contract OwnedRegistrant is Ownable2Step { - /// @dev The constructor that is called when the contract is being deployed. - constructor(address _owner) { - IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS).register(address(this)); - transferOwnership(_owner); - } -} diff --git a/src/RevokableDefaultOperatorFilterer.sol b/src/RevokableDefaultOperatorFilterer.sol deleted file mode 100644 index 6e0ec66..0000000 --- a/src/RevokableDefaultOperatorFilterer.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableOperatorFilterer} from "./RevokableOperatorFilterer.sol"; -import {CANONICAL_CORI_SUBSCRIPTION, CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS} from "./lib/Constants.sol"; -/** - * @title RevokableDefaultOperatorFilterer - * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription. - * Note that OpenSea will disable creator earnings enforcement if filtered operators begin fulfilling orders - * on-chain, eg, if the registry is revoked or bypassed. - */ - -abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer { - /// @dev The constructor that is called when the contract is being deployed. - constructor() - RevokableOperatorFilterer(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS, CANONICAL_CORI_SUBSCRIPTION, true) - {} -} diff --git a/src/RevokableOperatorFilterer.sol b/src/RevokableOperatorFilterer.sol deleted file mode 100644 index a2ad1d9..0000000 --- a/src/RevokableOperatorFilterer.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {UpdatableOperatorFilterer} from "./UpdatableOperatorFilterer.sol"; -import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; - -/** - * @title RevokableOperatorFilterer - * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The - * Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at - * any point. As implemented, this abstract contract allows the contract owner to permanently skip the - * OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry - * address cannot be further updated. - * Note that OpenSea will still disable creator earnings enforcement if filtered operators begin fulfilling orders - * on-chain, eg, if the registry is revoked or bypassed. - */ -abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer { - /// @dev Emitted when the registry has already been revoked. - error RegistryHasBeenRevoked(); - /// @dev Emitted when the initial registry address is attempted to be set to the zero address. - error InitialRegistryAddressCannotBeZeroAddress(); - - event OperatorFilterRegistryRevoked(); - - bool public isOperatorFilterRegistryRevoked; - - /// @dev The constructor that is called when the contract is being deployed. - constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) - UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe) - { - // don't allow creating a contract with a permanently revoked registry - if (_registry == address(0)) { - revert InitialRegistryAddressCannotBeZeroAddress(); - } - } - - /** - * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero - * address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner. - */ - function updateOperatorFilterRegistryAddress(address newRegistry) public override { - if (msg.sender != owner()) { - revert OnlyOwner(); - } - // if registry has been revoked, do not allow further updates - if (isOperatorFilterRegistryRevoked) { - revert RegistryHasBeenRevoked(); - } - - operatorFilterRegistry = IOperatorFilterRegistry(newRegistry); - emit OperatorFilterRegistryAddressUpdated(newRegistry); - } - - /** - * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner. - */ - function revokeOperatorFilterRegistry() public { - if (msg.sender != owner()) { - revert OnlyOwner(); - } - // if registry has been revoked, do not allow further updates - if (isOperatorFilterRegistryRevoked) { - revert RegistryHasBeenRevoked(); - } - - // set to zero address to bypass checks - operatorFilterRegistry = IOperatorFilterRegistry(address(0)); - isOperatorFilterRegistryRevoked = true; - emit OperatorFilterRegistryRevoked(); - } -} diff --git a/src/UpdatableOperatorFilterer.sol b/src/UpdatableOperatorFilterer.sol deleted file mode 100644 index 74c4257..0000000 --- a/src/UpdatableOperatorFilterer.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; - -/** - * @title UpdatableOperatorFilterer - * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another - * registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the - * OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address, - * which will bypass registry checks. - * Note that OpenSea will still disable creator earnings enforcement if filtered operators begin fulfilling orders - * on-chain, eg, if the registry is revoked or bypassed. - * @dev This smart contract is meant to be inherited by token contracts so they can use the following: - * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. - * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. - */ -abstract contract UpdatableOperatorFilterer { - /// @dev Emitted when an operator is not allowed. - error OperatorNotAllowed(address operator); - /// @dev Emitted when someone other than the owner is trying to call an only owner function. - error OnlyOwner(); - - event OperatorFilterRegistryAddressUpdated(address newRegistry); - - IOperatorFilterRegistry public operatorFilterRegistry; - - /// @dev The constructor that is called when the contract is being deployed. - constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) { - IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry); - operatorFilterRegistry = registry; - // If an inheriting token contract is deployed to a network without the registry deployed, the modifier - // will not revert, but the contract will need to be registered with the registry once it is deployed in - // order for the modifier to filter addresses. - if (address(registry).code.length > 0) { - if (subscribe) { - registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); - } else { - if (subscriptionOrRegistrantToCopy != address(0)) { - registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); - } else { - registry.register(address(this)); - } - } - } - } - - /** - * @dev A helper function to check if the operator is allowed. - */ - modifier onlyAllowedOperator(address from) virtual { - // Allow spending tokens from addresses with balance - // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred - // from an EOA. - if (from != msg.sender) { - _checkFilterOperator(msg.sender); - } - _; - } - - /** - * @dev A helper function to check if the operator approval is allowed. - */ - modifier onlyAllowedOperatorApproval(address operator) virtual { - _checkFilterOperator(operator); - _; - } - - /** - * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero - * address, checks will be bypassed. OnlyOwner. - */ - function updateOperatorFilterRegistryAddress(address newRegistry) public virtual { - if (msg.sender != owner()) { - revert OnlyOwner(); - } - operatorFilterRegistry = IOperatorFilterRegistry(newRegistry); - emit OperatorFilterRegistryAddressUpdated(newRegistry); - } - - /** - * @dev Assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract. - */ - function owner() public view virtual returns (address); - - /** - * @dev A helper function to check if the operator is allowed. - */ - function _checkFilterOperator(address operator) internal view virtual { - IOperatorFilterRegistry registry = operatorFilterRegistry; - // Check registry code length to facilitate testing in environments without a deployed registry. - if (address(registry) != address(0) && address(registry).code.length > 0) { - // under normal circumstances, this function will revert rather than return false, but inheriting contracts - // may specify their own OperatorFilterRegistry implementations, which may behave differently - if (!registry.isOperatorAllowed(address(this), operator)) { - revert OperatorNotAllowed(operator); - } - } - } -} diff --git a/src/example/ExampleERC1155.sol b/src/example/ExampleERC1155.sol deleted file mode 100644 index 07aae4d..0000000 --- a/src/example/ExampleERC1155.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ERC1155} from "openzeppelin-contracts/token/ERC1155/ERC1155.sol"; -import {ERC2981} from "openzeppelin-contracts/token/common/ERC2981.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; -import {DefaultOperatorFilterer} from "../DefaultOperatorFilterer.sol"; - -/** - * @title ExampleERC1155 - * @notice This example contract is configured to use the DefaultOperatorFilterer, which automatically registers the - * token and subscribes it to OpenSea's curated filters. - * Adding the onlyAllowedOperator modifier to the safeTransferFrom methods ensures that - * the msg.sender (operator) is allowed by the OperatorFilterRegistry. Adding the onlyAllowedOperatorApproval - * modifier to the setApprovalForAll method ensures that owners do not approve operators that are not allowed. - */ -abstract contract ExampleERC1155 is ERC1155(""), ERC2981, DefaultOperatorFilterer, Ownable { - /** - * @dev See {IERC1155-setApprovalForAll}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - /** - * @dev See {IERC1155-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, uint256 amount, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, amount, data); - } - - /** - * @dev See {IERC1155-safeBatchTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual override onlyAllowedOperator(from) { - super.safeBatchTransferFrom(from, to, ids, amounts, data); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155, ERC2981) returns (bool) { - return ERC1155.supportsInterface(interfaceId) || ERC2981.supportsInterface(interfaceId); - } -} diff --git a/src/example/ExampleERC721.sol b/src/example/ExampleERC721.sol deleted file mode 100644 index e578f4b..0000000 --- a/src/example/ExampleERC721.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ERC721} from "openzeppelin-contracts/token/ERC721/ERC721.sol"; -import {ERC2981} from "openzeppelin-contracts/token/common/ERC2981.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; -import {DefaultOperatorFilterer} from "../DefaultOperatorFilterer.sol"; - -/** - * @title ExampleERC721 - * @notice This example contract is configured to use the DefaultOperatorFilterer, which automatically registers the - * token and subscribes it to OpenSea's curated filters. - * Adding the onlyAllowedOperator modifier to the transferFrom and both safeTransferFrom methods ensures that - * the msg.sender (operator) is allowed by the OperatorFilterRegistry. Adding the onlyAllowedOperatorApproval - * modifier to the approval methods ensures that owners do not approve operators that are not allowed. - */ -abstract contract ExampleERC721 is ERC721("Example", "EXAMPLE"), ERC2981, DefaultOperatorFilterer, Ownable { - /** - * @dev See {IERC721-setApprovalForAll}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - /** - * @dev See {IERC721-approve}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) { - super.approve(operator, tokenId); - } - - /** - * @dev See {IERC721-transferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.transferFrom(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.safeTransferFrom(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, data); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) { - return super.supportsInterface(interfaceId); - } -} diff --git a/src/example/RevokableExampleERC1155.sol b/src/example/RevokableExampleERC1155.sol deleted file mode 100644 index 390cdca..0000000 --- a/src/example/RevokableExampleERC1155.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ERC1155} from "openzeppelin-contracts/token/ERC1155/ERC1155.sol"; -import {ERC2981} from "openzeppelin-contracts/token/common/ERC2981.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; -import {UpdatableOperatorFilterer} from "../UpdatableOperatorFilterer.sol"; -import {RevokableDefaultOperatorFilterer} from "../RevokableDefaultOperatorFilterer.sol"; - -/** - * @title RevokableExampleERC1155 - * @notice This example contract is configured to use the RevokableDefaultOperatorFilterer, which automatically - * registers the token and subscribes it to OpenSea's curated filters. The owner of the contract can - * permanently revoke checks to the filter registry by calling revokeOperatorFilterRegistry. - * Adding the onlyAllowedOperator modifier to the safeTransferFrom methods ensures that - * the msg.sender (operator) is allowed by the OperatorFilterRegistry. Adding the onlyAllowedOperatorApproval - * modifier to the setApprovalForAll method ensures that owners do not approve operators that are not allowed. - */ -abstract contract RevokableExampleERC1155 is ERC1155(""), ERC2981, RevokableDefaultOperatorFilterer, Ownable { - /** - * @dev See {IERC1155-setApprovalForAll}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - /** - * @dev See {IERC1155-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, uint256 amount, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, amount, data); - } - - /** - * @dev See {IERC1155-safeBatchTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual override onlyAllowedOperator(from) { - super.safeBatchTransferFrom(from, to, ids, amounts, data); - } - - /** - * @dev Returns the owner of the ERC1155 token contract. - */ - function owner() public view virtual override(Ownable, UpdatableOperatorFilterer) returns (address) { - return Ownable.owner(); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155, ERC2981) returns (bool) { - return super.supportsInterface(interfaceId); - } -} diff --git a/src/example/RevokableExampleERC721.sol b/src/example/RevokableExampleERC721.sol deleted file mode 100644 index 8f5b150..0000000 --- a/src/example/RevokableExampleERC721.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ERC721} from "openzeppelin-contracts/token/ERC721/ERC721.sol"; -import {ERC2981} from "openzeppelin-contracts/token/common/ERC2981.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; -import {UpdatableOperatorFilterer} from "../UpdatableOperatorFilterer.sol"; -import {RevokableDefaultOperatorFilterer} from "../RevokableDefaultOperatorFilterer.sol"; - -/** - * @title ExampleERC721 - * @notice This example contract is configured to use the RevokableDefaultOperatorFilterer, which automatically - * registers the token and subscribes it to OpenSea's curated filters. The owner of the contract can - * permanently revoke checks to the filter registry by calling revokeOperatorFilterRegistry. - * Adding the onlyAllowedOperator modifier to the transferFrom and both safeTransferFrom methods ensures that - * the msg.sender (operator) is allowed by the OperatorFilterRegistry. Adding the onlyAllowedOperatorApproval - * modifier to the approval methods ensures that owners do not approve operators that are not allowed. - */ -abstract contract RevokableExampleERC721 is - ERC721("Example", "EXAMPLE"), - ERC2981, - RevokableDefaultOperatorFilterer, - Ownable -{ - /** - * @dev See {IERC721-setApprovalForAll}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - /** - * @dev See {IERC721-approve}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) { - super.approve(operator, tokenId); - } - - /** - * @dev See {IERC721-transferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.transferFrom(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.safeTransferFrom(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, data); - } - - /** - * @dev Returns the owner of the ERC721 token contract. - */ - function owner() public view virtual override(Ownable, UpdatableOperatorFilterer) returns (address) { - return Ownable.owner(); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) { - return super.supportsInterface(interfaceId); - } -} diff --git a/src/example/upgradeable/ExampleERC1155Upgradeable.sol b/src/example/upgradeable/ExampleERC1155Upgradeable.sol deleted file mode 100644 index 68ea738..0000000 --- a/src/example/upgradeable/ExampleERC1155Upgradeable.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ERC1155Upgradeable} from "openzeppelin-contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; -import {ERC2981Upgradeable} from "openzeppelin-contracts-upgradeable/token/common/ERC2981Upgradeable.sol"; -import {OwnableUpgradeable} from "openzeppelin-contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {DefaultOperatorFiltererUpgradeable} from "../../upgradeable/DefaultOperatorFiltererUpgradeable.sol"; - -/** - * @title ExampleERC1155Upgradeable - * @notice This example contract is configured to use the DefaultOperatorFilterer, which automatically registers the - * token and subscribes it to OpenSea's curated filters. - * Adding the onlyAllowedOperator modifier to the transferFrom and both safeTransferFrom methods ensures that - * the msg.sender (operator) is allowed by the OperatorFilterRegistry. - */ -abstract contract ExampleERC1155Upgradeable is - ERC1155Upgradeable, - ERC2981Upgradeable, - DefaultOperatorFiltererUpgradeable, - OwnableUpgradeable -{ - /** - * @dev Initializes the upgradeable contract. - */ - function initialize() public initializer { - __ERC1155_init(""); - __ERC2981_init(); - __Ownable_init(); - __DefaultOperatorFilterer_init(); - } - - /** - * @dev See {IERC1155-setApprovalForAll}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - /** - * @dev See {IERC1155-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, uint256 amount, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, amount, data); - } - - /** - * @dev See {IERC1155-safeBatchTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual override onlyAllowedOperator(from) { - super.safeBatchTransferFrom(from, to, ids, amounts, data); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(ERC1155Upgradeable, ERC2981Upgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/src/example/upgradeable/ExampleERC721Upgradeable.sol b/src/example/upgradeable/ExampleERC721Upgradeable.sol deleted file mode 100644 index 9ae58dd..0000000 --- a/src/example/upgradeable/ExampleERC721Upgradeable.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ERC721Upgradeable} from "openzeppelin-contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; -import {ERC2981Upgradeable} from "openzeppelin-contracts-upgradeable/token/common/ERC2981Upgradeable.sol"; -import {OwnableUpgradeable} from "openzeppelin-contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {DefaultOperatorFiltererUpgradeable} from "../../upgradeable/DefaultOperatorFiltererUpgradeable.sol"; - -/** - * @title ExampleERC721Upgradeable - * @notice This example contract is configured to use the DefaultOperatorFilterer, which automatically registers the - * token and subscribes it to OpenSea's curated filters. - * Adding the onlyAllowedOperator modifier to the transferFrom and both safeTransferFrom methods ensures that - * the msg.sender (operator) is allowed by the OperatorFilterRegistry. - */ -abstract contract ExampleERC721Upgradeable is - ERC721Upgradeable, - ERC2981Upgradeable, - DefaultOperatorFiltererUpgradeable, - OwnableUpgradeable -{ - /** - * @dev Initializes the upgradeable contract. - */ - function initialize() public initializer { - __ERC721_init("Example", "EXAMPLE"); - __ERC2981_init(); - __Ownable_init(); - __DefaultOperatorFilterer_init(); - } - - /** - * @dev See {IERC721-setApprovalForAll}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - /** - * @dev See {IERC721-approve}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) { - super.approve(operator, tokenId); - } - - /** - * @dev See {IERC721-transferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.transferFrom(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.safeTransferFrom(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, data); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(ERC721Upgradeable, ERC2981Upgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/src/example/upgradeable/RevokableExampleERC1155Upgradeable.sol b/src/example/upgradeable/RevokableExampleERC1155Upgradeable.sol deleted file mode 100644 index e563986..0000000 --- a/src/example/upgradeable/RevokableExampleERC1155Upgradeable.sol +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ERC1155Upgradeable} from "openzeppelin-contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; -import {ERC2981Upgradeable} from "openzeppelin-contracts-upgradeable/token/common/ERC2981Upgradeable.sol"; -import {OwnableUpgradeable} from "openzeppelin-contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {RevokableDefaultOperatorFiltererUpgradeable} from - "../../upgradeable/RevokableDefaultOperatorFiltererUpgradeable.sol"; -import {RevokableOperatorFiltererUpgradeable} from "../../upgradeable/RevokableOperatorFiltererUpgradeable.sol"; - -/** - * @title ExampleERC1155Upgradeable - * @notice This example contract is configured to use the DefaultOperatorFilterer, which automatically registers the - * token and subscribes it to OpenSea's curated filters. - * Adding the onlyAllowedOperator modifier to the transferFrom and both safeTransferFrom methods ensures that - * the msg.sender (operator) is allowed by the OperatorFilterRegistry. - */ -abstract contract RevokableExampleERC1155Upgradeable is - ERC1155Upgradeable, - ERC2981Upgradeable, - RevokableDefaultOperatorFiltererUpgradeable, - OwnableUpgradeable -{ - /** - * @dev Initializes the upgradeable contract. - */ - function initialize() public initializer { - __ERC1155_init(""); - __ERC2981_init(); - __Ownable_init(); - __RevokableDefaultOperatorFilterer_init(); - } - - /** - * @dev See {IERC1155-setApprovalForAll}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - /** - * @dev See {IERC1155-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, uint256 amount, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, amount, data); - } - - /** - * @dev See {IERC1155-safeBatchTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual override onlyAllowedOperator(from) { - super.safeBatchTransferFrom(from, to, ids, amounts, data); - } - - /** - * @dev Returns the owner of the ERC1155 token contract. - */ - function owner() - public - view - virtual - override(OwnableUpgradeable, RevokableOperatorFiltererUpgradeable) - returns (address) - { - return OwnableUpgradeable.owner(); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(ERC1155Upgradeable, ERC2981Upgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/src/example/upgradeable/RevokableExampleERC721Upgradeable.sol b/src/example/upgradeable/RevokableExampleERC721Upgradeable.sol deleted file mode 100644 index 39d267d..0000000 --- a/src/example/upgradeable/RevokableExampleERC721Upgradeable.sol +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ERC721Upgradeable} from "openzeppelin-contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; -import {ERC2981Upgradeable} from "openzeppelin-contracts-upgradeable/token/common/ERC2981Upgradeable.sol"; -import {OwnableUpgradeable} from "openzeppelin-contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {RevokableDefaultOperatorFiltererUpgradeable} from - "../../upgradeable/RevokableDefaultOperatorFiltererUpgradeable.sol"; -import {RevokableOperatorFiltererUpgradeable} from "../../upgradeable/RevokableOperatorFiltererUpgradeable.sol"; - -/** - * @title ExampleERC721Upgradeable - * @notice This example contract is configured to use the DefaultOperatorFilterer, which automatically registers the - * token and subscribes it to OpenSea's curated filters. - * Adding the onlyAllowedOperator modifier to the transferFrom and both safeTransferFrom methods ensures that - * the msg.sender (operator) is allowed by the OperatorFilterRegistry. - */ -abstract contract RevokableExampleERC721Upgradeable is - ERC721Upgradeable, - ERC2981Upgradeable, - RevokableDefaultOperatorFiltererUpgradeable, - OwnableUpgradeable -{ - /** - * @dev Initializes the upgradeable contract. - */ - function initialize() public initializer { - __ERC721_init("Example", "EXAMPLE"); - __ERC2981_init(); - __Ownable_init(); - __RevokableDefaultOperatorFilterer_init(); - } - - /** - * @dev See {IERC721-setApprovalForAll}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - /** - * @dev See {IERC721-approve}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) { - super.approve(operator, tokenId); - } - - /** - * @dev See {IERC721-transferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.transferFrom(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.safeTransferFrom(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - * In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, data); - } - - /** - * @dev Returns the owner of the ERC721 token contract. - */ - function owner() - public - view - virtual - override(OwnableUpgradeable, RevokableOperatorFiltererUpgradeable) - returns (address) - { - return OwnableUpgradeable.owner(); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(ERC721Upgradeable, ERC2981Upgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/src/example/upgradeable/UpdatableExampleERC721Upgradeable.sol b/src/example/upgradeable/UpdatableExampleERC721Upgradeable.sol deleted file mode 100644 index 450da9e..0000000 --- a/src/example/upgradeable/UpdatableExampleERC721Upgradeable.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ERC721Upgradeable} from "openzeppelin-contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; -import {OwnableUpgradeable} from "openzeppelin-contracts-upgradeable/access/OwnableUpgradeable.sol"; - -import {UpdatableOperatorFiltererUpgradeable} from "../../upgradeable/UpdatableOperatorFiltererUpgradeable.sol"; - -/** - * @title UpdatableExampleERC721Upgradeable - * @author qed.team, abarbatei, balajmarius - * @notice This example contract is configured to use the UpdatableOperatorFiltererUpgradeable, which registers the - * token and subscribes it to a give register filter. - * Adding the onlyAllowedOperator modifier to the setApprovalForAll, approve, transferFrom, safeTransferFrom (both version) methods ensures that - * the msg.sender (operator) is allowed by the OperatorFilterRegistry. - */ -abstract contract UpdatableExampleERC721Upgradeable is - ERC721Upgradeable, - UpdatableOperatorFiltererUpgradeable, - OwnableUpgradeable -{ - function initialize(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) public initializer { - __ERC721_init("Example", "EXAMPLE"); - __Ownable_init(); - __UpdatableOperatorFiltererUpgradeable_init(_registry, subscriptionOrRegistrantToCopy, subscribe); - } - - function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { - super.setApprovalForAll(operator, approved); - } - - function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) { - super.approve(operator, tokenId); - } - - function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.transferFrom(from, to, tokenId); - } - - function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { - super.safeTransferFrom(from, to, tokenId); - } - - function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) - public - override - onlyAllowedOperator(from) - { - super.safeTransferFrom(from, to, tokenId, data); - } - - function owner() - public - view - virtual - override(OwnableUpgradeable, UpdatableOperatorFiltererUpgradeable) - returns (address) - { - return OwnableUpgradeable.owner(); - } -} diff --git a/src/lib/Constants.sol b/src/lib/Constants.sol deleted file mode 100644 index 06b811e..0000000 --- a/src/lib/Constants.sol +++ /dev/null @@ -1,5 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E; -address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6; diff --git a/src/upgradeable/DefaultOperatorFiltererUpgradeable.sol b/src/upgradeable/DefaultOperatorFiltererUpgradeable.sol deleted file mode 100644 index 0e1ff0d..0000000 --- a/src/upgradeable/DefaultOperatorFiltererUpgradeable.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFiltererUpgradeable} from "./OperatorFiltererUpgradeable.sol"; -import {CANONICAL_CORI_SUBSCRIPTION} from "../lib/Constants.sol"; - -/** - * @title DefaultOperatorFiltererUpgradeable - * @notice Inherits from OperatorFiltererUpgradeable and automatically subscribes to the default OpenSea subscription - * when the init function is called. - */ -abstract contract DefaultOperatorFiltererUpgradeable is OperatorFiltererUpgradeable { - /// @dev The upgradeable initialize function that should be called when the contract is being deployed. - function __DefaultOperatorFilterer_init() internal onlyInitializing { - OperatorFiltererUpgradeable.__OperatorFilterer_init(CANONICAL_CORI_SUBSCRIPTION, true); - } -} diff --git a/src/upgradeable/OperatorFiltererUpgradeable.sol b/src/upgradeable/OperatorFiltererUpgradeable.sol deleted file mode 100644 index 879afba..0000000 --- a/src/upgradeable/OperatorFiltererUpgradeable.sol +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {IOperatorFilterRegistry} from "../IOperatorFilterRegistry.sol"; -import {Initializable} from "openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol"; - -/** - * @title OperatorFiltererUpgradeable - * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another - * registrant's entries in the OperatorFilterRegistry when the init function is called. - * @dev This smart contract is meant to be inherited by token contracts so they can use the following: - * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. - * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. - */ -abstract contract OperatorFiltererUpgradeable is Initializable { - /// @notice Emitted when an operator is not allowed. - error OperatorNotAllowed(address operator); - - IOperatorFilterRegistry constant OPERATOR_FILTER_REGISTRY = - IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); - - /// @dev The upgradeable initialize function that should be called when the contract is being upgraded. - function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) - internal - onlyInitializing - { - // If an inheriting token contract is deployed to a network without the registry deployed, the modifier - // will not revert, but the contract will need to be registered with the registry once it is deployed in - // order for the modifier to filter addresses. - if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { - if (!OPERATOR_FILTER_REGISTRY.isRegistered(address(this))) { - if (subscribe) { - OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); - } else { - if (subscriptionOrRegistrantToCopy != address(0)) { - OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); - } else { - OPERATOR_FILTER_REGISTRY.register(address(this)); - } - } - } - } - } - - /** - * @dev A helper modifier to check if the operator is allowed. - */ - modifier onlyAllowedOperator(address from) virtual { - // Allow spending tokens from addresses with balance - // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred - // from an EOA. - if (from != msg.sender) { - _checkFilterOperator(msg.sender); - } - _; - } - - /** - * @dev A helper modifier to check if the operator approval is allowed. - */ - modifier onlyAllowedOperatorApproval(address operator) virtual { - _checkFilterOperator(operator); - _; - } - - /** - * @dev A helper function to check if the operator is allowed. - */ - function _checkFilterOperator(address operator) internal view virtual { - // Check registry code length to facilitate testing in environments without a deployed registry. - if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { - // under normal circumstances, this function will revert rather than return false, but inheriting or - // upgraded contracts may specify their own OperatorFilterRegistry implementations, which may behave - // differently - if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { - revert OperatorNotAllowed(operator); - } - } - } -} diff --git a/src/upgradeable/RevokableDefaultOperatorFiltererUpgradeable.sol b/src/upgradeable/RevokableDefaultOperatorFiltererUpgradeable.sol deleted file mode 100644 index 0ea4b44..0000000 --- a/src/upgradeable/RevokableDefaultOperatorFiltererUpgradeable.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableOperatorFiltererUpgradeable} from "./RevokableOperatorFiltererUpgradeable.sol"; -import {CANONICAL_CORI_SUBSCRIPTION} from "../lib/Constants.sol"; - -/** - * @title RevokableDefaultOperatorFiltererUpgradeable - * @notice Inherits from RevokableOperatorFiltererUpgradeable and automatically subscribes to the default OpenSea subscription - * when the init function is called. - * Note that OpenSea will disable creator earnings enforcement if filtered operators begin fulfilling orders - * on-chain, eg, if the registry is revoked or bypassed. - */ -abstract contract RevokableDefaultOperatorFiltererUpgradeable is RevokableOperatorFiltererUpgradeable { - /// @dev The upgradeable initialize function that should be called when the contract is being upgraded. - function __RevokableDefaultOperatorFilterer_init() internal onlyInitializing { - RevokableOperatorFiltererUpgradeable.__RevokableOperatorFilterer_init(CANONICAL_CORI_SUBSCRIPTION, true); - } -} diff --git a/src/upgradeable/RevokableOperatorFiltererUpgradeable.sol b/src/upgradeable/RevokableOperatorFiltererUpgradeable.sol deleted file mode 100644 index 196ddcc..0000000 --- a/src/upgradeable/RevokableOperatorFiltererUpgradeable.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFiltererUpgradeable} from "./OperatorFiltererUpgradeable.sol"; - -/** - * @title Upgradeable storage layout for RevokableOperatorFiltererUpgradeable. - * @notice Upgradeable contracts must use a storage layout that can be used across upgrades. - * Only append new variables to the end of the layout. - */ -library RevokableOperatorFiltererUpgradeableStorage { - struct Layout { - /// @dev Whether the OperatorFilterRegistry has been revoked. - bool _isOperatorFilterRegistryRevoked; - } - - /// @dev The storage slot for the layout. - bytes32 internal constant STORAGE_SLOT = keccak256("RevokableOperatorFiltererUpgradeable.contracts.storage"); - - /// @dev The layout of the storage. - function layout() internal pure returns (Layout storage l) { - bytes32 slot = STORAGE_SLOT; - assembly { - l.slot := slot - } - } -} - -/** - * @title RevokableOperatorFilterer - * @notice This contract is meant to allow contracts to permanently opt out of the OperatorFilterRegistry. The Registry - * itself has an "unregister" function, but if the contract is ownable, the owner can re-register at any point. - * As implemented, this abstract contract allows the contract owner to toggle the - * isOperatorFilterRegistryRevoked flag in order to permanently bypass the OperatorFilterRegistry checks. - */ -abstract contract RevokableOperatorFiltererUpgradeable is OperatorFiltererUpgradeable { - using RevokableOperatorFiltererUpgradeableStorage for RevokableOperatorFiltererUpgradeableStorage.Layout; - - error OnlyOwner(); - error AlreadyRevoked(); - - event OperatorFilterRegistryRevoked(); - - function __RevokableOperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal { - OperatorFiltererUpgradeable.__OperatorFilterer_init(subscriptionOrRegistrantToCopy, subscribe); - } - - /** - * @dev A helper function to check if the operator is allowed. - */ - function _checkFilterOperator(address operator) internal view virtual override { - // Check registry code length to facilitate testing in environments without a deployed registry. - if ( - !RevokableOperatorFiltererUpgradeableStorage.layout()._isOperatorFilterRegistryRevoked - && address(OPERATOR_FILTER_REGISTRY).code.length > 0 - ) { - // under normal circumstances, this function will revert rather than return false, but inheriting or - // upgraded contracts may specify their own OperatorFilterRegistry implementations, which may behave - // differently - if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { - revert OperatorNotAllowed(operator); - } - } - } - - /** - * @notice Disable the isOperatorFilterRegistryRevoked flag. OnlyOwner. - */ - function revokeOperatorFilterRegistry() external { - if (msg.sender != owner()) { - revert OnlyOwner(); - } - if (RevokableOperatorFiltererUpgradeableStorage.layout()._isOperatorFilterRegistryRevoked) { - revert AlreadyRevoked(); - } - RevokableOperatorFiltererUpgradeableStorage.layout()._isOperatorFilterRegistryRevoked = true; - emit OperatorFilterRegistryRevoked(); - } - - function isOperatorFilterRegistryRevoked() public view returns (bool) { - return RevokableOperatorFiltererUpgradeableStorage.layout()._isOperatorFilterRegistryRevoked; - } - - /** - * @dev assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract - */ - function owner() public view virtual returns (address); -} diff --git a/src/upgradeable/UpdatableOperatorFiltererUpgradeable.sol b/src/upgradeable/UpdatableOperatorFiltererUpgradeable.sol deleted file mode 100644 index 1cbdf1c..0000000 --- a/src/upgradeable/UpdatableOperatorFiltererUpgradeable.sol +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFiltererUpgradeable} from "./OperatorFiltererUpgradeable.sol"; -import {IOperatorFilterRegistry} from "../IOperatorFilterRegistry.sol"; - -/** - * @title Upgradeable storage layout for UpdatableOperatorFiltererUpgradeable. - * @author qed.team, abarbatei, balajmarius - * @notice Upgradeable contracts must use a storage layout that can be used across upgrades. - * Only append new variables to the end of the layout. - */ -library UpdatableOperatorFiltererUpgradeableStorage { - struct Layout { - /// @dev Address of the opensea filter register contract - address _operatorFilterRegistry; - } - - /// @dev The EIP-1967 specific storage slot for the layout - bytes32 internal constant STORAGE_SLOT = - bytes32(uint256(keccak256(bytes("UpdatableOperatorFiltererUpgradeable.contracts.storage"))) - 1); - - /// @dev The layout of the storage. - function layout() internal pure returns (Layout storage l) { - bytes32 slot = STORAGE_SLOT; - assembly { - l.slot := slot - } - } -} - -/** - * @title UpdatableOperatorFiltererUpgradeable - * @author qed.team, abarbatei, balajmarius - * @notice Abstract contract whose init function automatically registers and optionally subscribes to or copies another - * registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the - * OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address, - * which will bypass registry checks. - * Note that OpenSea will still disable creator earnings enforcement if filtered operators begin fulfilling orders - * on-chain, eg, if the registry is revoked or bypassed. - * @dev This smart contract is meant to be inherited by token contracts so they can use the following: - * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. - * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. - * Use updateOperatorFilterRegistryAddress function to change registry address if needed - */ -abstract contract UpdatableOperatorFiltererUpgradeable is OperatorFiltererUpgradeable { - using UpdatableOperatorFiltererUpgradeableStorage for UpdatableOperatorFiltererUpgradeableStorage.Layout; - - /// @notice Emitted when someone other than the owner is trying to call an only owner function. - error OnlyOwner(); - - /// @notice Emitted when the operator filter registry address is changed by the owner of the contract - event OperatorFilterRegistryAddressUpdated(address newRegistry); - - /** - * @notice Initialization function in accordance with the upgradable pattern - * @dev The upgradeable initialize function specific to proxied contracts - * @param _registry Registry address to which to register to for blocking operators that do not respect royalties - * @param subscriptionOrRegistrantToCopy Subscription address to use as a template for when - * imitating/copying blocked addresses and codehashes - * @param subscribe If to subscribe to the subscriptionOrRegistrantToCopy address or just copy entries from it - */ - function __UpdatableOperatorFiltererUpgradeable_init( - address _registry, - address subscriptionOrRegistrantToCopy, - bool subscribe - ) internal onlyInitializing { - UpdatableOperatorFiltererUpgradeableStorage.layout()._operatorFilterRegistry = _registry; - IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry); - // If an inheriting token contract is deployed to a network without the registry deployed, the modifier - // will not revert, but the contract will need to be registered with the registry once it is deployed in - // order for the modifier to filter addresses. - if (address(registry).code.length > 0) { - if (subscribe) { - registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); - } else { - if (subscriptionOrRegistrantToCopy != address(0)) { - registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); - } else { - registry.register(address(this)); - } - } - } - } - - /** - * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero - * address, checks will be bypassed. OnlyOwner. - * @custom:event OperatorFilterRegistryAddressUpdated - * @param newRegistry The address of the registry that will be used for this contract - */ - function updateOperatorFilterRegistryAddress(address newRegistry) public virtual { - if (msg.sender != owner()) { - revert OnlyOwner(); - } - UpdatableOperatorFiltererUpgradeableStorage.layout()._operatorFilterRegistry = newRegistry; - emit OperatorFilterRegistryAddressUpdated(newRegistry); - } - - /** - * @dev Helper function to return the value of the currently used registry address - */ - function operatorFilterRegistry() public view returns (address) { - return address(UpdatableOperatorFiltererUpgradeableStorage.layout()._operatorFilterRegistry); - } - - /** - * @dev Assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract - */ - function owner() public view virtual returns (address); - - /** - * @dev A helper function to check if the operator is allowed - */ - function _checkFilterOperator(address operator) internal view virtual override { - IOperatorFilterRegistry registry = - IOperatorFilterRegistry(UpdatableOperatorFiltererUpgradeableStorage.layout()._operatorFilterRegistry); - // Check registry code length to facilitate testing in environments without a deployed registry. - if (address(registry) != address(0) && address(registry).code.length > 0) { - // under normal circumstances, this function will revert rather than return false, but inheriting or - // upgraded contracts may specify their own OperatorFilterRegistry implementations, which may behave - // differently - if (!registry.isOperatorAllowed(address(this), operator)) { - revert OperatorNotAllowed(operator); - } - } - } -} diff --git a/test/BaseRegistryTest.sol b/test/BaseRegistryTest.sol deleted file mode 100644 index 1e22530..0000000 --- a/test/BaseRegistryTest.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {Test} from "forge-std/Test.sol"; -import {OperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents} from "../src/OperatorFilterRegistry.sol"; - -contract BaseRegistryTest is Test, OperatorFilterRegistryErrorsAndEvents { - OperatorFilterRegistry constant registry = OperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); - - function setUp() public virtual { - address deployedRegistry = address(new OperatorFilterRegistry()); - vm.etch(address(registry), deployedRegistry.code); - } -} diff --git a/test/DefaultOperatorFilterer.t.sol b/test/DefaultOperatorFilterer.t.sol deleted file mode 100644 index cef4c55..0000000 --- a/test/DefaultOperatorFilterer.t.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {DefaultOperatorFilterer} from "../src/DefaultOperatorFilterer.sol"; -import {BaseRegistryTest} from "./BaseRegistryTest.sol"; -import {DefaultFilterer} from "./helpers/DefaultFilterer.sol"; - -import {OperatorFilterer} from "../src/OperatorFilterer.sol"; -import {UpdatableFilterer} from "./helpers/UpdatableFilterer.sol"; -import {OperatorFilterRegistryStub} from "./helpers/OperatorFilterRegistryStub.sol"; - -contract DefaultOperatorFiltererTest is BaseRegistryTest { - DefaultFilterer filterer; - address filteredAddress; - address filteredCodeHashAddress; - bytes32 filteredCodeHash; - address notFiltered; - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - notFiltered = makeAddr("not filtered"); - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - filteredCodeHashAddress = makeAddr("filtered code hash"); - bytes memory code = hex"deadbeef"; - filteredCodeHash = keccak256(code); - registry.updateCodeHash(address(DEFAULT_SUBSCRIPTION), filteredCodeHash, true); - vm.etch(filteredCodeHashAddress, code); - - filterer = new DefaultFilterer(); - vm.stopPrank(); - } - - function testFilter() public { - assertTrue(filterer.filterTest(notFiltered)); - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.filterTest(address(0)); - vm.stopPrank(); - vm.startPrank(filteredCodeHashAddress); - vm.expectRevert(abi.encodeWithSelector(CodeHashFiltered.selector, filteredCodeHashAddress, filteredCodeHash)); - filterer.filterTest(address(0)); - } - - function testRevert_OperatorNotAllowed() public { - address stubRegistry = address(new OperatorFilterRegistryStub()); - UpdatableFilterer updatableFilterer = new UpdatableFilterer(stubRegistry); - vm.expectRevert(abi.encodeWithSelector(OperatorFilterer.OperatorNotAllowed.selector, address(filteredAddress))); - updatableFilterer.checkFilterOperator(filteredAddress); - } -} diff --git a/test/OperatorFilterRegistry.t.sol b/test/OperatorFilterRegistry.t.sol deleted file mode 100644 index 6b5dd53..0000000 --- a/test/OperatorFilterRegistry.t.sol +++ /dev/null @@ -1,864 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {BaseRegistryTest} from "./BaseRegistryTest.sol"; -import {OperatorFilterer} from "../src/OperatorFilterer.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; - -contract Filterer is OperatorFilterer, Ownable { - constructor(address registry) OperatorFilterer(address(0), false) {} - - function testFilter(address from) public view onlyAllowedOperator(from) returns (bool) { - return true; - } -} - -contract Owned is Ownable {} - -contract OwnableReverter { - error Bad(); - - function owner() public pure returns (address) { - revert Bad(); - } -} - -contract OperatorFilterRegistryTest is BaseRegistryTest { - Filterer filterer; - Ownable owned; - OwnableReverter reverter; - - function setUp() public override { - super.setUp(); - filterer = new Filterer(address(registry)); - owned = new Owned(); - reverter = new OwnableReverter(); - } - - function testOnlyAddressOrOwner() public { - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(NotOwnable.selector)); - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - registry.register(address(owned)); - vm.expectRevert(abi.encodeWithSelector(OwnableReverter.Bad.selector)); - registry.register(address(reverter)); - } - - function testRegister_constructor() public { - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(address(this), true); - registry.register(address(this)); - - assertTrue(registry.isRegistered(address(filterer))); - assertEq(registry.subscriptionOf(address(filterer)), address(0)); - } - - function testRegister_onlyAddressOrOwner() public { - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - registry.register(address(filterer)); - } - - function testRegister_alreadyRegistered() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(AlreadyRegistered.selector)); - registry.register(address(this)); - } - - function testRegisterAndSubscribe() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(address(this), true); - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(address(this), subscription, true); - registry.registerAndSubscribe(address(this), subscription); - assertEq(registry.subscribers(subscription).length, 1); - assertEq(registry.subscribers(subscription)[0], address(this)); - assertEq(registry.subscriberAt(subscription, 0), address(this)); - } - - function testRegisterAndSubscribe_OnlyAddressOrOwner() public { - address subscription = makeAddr("subscription"); - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - registry.registerAndSubscribe(address(owned), subscription); - } - - function testRegisterAndSubscribe_AlreadyRegistered() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(AlreadyRegistered.selector)); - registry.registerAndSubscribe(address(this), makeAddr("subscription")); - } - - function testRegisterAndSubscribe_CannotRegisterToSelf() public { - vm.expectRevert(abi.encodeWithSelector(CannotSubscribeToSelf.selector)); - registry.registerAndSubscribe(address(this), address(this)); - } - - function testRegisterAndSubscribe_NotRegistered() public { - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, makeAddr("subscription"))); - registry.registerAndSubscribe(address(this), makeAddr("subscription")); - } - - function testRegisterAndSubscribe_CannotSubscribeToRegistrantWithSubscription() public { - address subscription = makeAddr("subscription"); - address superSubscription = makeAddr("superSubscription"); - vm.prank(superSubscription); - registry.register(superSubscription); - vm.prank(subscription); - registry.registerAndSubscribe(subscription, superSubscription); - vm.expectRevert(abi.encodeWithSelector(CannotSubscribeToRegistrantWithSubscription.selector, subscription)); - registry.registerAndSubscribe(address(this), subscription); - } - - function testRegisterAndCopyEntries() public { - registry.register(address(this)); - registry.updateOperator(address(this), makeAddr("operator"), true); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), true); - - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorUpdated(address(filterer), makeAddr("operator"), true); - vm.expectEmit(true, true, true, false, address(registry)); - emit CodeHashUpdated(address(filterer), bytes32(bytes4(0xdeadbeef)), true); - - registry.copyEntriesOf(address(filterer), address(this)); - - assertEq(registry.subscribers(address(this)).length, 0); - assertTrue(registry.isRegistered(address(filterer))); - assertEq(registry.filteredOperatorAt(address(filterer), 0), makeAddr("operator")); - assertEq(registry.filteredCodeHashAt(address(filterer), 0), bytes32(bytes4(0xdeadbeef))); - } - - function testRegisterAndCopyEntries_OnlyAddressOrOwner() public { - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - registry.registerAndCopyEntries(address(filterer), address(this)); - } - - function testRegisterAndCopyEntries_CannotCopyFromSelf() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(CannotCopyFromSelf.selector)); - registry.registerAndCopyEntries(address(this), address(this)); - } - - function testRegisterAndCopyEntries_AlreadyRegistered() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(AlreadyRegistered.selector)); - registry.registerAndCopyEntries(address(this), makeAddr("not registered but fail fast")); - } - - function testRegisterAndCopyEntries_NotRegistered() public { - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, makeAddr("registrant"))); - registry.registerAndCopyEntries(address(this), makeAddr("registrant")); - } - - function testUpdateOperator() public { - registry.register(address(this)); - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorUpdated(address(this), makeAddr("operator"), true); - registry.updateOperator(address(this), makeAddr("operator"), true); - assertTrue(registry.isOperatorFiltered(address(this), makeAddr("operator"))); - assertEq(registry.filteredOperatorAt(address(this), 0), makeAddr("operator")); - } - - function testUpdateOperator_OnlyAddressOrOwner() public { - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - registry.updateOperator(address(owned), makeAddr("operator"), true); - } - - function testUpdateOperator_notRegistered() public { - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, address(this))); - registry.updateOperator(address(this), makeAddr("operator"), true); - } - - function testUpdateOperator_CannotUpdateWhileSubscribed() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - registry.registerAndSubscribe(address(this), subscription); - vm.expectRevert(abi.encodeWithSelector(CannotUpdateWhileSubscribed.selector, subscription)); - registry.updateOperator(address(this), makeAddr("operator"), true); - } - - function testUpdateOperator_unfilter() public { - registry.register(address(this)); - registry.updateOperator(address(this), makeAddr("operator"), true); - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorUpdated(address(this), makeAddr("operator"), false); - registry.updateOperator(address(this), makeAddr("operator"), false); - assertFalse(registry.isOperatorFiltered(address(this), makeAddr("operator"))); - vm.expectRevert(); - registry.filteredOperatorAt(address(this), 0); - } - - function testUpdateOperator_AddressNotFiltered() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(AddressNotFiltered.selector, makeAddr("operator"))); - registry.updateOperator(address(this), makeAddr("operator"), false); - } - - function testUpdateOperator_AddressAlreadyFiltered() public { - registry.register(address(this)); - registry.updateOperator(address(this), makeAddr("operator"), true); - vm.expectRevert(abi.encodeWithSelector(AddressAlreadyFiltered.selector, makeAddr("operator"))); - registry.updateOperator(address(this), makeAddr("operator"), true); - } - - function testUpdateCodeHash() public { - registry.register(address(this)); - vm.expectEmit(true, true, true, false, address(registry)); - emit CodeHashUpdated(address(this), bytes32(bytes4(0xdeadbeef)), true); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), true); - assertTrue(registry.isCodeHashFiltered(address(this), bytes32(bytes4(0xdeadbeef)))); - assertEq(registry.filteredCodeHashAt(address(this), 0), bytes32(bytes4(0xdeadbeef))); - } - - function testUpdateCodeHash_OnlyAddressOrOwner() public { - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - registry.updateCodeHash(address(owned), bytes32(bytes4(0xdeadbeef)), true); - } - - function testUpdateCodeHash_CannotFilterEOAs() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(CannotFilterEOAs.selector)); - registry.updateCodeHash(address(this), keccak256(""), true); - } - - function testUpdateCodeHash_NotRegistered() public { - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, address(this))); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), true); - } - - function testUpdateCodeHash_CannotUpdateWhileSubscribed() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - registry.registerAndSubscribe(address(this), subscription); - vm.expectRevert(abi.encodeWithSelector(CannotUpdateWhileSubscribed.selector, subscription)); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), true); - } - - function testUpdateCodeHash_unfilter() public { - registry.register(address(this)); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), true); - vm.expectEmit(true, true, true, false, address(registry)); - emit CodeHashUpdated(address(this), bytes32(bytes4(0xdeadbeef)), false); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), false); - assertFalse(registry.isCodeHashFiltered(address(this), bytes32(bytes4(0xdeadbeef)))); - vm.expectRevert(); - registry.filteredCodeHashAt(address(this), 0); - } - - function testUpdateCodeHash_CodeHashNotFiltered() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(CodeHashNotFiltered.selector, bytes32(bytes4(0xdeadbeef)))); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), false); - } - - function testUpdateCodeHash_CodeHashAlreadyFiltered() public { - registry.register(address(this)); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), true); - vm.expectRevert(abi.encodeWithSelector(CodeHashAlreadyFiltered.selector, bytes32(bytes4(0xdeadbeef)))); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), true); - } - - function testUpdateOperators() public { - registry.register(address(this)); - - address[] memory operator = new address[](2); - operator[0] = makeAddr("operator1"); - operator[1] = makeAddr("operator2"); - vm.expectEmit(true, true, false, false, address(registry)); - emit OperatorsUpdated(address(this), operator, true); - registry.updateOperators(address(this), operator, true); - assertTrue(registry.isOperatorFiltered(address(this), operator[0])); - assertTrue(registry.isOperatorFiltered(address(this), operator[1])); - assertEq(registry.filteredOperatorAt(address(this), 0), operator[0]); - assertEq(registry.filteredOperatorAt(address(this), 1), operator[1]); - } - - function testUpdateOperators_OnlyAddressOrOwner() public { - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - address[] memory operator = new address[](1); - operator[0] = makeAddr("operator1"); - registry.updateOperators(address(owned), operator, true); - } - - function testUpdateOperators_notRegistered() public { - address[] memory operator = new address[](2); - operator[0] = makeAddr("operator1"); - operator[1] = makeAddr("operator2"); - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, address(this))); - registry.updateOperators(address(this), operator, true); - } - - function testUpdateOperators_CannotUpdateWhileSubscribed() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - registry.registerAndSubscribe(address(this), subscription); - address[] memory operator = new address[](2); - operator[0] = makeAddr("operator1"); - operator[1] = makeAddr("operator2"); - vm.expectRevert(abi.encodeWithSelector(CannotUpdateWhileSubscribed.selector, subscription)); - registry.updateOperators(address(this), operator, true); - } - - function testUpdateOperators_unfilter() public { - registry.register(address(this)); - registry.updateOperator(address(this), makeAddr("operator1"), true); - registry.updateOperator(address(this), makeAddr("operator2"), true); - - address[] memory operator = new address[](2); - operator[0] = makeAddr("operator1"); - operator[1] = makeAddr("operator2"); - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorsUpdated(address(this), operator, false); - registry.updateOperators(address(this), operator, false); - assertFalse(registry.isOperatorFiltered(address(this), operator[0])); - assertFalse(registry.isOperatorFiltered(address(this), operator[1])); - vm.expectRevert(); - registry.filteredOperatorAt(address(this), 0); - } - - function testUpdateOperators_AddressNotFiltered() public { - registry.register(address(this)); - address[] memory operator = new address[](2); - operator[0] = makeAddr("operator1"); - operator[1] = makeAddr("operator2"); - vm.expectRevert(abi.encodeWithSelector(AddressNotFiltered.selector, makeAddr("operator1"))); - registry.updateOperators(address(this), operator, false); - } - - function testUpdateOperators_AddressAlreadyFiltered() public { - registry.register(address(this)); - registry.updateOperator(address(this), makeAddr("operator1"), true); - registry.updateOperator(address(this), makeAddr("operator2"), true); - address[] memory operator = new address[](2); - operator[0] = makeAddr("operator1"); - operator[1] = makeAddr("operator2"); - vm.expectRevert(abi.encodeWithSelector(AddressAlreadyFiltered.selector, makeAddr("operator1"))); - registry.updateOperators(address(this), operator, true); - } - - function testUpdateCodeHashes() public { - registry.register(address(this)); - bytes32[] memory codeHash = new bytes32[](2); - codeHash[0] = bytes32(bytes4(0xdeadbeef)); - codeHash[1] = bytes32(bytes4(0xdeafbeef)); - vm.expectEmit(true, true, false, false, address(registry)); - emit CodeHashesUpdated(address(this), codeHash, true); - registry.updateCodeHashes(address(this), codeHash, true); - } - - function testUpdateCodeHashes_OnlyAddressOrOwner() public { - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - bytes32[] memory codeHash = new bytes32[](1); - codeHash[0] = bytes32(bytes4(0xdeadbeef)); - registry.updateCodeHashes(address(owned), codeHash, true); - } - - function testUpdateCodeHashes_notRegistered() public { - bytes32[] memory codeHash = new bytes32[](2); - codeHash[0] = bytes32(bytes4(0xdeadbeef)); - codeHash[1] = bytes32(bytes4(0xdeafbeef)); - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, address(this))); - registry.updateCodeHashes(address(this), codeHash, true); - } - - function testUpdateCodeHashes_CannotUpdateWhileSubscribed() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - registry.registerAndSubscribe(address(this), subscription); - bytes32[] memory codeHash = new bytes32[](2); - codeHash[0] = bytes32(bytes4(0xdeadbeef)); - codeHash[1] = bytes32(bytes4(0xdeafbeef)); - vm.expectRevert(abi.encodeWithSelector(CannotUpdateWhileSubscribed.selector, subscription)); - registry.updateCodeHashes(address(this), codeHash, true); - } - - function testUpdateCodeHashes_unfilter() public { - registry.register(address(this)); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), true); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeafbeef)), true); - - bytes32[] memory codeHash = new bytes32[](2); - codeHash[0] = bytes32(bytes4(0xdeadbeef)); - codeHash[1] = bytes32(bytes4(0xdeafbeef)); - vm.expectEmit(true, true, false, false, address(registry)); - emit CodeHashesUpdated(address(this), codeHash, false); - registry.updateCodeHashes(address(this), codeHash, false); - assertFalse(registry.isCodeHashFiltered(address(this), codeHash[0])); - assertFalse(registry.isCodeHashFiltered(address(this), codeHash[1])); - vm.expectRevert(); - registry.filteredCodeHashAt(address(this), 0); - } - - function testUpdateCodeHashes_CodeHashNotFiltered() public { - registry.register(address(this)); - bytes32[] memory codeHash = new bytes32[](2); - codeHash[0] = bytes32(bytes4(0xdeadbeef)); - codeHash[1] = bytes32(bytes4(0xdeafbeef)); - vm.expectRevert(abi.encodeWithSelector(CodeHashNotFiltered.selector, bytes32(bytes4(0xdeadbeef)))); - registry.updateCodeHashes(address(this), codeHash, false); - } - - function testUpdateCodeHashes_CannotFilterEOAs() public { - registry.register(address(this)); - bytes32[] memory codeHash = new bytes32[](2); - codeHash[0] = bytes32(bytes4(0xdeadbeef)); - codeHash[1] = keccak256(""); - vm.expectRevert(CannotFilterEOAs.selector); - registry.updateCodeHashes(address(this), codeHash, true); - } - - function testUpdateCodeHashes_CodeHashAlreadyFiltered() public { - registry.register(address(this)); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeadbeef)), true); - registry.updateCodeHash(address(this), bytes32(bytes4(0xdeafbeef)), true); - bytes32[] memory codeHash = new bytes32[](2); - codeHash[0] = bytes32(bytes4(0xdeadbeef)); - codeHash[1] = bytes32(bytes4(0xdeafbeef)); - vm.expectRevert(abi.encodeWithSelector(CodeHashAlreadyFiltered.selector, bytes32(bytes4(0xdeadbeef)))); - registry.updateCodeHashes(address(this), codeHash, true); - } - - function testSubscribe() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - registry.register(address(this)); - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(address(this), subscription, true); - registry.subscribe(address(this), subscription); - - assertEq(registry.subscriptionOf(address(this)), subscription); - assertEq(registry.subscribers(subscription).length, 1); - assertEq(registry.subscribers(subscription)[0], address(this)); - assertEq(registry.subscriberAt(subscription, 0), address(this)); - } - - function testSubscribe_OnlyAddressOrOwner() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - registry.subscribe(address(owned), subscription); - } - - function testSubscribe_CannotSubscribeToSelf() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(CannotSubscribeToSelf.selector)); - registry.subscribe(address(this), address(this)); - } - - function testSubscribe_CannotSubscribeToZeroAddress() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(CannotSubscribeToZeroAddress.selector)); - registry.subscribe(address(this), address(0)); - } - - function testSubscribe_notRegistered() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, address(this))); - registry.subscribe(address(this), subscription); - } - - function testSubscribe_AlreadySubscribed() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - registry.register(address(this)); - registry.subscribe(address(this), subscription); - vm.expectRevert(abi.encodeWithSelector(AlreadySubscribed.selector, subscription)); - registry.subscribe(address(this), subscription); - } - - function testSubscribe_SubscriptionNotRegistered() public { - registry.register(address(this)); - address subscription = makeAddr("subscription"); - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, subscription)); - registry.subscribe(address(this), subscription); - } - - function testSubscribe_removeOldSubscription() public { - address oldSubscription = makeAddr("oldSubscription"); - vm.prank(oldSubscription); - registry.register(oldSubscription); - registry.register(address(this)); - registry.subscribe(address(this), oldSubscription); - - address newSubscription = makeAddr("newSubscription"); - vm.prank(newSubscription); - registry.register(newSubscription); - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(address(this), oldSubscription, false); - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(address(this), newSubscription, true); - registry.subscribe(address(this), newSubscription); - - assertEq(registry.subscriptionOf(address(this)), newSubscription); - assertEq(registry.subscribers(oldSubscription).length, 0); - assertEq(registry.subscribers(newSubscription).length, 1); - assertEq(registry.subscribers(newSubscription)[0], address(this)); - assertEq(registry.subscriberAt(newSubscription, 0), address(this)); - } - - function testSubscribe_CannotSubscribeToRegistrantWithSubscription() public { - address subscription = makeAddr("subscription"); - address superSubscription = makeAddr("superSubscription"); - vm.prank(superSubscription); - registry.register(superSubscription); - vm.prank(subscription); - registry.registerAndSubscribe(subscription, superSubscription); - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(CannotSubscribeToRegistrantWithSubscription.selector, subscription)); - registry.subscribe(address(this), subscription); - } - - function testUnsubscribe() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - registry.register(address(this)); - registry.subscribe(address(this), subscription); - - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(address(this), subscription, false); - registry.unsubscribe(address(this), false); - - assertEq(registry.subscriptionOf(address(this)), address(0)); - assertEq(registry.subscribers(subscription).length, 0); - assertEq(registry.subscriptionOf(address(this)), address(0)); - } - - function testUnsubscribe_notRegistered() public { - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, address(this))); - registry.unregister(address(this)); - } - - function testUnsubscribe_onlyAddressOrOwner() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - registry.register(address(this)); - registry.subscribe(address(this), subscription); - - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - registry.unsubscribe(address(owned), false); - } - - function testUnsubscribe_copyExistingEntries() public { - address subscription = makeAddr("subscription"); - address operator = makeAddr("operator"); - bytes32 codeHash = bytes32(bytes4(0xdeadbeef)); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateOperator(subscription, operator, true); - registry.updateCodeHash(subscription, codeHash, true); - vm.stopPrank(); - registry.register(address(this)); - registry.subscribe(address(this), subscription); - - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(address(this), subscription, false); - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorUpdated(address(this), operator, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit CodeHashUpdated(address(this), codeHash, true); - registry.unsubscribe(address(this), true); - - assertEq(registry.subscriptionOf(address(this)), address(0)); - } - - function testUnsubscribe_NotRegistered() public { - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, address(this))); - registry.unsubscribe(address(this), false); - } - - function testUnsubscribe_NotSubscribed() public { - registry.register(address(this)); - vm.expectRevert(abi.encodeWithSelector(NotSubscribed.selector)); - registry.unsubscribe(address(this), false); - } - - function testCopyEntriesOf() public { - address subscription = makeAddr("subscription"); - address operator = makeAddr("operator"); - address duplicateOperator = makeAddr("duplicateOperator"); - bytes32 codeHash = bytes32(bytes4(0xdeadbeef)); - bytes32 duplicateCodeHash = bytes32(bytes5(0xdeadbeef22)); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateOperator(subscription, operator, true); - registry.updateOperator(subscription, duplicateOperator, true); - registry.updateCodeHash(subscription, codeHash, true); - registry.updateCodeHash(subscription, duplicateCodeHash, true); - vm.stopPrank(); - // test that it does not throw errors for duplicate entries - // and that events are not emitted for them - registry.register(address(this)); - registry.updateOperator(address(this), duplicateOperator, true); - registry.updateCodeHash(address(this), duplicateCodeHash, true); - - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorUpdated(address(this), operator, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit CodeHashUpdated(address(this), codeHash, true); - registry.copyEntriesOf(address(this), subscription); - - assertEq(registry.filteredOperators(address(this)).length, 2); - assertEq(registry.filteredOperators(address(this))[0], duplicateOperator); - assertEq(registry.filteredOperatorAt(address(this), 0), duplicateOperator); - assertEq(registry.filteredOperators(address(this))[1], operator); - assertEq(registry.filteredOperatorAt(address(this), 1), operator); - - assertEq(registry.filteredCodeHashes(address(this)).length, 2); - assertEq(registry.filteredCodeHashes(address(this))[0], duplicateCodeHash); - assertEq(registry.filteredCodeHashAt(address(this), 0), duplicateCodeHash); - assertEq(registry.filteredCodeHashes(address(this))[1], codeHash); - assertEq(registry.filteredCodeHashAt(address(this), 1), codeHash); - } - - function testCopyEntriesOf_cannotCopySelf() public { - registry.register(address(this)); - vm.expectRevert(CannotCopyFromSelf.selector); - registry.copyEntriesOf(address(this), address(this)); - } - - function testCopyEntriesOf_OnlyAddressOrOwner() public { - address subscription = makeAddr("subscription"); - vm.startPrank(subscription); - registry.register(subscription); - vm.stopPrank(); - registry.register(address(this)); - - vm.startPrank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSelector(OnlyAddressOrOwner.selector)); - registry.copyEntriesOf(address(owned), subscription); - } - - function testCopyEntriesOf_NotRegistered() public { - address subscription = makeAddr("subscription"); - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, address(this))); - registry.copyEntriesOf(address(this), subscription); - } - - function testCopyEntriesOf_CannotUpdateWhileSubscribed() public { - address subscription = makeAddr("subscription"); - address operator = makeAddr("operator"); - bytes32 codeHash = bytes32(bytes4(0xdeadbeef)); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateOperator(subscription, operator, true); - registry.updateCodeHash(subscription, codeHash, true); - vm.stopPrank(); - registry.register(address(this)); - registry.subscribe(address(this), subscription); - - vm.expectRevert(abi.encodeWithSelector(CannotUpdateWhileSubscribed.selector, subscription)); - registry.copyEntriesOf(address(this), subscription); - } - - function testCopyEntriesOf_NotRegistered_registrant() public { - registry.register(address(this)); - address subscription = makeAddr("subscription"); - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, subscription)); - registry.copyEntriesOf(address(this), subscription); - } - - function testCodeHashOf() public { - address toCheck = makeAddr("toCheck"); - bytes memory code = hex"deadbeef"; - bytes32 codeHash = keccak256(code); - vm.etch(toCheck, code); - assertEq(registry.codeHashOf(toCheck), codeHash); - } - - function testIsCodeHashOfFiltered() public { - address toCheck = makeAddr("toCheck"); - bytes memory code = hex"deadbeef"; - bytes32 codeHash = keccak256(code); - vm.etch(toCheck, code); - registry.register(address(this)); - registry.updateCodeHash(address(this), codeHash, true); - assertTrue(registry.isCodeHashOfFiltered(address(this), toCheck)); - assertFalse(registry.isCodeHashOfFiltered(address(this), makeAddr("not filtered"))); - } - - function testIsCodeHashOfFiltered_subscription() public { - address toCheck = makeAddr("toCheck"); - bytes memory code = hex"deadbeef"; - bytes32 codeHash = keccak256(code); - vm.etch(toCheck, code); - address subscription = makeAddr("subscription"); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateCodeHash(subscription, codeHash, true); - vm.stopPrank(); - registry.registerAndSubscribe(address(this), subscription); - assertTrue(registry.isCodeHashOfFiltered(address(this), toCheck)); - assertFalse(registry.isCodeHashOfFiltered(address(this), makeAddr("not filtered"))); - } - - function testIsCodeHashFiltered_subscription() public { - address toCheck = makeAddr("toCheck"); - bytes memory code = hex"deadbeef"; - bytes32 codeHash = keccak256(code); - vm.etch(toCheck, code); - address subscription = makeAddr("subscription"); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateCodeHash(subscription, codeHash, true); - vm.stopPrank(); - registry.registerAndSubscribe(address(this), subscription); - assertTrue(registry.isCodeHashFiltered(address(this), codeHash)); - assertFalse(registry.isCodeHashFiltered(address(this), bytes32(bytes4(0xdeadbeef)))); - } - - function testIsOperatorFiltered_subscription() public { - address operator = makeAddr("operator"); - address subscription = makeAddr("subscription"); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateOperator(subscription, operator, true); - vm.stopPrank(); - registry.registerAndSubscribe(address(this), subscription); - assertTrue(registry.isOperatorFiltered(address(this), operator)); - assertFalse(registry.isOperatorFiltered(address(this), makeAddr("not filtered"))); - } - - function testFilteredOperators_subscription() public { - address operator = makeAddr("operator"); - address subscription = makeAddr("subscription"); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateOperator(subscription, operator, true); - vm.stopPrank(); - registry.registerAndSubscribe(address(this), subscription); - assertEq(registry.filteredOperators(address(this)).length, 1); - assertEq(registry.filteredOperators(address(this))[0], operator); - assertEq(registry.filteredOperatorAt(address(this), 0), operator); - } - - function testFilteredCodeHashes_subscription() public { - address toCheck = makeAddr("toCheck"); - bytes memory code = hex"deadbeef"; - bytes32 codeHash = keccak256(code); - vm.etch(toCheck, code); - address subscription = makeAddr("subscription"); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateCodeHash(subscription, codeHash, true); - vm.stopPrank(); - registry.registerAndSubscribe(address(this), subscription); - assertEq(registry.filteredCodeHashes(address(this)).length, 1); - assertEq(registry.filteredCodeHashes(address(this))[0], codeHash); - assertEq(registry.filteredCodeHashAt(address(this), 0), codeHash); - } - - function testFilteredOperatorAt_subscription() public { - address operator = makeAddr("operator"); - address subscription = makeAddr("subscription"); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateOperator(subscription, operator, true); - vm.stopPrank(); - registry.registerAndSubscribe(address(this), subscription); - assertEq(registry.filteredOperatorAt(address(this), 0), operator); - } - - function testFilteredCodeHashAt_subscription() public { - address toCheck = makeAddr("toCheck"); - bytes memory code = hex"deadbeef"; - bytes32 codeHash = keccak256(code); - vm.etch(toCheck, code); - address subscription = makeAddr("subscription"); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateCodeHash(subscription, codeHash, true); - vm.stopPrank(); - registry.registerAndSubscribe(address(this), subscription); - assertEq(registry.filteredCodeHashAt(address(this), 0), codeHash); - } - - function testIsRegistered() public { - registry.register(address(this)); - assertTrue(registry.isRegistered(address(this))); - assertFalse(registry.isRegistered(makeAddr("not registered"))); - } - - function testIsOperatorAllowed_NotRegistered() public { - assertTrue(registry.isOperatorAllowed(address(this), makeAddr("allowed"))); - } - - function testIsOperatorAllowed() public { - address operator = makeAddr("operator"); - address toCheck = makeAddr("toCheck"); - bytes memory code = hex"deadbeef"; - bytes32 codeHash = keccak256(code); - vm.etch(toCheck, code); - registry.register(address(this)); - registry.updateOperator(address(this), operator, true); - registry.updateCodeHash(address(this), codeHash, true); - - assertTrue(registry.isOperatorAllowed(address(this), makeAddr("allowed"))); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, address(operator))); - registry.isOperatorAllowed(address(this), operator); - vm.expectRevert(abi.encodeWithSelector(CodeHashFiltered.selector, address(toCheck), codeHash)); - registry.isOperatorAllowed(address(this), toCheck); - } - - function testIsOperatorAllowed_subscription() public { - address operator = makeAddr("operator"); - address toCheck = makeAddr("toCheck"); - bytes memory code = hex"deadbeef"; - bytes32 codeHash = keccak256(code); - vm.etch(toCheck, code); - address subscription = makeAddr("subscription"); - vm.startPrank(subscription); - registry.register(subscription); - registry.updateOperator(subscription, operator, true); - registry.updateCodeHash(subscription, codeHash, true); - vm.stopPrank(); - registry.registerAndSubscribe(address(this), subscription); - - assertTrue(registry.isOperatorAllowed(address(this), makeAddr("allowed"))); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, address(operator))); - registry.isOperatorAllowed(address(this), operator); - vm.expectRevert(abi.encodeWithSelector(CodeHashFiltered.selector, address(toCheck), codeHash)); - registry.isOperatorAllowed(address(this), toCheck); - } - - function testUnregister() public { - address subscription = makeAddr("subscription"); - vm.prank(subscription); - registry.register(subscription); - registry.registerAndSubscribe(address(this), subscription); - assertTrue(registry.isRegistered(address(this))); - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(address(this), subscription, false); - vm.expectEmit(true, true, true, false, address(registry)); - emit RegistrationUpdated(address(this), false); - registry.unregister(address(this)); - assertFalse(registry.isRegistered(address(this))); - assertEq(registry.subscribers(subscription).length, 0); - } - - function testSubscriptionOf_notRegistered() public { - vm.expectRevert(abi.encodeWithSelector(NotRegistered.selector, address(this))); - registry.subscriptionOf(address(this)); - } -} diff --git a/test/OperatorFilterer.t.sol b/test/OperatorFilterer.t.sol deleted file mode 100644 index 68c2c67..0000000 --- a/test/OperatorFilterer.t.sol +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFilterer} from "../src/OperatorFilterer.sol"; -import {BaseRegistryTest} from "./BaseRegistryTest.sol"; -import {Vm} from "forge-std/Vm.sol"; -import {Filterer} from "./helpers/Filterer.sol"; -import {UpdatableFilterer} from "./helpers/UpdatableFilterer.sol"; -import {OperatorFilterRegistryStub} from "./helpers/OperatorFilterRegistryStub.sol"; - -contract ConcreteOperatorFilterer is OperatorFilterer { - constructor(address registrant, bool sub) OperatorFilterer(registrant, sub) {} -} - -contract OperatorFiltererTest1 is BaseRegistryTest { - Filterer filterer; - address filteredAddress; - address filteredCodeHashAddress; - bytes32 filteredCodeHash; - address notFiltered; - - function setUp() public override { - super.setUp(); - notFiltered = makeAddr("not filtered"); - filterer = new Filterer(); - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(filterer), filteredAddress, true); - filteredCodeHashAddress = makeAddr("filtered code hash"); - bytes memory code = hex"deadbeef"; - filteredCodeHash = keccak256(code); - registry.updateCodeHash(address(filterer), filteredCodeHash, true); - vm.etch(filteredCodeHashAddress, code); - } - - function testFilter() public { - assertTrue(filterer.testFilter(notFiltered)); - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.testFilter(address(0)); - vm.stopPrank(); - vm.startPrank(filteredCodeHashAddress); - vm.expectRevert(abi.encodeWithSelector(CodeHashFiltered.selector, filteredCodeHashAddress, filteredCodeHash)); - filterer.testFilter(address(0)); - } - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - function testConstructory_noSubscribeOrCopy() public { - vm.recordLogs(); - Filterer filterer2 = new Filterer(); - Vm.Log[] memory logs = vm.getRecordedLogs(); - - assertEq(logs.length, 2); - assertEq(logs[0].topics[0], keccak256("RegistrationUpdated(address,bool)")); - assertEq(address(uint160(uint256(logs[0].topics[1]))), address(filterer2)); - assertEq(logs[1].topics[0], keccak256("OwnershipTransferred(address,address)")); - } - - function testConstructor_copy() public { - address deployed = computeCreateAddress(address(this), vm.getNonce(address(this))); - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(deployed, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorUpdated(deployed, filteredAddress, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit CodeHashUpdated(deployed, filteredCodeHash, true); - new ConcreteOperatorFilterer(address(filterer), false); - } - - function testConstructor_subscribe() public { - address deployed = computeCreateAddress(address(this), vm.getNonce(address(this))); - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(deployed, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(deployed, address(filterer), true); - vm.recordLogs(); - new ConcreteOperatorFilterer(address(filterer), true); - assertEq(vm.getRecordedLogs().length, 2); - } - - function testRegistryNotDeployedDoesNotRevert() public { - vm.etch(address(registry), ""); - Filterer filterer2 = new Filterer(); - assertTrue(filterer2.testFilter(notFiltered)); - } - - function testRevert_OperatorNotAllowed() public { - address stubRegistry = address(new OperatorFilterRegistryStub()); - UpdatableFilterer updatableFilterer = new UpdatableFilterer(stubRegistry); - vm.expectRevert(abi.encodeWithSelector(OperatorFilterer.OperatorNotAllowed.selector, address(filteredAddress))); - updatableFilterer.checkFilterOperator(filteredAddress); - } -} diff --git a/test/OwnedRegistrant.t.sol b/test/OwnedRegistrant.t.sol deleted file mode 100644 index 76ee496..0000000 --- a/test/OwnedRegistrant.t.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OwnedRegistrant} from "../src/OwnedRegistrant.sol"; -import {BaseRegistryTest} from "./BaseRegistryTest.sol"; - -contract OperatorFiltererTest is BaseRegistryTest { - OwnedRegistrant registrant; - address filteredAddress; - address filteredCodeHashAddress; - bytes32 filteredCodeHash; - - function setUp() public override { - super.setUp(); - - registrant = new OwnedRegistrant(address(this)); - filteredAddress = makeAddr("filtered address"); - filteredCodeHashAddress = makeAddr("filtered code hash"); - bytes memory code = hex"deadbeef"; - filteredCodeHash = keccak256(code); - } - - function testConstructor() public { - assertTrue(registry.isRegistered(address(registrant))); - registry.updateOperator(address(registrant), filteredAddress, true); - assertTrue(registry.isOperatorFiltered(address(registrant), filteredAddress)); - } -} diff --git a/test/RevokableDefaultOperatorFilterer.t.sol b/test/RevokableDefaultOperatorFilterer.t.sol deleted file mode 100644 index e0d6b81..0000000 --- a/test/RevokableDefaultOperatorFilterer.t.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableDefaultOperatorFilterer} from "src/RevokableDefaultOperatorFilterer.sol"; -import {RevokableOperatorFilterer} from "src/RevokableOperatorFilterer.sol"; -import {BaseRegistryTest} from "./BaseRegistryTest.sol"; -import {RevokableDefaultFilterer} from "./helpers/RevokableDefaultFilterer.sol"; - -contract RevokableDefaultOperatorFiltererTest is BaseRegistryTest { - RevokableDefaultFilterer filterer; - address filteredAddress; - address filteredCodeHashAddress; - bytes32 filteredCodeHash; - address notFiltered; - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - notFiltered = makeAddr("not filtered"); - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - filteredCodeHashAddress = makeAddr("filtered code hash"); - bytes memory code = hex"deadbeef"; - filteredCodeHash = keccak256(code); - registry.updateCodeHash(address(DEFAULT_SUBSCRIPTION), filteredCodeHash, true); - vm.etch(filteredCodeHashAddress, code); - - filterer = new RevokableDefaultFilterer(); - vm.stopPrank(); - } - - function testFilter() public { - assertTrue(filterer.filterTest(notFiltered)); - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.filterTest(address(0)); - vm.stopPrank(); - vm.startPrank(filteredCodeHashAddress); - vm.expectRevert(abi.encodeWithSelector(CodeHashFiltered.selector, filteredCodeHashAddress, filteredCodeHash)); - filterer.filterTest(address(0)); - } - - function testRevoke() public { - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.filterTest(address(0)); - vm.stopPrank(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - filterer.updateOperatorFilterRegistryAddress(address(0)); - assertFalse(filterer.isOperatorFilterRegistryRevoked()); - vm.stopPrank(); - vm.expectRevert(abi.encodeWithSignature("OnlyOwner()")); - filterer.updateOperatorFilterRegistryAddress(address(0)); - vm.expectRevert(abi.encodeWithSignature("OnlyOwner()")); - filterer.revokeOperatorFilterRegistry(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - filterer.revokeOperatorFilterRegistry(); - - vm.expectRevert(abi.encodeWithSignature("RegistryHasBeenRevoked()")); - filterer.updateOperatorFilterRegistryAddress(address(0)); - vm.expectRevert(abi.encodeWithSignature("RegistryHasBeenRevoked()")); - filterer.revokeOperatorFilterRegistry(); - vm.stopPrank(); - - vm.startPrank(filteredAddress); - assertTrue(filterer.filterTest(address(0))); - vm.stopPrank(); - } -} diff --git a/test/RevokableOperatorFilterer.t.sol b/test/RevokableOperatorFilterer.t.sol deleted file mode 100644 index 290baab..0000000 --- a/test/RevokableOperatorFilterer.t.sol +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableOperatorFilterer} from "../src/RevokableOperatorFilterer.sol"; -import {BaseRegistryTest} from "./BaseRegistryTest.sol"; -import {Vm} from "forge-std/Vm.sol"; -import {RevokableFilterer} from "./helpers/RevokableFilterer.sol"; - -contract ConcreteRevokableOperatorFilterer is RevokableOperatorFilterer { - address _owner; - - constructor(address registry, address registrant, bool sub) RevokableOperatorFilterer(registry, registrant, sub) { - _owner = msg.sender; - } - - function owner() public view override returns (address) { - return _owner; - } -} - -contract RevokableOperatorFiltererTest is BaseRegistryTest { - RevokableFilterer filterer; - address filteredAddress; - address filteredCodeHashAddress; - bytes32 filteredCodeHash; - address notFiltered; - - function setUp() public override { - super.setUp(); - notFiltered = makeAddr("not filtered"); - filterer = new RevokableFilterer(address(registry)); - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(filterer), filteredAddress, true); - filteredCodeHashAddress = makeAddr("filtered code hash"); - bytes memory code = hex"deadbeef"; - filteredCodeHash = keccak256(code); - registry.updateCodeHash(address(filterer), filteredCodeHash, true); - vm.etch(filteredCodeHashAddress, code); - } - - function testFilter() public { - assertTrue(filterer.testFilter(notFiltered)); - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.testFilter(address(0)); - vm.stopPrank(); - vm.startPrank(filteredCodeHashAddress); - vm.expectRevert(abi.encodeWithSelector(CodeHashFiltered.selector, filteredCodeHashAddress, filteredCodeHash)); - filterer.testFilter(address(0)); - } - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - function testConstructory_noSubscribeOrCopy() public { - vm.recordLogs(); - RevokableFilterer filterer2 = new RevokableFilterer(address(registry)); - Vm.Log[] memory logs = vm.getRecordedLogs(); - - assertEq(logs.length, 2); - assertEq(logs[0].topics[0], keccak256("RegistrationUpdated(address,bool)")); - assertEq(address(uint160(uint256(logs[0].topics[1]))), address(filterer2)); - assertEq(logs[1].topics[0], keccak256("OwnershipTransferred(address,address)")); - } - - function testConstructor_copy() public { - address deployed = computeCreateAddress(address(this), vm.getNonce(address(this))); - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(deployed, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorUpdated(deployed, filteredAddress, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit CodeHashUpdated(deployed, filteredCodeHash, true); - new ConcreteRevokableOperatorFilterer(address(registry), address(filterer), false); - } - - function testConstructor_subscribe() public { - address deployed = computeCreateAddress(address(this), vm.getNonce(address(this))); - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(deployed, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(deployed, address(filterer), true); - vm.recordLogs(); - new ConcreteRevokableOperatorFilterer(address(registry), address(filterer), true); - assertEq(vm.getRecordedLogs().length, 2); - } - - function testRegistryNotDeployedDoesNotRevert() public { - vm.etch(address(registry), ""); - RevokableFilterer filterer2 = new RevokableFilterer(address(registry)); - assertTrue(filterer2.testFilter(notFiltered)); - } - - function testUpdateRegistry() public { - address newRegistry = makeAddr("new registry"); - filterer.updateOperatorFilterRegistryAddress(newRegistry); - assertEq(address(filterer.operatorFilterRegistry()), newRegistry); - } - - function testUpdateRegistry_onlyOwner() public { - vm.startPrank(makeAddr("notOwner")); - vm.expectRevert(abi.encodeWithSignature("OnlyOwner()")); - filterer.updateOperatorFilterRegistryAddress(address(0)); - } - - function testZeroAddressBypass() public { - filterer.updateOperatorFilterRegistryAddress(address(0)); - vm.prank(filteredAddress); - assertTrue(filterer.testFilter(address(0))); - - // cannot update even if registry is zero address - // vm.expectRevert(abi.encodeWithSignature("RegistryHasBeenRevoked()")); - filterer.updateOperatorFilterRegistryAddress(address(registry)); - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.testFilter(address(0)); - vm.stopPrank(); - - filterer.revokeOperatorFilterRegistry(); - vm.prank(filteredAddress); - assertTrue(filterer.testFilter(address(0))); - - assertEq(address(filterer.operatorFilterRegistry()), address(0)); - assertTrue(filterer.isOperatorFilterRegistryRevoked()); - - vm.expectRevert(abi.encodeWithSignature("RegistryHasBeenRevoked()")); - filterer.updateOperatorFilterRegistryAddress(address(registry)); - vm.expectRevert(abi.encodeWithSignature("RegistryHasBeenRevoked()")); - filterer.revokeOperatorFilterRegistry(); - } - - function testConstructor_revertOnZeroAddress() public { - vm.expectRevert(abi.encodeWithSignature("InitialRegistryAddressCannotBeZeroAddress()")); - new ConcreteRevokableOperatorFilterer(address(0), address(filterer), false); - } -} diff --git a/test/UpdatableOperatorFilterer.t.sol b/test/UpdatableOperatorFilterer.t.sol deleted file mode 100644 index 93faba1..0000000 --- a/test/UpdatableOperatorFilterer.t.sol +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {UpdatableOperatorFilterer} from "../src/UpdatableOperatorFilterer.sol"; -import {BaseRegistryTest} from "./BaseRegistryTest.sol"; -import {Vm} from "forge-std/Vm.sol"; -import {UpdatableFilterer} from "./helpers/UpdatableFilterer.sol"; -import {OperatorFilterer} from "../src/OperatorFilterer.sol"; -import {OperatorFilterRegistryStub} from "./helpers/OperatorFilterRegistryStub.sol"; - -contract ConcreteUpdatableOperatorFilterer is UpdatableOperatorFilterer { - address _owner; - - constructor(address registry, address registrant, bool sub) UpdatableOperatorFilterer(registry, registrant, sub) { - _owner = msg.sender; - } - - function owner() public view override returns (address) { - return _owner; - } -} - -contract UpdatableOperatorFiltererTest is BaseRegistryTest { - UpdatableFilterer filterer; - address filteredAddress; - address filteredCodeHashAddress; - bytes32 filteredCodeHash; - address notFiltered; - - function setUp() public override { - super.setUp(); - notFiltered = makeAddr("not filtered"); - filterer = new UpdatableFilterer(address(registry)); - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(filterer), filteredAddress, true); - filteredCodeHashAddress = makeAddr("filtered code hash"); - bytes memory code = hex"deadbeef"; - filteredCodeHash = keccak256(code); - registry.updateCodeHash(address(filterer), filteredCodeHash, true); - vm.etch(filteredCodeHashAddress, code); - } - - function testFilter() public { - assertTrue(filterer.testFilter(notFiltered)); - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.testFilter(address(0)); - vm.stopPrank(); - vm.startPrank(filteredCodeHashAddress); - vm.expectRevert(abi.encodeWithSelector(CodeHashFiltered.selector, filteredCodeHashAddress, filteredCodeHash)); - filterer.testFilter(address(0)); - } - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - function testConstructory_noSubscribeOrCopy() public { - vm.recordLogs(); - UpdatableFilterer filterer2 = new UpdatableFilterer(address(registry)); - Vm.Log[] memory logs = vm.getRecordedLogs(); - - assertEq(logs.length, 2); - assertEq(logs[0].topics[0], keccak256("RegistrationUpdated(address,bool)")); - assertEq(address(uint160(uint256(logs[0].topics[1]))), address(filterer2)); - assertEq(logs[1].topics[0], keccak256("OwnershipTransferred(address,address)")); - } - - function testConstructor_copy() public { - address deployed = computeCreateAddress(address(this), vm.getNonce(address(this))); - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(deployed, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorUpdated(deployed, filteredAddress, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit CodeHashUpdated(deployed, filteredCodeHash, true); - new ConcreteUpdatableOperatorFilterer(address(registry), address(filterer), false); - } - - function testConstructor_subscribe() public { - address deployed = computeCreateAddress(address(this), vm.getNonce(address(this))); - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(deployed, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(deployed, address(filterer), true); - vm.recordLogs(); - new ConcreteUpdatableOperatorFilterer(address(registry), address(filterer), true); - assertEq(vm.getRecordedLogs().length, 2); - } - - function testRegistryNotDeployedDoesNotRevert() public { - vm.etch(address(registry), ""); - UpdatableFilterer filterer2 = new UpdatableFilterer(address(registry)); - assertTrue(filterer2.testFilter(notFiltered)); - } - - function testUpdateRegistry() public { - address newRegistry = makeAddr("new registry"); - filterer.updateOperatorFilterRegistryAddress(newRegistry); - assertEq(address(filterer.operatorFilterRegistry()), newRegistry); - } - - function testUpdateRegistry_onlyOwner() public { - vm.startPrank(makeAddr("notOwner")); - vm.expectRevert(abi.encodeWithSignature("OnlyOwner()")); - filterer.updateOperatorFilterRegistryAddress(address(0)); - } - - function testZeroAddressBypass() public { - filterer.updateOperatorFilterRegistryAddress(address(0)); - vm.prank(filteredAddress); - assertTrue(filterer.testFilter(address(0))); - - // can update even if registry is zero address - filterer.updateOperatorFilterRegistryAddress(address(registry)); - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.testFilter(address(0)); - } - - function testRevert_OperatorNotAllowed() public { - address stubRegistry = address(new OperatorFilterRegistryStub()); - UpdatableFilterer updatableFilterer = new UpdatableFilterer(stubRegistry); - vm.expectRevert(abi.encodeWithSelector(OperatorFilterer.OperatorNotAllowed.selector, address(filteredAddress))); - updatableFilterer.checkFilterOperator(filteredAddress); - } -} diff --git a/test/example/ExampleERC1155.t.sol b/test/example/ExampleERC1155.t.sol deleted file mode 100644 index 769d62c..0000000 --- a/test/example/ExampleERC1155.t.sol +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ExampleERC1155} from "../../src/example/ExampleERC1155.sol"; -import {BaseRegistryTest} from "../BaseRegistryTest.sol"; -import {IERC165} from "openzeppelin-contracts/interfaces/IERC165.sol"; -import {IERC1155} from "openzeppelin-contracts/interfaces/IERC1155.sol"; -import {IERC2981} from "openzeppelin-contracts/interfaces/IERC2981.sol"; - -contract TestableExampleERC1155 is ExampleERC1155 { - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId, 1, ""); - } -} - -contract ExampleERC1155Test is BaseRegistryTest { - TestableExampleERC1155 example; - address filteredAddress; - - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - vm.stopPrank(); - - example = new TestableExampleERC1155(); - } - - function testFilter() public { - vm.startPrank(address(filteredAddress)); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1, 1, ""); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amounts = new uint256[](1); - amounts[0] = 1; - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeBatchTransferFrom(makeAddr("from"), makeAddr("to"), ids, amounts, ""); - } - - function testOwnersNotExcluded() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.safeTransferFrom(alice, makeAddr("to"), 1, 1, ""); - } - - function testOwnersNotExcludedBatch() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amounts = new uint256[](1); - amounts[0] = 1; - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.safeBatchTransferFrom(alice, makeAddr("to"), ids, amounts, ""); - } - - function testExclusionExceptionDoesNotApplyToOperators() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(bob); - example.setApprovalForAll(alice, true); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.safeTransferFrom(bob, makeAddr("to"), 1, 1, ""); - } - - function testExcludeApprovals() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(bob); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.setApprovalForAll(alice, true); - } - - function testSupportsInterface() public { - assertTrue(example.supportsInterface(type(IERC165).interfaceId)); - assertTrue(example.supportsInterface(type(IERC1155).interfaceId)); - assertTrue(example.supportsInterface(type(IERC2981).interfaceId)); - } -} diff --git a/test/example/ExampleERC721.t.sol b/test/example/ExampleERC721.t.sol deleted file mode 100644 index dbd015c..0000000 --- a/test/example/ExampleERC721.t.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ExampleERC721} from "../../src/example/ExampleERC721.sol"; -import {BaseRegistryTest} from "../BaseRegistryTest.sol"; -import {IERC165} from "openzeppelin-contracts/interfaces/IERC165.sol"; -import {IERC721} from "openzeppelin-contracts/interfaces/IERC721.sol"; -import {IERC2981} from "openzeppelin-contracts/interfaces/IERC2981.sol"; - -contract TestableExampleERC721 is ExampleERC721 { - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId); - } -} - -contract ExampleERC721Test is BaseRegistryTest { - TestableExampleERC721 example; - address filteredAddress; - - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - vm.stopPrank(); - - example = new TestableExampleERC721(); - } - - function testFilter() public { - vm.startPrank(address(filteredAddress)); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.transferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1, ""); - } - - function testOwnersNotExcluded() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.transferFrom(alice, makeAddr("to"), 1); - } - - function testOwnersNotExcludedSafeTransfer() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - example.mint(alice, 2); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - example.safeTransferFrom(alice, makeAddr("to"), 1); - example.safeTransferFrom(alice, makeAddr("to"), 2, ""); - } - - function testExclusionExceptionDoesNotApplyToOperators() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - vm.prank(bob); - example.setApprovalForAll(alice, true); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.transferFrom(bob, makeAddr("to"), 1); - } - - function testExcludeApprovals() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(bob); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.setApprovalForAll(alice, true); - - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.approve(alice, 1); - } - - function testSupportsInterface() public { - assertTrue(example.supportsInterface(type(IERC165).interfaceId)); - assertTrue(example.supportsInterface(type(IERC721).interfaceId)); - assertTrue(example.supportsInterface(type(IERC2981).interfaceId)); - } -} diff --git a/test/example/RevokableERC1155.t.sol b/test/example/RevokableERC1155.t.sol deleted file mode 100644 index b1d9bc6..0000000 --- a/test/example/RevokableERC1155.t.sol +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableExampleERC1155} from "../../src/example/RevokableExampleERC1155.sol"; -import {BaseRegistryTest} from "../BaseRegistryTest.sol"; -import {IERC165} from "openzeppelin-contracts/interfaces/IERC165.sol"; -import {IERC1155} from "openzeppelin-contracts/interfaces/IERC1155.sol"; -import {IERC2981} from "openzeppelin-contracts/interfaces/IERC2981.sol"; - -contract TestableExampleERC1155 is RevokableExampleERC1155 { - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId, 1, ""); - } -} - -contract RevokeExampleERC1155Test is BaseRegistryTest { - TestableExampleERC1155 example; - address filteredAddress; - - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - vm.stopPrank(); - - example = new TestableExampleERC1155(); - } - - function testFilter() public { - vm.startPrank(address(filteredAddress)); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1, 1, ""); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amounts = new uint256[](1); - amounts[0] = 1; - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeBatchTransferFrom(makeAddr("from"), makeAddr("to"), ids, amounts, ""); - } - - function testOwnersNotExcluded() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.safeTransferFrom(alice, makeAddr("to"), 1, 1, ""); - } - - function testOwnersNotExcludedBatch() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amounts = new uint256[](1); - amounts[0] = 1; - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.safeBatchTransferFrom(alice, makeAddr("to"), ids, amounts, ""); - } - - function testExclusionExceptionDoesNotApplyToOperators() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(bob); - example.setApprovalForAll(alice, true); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.safeTransferFrom(bob, makeAddr("to"), 1, 1, ""); - } - - function testExcludeApprovals() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(bob); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.setApprovalForAll(alice, true); - } - - function testRevoke() public { - address alice = makeAddr("alice"); - address bob = makeAddr("bob"); - example.mint(makeAddr("bob"), 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - example.updateOperatorFilterRegistryAddress(address(0)); - - vm.prank(bob); - example.setApprovalForAll(alice, true); - vm.startPrank(alice); - example.safeTransferFrom(bob, makeAddr("to"), 1, 1, ""); - } - - function testSupportsInterface() public { - assertTrue(example.supportsInterface(type(IERC165).interfaceId)); - assertTrue(example.supportsInterface(type(IERC1155).interfaceId)); - assertTrue(example.supportsInterface(type(IERC2981).interfaceId)); - } -} diff --git a/test/example/RevokableERC721.t.sol b/test/example/RevokableERC721.t.sol deleted file mode 100644 index 20f8a2f..0000000 --- a/test/example/RevokableERC721.t.sol +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableExampleERC721} from "../../src/example/RevokableExampleERC721.sol"; -import {BaseRegistryTest} from "../BaseRegistryTest.sol"; -import {IERC165} from "openzeppelin-contracts/interfaces/IERC165.sol"; -import {IERC721} from "openzeppelin-contracts/interfaces/IERC721.sol"; -import {IERC2981} from "openzeppelin-contracts/interfaces/IERC2981.sol"; - -contract TestableExampleERC721 is RevokableExampleERC721 { - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId); - } -} - -contract RevokableExampleERC721Test is BaseRegistryTest { - TestableExampleERC721 example; - address filteredAddress; - - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - vm.stopPrank(); - - example = new TestableExampleERC721(); - } - - function testFilter() public { - vm.startPrank(address(filteredAddress)); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.transferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1, ""); - } - - function testOwnersNotExcluded() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.transferFrom(alice, makeAddr("to"), 1); - } - - function testOwnersNotExcludedSafeTransfer() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - example.mint(alice, 2); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - example.safeTransferFrom(alice, makeAddr("to"), 1); - example.safeTransferFrom(alice, makeAddr("to"), 2, ""); - } - - function testExclusionExceptionDoesNotApplyToOperators() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - vm.prank(bob); - example.setApprovalForAll(alice, true); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.transferFrom(bob, makeAddr("to"), 1); - } - - function testExcludeApprovals() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(bob); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.setApprovalForAll(alice, true); - - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.approve(alice, 1); - } - - function testRevoke() public { - address alice = makeAddr("alice"); - address bob = makeAddr("bob"); - example.mint(makeAddr("bob"), 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - example.updateOperatorFilterRegistryAddress(address(0)); - - vm.prank(bob); - example.setApprovalForAll(alice, true); - vm.startPrank(alice); - example.safeTransferFrom(bob, makeAddr("to"), 1); - } - - function testSupportsInterface() public { - assertTrue(example.supportsInterface(type(IERC165).interfaceId)); - assertTrue(example.supportsInterface(type(IERC721).interfaceId)); - assertTrue(example.supportsInterface(type(IERC2981).interfaceId)); - } -} diff --git a/test/example/upgradeable/ExampleERC1155Upgradeable.t.sol b/test/example/upgradeable/ExampleERC1155Upgradeable.t.sol deleted file mode 100644 index 6524e4d..0000000 --- a/test/example/upgradeable/ExampleERC1155Upgradeable.t.sol +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ExampleERC1155Upgradeable} from "../../../src/example/upgradeable/ExampleERC1155Upgradeable.sol"; -import {BaseRegistryTest} from "../../BaseRegistryTest.sol"; -import {Initializable} from "openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol"; -import {IERC165} from "openzeppelin-contracts/interfaces/IERC165.sol"; -import {IERC1155} from "openzeppelin-contracts/interfaces/IERC1155.sol"; -import {IERC2981} from "openzeppelin-contracts/interfaces/IERC2981.sol"; - -contract TestableExampleERC1155 is ExampleERC1155Upgradeable { - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId, 1, ""); - } -} - -contract ExampleER1155UpgradeableTest is BaseRegistryTest, Initializable { - TestableExampleERC1155 example; - address filteredAddress; - - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - vm.stopPrank(); - - example = new TestableExampleERC1155(); - example.initialize(); - } - - function testUpgradeable() public { - TestableExampleERC1155 example2 = new TestableExampleERC1155(); - vm.expectEmit(true, true, false, true, address(example2)); - emit Initialized(1); - example2.initialize(); - vm.expectRevert(bytes("Initializable: contract is already initialized")); - example2.initialize(); - } - - function testFilter() public { - vm.startPrank(address(filteredAddress)); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1, 1, ""); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amounts = new uint256[](1); - amounts[0] = 1; - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeBatchTransferFrom(makeAddr("from"), makeAddr("to"), ids, amounts, ""); - } - - function testOwnersNotExcluded() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.safeTransferFrom(alice, makeAddr("to"), 1, 1, ""); - } - - function testOwnersNotExcludedBatch() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amounts = new uint256[](1); - amounts[0] = 1; - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.safeBatchTransferFrom(alice, makeAddr("to"), ids, amounts, ""); - } - - function testExclusionExceptionDoesNotApplyToOperators() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(bob); - example.setApprovalForAll(alice, true); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.safeTransferFrom(bob, makeAddr("to"), 1, 1, ""); - } - - function testExcludeApprovals() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(bob); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.setApprovalForAll(alice, true); - } - - function testSupportsInterface() public { - assertTrue(example.supportsInterface(type(IERC165).interfaceId)); - assertTrue(example.supportsInterface(type(IERC1155).interfaceId)); - assertTrue(example.supportsInterface(type(IERC2981).interfaceId)); - } -} diff --git a/test/example/upgradeable/ExampleERC721Upgradeable.t.sol b/test/example/upgradeable/ExampleERC721Upgradeable.t.sol deleted file mode 100644 index 16c5f74..0000000 --- a/test/example/upgradeable/ExampleERC721Upgradeable.t.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ExampleERC721Upgradeable} from "../../../src/example/upgradeable/ExampleERC721Upgradeable.sol"; -import {BaseRegistryTest} from "../../BaseRegistryTest.sol"; -import {Initializable} from "openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol"; -import {IERC165} from "openzeppelin-contracts/interfaces/IERC165.sol"; -import {IERC721} from "openzeppelin-contracts/interfaces/IERC721.sol"; -import {IERC2981} from "openzeppelin-contracts/interfaces/IERC2981.sol"; - -contract TestableExampleERC721 is ExampleERC721Upgradeable { - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId); - } -} - -contract ExampleERC721UpgradeableTest is BaseRegistryTest, Initializable { - TestableExampleERC721 example; - address filteredAddress; - - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - vm.stopPrank(); - - example = new TestableExampleERC721(); - example.initialize(); - } - - function testUpgradeable() public { - TestableExampleERC721 example2 = new TestableExampleERC721(); - vm.expectEmit(true, true, false, true, address(example2)); - emit Initialized(1); - example2.initialize(); - vm.expectRevert(bytes("Initializable: contract is already initialized")); - example2.initialize(); - } - - function testFilter() public { - vm.startPrank(address(filteredAddress)); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.transferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1, ""); - } - - function testOwnersNotExcluded() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.transferFrom(alice, makeAddr("to"), 1); - } - - function testOwnersNotExcludedSafeTransfer() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - example.mint(alice, 2); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - example.safeTransferFrom(alice, makeAddr("to"), 1); - example.safeTransferFrom(alice, makeAddr("to"), 2, ""); - } - - function testExclusionExceptionDoesNotApplyToOperators() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - vm.prank(bob); - example.setApprovalForAll(alice, true); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.transferFrom(bob, makeAddr("to"), 1); - } - - function testExcludeApprovals() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(bob); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.setApprovalForAll(alice, true); - - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.approve(alice, 1); - } - - function testSupportsInterface() public { - assertTrue(example.supportsInterface(type(IERC165).interfaceId)); - assertTrue(example.supportsInterface(type(IERC721).interfaceId)); - assertTrue(example.supportsInterface(type(IERC2981).interfaceId)); - } -} diff --git a/test/example/upgradeable/RevokableExampleERC1155Upgradeable.t.sol b/test/example/upgradeable/RevokableExampleERC1155Upgradeable.t.sol deleted file mode 100644 index 9fba1d1..0000000 --- a/test/example/upgradeable/RevokableExampleERC1155Upgradeable.t.sol +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableExampleERC1155Upgradeable} from - "../../../src/example/upgradeable/RevokableExampleERC1155Upgradeable.sol"; -import {BaseRegistryTest} from "../../BaseRegistryTest.sol"; -import {Initializable} from "openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol"; -import {IERC165} from "openzeppelin-contracts/interfaces/IERC165.sol"; -import {IERC1155} from "openzeppelin-contracts/interfaces/IERC1155.sol"; -import {IERC2981} from "openzeppelin-contracts/interfaces/IERC2981.sol"; - -contract TestableExampleERC1155 is RevokableExampleERC1155Upgradeable { - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId, 1, ""); - } -} - -contract RevokableExampleER1155UpgradeableTest is BaseRegistryTest, Initializable { - TestableExampleERC1155 example; - address filteredAddress; - - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - vm.stopPrank(); - - example = new TestableExampleERC1155(); - example.initialize(); - } - - function testUpgradeable() public { - TestableExampleERC1155 example2 = new TestableExampleERC1155(); - vm.expectEmit(true, true, false, true, address(example2)); - emit Initialized(1); - example2.initialize(); - vm.expectRevert(bytes("Initializable: contract is already initialized")); - example2.initialize(); - } - - function testFilter() public { - vm.startPrank(address(filteredAddress)); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1, 1, ""); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amounts = new uint256[](1); - amounts[0] = 1; - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeBatchTransferFrom(makeAddr("from"), makeAddr("to"), ids, amounts, ""); - } - - function testOwnersNotExcluded() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.safeTransferFrom(alice, makeAddr("to"), 1, 1, ""); - } - - function testOwnersNotExcludedBatch() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amounts = new uint256[](1); - amounts[0] = 1; - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.safeBatchTransferFrom(alice, makeAddr("to"), ids, amounts, ""); - } - - function testExclusionExceptionDoesNotApplyToOperators() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(bob); - example.setApprovalForAll(alice, true); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.safeTransferFrom(bob, makeAddr("to"), 1, 1, ""); - } - - function testExcludeApprovals() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(bob); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.setApprovalForAll(alice, true); - } - - function testRevoke() public { - address alice = makeAddr("alice"); - address bob = makeAddr("bob"); - example.mint(makeAddr("bob"), 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - example.revokeOperatorFilterRegistry(); - - vm.prank(bob); - example.setApprovalForAll(alice, true); - vm.startPrank(alice); - example.safeTransferFrom(bob, makeAddr("to"), 1, 1, ""); - } - - function testSupportsInterface() public { - assertTrue(example.supportsInterface(type(IERC165).interfaceId)); - assertTrue(example.supportsInterface(type(IERC1155).interfaceId)); - assertTrue(example.supportsInterface(type(IERC2981).interfaceId)); - } -} diff --git a/test/example/upgradeable/RevokableExampleERC721Upgradeable.t.sol b/test/example/upgradeable/RevokableExampleERC721Upgradeable.t.sol deleted file mode 100644 index b92b0ed..0000000 --- a/test/example/upgradeable/RevokableExampleERC721Upgradeable.t.sol +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableExampleERC721Upgradeable} from "../../../src/example/upgradeable/RevokableExampleERC721Upgradeable.sol"; -import {BaseRegistryTest} from "../../BaseRegistryTest.sol"; -import {Initializable} from "openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol"; -import {IERC165} from "openzeppelin-contracts/interfaces/IERC165.sol"; -import {IERC721} from "openzeppelin-contracts/interfaces/IERC721.sol"; -import {IERC2981} from "openzeppelin-contracts/interfaces/IERC2981.sol"; - -contract TestableExampleERC721 is RevokableExampleERC721Upgradeable { - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId); - } -} - -contract ExampleERC721UpgradeableTest is BaseRegistryTest, Initializable { - TestableExampleERC721 example; - address filteredAddress; - - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - vm.stopPrank(); - - example = new TestableExampleERC721(); - example.initialize(); - } - - function testUpgradeable() public { - TestableExampleERC721 example2 = new TestableExampleERC721(); - vm.expectEmit(true, true, false, true, address(example2)); - emit Initialized(1); - example2.initialize(); - vm.expectRevert(bytes("Initializable: contract is already initialized")); - example2.initialize(); - } - - function testFilter() public { - vm.startPrank(address(filteredAddress)); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.transferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1, ""); - } - - function testOwnersNotExcluded() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.transferFrom(alice, makeAddr("to"), 1); - } - - function testOwnersNotExcludedSafeTransfer() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - example.mint(alice, 2); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - example.safeTransferFrom(alice, makeAddr("to"), 1); - example.safeTransferFrom(alice, makeAddr("to"), 2, ""); - } - - function testExclusionExceptionDoesNotApplyToOperators() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - vm.prank(bob); - example.setApprovalForAll(alice, true); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.transferFrom(bob, makeAddr("to"), 1); - } - - function testExcludeApprovals() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(bob); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.setApprovalForAll(alice, true); - - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.approve(alice, 1); - } - - function testRevoke() public { - address alice = makeAddr("alice"); - address bob = makeAddr("bob"); - example.mint(makeAddr("bob"), 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - example.revokeOperatorFilterRegistry(); - - vm.prank(bob); - example.setApprovalForAll(alice, true); - vm.startPrank(alice); - example.safeTransferFrom(bob, makeAddr("to"), 1); - } - - function testSupportsInterface() public { - assertTrue(example.supportsInterface(type(IERC165).interfaceId)); - assertTrue(example.supportsInterface(type(IERC721).interfaceId)); - assertTrue(example.supportsInterface(type(IERC2981).interfaceId)); - } -} diff --git a/test/example/upgradeable/UpdatableExampleERC721Upgradeable.t.sol b/test/example/upgradeable/UpdatableExampleERC721Upgradeable.t.sol deleted file mode 100644 index 9eda09a..0000000 --- a/test/example/upgradeable/UpdatableExampleERC721Upgradeable.t.sol +++ /dev/null @@ -1,272 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {Vm} from "forge-std/Vm.sol"; -import {Initializable} from "openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol"; -import {OwnableUpgradeable} from "openzeppelin-contracts-upgradeable/access/OwnableUpgradeable.sol"; - -import {UpdatableExampleERC721Upgradeable} from "../../../src/example/upgradeable/UpdatableExampleERC721Upgradeable.sol"; -import {UpdatableOperatorFiltererUpgradeable} from "../../../src/upgradeable/UpdatableOperatorFiltererUpgradeable.sol"; -import {BaseRegistryTest} from "../../BaseRegistryTest.sol"; - -import {OperatorFilterRegistryStub} from "../../helpers/OperatorFilterRegistryStub.sol"; - -import {OperatorFilterer} from "../../../src/OperatorFilterer.sol"; - -contract TestableUpdatableExampleERC721Upgradeable is UpdatableExampleERC721Upgradeable { - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId); - } -} - -contract UpdatableERC721UpgradeableForUpgradableTest is BaseRegistryTest, Initializable { - TestableUpdatableExampleERC721Upgradeable example; - address filteredAddress; - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public override { - super.setUp(); - - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), filteredAddress, true); - vm.stopPrank(); - - example = new TestableUpdatableExampleERC721Upgradeable(); - example.initialize(address(registry), DEFAULT_SUBSCRIPTION, true); - } - - function testUpgradeable() public { - TestableUpdatableExampleERC721Upgradeable example2 = new TestableUpdatableExampleERC721Upgradeable(); - vm.expectEmit(true, true, false, true, address(example2)); - emit Initialized(1); - example2.initialize(address(registry), DEFAULT_SUBSCRIPTION, true); - vm.expectRevert(bytes("Initializable: contract is already initialized")); - example2.initialize(address(registry), DEFAULT_SUBSCRIPTION, true); - } - - function testFilter() public { - vm.startPrank(address(filteredAddress)); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.transferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - example.safeTransferFrom(makeAddr("from"), makeAddr("to"), 1, ""); - } - - function testOwnersNotExcluded() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.prank(alice); - example.transferFrom(alice, makeAddr("to"), 1); - } - - function testOwnersNotExcludedSafeTransfer() public { - address alice = address(0xA11CE); - example.mint(alice, 1); - example.mint(alice, 2); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - example.safeTransferFrom(alice, makeAddr("to"), 1); - example.safeTransferFrom(alice, makeAddr("to"), 2, ""); - } - - function testExclusionExceptionDoesNotApplyToOperators() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - vm.prank(bob); - example.setApprovalForAll(alice, true); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(alice); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.transferFrom(bob, makeAddr("to"), 1); - } - - function testExcludeApprovals() public { - address alice = address(0xA11CE); - address bob = address(0xB0B); - example.mint(bob, 1); - - vm.prank(DEFAULT_SUBSCRIPTION); - registry.updateOperator(address(DEFAULT_SUBSCRIPTION), alice, true); - - vm.startPrank(bob); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.setApprovalForAll(alice, true); - - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, alice)); - example.approve(alice, 1); - } -} - -contract ConcreteUpdatableOperatorFiltererUpgradable is UpdatableOperatorFiltererUpgradeable, OwnableUpgradeable { - function initialize(address registry, address registrant, bool sub) public initializer { - __Ownable_init(); - __UpdatableOperatorFiltererUpgradeable_init(registry, registrant, sub); - } - - function testFilter(address from) public view onlyAllowedOperator(from) returns (bool) { - return true; - } - - function checkFilterOperator(address operator) public view { - _checkFilterOperator(operator); - } - - function owner() - public - view - virtual - override(OwnableUpgradeable, UpdatableOperatorFiltererUpgradeable) - returns (address) - { - return OwnableUpgradeable.owner(); - } -} - -contract UpdatableERC721UpgradeableForUpdatableTest is BaseRegistryTest { - ConcreteUpdatableOperatorFiltererUpgradable filterer; - address filteredAddress; - address filteredCodeHashAddress; - bytes32 filteredCodeHash; - address notFiltered; - - function setUp() public override { - super.setUp(); - notFiltered = makeAddr("not filtered"); - filterer = new ConcreteUpdatableOperatorFiltererUpgradable(); - filterer.initialize(address(registry), address(0), false); - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(filterer), filteredAddress, true); - filteredCodeHashAddress = makeAddr("filtered code hash"); - bytes memory code = hex"deadbeef"; - filteredCodeHash = keccak256(code); - registry.updateCodeHash(address(filterer), filteredCodeHash, true); - vm.etch(filteredCodeHashAddress, code); - } - - function testFilter() public { - assertTrue(filterer.testFilter(notFiltered)); - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.testFilter(address(0)); - vm.stopPrank(); - vm.startPrank(filteredCodeHashAddress); - vm.expectRevert(abi.encodeWithSelector(CodeHashFiltered.selector, filteredCodeHashAddress, filteredCodeHash)); - filterer.testFilter(address(0)); - } - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - function testConstructory_noSubscribeOrCopy() public { - vm.recordLogs(); - ConcreteUpdatableOperatorFiltererUpgradable filterer2 = new ConcreteUpdatableOperatorFiltererUpgradable(); - filterer2.initialize(address(registry), address(0), false); - Vm.Log[] memory logs = vm.getRecordedLogs(); - assertEq(logs.length, 3); - assertEq(logs[0].topics[0], keccak256("OwnershipTransferred(address,address)")); - assertEq(logs[1].topics[0], keccak256("RegistrationUpdated(address,bool)")); - assertEq(address(uint160(uint256(logs[1].topics[1]))), address(filterer2)); - assertEq(logs[2].topics[0], keccak256("Initialized(uint8)")); - } - - function testConstructor_copy() public { - address deployed = computeCreateAddress(address(this), vm.getNonce(address(this))); - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(deployed, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit OperatorUpdated(deployed, filteredAddress, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit CodeHashUpdated(deployed, filteredCodeHash, true); - - vm.recordLogs(); - ConcreteUpdatableOperatorFiltererUpgradable filterer2 = new ConcreteUpdatableOperatorFiltererUpgradable(); - filterer2.initialize(address(registry), address(filterer), false); - - Vm.Log[] memory logs = vm.getRecordedLogs(); - assertEq(logs.length, 5); - assertEq(logs[0].topics[0], keccak256("OwnershipTransferred(address,address)")); - assertEq(logs[1].topics[0], keccak256("RegistrationUpdated(address,bool)")); - assertEq(address(uint160(uint256(logs[1].topics[1]))), address(filterer2)); - assertEq(logs[2].topics[0], keccak256("OperatorUpdated(address,address,bool)")); - assertEq(address(uint160(uint256(logs[2].topics[1]))), address(filterer2)); - assertEq(logs[3].topics[0], keccak256("CodeHashUpdated(address,bytes32,bool)")); - assertEq(address(uint160(uint256(logs[3].topics[1]))), address(filterer2)); - assertEq(logs[4].topics[0], keccak256("Initialized(uint8)")); - } - - function testConstructor_subscribe() public { - address deployed = computeCreateAddress(address(this), vm.getNonce(address(this))); - vm.expectEmit(true, false, false, false, address(registry)); - emit RegistrationUpdated(deployed, true); - vm.expectEmit(true, true, true, false, address(registry)); - emit SubscriptionUpdated(deployed, address(filterer), true); - - vm.recordLogs(); - ConcreteUpdatableOperatorFiltererUpgradable filterer2 = new ConcreteUpdatableOperatorFiltererUpgradable(); - filterer2.initialize(address(registry), address(filterer), true); - - Vm.Log[] memory logs = vm.getRecordedLogs(); - assertEq(logs.length, 4); - assertEq(logs[0].topics[0], keccak256("OwnershipTransferred(address,address)")); - assertEq(logs[1].topics[0], keccak256("RegistrationUpdated(address,bool)")); - assertEq(address(uint160(uint256(logs[1].topics[1]))), address(filterer2)); - assertEq(logs[2].topics[0], keccak256("SubscriptionUpdated(address,address,bool)")); - assertEq(address(uint160(uint256(logs[2].topics[1]))), address(filterer2)); - assertEq(logs[3].topics[0], keccak256("Initialized(uint8)")); - } - - function testRegistryNotDeployedDoesNotRevert() public { - vm.etch(address(registry), ""); - ConcreteUpdatableOperatorFiltererUpgradable filterer2 = new ConcreteUpdatableOperatorFiltererUpgradable(); - filterer2.initialize(address(registry), address(0), false); - assertTrue(filterer2.testFilter(notFiltered)); - } - - function testUpdateRegistry() public { - address newRegistry = makeAddr("new registry"); - filterer.updateOperatorFilterRegistryAddress(newRegistry); - assertEq(address(filterer.operatorFilterRegistry()), newRegistry); - } - - function testUpdateRegistry_onlyOwner() public { - vm.startPrank(makeAddr("notOwner")); - vm.expectRevert(abi.encodeWithSignature("OnlyOwner()")); - filterer.updateOperatorFilterRegistryAddress(address(0)); - } - - function testZeroAddressBypass() public { - filterer.updateOperatorFilterRegistryAddress(address(0)); - vm.prank(filteredAddress); - assertTrue(filterer.testFilter(address(0))); - - // can update even if registry is zero address - filterer.updateOperatorFilterRegistryAddress(address(registry)); - vm.startPrank(filteredAddress); - vm.expectRevert(abi.encodeWithSelector(AddressFiltered.selector, filteredAddress)); - filterer.testFilter(address(0)); - } - - function testRevert_OperatorNotAllowed() public { - address stubRegistry = address(new OperatorFilterRegistryStub()); - ConcreteUpdatableOperatorFiltererUpgradable updatableFilterer = - new ConcreteUpdatableOperatorFiltererUpgradable(); - updatableFilterer.initialize(stubRegistry, address(0), false); - vm.expectRevert(abi.encodeWithSelector(OperatorFilterer.OperatorNotAllowed.selector, address(filteredAddress))); - updatableFilterer.checkFilterOperator(filteredAddress); - } -} diff --git a/test/helpers/DefaultFilterer.sol b/test/helpers/DefaultFilterer.sol deleted file mode 100644 index 4da9fe7..0000000 --- a/test/helpers/DefaultFilterer.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {DefaultOperatorFilterer} from "../../src/DefaultOperatorFilterer.sol"; - -contract DefaultFilterer is DefaultOperatorFilterer { - constructor() DefaultOperatorFilterer() {} - - function filterTest(address from) public view onlyAllowedOperator(from) returns (bool) { - return true; - } -} diff --git a/test/helpers/Filterer.sol b/test/helpers/Filterer.sol deleted file mode 100644 index 8e264ec..0000000 --- a/test/helpers/Filterer.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFilterer} from "../../src/OperatorFilterer.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; - -contract Filterer is OperatorFilterer, Ownable { - constructor() OperatorFilterer(address(0), false) {} - - function testFilter(address from) public view onlyAllowedOperator(from) returns (bool) { - return true; - } - - function checkFilterOperator(address operator) public view { - _checkFilterOperator(operator); - } -} diff --git a/test/helpers/OperatorFilterRegistryStub.sol b/test/helpers/OperatorFilterRegistryStub.sol deleted file mode 100644 index 86522b0..0000000 --- a/test/helpers/OperatorFilterRegistryStub.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -contract OperatorFilterRegistryStub { - function register(address) public pure {} - - function isOperatorAllowed(address, address) public pure returns (bool) { - return false; - } -} diff --git a/test/helpers/RevokableDefaultFilterer.sol b/test/helpers/RevokableDefaultFilterer.sol deleted file mode 100644 index 839d292..0000000 --- a/test/helpers/RevokableDefaultFilterer.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableDefaultOperatorFilterer} from "../../src/RevokableDefaultOperatorFilterer.sol"; - -contract RevokableDefaultFilterer is RevokableDefaultOperatorFilterer { - address _owner; - - constructor() RevokableDefaultOperatorFilterer() { - _owner = msg.sender; - } - - function filterTest(address from) public view onlyAllowedOperator(from) returns (bool) { - return true; - } - - function owner() public view override returns (address) { - return _owner; - } -} diff --git a/test/helpers/RevokableFilterer.sol b/test/helpers/RevokableFilterer.sol deleted file mode 100644 index 0448cf5..0000000 --- a/test/helpers/RevokableFilterer.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableOperatorFilterer} from "../../src/RevokableOperatorFilterer.sol"; -import {UpdatableOperatorFilterer} from "../../src/UpdatableOperatorFilterer.sol"; - -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; - -contract RevokableFilterer is RevokableOperatorFilterer, Ownable { - constructor(address registry) RevokableOperatorFilterer(registry, address(0), false) {} - - function testFilter(address from) public view onlyAllowedOperator(from) returns (bool) { - return true; - } - - function owner() public view override(Ownable, UpdatableOperatorFilterer) returns (address) { - return Ownable.owner(); - } -} diff --git a/test/helpers/RevokableUpgradeableFilterer.sol b/test/helpers/RevokableUpgradeableFilterer.sol deleted file mode 100644 index 028cac8..0000000 --- a/test/helpers/RevokableUpgradeableFilterer.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {RevokableOperatorFiltererUpgradeable} from "../../src/upgradeable/RevokableOperatorFiltererUpgradeable.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; - -contract RevokableUpgradeableFilterer is RevokableOperatorFiltererUpgradeable, Ownable { - constructor() RevokableOperatorFiltererUpgradeable() {} - - function testFilter(address from) public view onlyAllowedOperator(from) returns (bool) { - return true; - } - - function checkFilterOperator(address operator) public view { - _checkFilterOperator(operator); - } - - function init(address subscription, bool subscribe) public initializer { - __OperatorFilterer_init(subscription, subscribe); - } - - function owner() public view override(Ownable, RevokableOperatorFiltererUpgradeable) returns (address) { - return Ownable.owner(); - } -} diff --git a/test/helpers/UpdatableFilterer.sol b/test/helpers/UpdatableFilterer.sol deleted file mode 100644 index af06c9b..0000000 --- a/test/helpers/UpdatableFilterer.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {UpdatableOperatorFilterer} from "../../src/UpdatableOperatorFilterer.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; - -contract UpdatableFilterer is UpdatableOperatorFilterer, Ownable { - constructor(address registry) UpdatableOperatorFilterer(registry, address(0), false) {} - - function testFilter(address from) public view onlyAllowedOperator(from) returns (bool) { - return true; - } - - function owner() public view override(Ownable, UpdatableOperatorFilterer) returns (address) { - return Ownable.owner(); - } - - function checkFilterOperator(address operator) public view { - _checkFilterOperator(operator); - } -} diff --git a/test/helpers/UpgradeableFilterer.sol b/test/helpers/UpgradeableFilterer.sol deleted file mode 100644 index 1374d5f..0000000 --- a/test/helpers/UpgradeableFilterer.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {OperatorFiltererUpgradeable} from "../../src/upgradeable/OperatorFiltererUpgradeable.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; - -contract UpgradeableFilterer is OperatorFiltererUpgradeable, Ownable { - constructor() OperatorFiltererUpgradeable() {} - - function testFilter(address from) public view onlyAllowedOperator(from) returns (bool) { - return true; - } - - function checkFilterOperator(address operator) public view { - _checkFilterOperator(operator); - } - - function init(address subscription, bool subscribe) public initializer { - __OperatorFilterer_init(subscription, subscribe); - } -} diff --git a/test/upgradeable/RevokableUpgradeableOperatorFilterer.t.sol b/test/upgradeable/RevokableUpgradeableOperatorFilterer.t.sol deleted file mode 100644 index 8b4208f..0000000 --- a/test/upgradeable/RevokableUpgradeableOperatorFilterer.t.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import {BaseRegistryTest} from "../BaseRegistryTest.sol"; -import {RevokableUpgradeableFilterer} from "../helpers/RevokableUpgradeableFilterer.sol"; - -contract RevokableUpgradeableOperatorFiltererTest is BaseRegistryTest { - RevokableUpgradeableFilterer filterer; - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - address filteredAddress; - address filteredCodeHashAddress; - bytes32 filteredCodeHash; - address notFiltered; - - function setUp() public virtual override { - super.setUp(); - notFiltered = makeAddr("not filtered"); - filterer = new RevokableUpgradeableFilterer(); - filterer.init(address(0), false); - filteredAddress = makeAddr("filtered address"); - registry.updateOperator(address(filterer), filteredAddress, true); - filteredCodeHashAddress = makeAddr("filtered code hash"); - bytes memory code = hex"deadbeef"; - filteredCodeHash = keccak256(code); - registry.updateCodeHash(address(filterer), filteredCodeHash, true); - vm.etch(filteredCodeHashAddress, code); - } - - function testRevoke() public { - filterer.revokeOperatorFilterRegistry(); - vm.prank(filteredAddress); - assertTrue(filterer.testFilter(address(0))); - - assertTrue(filterer.isOperatorFilterRegistryRevoked()); - - vm.expectRevert(abi.encodeWithSignature("AlreadyRevoked()")); - filterer.revokeOperatorFilterRegistry(); - - vm.prank(makeAddr("not owner")); - vm.expectRevert(abi.encodeWithSignature("OnlyOwner()")); - filterer.revokeOperatorFilterRegistry(); - } -} diff --git a/test/upgradeable/UpgradeableOperatorFilterer.t.sol b/test/upgradeable/UpgradeableOperatorFilterer.t.sol deleted file mode 100644 index cb0a849..0000000 --- a/test/upgradeable/UpgradeableOperatorFilterer.t.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import {BaseRegistryTest} from "../BaseRegistryTest.sol"; -import {UpgradeableFilterer} from "../helpers/UpgradeableFilterer.sol"; - -contract UpgradeableOperatorFiltererTest is BaseRegistryTest { - UpgradeableFilterer filterer; - address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); - - function setUp() public virtual override { - super.setUp(); - filterer = new UpgradeableFilterer(); - vm.startPrank(DEFAULT_SUBSCRIPTION); - registry.register(DEFAULT_SUBSCRIPTION); - registry.updateOperator(DEFAULT_SUBSCRIPTION, makeAddr("operator"), true); - vm.stopPrank(); - } - - function testInit_copy() public { - filterer.init(DEFAULT_SUBSCRIPTION, false); - assertTrue(registry.isOperatorFiltered(address(filterer), makeAddr("operator"))); - } - - function testInit_noSubscription() public { - filterer.init(address(0), false); - assertTrue(registry.isRegistered(address(filterer))); - } - - function testInit_registered() public { - vm.prank(address(filterer)); - registry.register(address(filterer)); - filterer.init(DEFAULT_SUBSCRIPTION, true); - // should not be subscribed since already registered - assertEq(registry.subscriptionOf(address(filterer)), address(0)); - } -} diff --git a/test/validation/ExampleERC1155Validation.t.sol b/test/validation/ExampleERC1155Validation.t.sol deleted file mode 100644 index ddced3d..0000000 --- a/test/validation/ExampleERC1155Validation.t.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ValidationTest} from "./Validation.t.sol"; -import {TestableExampleERC1155} from "../example/ExampleERC1155.t.sol"; - -interface IOperatorFilterRegistry { - function filteredOperators(address addr) external returns (address[] memory); -} - -contract ExampleERC1155ValidationTest is ValidationTest { - function setUp() public override { - owner = makeAddr("owner"); - tokenId = 1; - - // Fork mainnet - vm.createSelectFork(getChain("mainnet").rpcUrl); - filteredOperators = - IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY).filteredOperators(CANONICAL_REGISTRANT); - TestableExampleERC1155 nftContract = new TestableExampleERC1155(); - nftContract.mint(owner, tokenId); - contractAddress = address(nftContract); - } -} diff --git a/test/validation/ExampleERC721Validation.t.sol b/test/validation/ExampleERC721Validation.t.sol deleted file mode 100644 index ac54155..0000000 --- a/test/validation/ExampleERC721Validation.t.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {ValidationTest} from "./Validation.t.sol"; -import {TestableExampleERC721} from "../example/ExampleERC721.t.sol"; - -interface IOperatorFilterRegistry { - function filteredOperators(address addr) external returns (address[] memory); -} - -contract ExampleERC721ValidationTest is ValidationTest { - function setUp() public override { - owner = makeAddr("owner"); - tokenId = 1; - - // Fork mainnet - vm.createSelectFork(getChain("mainnet").rpcUrl); - filteredOperators = - IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY).filteredOperators(CANONICAL_REGISTRANT); - TestableExampleERC721 nftContract = new TestableExampleERC721(); - nftContract.mint(owner, tokenId); - contractAddress = address(nftContract); - } -} diff --git a/test/validation/Validation.t.sol b/test/validation/Validation.t.sol deleted file mode 100644 index 91e2ece..0000000 --- a/test/validation/Validation.t.sol +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {Test, console2} from "forge-std/Test.sol"; -import {IERC721} from "forge-std/interfaces/IERC721.sol"; -import {IERC1155} from "forge-std/interfaces/IERC1155.sol"; -import {IERC165} from "forge-std/interfaces/IERC165.sol"; -import {TestableExampleERC721} from "../example/ExampleERC721.t.sol"; - -interface IOperatorFilterRegistry { - function filteredOperators(address addr) external returns (address[] memory); -} - -interface IERC721SeaDrop { - function owner() external view returns (address); - - function setMaxSupply(uint256 newMaxSupply) external; - - function updateAllowedSeaDrop(address[] calldata allowedSeaDrop) external; - - function mintSeaDrop(address minter, uint256 quantity) external; - - function totalSupply() external view returns (uint256); -} - -contract ValidationTest is Test { - address constant LOOKSRAREV2_TRANSFER_MANAGER = 0x000000000060C4Ca14CfC4325359062ace33Fe3D; - - address constant CANONICAL_OPERATOR_FILTER_REGISTRY = 0x000000000000AAeB6D7670E522A718067333cd4E; - address constant CANONICAL_REGISTRANT = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6; - - // Contract to test against - /// The token contract to test against. - address contractAddress; - - /// The token ID to test against. - uint256 tokenId; - - /// The owner of the NFT. - address owner; - - /// The filtered operators to check compliance against. - address[] filteredOperators; - - /// The canonical cross-chain SeaDrop contract. - address seaDrop = 0x00005EA00Ac477B1030CE78506496e8C2dE24bf5; - - /// The INonFungibleSeaDropToken interface ID. - bytes4 constant SEADROP_TOKEN_INTERFACE_ID = 0x1890fe8e; - - function setUp() public virtual { - // Fork network - try vm.envString("NETWORK") returns (string memory envNetwork) { - vm.createSelectFork(getChain(envNetwork).rpcUrl); - } catch { - // fallback to mainnet - vm.createSelectFork(getChain("mainnet").rpcUrl); - } - - filteredOperators = - IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY).filteredOperators(CANONICAL_REGISTRANT); - - // try to load token ID from .env - try vm.envUint("TOKEN_ID") returns (uint256 _tokenId) { - tokenId = _tokenId; - } catch (bytes memory) { - // fallback to 1 - tokenId = 1; - } - - // try to load owner from .env - try vm.envAddress("OWNER") returns (address _owner) { - owner = _owner; - } catch (bytes memory) { - // fallback to dummy EOA - owner = makeAddr("owner"); - } - - // try to load contract address from .env - try vm.envAddress("CONTRACT_ADDRESS") returns (address _contractAddress) { - contractAddress = _contractAddress; - } catch (bytes memory) { - // fallback to deploying new contract - TestableExampleERC721 nftContract = new TestableExampleERC721(); - nftContract.mint(owner, tokenId); - contractAddress = address(nftContract); - } - } - - function testValidateEnforcement() public { - IERC165 tokenContract = IERC165(contractAddress); - try tokenContract.supportsInterface(type(IERC721).interfaceId) returns (bool _supports) { - if (_supports) { - _testERC721(); - } else { - if (tokenContract.supportsInterface(type(IERC1155).interfaceId)) { - _testERC1155(); - } else { - // else fall back to ERC721 - console2.log("ERC165 check returned false for both ERC721 and ERC1155, falling back to ERC721."); - _testERC721(); - } - } - } catch { - // if ERC165 check fails, fall back to ERC721 - console2.log("ERC165 check reverted, falling back to ERC721."); - _testERC721(); - } - } - - function _testERC721() internal { - // Cast the contract to an ERC721. - IERC721 nftContract = IERC721(contractAddress); - - // Get the current owner of the NFT - try nftContract.ownerOf(tokenId) returns (address _owner) { - owner = _owner; - } catch { - // If the tokenId doesn't exist, check if this is a SeaDrop token, - // which we can simulate a mint for. - if (!nftContract.supportsInterface(SEADROP_TOKEN_INTERFACE_ID)) { - revert("The token reverted on ownerOf(tokenId) and it is not a SeaDrop token."); - } - - // Cast the contract to a SeaDrop token. - IERC721SeaDrop seaDropToken = IERC721SeaDrop(contractAddress); - - // Set the token owner to an address, it doesn't matter who this is. - owner = makeAddr("alice"); - - // Increase the max supply by 1 so we can mint. - vm.startPrank(seaDropToken.owner()); - uint256 newMaxSupply = seaDropToken.totalSupply() + 1; - seaDropToken.setMaxSupply(newMaxSupply); - - // Ensure SeaDrop is allowed to mint. - address[] memory allowedSeaDrop = new address[](1); - allowedSeaDrop[0] = seaDrop; - seaDropToken.updateAllowedSeaDrop(allowedSeaDrop); - vm.stopPrank(); - - // Mint the token to the token owner. - vm.prank(seaDrop); - seaDropToken.mintSeaDrop(owner, 1); - - // SeaDrop tokens have a start token id of 1, - // so the newly minted token id should be totalSupply() - tokenId = seaDropToken.totalSupply(); - } - - for (uint256 i = 0; i < filteredOperators.length; i++) { - // skip LOOKSRAREV2_TRANSFER_MANAGER as updates are subject to grace period - if (filteredOperators[i] == LOOKSRAREV2_TRANSFER_MANAGER) { - continue; - } - address operator = filteredOperators[i]; - - // Try to set approval for the operator. - vm.startPrank(owner); - try nftContract.setApprovalForAll(operator, true) { - // Blocking approvals is not required, so continue to check transfers. - } catch { - // Continue to test transfer methods, since marketplace approvals can be - // hard-coded into contracts. - } - - // Also include per-token approvals as those may not be blocked. - try nftContract.approve(operator, tokenId) { - // Continue to check transfers. - } catch { - // Continue to test transfer methods, since marketplace approvals can be - // hard-coded into contracts. - } - vm.stopPrank(); - - // Ensure operator is not able to transfer the token. - vm.startPrank(operator); - vm.expectRevert(); - nftContract.safeTransferFrom(owner, address(1), tokenId); - - vm.expectRevert(); - nftContract.safeTransferFrom(owner, address(1), tokenId, ""); - - vm.expectRevert(); - nftContract.transferFrom(owner, address(1), tokenId); - vm.stopPrank(); - } - } - - function _testERC1155() internal { - // Cast the contract to an ERC1155. - IERC1155 nftContract = IERC1155(contractAddress); - - for (uint256 i = 0; i < filteredOperators.length; i++) { - address operator = filteredOperators[i]; - - // Try to set approval for the operator. - vm.prank(owner); - try nftContract.setApprovalForAll(operator, true) {} - catch (bytes memory) { - // even if approval reverts, continue to test transfer methods, since marketplace approvals can be - // hard-coded into contracts - } - - uint256[] memory tokenIds = new uint256[](1); - tokenIds[0] = tokenId; - uint256[] memory amounts = new uint256[](1); - amounts[0] = 1; - - // Ensure operator is not able to transfer the token. - vm.startPrank(operator); - vm.expectRevert(); - nftContract.safeTransferFrom(owner, address(1), tokenId, 1, ""); - - vm.expectRevert(); - nftContract.safeBatchTransferFrom(owner, address(1), tokenIds, amounts, ""); - vm.stopPrank(); - } - } -} diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index ebafeed..0000000 --- a/yarn.lock +++ /dev/null @@ -1,13 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@openzeppelin/contracts-upgradeable@^4.8.2": - version "4.8.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.2.tgz#edef522bdbc46d478481391553bababdd2199e27" - integrity sha512-zIggnBwemUmmt9IS73qxi+tumALxCY4QEs3zLCII78k0Gfse2hAOdAkuAeLUzvWUpneMUfFE5sGHzEUSTvn4Ag== - -"@openzeppelin/contracts@^4.7.3": - version "4.7.3" - resolved "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.3.tgz" - integrity sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==