From 4b650bb4d413272747a73b062098b7cd1cc26590 Mon Sep 17 00:00:00 2001 From: Rishabh Sharma Date: Mon, 14 Aug 2023 10:43:16 +0530 Subject: [PATCH 1/3] fix: updated deployment script --- packages/deploy/deploy/300_catalyst/302_catalyst_setup.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/deploy/deploy/300_catalyst/302_catalyst_setup.ts b/packages/deploy/deploy/300_catalyst/302_catalyst_setup.ts index 07111e5c52..c193de5896 100644 --- a/packages/deploy/deploy/300_catalyst/302_catalyst_setup.ts +++ b/packages/deploy/deploy/300_catalyst/302_catalyst_setup.ts @@ -1,6 +1,9 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; +// TODO this should not be hardcoded here +export const royaltyAmount = 500; + const func: DeployFunction = async function ( hre: HardhatRuntimeEnvironment ): Promise { @@ -33,8 +36,7 @@ const func: DeployFunction = async function ( // set catalyst on Royalty Manager const catalyst = await deployments.get('Catalyst'); - // TODO this should not be hardcoded here - const royaltyAmount = 500; + if ( (await read( 'RoyaltyManager', From 30260d73db8b1598c5973e0560c4457e5534668b Mon Sep 17 00:00:00 2001 From: Rishabh Sharma Date: Mon, 14 Aug 2023 10:43:55 +0530 Subject: [PATCH 2/3] fix: added deployment scripts --- .../deploy/deploy_mocks/200_marketplace_1.ts | 17 +++++++++++++++++ .../deploy/deploy_mocks/300_marketplace_2.ts | 17 +++++++++++++++++ .../deploy/deploy_mocks/400_marketplace_3.ts | 17 +++++++++++++++++ .../deploy/deploy_mocks/500_marketplace_4.ts | 17 +++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 packages/deploy/deploy_mocks/200_marketplace_1.ts create mode 100644 packages/deploy/deploy_mocks/300_marketplace_2.ts create mode 100644 packages/deploy/deploy_mocks/400_marketplace_3.ts create mode 100644 packages/deploy/deploy_mocks/500_marketplace_4.ts diff --git a/packages/deploy/deploy_mocks/200_marketplace_1.ts b/packages/deploy/deploy_mocks/200_marketplace_1.ts new file mode 100644 index 0000000000..f960ecfca7 --- /dev/null +++ b/packages/deploy/deploy_mocks/200_marketplace_1.ts @@ -0,0 +1,17 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + await deploy('MockERC1155MarketPlace1', { + from: deployer, + contract: + '@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol:MockERC1155MarketPlace1', + log: true, + }); +}; +export default func; +func.tags = ['MockERC1155MarketPlace1']; diff --git a/packages/deploy/deploy_mocks/300_marketplace_2.ts b/packages/deploy/deploy_mocks/300_marketplace_2.ts new file mode 100644 index 0000000000..0e6010828c --- /dev/null +++ b/packages/deploy/deploy_mocks/300_marketplace_2.ts @@ -0,0 +1,17 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + await deploy('MockERC1155MarketPlace2', { + from: deployer, + contract: + '@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol:MockERC1155MarketPlace2', + log: true, + }); +}; +export default func; +func.tags = ['MockERC1155MarketPlace2']; diff --git a/packages/deploy/deploy_mocks/400_marketplace_3.ts b/packages/deploy/deploy_mocks/400_marketplace_3.ts new file mode 100644 index 0000000000..2f846baceb --- /dev/null +++ b/packages/deploy/deploy_mocks/400_marketplace_3.ts @@ -0,0 +1,17 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + await deploy('MockERC1155MarketPlace3', { + from: deployer, + contract: + '@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol:MockERC1155MarketPlace3', + log: true, + }); +}; +export default func; +func.tags = ['MockERC1155MarketPlace3']; diff --git a/packages/deploy/deploy_mocks/500_marketplace_4.ts b/packages/deploy/deploy_mocks/500_marketplace_4.ts new file mode 100644 index 0000000000..ce37a38e09 --- /dev/null +++ b/packages/deploy/deploy_mocks/500_marketplace_4.ts @@ -0,0 +1,17 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + await deploy('MockERC1155MarketPlace4', { + from: deployer, + contract: + '@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol:MockERC1155MarketPlace4', + log: true, + }); +}; +export default func; +func.tags = ['MockERC1155MarketPlace4']; From 520949dbfc2f549bc67730f873440d27863acc37 Mon Sep 17 00:00:00 2001 From: Rishabh Sharma Date: Mon, 14 Aug 2023 10:45:01 +0530 Subject: [PATCH 3/3] feat: added intregration tests --- .../deploy/test/asset/AssetReveal.test.ts | 103 +++++ .../deploy/test/catalyst/catalyst.test.ts | 226 ++++++++++ packages/deploy/utils/abi.ts | 397 ++++++++++++++++++ packages/deploy/utils/bytecodes.ts | 2 + 4 files changed, 728 insertions(+) create mode 100644 packages/deploy/test/asset/AssetReveal.test.ts create mode 100644 packages/deploy/test/catalyst/catalyst.test.ts create mode 100644 packages/deploy/utils/abi.ts create mode 100644 packages/deploy/utils/bytecodes.ts diff --git a/packages/deploy/test/asset/AssetReveal.test.ts b/packages/deploy/test/asset/AssetReveal.test.ts new file mode 100644 index 0000000000..ca19b2eb3f --- /dev/null +++ b/packages/deploy/test/asset/AssetReveal.test.ts @@ -0,0 +1,103 @@ +import {expect} from 'chai'; +import {deployments} from 'hardhat'; + +const setupTest = deployments.createFixture( + async ({deployments, getNamedAccounts, ethers}) => { + const {assetAdmin, backendAuthWallet} = await getNamedAccounts(); + await deployments.fixture('Asset'); + const Asset = await deployments.get('Asset'); + const AssetContract = await ethers.getContractAt('Asset', Asset.address); + const AssetReveal = await deployments.get('AssetReveal'); + const AssetRevealContract = await ethers.getContractAt( + 'AssetReveal', + AssetReveal.address + ); + const Catalyst = await deployments.get('Catalyst'); + const CatalystContract = await ethers.getContractAt( + 'Catalyst', + Catalyst.address + ); + const TRUSTED_FORWARDER = await deployments.get('TRUSTED_FORWARDER_V2'); + const AuthSuperValidator = await deployments.get('AuthSuperValidator'); + const AuthSuperValidatorContract = await ethers.getContractAt( + 'AuthSuperValidator', + AuthSuperValidator.address + ); + + return { + AssetContract, + AssetRevealContract, + CatalystContract, + TRUSTED_FORWARDER, + AuthSuperValidatorContract, + assetAdmin, + backendAuthWallet, + }; + } +); + +describe('Asset Reveal', function () { + describe('Contract references', function () { + it('AuthSuperValidator', async function () { + const {AssetRevealContract, AuthSuperValidatorContract} = + await setupTest(); + expect(await AssetRevealContract.getAuthValidator()).to.be.equal( + AuthSuperValidatorContract.address + ); + }); + it('Asset', async function () { + const {AssetRevealContract, AssetContract} = await setupTest(); + expect(await AssetRevealContract.getAssetContract()).to.be.equal( + AssetContract.address + ); + }); + }); + describe('Roles', function () { + it('Admin', async function () { + const {AssetRevealContract, assetAdmin} = await setupTest(); + const defaultAdminRole = await AssetRevealContract.DEFAULT_ADMIN_ROLE(); + expect(await AssetRevealContract.hasRole(defaultAdminRole, assetAdmin)).to + .be.true; + }); + it("Asset's Minter role is granted to AssetReveal", async function () { + const {AssetRevealContract, AssetContract} = await setupTest(); + const minterRole = await AssetContract.MINTER_ROLE(); + expect( + await AssetContract.hasRole(minterRole, AssetRevealContract.address) + ).to.be.true; + }); + it('AuthSuperValidator signer is set to backendAuthWallet', async function () { + const { + AssetRevealContract, + AuthSuperValidatorContract, + backendAuthWallet, + } = await setupTest(); + expect( + await AuthSuperValidatorContract.getSigner(AssetRevealContract.address) + ).to.be.equal(backendAuthWallet); + expect( + await AuthSuperValidatorContract.getSigner(AssetRevealContract.address) + ).to.be.equal(backendAuthWallet); + }); + }); + describe('EIP712', function () { + it("name is 'Sandbox Asset Reveal'", async function () { + const {AssetRevealContract} = await setupTest(); + const eip712Domain = await AssetRevealContract.eip712Domain(); + expect(eip712Domain.name).to.be.equal('Sandbox Asset Reveal'); + }); + it("version is '1.0'", async function () { + const {AssetRevealContract} = await setupTest(); + const eip712Domain = await AssetRevealContract.eip712Domain(); + expect(eip712Domain.version).to.be.equal('1.0'); + }); + }); + describe('Trusted Forwarder', function () { + it('Trusted forwarder address is set correctly', async function () { + const {AssetRevealContract, TRUSTED_FORWARDER} = await setupTest(); + expect(await AssetRevealContract.getTrustedForwarder()).to.be.equal( + TRUSTED_FORWARDER.address + ); + }); + }); +}); diff --git a/packages/deploy/test/catalyst/catalyst.test.ts b/packages/deploy/test/catalyst/catalyst.test.ts new file mode 100644 index 0000000000..d4868133fb --- /dev/null +++ b/packages/deploy/test/catalyst/catalyst.test.ts @@ -0,0 +1,226 @@ +import {royaltyAmount} from '../../deploy/300_catalyst/302_catalyst_setup'; +import {OPERATOR_FILTER_REGISTRY} from './../../../asset/data/constants'; +import {expect} from 'chai'; +import {OperatorFilterRegistryBytecode} from '../../utils/bytecodes'; +import {OperatorFilterRegistry_ABI} from '../../utils/abi'; +import {deployments} from 'hardhat'; + +const setupTest = deployments.createFixture( + async ({deployments, network, getNamedAccounts, ethers}) => { + const {catalystAdmin, catalystMinter} = await getNamedAccounts(); + await network.provider.send('hardhat_setCode', [ + OPERATOR_FILTER_REGISTRY, + OperatorFilterRegistryBytecode, + ]); + const OperatorFilterRegistryContract = await ethers.getContractAt( + OperatorFilterRegistry_ABI, + OPERATOR_FILTER_REGISTRY + ); + + await deployments.fixture([ + 'MockERC1155MarketPlace1', + 'MockERC1155MarketPlace2', + 'MockERC1155MarketPlace3', + 'MockERC1155MarketPlace4', + ]); + + const MockERC1155MarketPlace1 = await deployments.get( + 'MockERC1155MarketPlace1' + ); + const MockERC1155MarketPlace2 = await deployments.get( + 'MockERC1155MarketPlace2' + ); + const MockERC1155MarketPlace3 = await deployments.get( + 'MockERC1155MarketPlace3' + ); + const MockERC1155MarketPlace4 = await deployments.get( + 'MockERC1155MarketPlace4' + ); + await network.provider.send('hardhat_setBalance', [ + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6', + '0xDE0B6B3A7640000', + ]); + await network.provider.request({ + method: 'hardhat_impersonateAccount', + params: ['0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6'], + }); + const signer = await ethers.getSigner( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6' + ); + const tx = await OperatorFilterRegistryContract.connect(signer).register( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6' + ); + const MockMarketPlace1CodeHash = + await OperatorFilterRegistryContract.connect(signer).codeHashOf( + MockERC1155MarketPlace1.address + ); + const MockMarketPlace2CodeHash = + await OperatorFilterRegistryContract.connect(signer).codeHashOf( + MockERC1155MarketPlace2.address + ); + await tx.wait(); + const tx2 = await OperatorFilterRegistryContract.connect( + signer + ).updateOperators( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6', + [MockERC1155MarketPlace1.address, MockERC1155MarketPlace2.address], + true + ); + await tx2.wait(); + const tx3 = await OperatorFilterRegistryContract.connect( + signer + ).updateCodeHashes( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6', + [MockMarketPlace1CodeHash, MockMarketPlace2CodeHash], + true + ); + await tx3.wait(); + await network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: ['0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6'], + }); + + await deployments.fixture('Catalyst'); + + const OperatorFilterSubscription = await deployments.get( + 'OperatorFilterSubscription' + ); + const OperatorFilterSubscriptionContract = await ethers.getContractAt( + OperatorFilterSubscription.abi, + OperatorFilterSubscription.address + ); + const Catalyst = await deployments.get('Catalyst'); + const CatalystContract = await ethers.getContractAt( + Catalyst.abi, + Catalyst.address + ); + + const RoyaltyManager = await deployments.get('RoyaltyManager'); + const RoyaltyManagerContract = await ethers.getContractAt( + RoyaltyManager.abi, + RoyaltyManager.address + ); + const TRUSTED_FORWARDER_Data = await deployments.get( + 'TRUSTED_FORWARDER_V2' + ); + const TRUSTED_FORWARDER = await ethers.getContractAt( + TRUSTED_FORWARDER_Data.abi, + TRUSTED_FORWARDER_Data.address + ); + + return { + CatalystContract, + OperatorFilterSubscriptionContract, + RoyaltyManagerContract, + catalystAdmin, + TRUSTED_FORWARDER, + OPERATOR_FILTER_REGISTRY, + OperatorFilterRegistryContract, + catalystMinter, + MockERC1155MarketPlace1, + MockERC1155MarketPlace2, + MockERC1155MarketPlace3, + MockERC1155MarketPlace4, + }; + } +); + +describe('Catalyst', function () { + describe('check roles', function () { + it('admin', async function () { + const {CatalystContract, catalystAdmin} = await setupTest(); + const defaultAdminRole = await CatalystContract.DEFAULT_ADMIN_ROLE(); + expect( + await CatalystContract.hasRole(defaultAdminRole, catalystAdmin) + ).to.be.equals(true); + }); + it('minter', async function () { + const {CatalystContract, catalystMinter} = await setupTest(); + const minterRole = await CatalystContract.MINTER_ROLE(); + expect( + await CatalystContract.hasRole(minterRole, catalystMinter) + ).to.be.equals(true); + }); + }); + describe('Check Royalty', function () { + it('RoyaltyManager contract is set correctly', async function () { + const {CatalystContract, RoyaltyManagerContract} = await setupTest(); + expect(await CatalystContract.royaltyManager()).to.be.equal( + RoyaltyManagerContract.address + ); + }); + it('Contract is registered on RoyaltyManager', async function () { + const {CatalystContract, RoyaltyManagerContract} = await setupTest(); + expect( + await RoyaltyManagerContract.getContractRoyalty( + CatalystContract.address + ) + ).to.be.equal(royaltyAmount); + }); + }); + describe('Operator Filter Registry', function () { + it('catalyst contract is registered correctly', async function () { + const {OperatorFilterRegistryContract, CatalystContract} = + await setupTest(); + expect( + await OperatorFilterRegistryContract.isRegistered( + CatalystContract.address + ) + ).to.be.true; + }); + it('catalyst contract is subscribed to correct address', async function () { + const { + OperatorFilterRegistryContract, + CatalystContract, + OperatorFilterSubscriptionContract, + } = await setupTest(); + expect( + await OperatorFilterRegistryContract.subscriptionOf( + CatalystContract.address + ) + ).to.be.equal(OperatorFilterSubscriptionContract.address); + }); + it('catalyst contract has correct market places black listed', async function () { + const { + OperatorFilterRegistryContract, + CatalystContract, + MockERC1155MarketPlace1, + MockERC1155MarketPlace2, + MockERC1155MarketPlace3, + MockERC1155MarketPlace4, + } = await setupTest(); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + CatalystContract.address, + MockERC1155MarketPlace1.address + ) + ).to.be.equal(true); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + CatalystContract.address, + MockERC1155MarketPlace2.address + ) + ).to.be.equal(true); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + CatalystContract.address, + MockERC1155MarketPlace3.address + ) + ).to.be.equal(false); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + CatalystContract.address, + MockERC1155MarketPlace4.address + ) + ).to.be.equal(false); + }); + }); + describe('Trusted Forwarder', function () { + it('Trusted forwarder address is set correctly', async function () { + const {CatalystContract, TRUSTED_FORWARDER} = await setupTest(); + expect(await CatalystContract.getTrustedForwarder()).to.be.equal( + TRUSTED_FORWARDER.address + ); + }); + }); +}); diff --git a/packages/deploy/utils/abi.ts b/packages/deploy/utils/abi.ts new file mode 100644 index 0000000000..0964231db9 --- /dev/null +++ b/packages/deploy/utils/abi.ts @@ -0,0 +1,397 @@ +export const OperatorFilterRegistry_ABI = [ + { + inputs: [{internalType: 'address', name: 'operator', type: 'address'}], + name: 'AddressAlreadyFiltered', + type: 'error', + }, + { + inputs: [{internalType: 'address', name: 'filtered', type: 'address'}], + name: 'AddressFiltered', + type: 'error', + }, + { + inputs: [{internalType: 'address', name: 'operator', type: 'address'}], + name: 'AddressNotFiltered', + type: 'error', + }, + {inputs: [], name: 'AlreadyRegistered', type: 'error'}, + { + inputs: [{internalType: 'address', name: 'subscription', type: 'address'}], + name: 'AlreadySubscribed', + type: 'error', + }, + {inputs: [], name: 'CannotCopyFromSelf', type: 'error'}, + {inputs: [], name: 'CannotFilterEOAs', type: 'error'}, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'CannotSubscribeToRegistrantWithSubscription', + type: 'error', + }, + {inputs: [], name: 'CannotSubscribeToSelf', type: 'error'}, + {inputs: [], name: 'CannotSubscribeToZeroAddress', type: 'error'}, + { + inputs: [{internalType: 'address', name: 'subscription', type: 'address'}], + name: 'CannotUpdateWhileSubscribed', + type: 'error', + }, + { + inputs: [{internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}], + name: 'CodeHashAlreadyFiltered', + type: 'error', + }, + { + inputs: [ + {internalType: 'address', name: 'account', type: 'address'}, + {internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}, + ], + name: 'CodeHashFiltered', + type: 'error', + }, + { + inputs: [{internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}], + name: 'CodeHashNotFiltered', + type: 'error', + }, + {inputs: [], name: 'NotOwnable', type: 'error'}, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'NotRegistered', + type: 'error', + }, + {inputs: [], name: 'NotSubscribed', type: 'error'}, + {inputs: [], name: 'OnlyAddressOrOwner', type: 'error'}, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'codeHash', + type: 'bytes32', + }, + {indexed: true, internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'CodeHashUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: false, + internalType: 'bytes32[]', + name: 'codeHashes', + type: 'bytes32[]', + }, + {indexed: true, internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'CodeHashesUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'operator', + type: 'address', + }, + {indexed: true, internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'OperatorUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: false, + internalType: 'address[]', + name: 'operators', + type: 'address[]', + }, + {indexed: true, internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'OperatorsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + {indexed: true, internalType: 'bool', name: 'registered', type: 'bool'}, + ], + name: 'RegistrationUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'subscription', + type: 'address', + }, + {indexed: true, internalType: 'bool', name: 'subscribed', type: 'bool'}, + ], + name: 'SubscriptionUpdated', + type: 'event', + }, + { + inputs: [{internalType: 'address', name: 'a', type: 'address'}], + name: 'codeHashOf', + outputs: [{internalType: 'bytes32', name: '', type: 'bytes32'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'registrantToCopy', type: 'address'}, + ], + name: 'copyEntriesOf', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'uint256', name: 'index', type: 'uint256'}, + ], + name: 'filteredCodeHashAt', + outputs: [{internalType: 'bytes32', name: '', type: 'bytes32'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'filteredCodeHashes', + outputs: [{internalType: 'bytes32[]', name: '', type: 'bytes32[]'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'uint256', name: 'index', type: 'uint256'}, + ], + name: 'filteredOperatorAt', + outputs: [{internalType: 'address', name: '', type: 'address'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'filteredOperators', + outputs: [{internalType: 'address[]', name: '', type: 'address[]'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}, + ], + name: 'isCodeHashFiltered', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'operatorWithCode', type: 'address'}, + ], + name: 'isCodeHashOfFiltered', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'operator', type: 'address'}, + ], + name: 'isOperatorAllowed', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'operator', type: 'address'}, + ], + name: 'isOperatorFiltered', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'isRegistered', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'register', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'registrantToCopy', type: 'address'}, + ], + name: 'registerAndCopyEntries', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'subscription', type: 'address'}, + ], + name: 'registerAndSubscribe', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'newSubscription', type: 'address'}, + ], + name: 'subscribe', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'uint256', name: 'index', type: 'uint256'}, + ], + name: 'subscriberAt', + outputs: [{internalType: 'address', name: '', type: 'address'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'subscribers', + outputs: [{internalType: 'address[]', name: '', type: 'address[]'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'subscriptionOf', + outputs: [{internalType: 'address', name: 'subscription', type: 'address'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'unregister', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'bool', name: 'copyExistingEntries', type: 'bool'}, + ], + name: 'unsubscribe', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}, + {internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'updateCodeHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'bytes32[]', name: 'codeHashes', type: 'bytes32[]'}, + {internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'updateCodeHashes', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'operator', type: 'address'}, + {internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'updateOperator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address[]', name: 'operators', type: 'address[]'}, + {internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'updateOperators', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/packages/deploy/utils/bytecodes.ts b/packages/deploy/utils/bytecodes.ts new file mode 100644 index 0000000000..c4cce30a24 --- /dev/null +++ b/packages/deploy/utils/bytecodes.ts @@ -0,0 +1,2 @@ +export const OperatorFilterRegistryBytecode = + '0x608060405234801561001057600080fd5b50600436106101985760003560e01c8063712fc00b116100e3578063b314d4141161008c578063c430880511610066578063c4308805146103d1578063c6171134146103e4578063e4aecb54146103f757600080fd5b8063b314d4141461035b578063bbd652c71461036e578063c3c5a5471461039657600080fd5b8063a14584c1116100bd578063a14584c114610314578063a2f367ab14610327578063a6529eb51461033a57600080fd5b8063712fc00b146102db5780637d3e3dbe146102ee578063a0af29031461030157600080fd5b80633f1cc5fa116101455780635745ae281161011f5780635745ae28146102855780635eae3173146102a55780636af0c315146102c857600080fd5b80633f1cc5fa1461024c5780634420e4861461025f57806355940e511461027257600080fd5b80632ec2c246116101765780632ec2c246146101ee57806334a0dc10146102015780633c5030bb1461021457600080fd5b8063063298b61461019d5780631e06b4b4146101b257806322fa2762146101c5575b600080fd5b6101b06101ab366004613484565b61040a565b005b6101b06101c03660046134eb565b610854565b6101d86101d3366004613524565b610b57565b6040516101e59190613541565b60405180910390f35b6101b06101fc366004613524565b610bec565b6101b061020f366004613585565b610eaa565b610227610222366004613524565b611168565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e5565b61022761025a3660046135ba565b61121b565b6101b061026d366004613524565b6112bc565b6102276102803660046135ba565b6114b7565b610298610293366004613524565b6114e6565b6040516101e591906135e6565b6102b86102b33660046134eb565b611517565b60405190151581526020016101e5565b6102b86102d63660046135ba565b6115be565b6101b06102e9366004613634565b61164d565b6101b06102fc3660046134eb565b6119cd565b6101b061030f3660046134eb565b611da3565b6101b0610322366004613484565b612081565b6101b0610335366004613672565b61244f565b61034d6103483660046135ba565b6127b6565b6040519081526020016101e5565b6101b06103693660046134eb565b612845565b61034d61037c366004613524565b73ffffffffffffffffffffffffffffffffffffffff163f90565b6102b86103a4366004613524565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b6102986103df366004613524565b612d63565b6102b86103f23660046134eb565b612df1565b6102b86104053660046134eb565b612f4c565b833373ffffffffffffffffffffffffffffffffffffffff821614610575578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156104ad575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526104aa918101906136b0565b60015b610524573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b606091505b50805160000361051c576040517fb2c1414000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b3373ffffffffffffffffffffffffffffffffffffffff821614610573576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80861660009081526002602052604090205416806105f1576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024015b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461066e576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260016020526040902084846107225760005b8181101561071c5760008888838181106106b8576106b86136cd565b90506020020135905060006106d68286612fdb90919063ffffffff16565b905080610712576040517f478730a8000000000000000000000000000000000000000000000000000000008152600481018390526024016105e8565b505060010161069c565b506107f7565b60005b818110156107f5576000888883818110610741576107416136cd565b9050602002013590507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081036107a3576040517ff575ead800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107af8583612fe7565b9050806107eb576040517f186bea00000000000000000000000000000000000000000000000000000000008152600481018390526024016105e8565b5050600101610725565b505b8415158873ffffffffffffffffffffffffffffffffffffffff167f34e9f70c5a16a4df2a396cf0cbc4735eb3c7fb6ae40aaa0b34be7720121d1b9689896040516108429291906136fc565b60405180910390a35050505050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614610976578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156108f7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526108f4918101906136b0565b60015b610925573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610974576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109db576040517f1acab6b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680610a52576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610acf576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680610b46576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b610b508585612ff3565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff80821660008181526002602052604090205460609216908114610bbe5773ffffffffffffffffffffffffffffffffffffffff81166000908152600160205260409020610bb79061318d565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600160205260409020610bb79061318d565b803373ffffffffffffffffffffffffffffffffffffffff821614610d0e578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610c8f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610c8c918101906136b0565b60015b610cbd573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610d0c576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020541680610d85576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016105e8565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610e305773ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260409020610de7908461319a565b5060405160009073ffffffffffffffffffffffffffffffffffffffff80841691908616907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a45b73ffffffffffffffffffffffffffffffffffffffff831660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055519091907f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59908390a3505050565b813373ffffffffffffffffffffffffffffffffffffffff821614610fcc578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610f4d575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610f4a918101906136b0565b60015b610f7b573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610fca576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680611043576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036110a8576040517f237e6c2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090206110d7908561319a565b5073ffffffffffffffffffffffffffffffffffffffff80851660008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055519092841691907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a48215611162576111628482612ff3565b50505050565b73ffffffffffffffffffffffffffffffffffffffff80821660009081526002602052604090205416806111df576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611216575060005b919050565b73ffffffffffffffffffffffffffffffffffffffff8083166000818152600260205260408120549092169081146112835773ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902061127b90846131bc565b9150506112b6565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090206112b290846131bc565b9150505b92915050565b803373ffffffffffffffffffffffffffffffffffffffff8216146113de578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561135f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261135c918101906136b0565b60015b61138d573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff8216146113dc576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff828116600090815260026020526040902054161561143d576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551600192917f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5991a35050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120610bb790836131bc565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090206060906112b69061318d565b73ffffffffffffffffffffffffffffffffffffffff82811660008181526002602052604081205490928085163f9291169081146115865773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061157d90836131c8565b925050506112b6565b73ffffffffffffffffffffffffffffffffffffffff851660009081526001602052604090206115b590836131c8565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff80831660008181526002602052604081205490921690811461161e5773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061127b90846131c8565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604090206112b290846131c8565b823373ffffffffffffffffffffffffffffffffffffffff82161461176f578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156116f0575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526116ed918101906136b0565b60015b61171e573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff82161461176d576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47083036117c8576040517ff575ead800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808516600090815260026020526040902054168061183f576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146118bc576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600160205260409020836119345760006118f28287612fdb565b90508061192e576040517f478730a8000000000000000000000000000000000000000000000000000000008152600481018790526024016105e8565b5061197e565b60006119408287612fe7565b90508061197c576040517f186bea00000000000000000000000000000000000000000000000000000000008152600481018790526024016105e8565b505b831515858773ffffffffffffffffffffffffffffffffffffffff167fb8036058bafea884aabc446ca15619fd86f5464a4ad96f64164ad6f77444354d60405160405180910390a4505050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614611aef578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a70575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611a6d918101906136b0565b60015b611a9e573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614611aed576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020526040902054168015611b4f576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611bb4576040517f347f118f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680611c2b576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611ca8576040517f768e549c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694891694851790559282526003905220611d0f90866131e0565b5060405160019073ffffffffffffffffffffffffffffffffffffffff8716907f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5990600090a360405160019073ffffffffffffffffffffffffffffffffffffffff80871691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e890600090a45050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614611ec5578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611e46575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611e43918101906136b0565b60015b611e74573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614611ec3576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611f2a576040517f1acab6b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020526040902054168015611f8a576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612001576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551600192917f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5991a3610b508585612ff3565b833373ffffffffffffffffffffffffffffffffffffffff8216146121a3578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612124575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612121918101906136b0565b60015b612152573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff8216146121a1576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff808616600090815260026020526040902054168061221a576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612297576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902084846123655760005b8181101561235f5760008888838181106122e1576122e16136cd565b90506020020160208101906122f69190613524565b90506000612304858361319a565b905080612355576040517f45525c0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b50506001016122c5565b50612404565b60005b81811015612402576000888883818110612384576123846136cd565b90506020020160208101906123999190613524565b905060006123a785836131e0565b9050806123f8576040517f0bb4423400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b5050600101612368565b505b8415158873ffffffffffffffffffffffffffffffffffffffff167f02b85afdacb82d5512c6f05566b3018677ffcbd7e5f75e498bc64081131cbd6c898960405161084292919061374e565b823373ffffffffffffffffffffffffffffffffffffffff821614612571578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156124f2575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526124ef918101906136b0565b60015b612520573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff82161461256f576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80851660009081526002602052604090205416806125e8576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612665576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85166000908152602081905260409020836126f257600061269b828761319a565b9050806126ec576040517f45525c0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b50612751565b60006126fe82876131e0565b90508061274f576040517f0bb4423400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b505b8315158573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f2738289d9deecdc30eb8ffc42876633caecca1ffa166e4efa89f408e17373a1a60405160405180910390a4505050505050565b73ffffffffffffffffffffffffffffffffffffffff8083166000818152600260205260408120549092169081146128165773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061127b90846131bc565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604090206112b290846131bc565b813373ffffffffffffffffffffffffffffffffffffffff821614612967578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128e8575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526128e5918101906136b0565b60015b612916573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614612965576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036129cc576040517f347f118f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216612a19576040517fb05574d300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612a90576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b0d576040517f73a4164900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612b84576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612c01576040517f768e549c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612cac5773ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260409020612c63908661319a565b5060405160009073ffffffffffffffffffffffffffffffffffffffff80851691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a45b73ffffffffffffffffffffffffffffffffffffffff858116600090815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694891694851790559282526003905220612d1390866131e0565b5060405160019073ffffffffffffffffffffffffffffffffffffffff80871691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e890600090a45050505050565b73ffffffffffffffffffffffffffffffffffffffff80821660008181526002602052604090205460609216908114612dc35773ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020610bb79061318d565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260409020610bb79061318d565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260408120549091168015612f425773ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260408083206001909252909120612e598286613202565b15612ea8576040517fa8cf495d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85163b15612f3f5773ffffffffffffffffffffffffffffffffffffffff85163f612ee782826131c8565b15612f3d576040517f5f3853a900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87166004820152602481018290526044016105e8565b505b50505b5060019392505050565b73ffffffffffffffffffffffffffffffffffffffff808316600081815260026020526040812054909216908114612fac5773ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902061127b9084613202565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090206112b29084613202565b6000610bb78383613231565b6000610bb78383613324565b73ffffffffffffffffffffffffffffffffffffffff811660009081526020818152604080832060019092528220909161302b83613373565b9050600061303883613373565b905060005b828110156130e057600061305186836131bc565b73ffffffffffffffffffffffffffffffffffffffff891660009081526020819052604081209192509061308490836131e0565b905080156130d65760405160019073ffffffffffffffffffffffffffffffffffffffff80851691908c16907f2738289d9deecdc30eb8ffc42876633caecca1ffa166e4efa89f408e17373a1a90600090a45b505060010161303d565b5060005b818110156131845760006130f885836131bc565b73ffffffffffffffffffffffffffffffffffffffff891660009081526001602052604081209192509061312b9083612fe7565b9050801561317a57604051600190839073ffffffffffffffffffffffffffffffffffffffff8c16907fb8036058bafea884aabc446ca15619fd86f5464a4ad96f64164ad6f77444354d90600090a45b50506001016130e4565b50505050505050565b60606000610bb78361337d565b6000610bb78373ffffffffffffffffffffffffffffffffffffffff8416613231565b6000610bb783836133d9565b60008181526001830160205260408120541515610bb7565b6000610bb78373ffffffffffffffffffffffffffffffffffffffff8416613324565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610bb7565b6000818152600183016020526040812054801561331a5760006132556001836137a9565b8554909150600090613269906001906137a9565b90508181146132ce576000866000018281548110613289576132896136cd565b90600052602060002001549050808760000184815481106132ac576132ac6136cd565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806132df576132df6137e3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112b6565b60009150506112b6565b600081815260018301602052604081205461336b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112b6565b5060006112b6565b60006112b6825490565b6060816000018054806020026020016040519081016040528092919081815260200182805480156133cd57602002820191906000526020600020905b8154815260200190600101908083116133b9575b50505050509050919050565b60008260000182815481106133f0576133f06136cd565b9060005260206000200154905092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461342557600080fd5b50565b60008083601f84011261343a57600080fd5b50813567ffffffffffffffff81111561345257600080fd5b6020830191508360208260051b850101111561346d57600080fd5b9250929050565b8035801515811461121657600080fd5b6000806000806060858703121561349a57600080fd5b84356134a581613403565b9350602085013567ffffffffffffffff8111156134c157600080fd5b6134cd87828801613428565b90945092506134e0905060408601613474565b905092959194509250565b600080604083850312156134fe57600080fd5b823561350981613403565b9150602083013561351981613403565b809150509250929050565b60006020828403121561353657600080fd5b8135610bb781613403565b6020808252825182820181905260009190848201906040850190845b818110156135795783518352928401929184019160010161355d565b50909695505050505050565b6000806040838503121561359857600080fd5b82356135a381613403565b91506135b160208401613474565b90509250929050565b600080604083850312156135cd57600080fd5b82356135d881613403565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561357957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613602565b60008060006060848603121561364957600080fd5b833561365481613403565b92506020840135915061366960408501613474565b90509250925092565b60008060006060848603121561368757600080fd5b833561369281613403565b925060208401356136a281613403565b915061366960408501613474565b6000602082840312156136c257600080fd5b8151610bb781613403565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561373557600080fd5b8260051b80856040850137919091016040019392505050565b60208082528181018390526000908460408401835b8681101561379e57823561377681613403565b73ffffffffffffffffffffffffffffffffffffffff1682529183019190830190600101613763565b509695505050505050565b818103818111156112b6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220d2eb4529f96412ccc09b0c0c04d7ff105932b0b691aea14b7aa158442949a08664736f6c63430008110033';