From 8ca131431ab96f82a1401863586e3dd3f437cc39 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Thu, 2 May 2024 20:17:24 -0500 Subject: [PATCH 01/18] refactor solidity contracts for modularity --- .../contracts/bridge/FlowEVMBridgeUtils.cdc | 2 +- solidity/src/FlowBridgeDeploymentRegistry.sol | 16 +++ solidity/src/FlowBridgeFactory.sol | 123 +++++++++++------- solidity/src/FlowEVMBridgedERC20Deployer.sol | 47 +++++++ solidity/src/FlowEVMBridgedERC721Deployer.sol | 48 +++++++ solidity/src/FlowEVMDeploymentRegistry.sol | 51 ++++++++ .../src/interfaces/IFlowEVMBridgeDeployer.sol | 15 +++ .../interfaces/IFlowEVMDeploymentRegistry.sol | 14 ++ ...idgedERC20.sol => FlowEVMBridgedERC20.sol} | 2 +- ...gedERC721.sol => FlowEVMBridgedERC721.sol} | 2 +- solidity/test/FlowBridgeFactory.t.sol | 66 ++++++++-- 11 files changed, 324 insertions(+), 62 deletions(-) create mode 100644 solidity/src/FlowBridgeDeploymentRegistry.sol create mode 100644 solidity/src/FlowEVMBridgedERC20Deployer.sol create mode 100644 solidity/src/FlowEVMBridgedERC721Deployer.sol create mode 100644 solidity/src/FlowEVMDeploymentRegistry.sol create mode 100644 solidity/src/interfaces/IFlowEVMBridgeDeployer.sol create mode 100644 solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol rename solidity/src/templates/{FlowBridgedERC20.sol => FlowEVMBridgedERC20.sol} (94%) rename solidity/src/templates/{FlowBridgedERC721.sol => FlowEVMBridgedERC721.sol} (95%) diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index 0a5a5f9d..8e43a28e 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -21,7 +21,7 @@ contract FlowEVMBridgeUtils { /// Address of the bridge factory Solidity contract access(all) - let bridgeFactoryEVMAddress: EVM.EVMAddress + var bridgeFactoryEVMAddress: EVM.EVMAddress /// Delimeter used to derive contract names access(self) let delimiter: String diff --git a/solidity/src/FlowBridgeDeploymentRegistry.sol b/solidity/src/FlowBridgeDeploymentRegistry.sol new file mode 100644 index 00000000..5e64c760 --- /dev/null +++ b/solidity/src/FlowBridgeDeploymentRegistry.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import "./FlowEVMDeploymentRegistry.sol"; + +contract FlowBridgeDeploymentRegistry is FlowEVMDeploymentRegistry, Ownable { + constructor() Ownable(msg.sender) { + registrar = msg.sender; + } + + function setRegistrar(address _registrar) external onlyOwner { + _setRegistrar(_registrar); + } +} diff --git a/solidity/src/FlowBridgeFactory.sol b/solidity/src/FlowBridgeFactory.sol index 93361415..ec0a09c2 100644 --- a/solidity/src/FlowBridgeFactory.sol +++ b/solidity/src/FlowBridgeFactory.sol @@ -4,71 +4,45 @@ pragma solidity ^0.8.17; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import "./templates/FlowBridgedERC721.sol"; -import "./templates/FlowBridgedERC20.sol"; import "./interfaces/IBridgePermissions.sol"; +import "./FlowEVMDeploymentRegistry.sol"; +import "./interfaces/IFlowEVMBridgeDeployer.sol"; contract FlowBridgeFactory is Ownable { - mapping(string => address) public flowIdentifierToContract; - mapping(address => string) public contractToflowIdentifier; + address public deploymentRegistry; + mapping(string => address) public deployers; constructor() Ownable(msg.sender) {} - event ERC20Deployed( - address contractAddress, string name, string symbol, string flowTokenAddress, string flowTokenIdentifier - ); - event ERC721Deployed( - address contractAddress, string name, string symbol, string flowNFTAddress, string flowNFTIdentifier - ); - - // Function to deploy a new ERC721 contract - function deployERC20( + function deploy( + string memory tag, string memory name, string memory symbol, - string memory flowTokenAddress, - string memory flowTokenIdentifier, + string memory cadenceAddress, + string memory cadenceIdentifier, string memory contractURI ) public onlyOwner returns (address) { - FlowBridgedERC20 newERC20 = - new FlowBridgedERC20(super.owner(), name, symbol, flowTokenAddress, flowTokenIdentifier, contractURI); + address deployerAddress = deployers[tag]; + _requireIsValidDeployer(deployerAddress); + IFlowEVMBridgeDeployer deployer = IFlowEVMBridgeDeployer(deployerAddress); - flowIdentifierToContract[flowTokenIdentifier] = address(newERC20); - contractToflowIdentifier[address(newERC20)] = flowTokenIdentifier; + address newContract = deployer.deploy(name, symbol, cadenceAddress, cadenceIdentifier, contractURI); - emit ERC20Deployed(address(newERC20), name, symbol, flowTokenAddress, flowTokenIdentifier); + _registerDeployment(cadenceIdentifier, newContract); - return address(newERC20); + return newContract; } - // Function to deploy a new ERC721 contract - function deployERC721( - string memory name, - string memory symbol, - string memory flowNFTAddress, - string memory flowNFTIdentifier, - string memory contractURI - ) public onlyOwner returns (address) { - FlowBridgedERC721 newERC721 = - new FlowBridgedERC721(super.owner(), name, symbol, flowNFTAddress, flowNFTIdentifier, contractURI); - - flowIdentifierToContract[flowNFTIdentifier] = address(newERC721); - contractToflowIdentifier[address(newERC721)] = flowNFTIdentifier; - - emit ERC721Deployed(address(newERC721), name, symbol, flowNFTAddress, flowNFTIdentifier); - - return address(newERC721); + function getCadenceIdentifier(address contractAddr) public view returns (string memory) { + return FlowEVMDeploymentRegistry(deploymentRegistry).getCadenceIdentifier(contractAddr); } - function getFlowAssetIdentifier(address contractAddr) public view returns (string memory) { - return contractToflowIdentifier[contractAddr]; + function getContractAddress(string memory cadenceIdentifier) public view returns (address) { + return FlowEVMDeploymentRegistry(deploymentRegistry).getContractAddress(cadenceIdentifier); } - function getContractAddress(string memory flowNFTIdentifier) public view returns (address) { - return flowIdentifierToContract[flowNFTIdentifier]; - } - - function isFactoryDeployed(address contractAddr) public view returns (bool) { - return bytes(contractToflowIdentifier[contractAddr]).length != 0; + function isBridgeDeployed(address contractAddr) public view returns (bool) { + return FlowEVMDeploymentRegistry(deploymentRegistry).isRegisteredDeployment(contractAddr); } function isERC20(address contractAddr) public view returns (bool) { @@ -107,4 +81,61 @@ contract FlowBridgeFactory is Ownable { return false; } } + + function getRegistry() public view returns (address) { + return deploymentRegistry; + } + + function getDeployer(string memory tag) public view returns (address) { + return deployers[tag]; + } + + function setDeploymentRegistry(address _deploymentRegistry) external onlyOwner { + _requireIsValidRegistry(_deploymentRegistry); + deploymentRegistry = _deploymentRegistry; + } + + function addDeployer(string memory tag, address deployerAddress) external onlyOwner { + _requireIsValidDeployer(deployerAddress); + require(deployers[tag] == address(0), "FlowBridgeFactory: Deployer already registered"); + deployers[tag] = deployerAddress; + } + + function upsertDeployer(string memory tag, address deployerAddress) external onlyOwner { + _requireIsValidDeployer(deployerAddress); + deployers[tag] = deployerAddress; + } + + function _registerDeployment(string memory cadenceIdentifier, address contractAddr) private { + FlowEVMDeploymentRegistry registry = FlowEVMDeploymentRegistry(deploymentRegistry); + registry.registerDeployment(cadenceIdentifier, contractAddr); + } + + function _requireIsValidRegistry(address registryAddr) internal view { + _requireNotZeroAddress(registryAddr); + require( + _implementsInterface(registryAddr, type(IFlowEVMDeploymentRegistry).interfaceId), + "FlowBridgeFactory: Invalid registry" + ); + } + + function _requireIsValidDeployer(address contractAddr) internal view { + _requireNotZeroAddress(contractAddr); + require( + _implementsInterface(contractAddr, type(IFlowEVMBridgeDeployer).interfaceId), + "FlowBridgeFactory: Invalid deployer" + ); + } + + function _implementsInterface(address contractAddr, bytes4 interfaceId) internal view returns (bool) { + try ERC165(contractAddr).supportsInterface(interfaceId) returns (bool support) { + return support; + } catch { + return false; + } + } + + function _requireNotZeroAddress(address addr) internal pure { + require(addr != address(0), "FlowBridgeFactory: Zero address"); + } } diff --git a/solidity/src/FlowEVMBridgedERC20Deployer.sol b/solidity/src/FlowEVMBridgedERC20Deployer.sol new file mode 100644 index 00000000..012f8a06 --- /dev/null +++ b/solidity/src/FlowEVMBridgedERC20Deployer.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import "./interfaces/IFlowEVMBridgeDeployer.sol"; +import "./templates/FlowEVMBridgedERC20.sol"; + +contract FlowEVMBridgedERC20Deployer is IFlowEVMBridgeDeployer, ERC165, Ownable { + address public delegatedDeployer; + + constructor() Ownable(msg.sender) {} + + modifier onlyDelegatedDeployer() { + require(msg.sender == delegatedDeployer, "FlowEVMBridgedERC20Deployer: Only delegated deployer can deploy"); + _; + } + + event ERC20Deployed( + address contractAddress, string name, string symbol, string cadenceTokenAddress, string cadenceVaultIdentifier + ); + + function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC165) returns (bool) { + return interfaceId == type(IFlowEVMBridgeDeployer).interfaceId || super.supportsInterface(interfaceId); + } + + function deploy( + string memory name, + string memory symbol, + string memory cadenceAddress, + string memory cadenceIdentifier, + string memory contractURI + ) external onlyDelegatedDeployer returns (address) { + FlowEVMBridgedERC20 newERC20 = + new FlowEVMBridgedERC20(super.owner(), name, symbol, cadenceAddress, cadenceIdentifier, contractURI); + + emit ERC20Deployed(address(newERC20), name, symbol, cadenceAddress, cadenceIdentifier); + + return address(newERC20); + } + + function setDelegatedDeployer(address _delegatedDeployer) external onlyOwner { + require(_delegatedDeployer != address(0), "FlowEVMBridgedERC20Deployer: Invalid delegated deployer address"); + delegatedDeployer = _delegatedDeployer; + } +} diff --git a/solidity/src/FlowEVMBridgedERC721Deployer.sol b/solidity/src/FlowEVMBridgedERC721Deployer.sol new file mode 100644 index 00000000..f186e419 --- /dev/null +++ b/solidity/src/FlowEVMBridgedERC721Deployer.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import "./interfaces/IFlowEVMBridgeDeployer.sol"; +import "./templates/FlowEVMBridgedERC721.sol"; + +contract FlowEVMBridgedERC721Deployer is IFlowEVMBridgeDeployer, ERC165, Ownable { + address public delegatedDeployer; + + constructor() Ownable(msg.sender) {} + + modifier onlyDelegatedDeployer() { + require(msg.sender == delegatedDeployer, "FlowEVMBridgedERC721Deployer: Only delegated deployer can deploy"); + _; + } + + event ERC721Deployed( + address contractAddress, string name, string symbol, string cadenceNFTAddress, string cadenceNFTIdentifier + ); + + function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC165) returns (bool) { + return interfaceId == type(IFlowEVMBridgeDeployer).interfaceId || super.supportsInterface(interfaceId); + } + + function deploy( + string memory name, + string memory symbol, + string memory cadenceAddress, + string memory cadenceIdentifier, + string memory contractURI + ) external onlyDelegatedDeployer returns (address) { + FlowEVMBridgedERC721 newERC721 = + new FlowEVMBridgedERC721(super.owner(), name, symbol, cadenceAddress, cadenceIdentifier, contractURI); + + emit ERC721Deployed(address(newERC721), name, symbol, cadenceAddress, cadenceIdentifier); + + return address(newERC721); + } + + function setDelegatedDeployer(address _delegatedDeployer) external onlyOwner { + require(_delegatedDeployer != address(0), "FlowEVMBridgedERC721Deployer: Invalid delegated deployer address"); + delegatedDeployer = _delegatedDeployer; + } +} diff --git a/solidity/src/FlowEVMDeploymentRegistry.sol b/solidity/src/FlowEVMDeploymentRegistry.sol new file mode 100644 index 00000000..23d13d97 --- /dev/null +++ b/solidity/src/FlowEVMDeploymentRegistry.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import "./interfaces/IFlowEVMDeploymentRegistry.sol"; + +abstract contract FlowEVMDeploymentRegistry is IFlowEVMDeploymentRegistry, ERC165 { + address public registrar; + mapping(string => address) public cadenceIdentifierToContract; + mapping(address => string) public contractToCadenceIdentifier; + + modifier onlyRegistrar() { + require(msg.sender == registrar, "FlowBridgeDeploymentRegistry: Only registrar can register association"); + _; + } + + function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC165) returns (bool) { + return interfaceId == type(IFlowEVMDeploymentRegistry).interfaceId || super.supportsInterface(interfaceId); + } + + function getCadenceIdentifier(address contractAddr) external view returns (string memory) { + return contractToCadenceIdentifier[contractAddr]; + } + + function getContractAddress(string memory cadenceIdentifier) external view returns (address) { + return cadenceIdentifierToContract[cadenceIdentifier]; + } + + function isRegisteredDeployment(string memory cadenceIdentifier) external view returns (bool) { + return cadenceIdentifierToContract[cadenceIdentifier] != address(0); + } + + function isRegisteredDeployment(address contractAddr) external view returns (bool) { + return bytes(contractToCadenceIdentifier[contractAddr]).length != 0; + } + + function registerDeployment(string memory cadenceIdentifier, address contractAddr) external onlyRegistrar { + _registerDeployment(cadenceIdentifier, contractAddr); + } + + function _registerDeployment(string memory cadenceIdentifier, address contractAddr) internal { + cadenceIdentifierToContract[cadenceIdentifier] = contractAddr; + contractToCadenceIdentifier[contractAddr] = cadenceIdentifier; + } + + function _setRegistrar(address _registrar) internal { + registrar = _registrar; + } +} diff --git a/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol b/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol new file mode 100644 index 00000000..bbdc562f --- /dev/null +++ b/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; + +interface IFlowEVMBridgeDeployer is IERC165 { + // Function to deploy a new CadenceBridgedERC20 contract + function deploy( + string memory name, + string memory symbol, + string memory cadenceAddress, + string memory cadenceIdentifier, + string memory contractURI + ) external returns (address); +} diff --git a/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol b/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol new file mode 100644 index 00000000..0f1fbb21 --- /dev/null +++ b/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; + +interface IFlowEVMDeploymentRegistry is IERC165 { + function getCadenceIdentifier(address contractAddr) external view returns (string memory); + + function getContractAddress(string memory cadenceIdentifier) external view returns (address); + + function isRegisteredDeployment(address contractAddr) external view returns (bool); + + function isRegisteredDeployment(string memory cadenceIdentifier) external view returns (bool); +} diff --git a/solidity/src/templates/FlowBridgedERC20.sol b/solidity/src/templates/FlowEVMBridgedERC20.sol similarity index 94% rename from solidity/src/templates/FlowBridgedERC20.sol rename to solidity/src/templates/FlowEVMBridgedERC20.sol index a8deb0a2..1ddc8941 100644 --- a/solidity/src/templates/FlowBridgedERC20.sol +++ b/solidity/src/templates/FlowEVMBridgedERC20.sol @@ -7,7 +7,7 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; -contract FlowBridgedERC20 is ERC20, ERC20Burnable, Ownable, ERC20Permit { +contract FlowEVMBridgedERC20 is ERC20, ERC20Burnable, Ownable, ERC20Permit { string public flowTokenAddress; string public flowTokenIdentifier; string public contractMetadata; diff --git a/solidity/src/templates/FlowBridgedERC721.sol b/solidity/src/templates/FlowEVMBridgedERC721.sol similarity index 95% rename from solidity/src/templates/FlowBridgedERC721.sol rename to solidity/src/templates/FlowEVMBridgedERC721.sol index 4742587c..597dc8da 100644 --- a/solidity/src/templates/FlowBridgedERC721.sol +++ b/solidity/src/templates/FlowEVMBridgedERC721.sol @@ -7,7 +7,7 @@ import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; -contract FlowBridgedERC721 is ERC721, ERC721URIStorage, ERC721Burnable, ERC721Enumerable, Ownable { +contract FlowEVMBridgedERC721 is ERC721, ERC721URIStorage, ERC721Burnable, ERC721Enumerable, Ownable { string public flowNFTAddress; string public flowNFTIdentifier; string public contractMetadata; diff --git a/solidity/test/FlowBridgeFactory.t.sol b/solidity/test/FlowBridgeFactory.t.sol index 5b87090a..95864b70 100644 --- a/solidity/test/FlowBridgeFactory.t.sol +++ b/solidity/test/FlowBridgeFactory.t.sol @@ -2,15 +2,24 @@ pragma solidity ^0.8.17; import {Test} from "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {FlowBridgeDeploymentRegistry} from "../src/FlowBridgeDeploymentRegistry.sol"; +import {FlowEVMBridgedERC721Deployer} from "../src/FlowEVMBridgedERC721Deployer.sol"; +import {FlowEVMBridgedERC20Deployer} from "../src/FlowEVMBridgedERC20Deployer.sol"; import {FlowBridgeFactory} from "../src/FlowBridgeFactory.sol"; -import {FlowBridgedERC721} from "../src/templates/FlowBridgedERC721.sol"; -import {FlowBridgedERC20} from "../src/templates/FlowBridgedERC20.sol"; +import {FlowEVMBridgedERC721} from "../src/templates/FlowEVMBridgedERC721.sol"; +import {FlowEVMBridgedERC20} from "../src/templates/FlowEVMBridgedERC20.sol"; contract FlowBridgeFactoryTest is Test { + address foundryTestOwner; + FlowBridgeFactory internal factory; - FlowBridgedERC721 internal deployedERC721Contract; - FlowBridgedERC20 internal deployedERC20Contract; + FlowBridgeDeploymentRegistry internal registry; + FlowEVMBridgedERC20Deployer internal erc20Deployer; + FlowEVMBridgedERC721Deployer internal erc721Deployer; + FlowEVMBridgedERC20 internal deployedERC20Contract; + FlowEVMBridgedERC721 internal deployedERC721Contract; string name; string symbol; @@ -19,10 +28,12 @@ contract FlowBridgeFactoryTest is Test { string flowTokenAddress; string flowTokenIdentifier; string contractURI; - address deployedERC721Address; address deployedERC20Address; + address deployedERC721Address; function setUp() public virtual { + foundryTestOwner = address(0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84); + factory = new FlowBridgeFactory(); name = "name"; symbol = "symbol"; @@ -32,15 +43,44 @@ contract FlowBridgeFactoryTest is Test { flowTokenIdentifier = "flowTokenIdentifier"; contractURI = "contractURI"; - deployedERC721Address = factory.deployERC721(name, symbol, flowNFTAddress, flowNFTIdentifier, contractURI); - deployedERC20Address = factory.deployERC20(name, symbol, flowTokenAddress, flowTokenIdentifier, contractURI); - deployedERC721Contract = FlowBridgedERC721(deployedERC721Address); - deployedERC20Contract = FlowBridgedERC20(deployedERC20Address); + registry = new FlowBridgeDeploymentRegistry(); + erc20Deployer = new FlowEVMBridgedERC20Deployer(); + erc721Deployer = new FlowEVMBridgedERC721Deployer(); + + factory.setDeploymentRegistry(address(registry)); + registry.setRegistrar(address(factory)); + + erc20Deployer.setDelegatedDeployer(address(factory)); + erc721Deployer.setDelegatedDeployer(address(factory)); + + factory.addDeployer("ERC20", address(erc20Deployer)); + factory.addDeployer("ERC721", address(erc721Deployer)); + + deployedERC20Address = factory.deploy("ERC20", name, symbol, flowTokenAddress, flowTokenIdentifier, contractURI); + deployedERC721Address = factory.deploy("ERC721", name, symbol, flowNFTAddress, flowNFTIdentifier, contractURI); + + deployedERC20Contract = FlowEVMBridgedERC20(deployedERC20Address); + deployedERC721Contract = FlowEVMBridgedERC721(deployedERC721Address); + } + + function test_RegistryIsNonZero() public { + address registryAddress = factory.getRegistry(); + assertNotEq(registryAddress, address(0)); + } + + function test_GetERC20Deployer() public { + address erc20DeployerAddress = factory.getDeployer("ERC20"); + assertEq(erc20DeployerAddress, address(erc20Deployer)); + } + + function test_GetERC721Deployer() public { + address erc721DeployerAddress = factory.getDeployer("ERC721"); + assertEq(erc721DeployerAddress, address(erc721Deployer)); } function test_DeployERC721() public { - bool isFactoryDeployed = factory.isFactoryDeployed(deployedERC721Address); - assertEq(isFactoryDeployed, true); + bool isBridgeDeployed = factory.isBridgeDeployed(deployedERC721Address); + assertEq(isBridgeDeployed, true); } function test_IsERC721True() public { @@ -54,8 +94,8 @@ contract FlowBridgeFactoryTest is Test { } function test_DeployERC20() public { - bool isFactoryDeployed = factory.isFactoryDeployed(deployedERC20Address); - assertEq(isFactoryDeployed, true); + bool isBridgeDeployed = factory.isBridgeDeployed(deployedERC20Address); + assertEq(isBridgeDeployed, true); } function test_IsERC20True() public { From c2110a2c77e3340b63f08ff3d281f375f974f688 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 3 May 2024 12:47:48 -0500 Subject: [PATCH 02/18] add comments to solidity contracts --- solidity/src/FlowBridgeDeploymentRegistry.sol | 12 +- solidity/src/FlowBridgeFactory.sol | 189 ++++++++++++++++-- solidity/src/FlowEVMBridgedERC20Deployer.sol | 42 +++- solidity/src/FlowEVMBridgedERC721Deployer.sol | 41 +++- solidity/src/FlowEVMDeploymentRegistry.sol | 51 ----- .../interfaces/FlowEVMDeploymentRegistry.sol | 106 ++++++++++ .../src/interfaces/IFlowEVMBridgeDeployer.sol | 16 +- .../interfaces/IFlowEVMDeploymentRegistry.sol | 17 ++ solidity/test/FlowBridgeFactory.t.sol | 20 +- 9 files changed, 412 insertions(+), 82 deletions(-) delete mode 100644 solidity/src/FlowEVMDeploymentRegistry.sol create mode 100644 solidity/src/interfaces/FlowEVMDeploymentRegistry.sol diff --git a/solidity/src/FlowBridgeDeploymentRegistry.sol b/solidity/src/FlowBridgeDeploymentRegistry.sol index 5e64c760..940377b8 100644 --- a/solidity/src/FlowBridgeDeploymentRegistry.sol +++ b/solidity/src/FlowBridgeDeploymentRegistry.sol @@ -3,13 +3,23 @@ pragma solidity ^0.8.17; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import "./FlowEVMDeploymentRegistry.sol"; +import "./interfaces/FlowEVMDeploymentRegistry.sol"; +/** + * @title FlowBridgeDeploymentRegistry + * @dev A contract to manage the deployment of Flow EVM contracts and their association with Cadence contracts + */ contract FlowBridgeDeploymentRegistry is FlowEVMDeploymentRegistry, Ownable { constructor() Ownable(msg.sender) { registrar = msg.sender; } + /** + * @dev Set the registrar address as the entity that can register new deployments. Only the owner can call this + * function. + * + * @param _registrar The address of the registrar + */ function setRegistrar(address _registrar) external onlyOwner { _setRegistrar(_registrar); } diff --git a/solidity/src/FlowBridgeFactory.sol b/solidity/src/FlowBridgeFactory.sol index ec0a09c2..8cd8e92c 100644 --- a/solidity/src/FlowBridgeFactory.sol +++ b/solidity/src/FlowBridgeFactory.sol @@ -1,28 +1,64 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import "./interfaces/IBridgePermissions.sol"; -import "./FlowEVMDeploymentRegistry.sol"; -import "./interfaces/IFlowEVMBridgeDeployer.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {IBridgePermissions} from "./interfaces/IBridgePermissions.sol"; +import {IFlowEVMBridgeDeployer} from "./interfaces/IFlowEVMBridgeDeployer.sol"; +import {IFlowEVMDeploymentRegistry} from "./interfaces/IFlowEVMDeploymentRegistry.sol"; +import {FlowEVMDeploymentRegistry} from "./interfaces/FlowEVMDeploymentRegistry.sol"; +/** + * @title FlowBridgeFactory + * @dev Factory contract to deploy new FlowEVM bridge contracts, defining Cadence-native assets in EVM + */ contract FlowBridgeFactory is Ownable { - address public deploymentRegistry; - mapping(string => address) public deployers; + // Address of the deployment registry where deployed contract associations are registered + address private deploymentRegistry; + // Mapping of deployer tags to their implementation addresses + mapping(string => address) private deployers; + + /** + * @dev Emitted when a deployer is added to the factory + */ + event DeployerAdded(string tag, address deployerAddress); + /** + * @dev Emitted when a deployer is updated in the factory + */ + event DeployerUpdated(string tag, address oldAddress, address newAddress); + /** + * @dev Emitted when a deployer is removed from the factory + */ + event DeployerRemoved(string tag, address oldAddress); + /** + * @dev Emitted when the deployment registry is updated + */ + event DeploymentRegistryUpdated(address registryAddress); constructor() Ownable(msg.sender) {} + /** + * @dev Deploys a new asset contract via a registered deployer + * + * @param deployerTag The tag of the deployer to use as set by the owner + * @param name The name of the asset + * @param symbol The symbol of the asset + * @param cadenceAddress The Flow account address of the Cadence implementation + * @param cadenceIdentifier The Cadence identifier of the asset type + * @param contractURI The URI of the contract metadata for the asset + * + * @return The address of the newly deployed contract + */ function deploy( - string memory tag, + string memory deployerTag, string memory name, string memory symbol, string memory cadenceAddress, string memory cadenceIdentifier, string memory contractURI ) public onlyOwner returns (address) { - address deployerAddress = deployers[tag]; + address deployerAddress = deployers[deployerTag]; _requireIsValidDeployer(deployerAddress); IFlowEVMBridgeDeployer deployer = IFlowEVMBridgeDeployer(deployerAddress); @@ -33,18 +69,48 @@ contract FlowBridgeFactory is Ownable { return newContract; } + /** + * @dev Retrieves the Cadence type identifier associated with the bridge-deployed contract + * + * @param contractAddr The address of the deployed contract + * + * @return The Cadence identifier of the contract + */ function getCadenceIdentifier(address contractAddr) public view returns (string memory) { return FlowEVMDeploymentRegistry(deploymentRegistry).getCadenceIdentifier(contractAddr); } + /** + * @dev Retrieves the address of a bridge-deployed contract by its associated Cadence type identifier + * + * @param cadenceIdentifier The Cadence type identifier of the contract + * + * @return The address of the deployed contract + */ function getContractAddress(string memory cadenceIdentifier) public view returns (address) { return FlowEVMDeploymentRegistry(deploymentRegistry).getContractAddress(cadenceIdentifier); } + /** + * @dev Checks if a contract address is associated with a registered deployment + * + * @param contractAddr The address of the deployed contract + * + * @return True if the contract is a registered deployment, false otherwise + */ function isBridgeDeployed(address contractAddr) public view returns (bool) { return FlowEVMDeploymentRegistry(deploymentRegistry).isRegisteredDeployment(contractAddr); } + /** + * @dev Makes a best guess if the contract address is an ERC20 token by calling the publicly accessible ERC20 + * interface methods on the contract via staticcall to prevent reverts. Note, since ERC20 does not implement + * ERC165, this is a best guess and may result in false positives. + * + * @param contractAddr The address of the contract to check + * + * @return True if the contract is an ERC20 token, false otherwise + */ function isERC20(address contractAddr) public view returns (bool) { (bool success, bytes memory data) = contractAddr.staticcall(abi.encodeWithSignature("totalSupply()")); if (!success || data.length == 0) { @@ -74,6 +140,14 @@ contract FlowBridgeFactory is Ownable { return true; } + /** + * @dev Determines if a contract is an ERC721 token by checking if it implements the ERC721 interface via ERC165 + * supportsInterface call. + * + * @param contractAddr The address of the contract to check + * + * @return True if the contract is an ERC721 token, false otherwise + */ function isERC721(address contractAddr) public view returns (bool) { try ERC165(contractAddr).supportsInterface(0x80ac58cd) returns (bool support) { return support; @@ -82,35 +156,105 @@ contract FlowBridgeFactory is Ownable { } } + /** + * @dev Retrieves the address of the deployment registry + * + * @return The address of the deployment registry + */ function getRegistry() public view returns (address) { return deploymentRegistry; } + /** + * @dev Retrieves the address of a deployer by its tag + * + * @param tag The tag of the deployer + * + * @return The address of the deployer + */ function getDeployer(string memory tag) public view returns (address) { return deployers[tag]; } - function setDeploymentRegistry(address _deploymentRegistry) external onlyOwner { + /** + * @dev Sets the address of the deployment registry + * + * @param _deploymentRegistry The address of the deployment registry + */ + function setDeploymentRegistry(address _deploymentRegistry) public onlyOwner { _requireIsValidRegistry(_deploymentRegistry); deploymentRegistry = _deploymentRegistry; } - function addDeployer(string memory tag, address deployerAddress) external onlyOwner { + /** + * @dev Adds a new deployer to the factory + * + * @param tag The tag of the deployer + * @param deployerAddress The address of the deployer + * + * emits a {DeployerAdded} event + */ + function addDeployer(string memory tag, address deployerAddress) public onlyOwner { _requireIsValidDeployer(deployerAddress); require(deployers[tag] == address(0), "FlowBridgeFactory: Deployer already registered"); deployers[tag] = deployerAddress; + + emit DeployerAdded(tag, deployerAddress); } - function upsertDeployer(string memory tag, address deployerAddress) external onlyOwner { + /** + * @dev Adds a deployer to the factory, or updates the address of an existing deployer + * + * @param tag The tag of the deployer + * + * emits a {DeployerUpdated} event if the deployer already exists otherwise a {DeployerAdded} event + */ + function upsertDeployer(string memory tag, address deployerAddress) public onlyOwner { _requireIsValidDeployer(deployerAddress); + + address oldAddress = deployers[tag]; + if (oldAddress == address(0)) { + addDeployer(tag, deployerAddress); + return; + } + deployers[tag] = deployerAddress; + + emit DeployerUpdated(tag, oldAddress, deployerAddress); + } + + /** + * @dev Removes a deployer from the factory + * + * @param tag The tag of the deployer + * + * emits a {DeployerRemoved} event + */ + function removeDeployer(string memory tag) public onlyOwner { + address oldAddress = deployers[tag]; + require(oldAddress != address(0), "FlowBridgeFactory: Deployer not registered"); + + delete deployers[tag]; + + emit DeployerRemoved(tag, oldAddress); } - function _registerDeployment(string memory cadenceIdentifier, address contractAddr) private { + /** + * @dev Registers a new deployment in the deployment registry + * + * @param cadenceIdentifier The Cadence identifier of the deployed contract + * @param contractAddr The address of the deployed contract + */ + function _registerDeployment(string memory cadenceIdentifier, address contractAddr) internal { FlowEVMDeploymentRegistry registry = FlowEVMDeploymentRegistry(deploymentRegistry); registry.registerDeployment(cadenceIdentifier, contractAddr); } + /** + * @dev Asserts that the registry address is non-zero and implements the IFlowEVMDeploymentRegistry interface + * + * @param registryAddr The address of the registry to check + */ function _requireIsValidRegistry(address registryAddr) internal view { _requireNotZeroAddress(registryAddr); require( @@ -119,6 +263,11 @@ contract FlowBridgeFactory is Ownable { ); } + /** + * @dev Asserts that the contract address is non-zero and implements the IFlowEVMBridgeDeployer interface + * + * @param contractAddr The address of the contract to check + */ function _requireIsValidDeployer(address contractAddr) internal view { _requireNotZeroAddress(contractAddr); require( @@ -127,6 +276,13 @@ contract FlowBridgeFactory is Ownable { ); } + /** + * @dev Checks if a contract implements a specific interface + * + * @param contractAddr The address of the contract to check + * + * @return True if the contract implements the interface, false otherwise + */ function _implementsInterface(address contractAddr, bytes4 interfaceId) internal view returns (bool) { try ERC165(contractAddr).supportsInterface(interfaceId) returns (bool support) { return support; @@ -135,6 +291,11 @@ contract FlowBridgeFactory is Ownable { } } + /** + * @dev Asserts that the address is non-zero + * + * @param addr The address to check + */ function _requireNotZeroAddress(address addr) internal pure { require(addr != address(0), "FlowBridgeFactory: Zero address"); } diff --git a/solidity/src/FlowEVMBridgedERC20Deployer.sol b/solidity/src/FlowEVMBridgedERC20Deployer.sol index 012f8a06..cd444344 100644 --- a/solidity/src/FlowEVMBridgedERC20Deployer.sol +++ b/solidity/src/FlowEVMBridgedERC20Deployer.sol @@ -7,24 +7,52 @@ import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "./interfaces/IFlowEVMBridgeDeployer.sol"; import "./templates/FlowEVMBridgedERC20.sol"; +/** + * @title FlowEVMBridgedERC20Deployer + * @dev A contract to deploy FlowEVMBridgedERC20 contracts with named associations to Cadence contracts. Only the + * delegated deployer can deploy new contracts. This contract is used by the Flow EVM bridge to deploy and define + * bridged ERC20 tokens which are defined natively in Cadence. + */ contract FlowEVMBridgedERC20Deployer is IFlowEVMBridgeDeployer, ERC165, Ownable { + // The address of the delegated deployer who can deploy new contracts address public delegatedDeployer; + + /** + * @dev Event emitted when a new ERC20 contract is deployed via this deployer + */ + event ERC20Deployed( + address contractAddress, string name, string symbol, string cadenceTokenAddress, string cadenceVaultIdentifier + ); constructor() Ownable(msg.sender) {} + /** + * @dev Modifier to check if the caller is the delegated deployer + */ modifier onlyDelegatedDeployer() { require(msg.sender == delegatedDeployer, "FlowEVMBridgedERC20Deployer: Only delegated deployer can deploy"); _; } - event ERC20Deployed( - address contractAddress, string name, string symbol, string cadenceTokenAddress, string cadenceVaultIdentifier - ); - + /** + * @dev ERC165 introspection + */ function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC165) returns (bool) { return interfaceId == type(IFlowEVMBridgeDeployer).interfaceId || super.supportsInterface(interfaceId); } + /** + * @dev Deploy a new FlowEVMBridgedERC20 contract with the given name, symbol, and association to a Cadence + * contract. + * + * @param name The name of the ERC20 + * @param symbol The symbol of the ERC20 + * @param cadenceAddress The address of the associated Cadence contract + * @param cadenceIdentifier The identifier of the associated Cadence asset type + * @param contractURI The URI of the contract metadata + * + * @return The address of the deployed EVM contract + */ function deploy( string memory name, string memory symbol, @@ -40,6 +68,12 @@ contract FlowEVMBridgedERC20Deployer is IFlowEVMBridgeDeployer, ERC165, Ownable return address(newERC20); } + /** + * @dev Set the delegated deployer address as the entity that can deploy new contracts. Only the owner can call this + * function. + * + * @param _delegatedDeployer The address of the delegated deployer + */ function setDelegatedDeployer(address _delegatedDeployer) external onlyOwner { require(_delegatedDeployer != address(0), "FlowEVMBridgedERC20Deployer: Invalid delegated deployer address"); delegatedDeployer = _delegatedDeployer; diff --git a/solidity/src/FlowEVMBridgedERC721Deployer.sol b/solidity/src/FlowEVMBridgedERC721Deployer.sol index f186e419..ff7753f9 100644 --- a/solidity/src/FlowEVMBridgedERC721Deployer.sol +++ b/solidity/src/FlowEVMBridgedERC721Deployer.sol @@ -8,24 +8,52 @@ import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "./interfaces/IFlowEVMBridgeDeployer.sol"; import "./templates/FlowEVMBridgedERC721.sol"; +/** + * @title FlowEVMBridgedERC721Deployer + * @dev A contract to deploy FlowEVMBridgedERC721 contracts with named associations to Cadence contracts. Only the + * delegated deployer can deploy new contracts. This contract is used by the Flow EVM bridge to deploy and define + * bridged ERC721 tokens which are defined natively in Cadence. + */ contract FlowEVMBridgedERC721Deployer is IFlowEVMBridgeDeployer, ERC165, Ownable { + // The address of the delegated deployer who can deploy new contracts address public delegatedDeployer; + /** + * @dev Event emitted when a new ERC721 contract is deployed via this deployer + */ + event ERC721Deployed( + address contractAddress, string name, string symbol, string cadenceNFTAddress, string cadenceNFTIdentifier + ); + constructor() Ownable(msg.sender) {} + /** + * @dev Modifier to check if the caller is the delegated deployer + */ modifier onlyDelegatedDeployer() { require(msg.sender == delegatedDeployer, "FlowEVMBridgedERC721Deployer: Only delegated deployer can deploy"); _; } - event ERC721Deployed( - address contractAddress, string name, string symbol, string cadenceNFTAddress, string cadenceNFTIdentifier - ); - + /** + * @dev ERC165 introspection + */ function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC165) returns (bool) { return interfaceId == type(IFlowEVMBridgeDeployer).interfaceId || super.supportsInterface(interfaceId); } + /** + * @dev Deploy a new FlowEVMBridgedERC721 contract with the given name, symbol, and association to a Cadence + * contract. + * + * @param name The name of the ERC721 + * @param symbol The symbol of the ERC721 + * @param cadenceAddress The address of the associated Cadence contract + * @param cadenceIdentifier The identifier of the associated Cadence asset type + * @param contractURI The URI of the contract metadata + * + * @return The address of the deployed EVM contract + */ function deploy( string memory name, string memory symbol, @@ -41,6 +69,11 @@ contract FlowEVMBridgedERC721Deployer is IFlowEVMBridgeDeployer, ERC165, Ownable return address(newERC721); } + /** + * @dev Set the address of the delegated deployer + * + * @param _delegatedDeployer The address of the delegated deployer + */ function setDelegatedDeployer(address _delegatedDeployer) external onlyOwner { require(_delegatedDeployer != address(0), "FlowEVMBridgedERC721Deployer: Invalid delegated deployer address"); delegatedDeployer = _delegatedDeployer; diff --git a/solidity/src/FlowEVMDeploymentRegistry.sol b/solidity/src/FlowEVMDeploymentRegistry.sol deleted file mode 100644 index 23d13d97..00000000 --- a/solidity/src/FlowEVMDeploymentRegistry.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import "./interfaces/IFlowEVMDeploymentRegistry.sol"; - -abstract contract FlowEVMDeploymentRegistry is IFlowEVMDeploymentRegistry, ERC165 { - address public registrar; - mapping(string => address) public cadenceIdentifierToContract; - mapping(address => string) public contractToCadenceIdentifier; - - modifier onlyRegistrar() { - require(msg.sender == registrar, "FlowBridgeDeploymentRegistry: Only registrar can register association"); - _; - } - - function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC165) returns (bool) { - return interfaceId == type(IFlowEVMDeploymentRegistry).interfaceId || super.supportsInterface(interfaceId); - } - - function getCadenceIdentifier(address contractAddr) external view returns (string memory) { - return contractToCadenceIdentifier[contractAddr]; - } - - function getContractAddress(string memory cadenceIdentifier) external view returns (address) { - return cadenceIdentifierToContract[cadenceIdentifier]; - } - - function isRegisteredDeployment(string memory cadenceIdentifier) external view returns (bool) { - return cadenceIdentifierToContract[cadenceIdentifier] != address(0); - } - - function isRegisteredDeployment(address contractAddr) external view returns (bool) { - return bytes(contractToCadenceIdentifier[contractAddr]).length != 0; - } - - function registerDeployment(string memory cadenceIdentifier, address contractAddr) external onlyRegistrar { - _registerDeployment(cadenceIdentifier, contractAddr); - } - - function _registerDeployment(string memory cadenceIdentifier, address contractAddr) internal { - cadenceIdentifierToContract[cadenceIdentifier] = contractAddr; - contractToCadenceIdentifier[contractAddr] = cadenceIdentifier; - } - - function _setRegistrar(address _registrar) internal { - registrar = _registrar; - } -} diff --git a/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol b/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol new file mode 100644 index 00000000..c30e57ca --- /dev/null +++ b/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import "./IFlowEVMDeploymentRegistry.sol"; + +/** + * @title FlowEVMDeploymentRegistry + * @dev A contract to manage the deployment of Flow EVM contracts and their association with Cadence contracts. Only the + * registrar can register new deployments. + */ +abstract contract FlowEVMDeploymentRegistry is IFlowEVMDeploymentRegistry, ERC165 { + // The address of the registrar who can register new deployments + address public registrar; + // Association between Cadence type identifiers and deployed contract addresses + mapping(string => address) private cadenceIdentifierToContract; + // Reverse association between deployed contract addresses and Cadence type identifiers + mapping(address => string) private contractToCadenceIdentifier; + + modifier onlyRegistrar() { + require(msg.sender == registrar, "FlowBridgeDeploymentRegistry: Only registrar can register association"); + _; + } + + /** + * @dev ERC165 introspection + */ + function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC165) returns (bool) { + return interfaceId == type(IFlowEVMDeploymentRegistry).interfaceId || super.supportsInterface(interfaceId); + } + + /** + * @dev Get the Cadence type identifier associated with a contract address + * + * @param contractAddr The address of the deployed contract + * + * @return The Cadence type identifier + */ + function getCadenceIdentifier(address contractAddr) external view returns (string memory) { + return contractToCadenceIdentifier[contractAddr]; + } + + /** + * @dev Get the contract address associated with a Cadence type identifier + * + * @param cadenceIdentifier The Cadence type identifier + * + * @return The address of the associated contract + */ + function getContractAddress(string memory cadenceIdentifier) external view returns (address) { + return cadenceIdentifierToContract[cadenceIdentifier]; + } + + /** + * @dev Check if a contract address is a registered deployment + * + * @param contractAddr The address of the deployed contract in question + * + * @return True if the contract address is associated with a Cadence type identifier + */ + function isRegisteredDeployment(string memory cadenceIdentifier) external view returns (bool) { + return cadenceIdentifierToContract[cadenceIdentifier] != address(0); + } + + /** + * @dev Check if a Cadence type identifier is associated with a registered deployment + * + * @param contractAddr The address of the contract in question + * + * @return True if the contract address is associated with a Cadence type identifier + */ + function isRegisteredDeployment(address contractAddr) external view returns (bool) { + return bytes(contractToCadenceIdentifier[contractAddr]).length != 0; + } + + /** + * @dev Register a new deployment address with the given Cadence type identifier. Can only be called by the + * current registrar. + * + * @param cadenceIdentifier The Cadence type identifier + * @param contractAddr The address of the deployed contract + */ + function registerDeployment(string memory cadenceIdentifier, address contractAddr) external onlyRegistrar { + _registerDeployment(cadenceIdentifier, contractAddr); + } + + /** + * @dev Internal function to register a new deployment address with the given Cadence type identifier + * + * @param cadenceIdentifier The Cadence type identifier + * @param contractAddr The address of the deployed contract + */ + function _registerDeployment(string memory cadenceIdentifier, address contractAddr) internal { + cadenceIdentifierToContract[cadenceIdentifier] = contractAddr; + contractToCadenceIdentifier[contractAddr] = cadenceIdentifier; + } + + /** + * @dev Set the registrar address as the entity that can register new deployments. Only the owner can execute this. + */ + function _setRegistrar(address _registrar) internal { + registrar = _registrar; + } +} diff --git a/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol b/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol index bbdc562f..247afad0 100644 --- a/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol +++ b/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol @@ -3,8 +3,22 @@ pragma solidity ^0.8.17; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +/** + * @title IFlowEVMBridgeDeployer + * @dev Interface contracts on FlowEVM which deploys EVM contracts with named associations to Cadence contracts. + */ interface IFlowEVMBridgeDeployer is IERC165 { - // Function to deploy a new CadenceBridgedERC20 contract + /** + * @dev Deploy a new EVM contract with the given name, symbol, and association to a Cadence contract. + * + * @param name The name of the EVM asset + * @param symbol The symbol of the EVM asset + * @param cadenceAddress The address of the associated Cadence contract + * @param cadenceIdentifier The identifier of the associated Cadence asset type + * @param contractURI The URI of the contract metadata + * + * @return The address of the deployed EVM contract + */ function deploy( string memory name, string memory symbol, diff --git a/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol b/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol index 0f1fbb21..c6cbc18e 100644 --- a/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol +++ b/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol @@ -3,12 +3,29 @@ pragma solidity ^0.8.17; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +/** + * @title IFlowEVMDeploymentRegistry + * @dev Interface for the FlowEVMDeploymentRegistry contract, intended to be used for contracts that need to manage + * associations between Flow EVM contracts and Cadence contracts. + */ interface IFlowEVMDeploymentRegistry is IERC165 { + /** + * @dev Get the Cadence type identifier associated with a contract address + */ function getCadenceIdentifier(address contractAddr) external view returns (string memory); + /** + * @dev Get the contract address associated with a Cadence type identifier + */ function getContractAddress(string memory cadenceIdentifier) external view returns (address); + /** + * @dev Check if a contract address is associated with a Cadence type identifier + */ function isRegisteredDeployment(address contractAddr) external view returns (bool); + /** + * @dev Check if a Cadence type identifier is associated with a contract address + */ function isRegisteredDeployment(string memory cadenceIdentifier) external view returns (bool); } diff --git a/solidity/test/FlowBridgeFactory.t.sol b/solidity/test/FlowBridgeFactory.t.sol index 95864b70..b34dcc5e 100644 --- a/solidity/test/FlowBridgeFactory.t.sol +++ b/solidity/test/FlowBridgeFactory.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.17; import {Test} from "forge-std/Test.sol"; -import "forge-std/console.sol"; +import {console} from "forge-std/console.sol"; import {FlowBridgeDeploymentRegistry} from "../src/FlowBridgeDeploymentRegistry.sol"; import {FlowEVMBridgedERC721Deployer} from "../src/FlowEVMBridgedERC721Deployer.sol"; @@ -12,8 +12,6 @@ import {FlowEVMBridgedERC721} from "../src/templates/FlowEVMBridgedERC721.sol"; import {FlowEVMBridgedERC20} from "../src/templates/FlowEVMBridgedERC20.sol"; contract FlowBridgeFactoryTest is Test { - address foundryTestOwner; - FlowBridgeFactory internal factory; FlowBridgeDeploymentRegistry internal registry; FlowEVMBridgedERC20Deployer internal erc20Deployer; @@ -32,9 +30,6 @@ contract FlowBridgeFactoryTest is Test { address deployedERC721Address; function setUp() public virtual { - foundryTestOwner = address(0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84); - - factory = new FlowBridgeFactory(); name = "name"; symbol = "symbol"; flowNFTAddress = "flowNFTAddress"; @@ -43,6 +38,8 @@ contract FlowBridgeFactoryTest is Test { flowTokenIdentifier = "flowTokenIdentifier"; contractURI = "contractURI"; + factory = new FlowBridgeFactory(); + registry = new FlowBridgeDeploymentRegistry(); erc20Deployer = new FlowEVMBridgedERC20Deployer(); erc721Deployer = new FlowEVMBridgedERC721Deployer(); @@ -144,7 +141,7 @@ contract FlowBridgeFactoryTest is Test { assertEq(factoryOwner, erc20Owner); } - function test_SuccessfulMint() public { + function test_MintERC721() public { address recipient = address(27); uint256 tokenId = 42; string memory uri = "MOCK_URI"; @@ -153,4 +150,13 @@ contract FlowBridgeFactoryTest is Test { address owner = deployedERC721Contract.ownerOf(tokenId); assertEq(owner, recipient); } + + function test_MintERC20() public { + address recipient = address(27); + uint256 amount = 100e18; + deployedERC20Contract.mint(recipient, amount); + + uint256 balance = deployedERC20Contract.balanceOf(recipient); + assertEq(balance, amount); + } } From 9f3b1999dcb9f6d533e5c20d3060a35ed6ff97e4 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 3 May 2024 13:49:07 -0500 Subject: [PATCH 03/18] begin Cadence test refactor against new .sol contracts --- .../tests/flow_evm_bridge_handler_tests.cdc | 2 +- cadence/tests/flow_evm_bridge_tests.cdc | 34 +++++++++++++++++- cadence/tests/scripts/type_at.cdc | 4 +++ cadence/tests/test_helpers.cdc | 23 +++++++++++- ...im_accessor_capability_and_save_router.cdc | 0 .../bridge/admin/evm/set_registrar.cdc | 36 +++++++++++++++++++ .../interfaces/FlowEVMDeploymentRegistry.sol | 6 ++-- 7 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 cadence/tests/scripts/type_at.cdc rename cadence/transactions/bridge/admin/{evm => evm-integration}/claim_accessor_capability_and_save_router.cdc (100%) create mode 100644 cadence/transactions/bridge/admin/evm/set_registrar.cdc diff --git a/cadence/tests/flow_evm_bridge_handler_tests.cdc b/cadence/tests/flow_evm_bridge_handler_tests.cdc index abf648b7..899ca7da 100644 --- a/cadence/tests/flow_evm_bridge_handler_tests.cdc +++ b/cadence/tests/flow_evm_bridge_handler_tests.cdc @@ -205,7 +205,7 @@ fun setup() { Test.expect(err, Test.beNil()) let claimAccessorResult = executeTransaction( - "../transactions/bridge/admin/evm/claim_accessor_capability_and_save_router.cdc", + "../transactions/bridge/admin/evm-integration/claim_accessor_capability_and_save_router.cdc", ["FlowEVMBridgeAccessor", bridgeAccount.address], serviceAccount ) diff --git a/cadence/tests/flow_evm_bridge_tests.cdc b/cadence/tests/flow_evm_bridge_tests.cdc index 7df9277b..fcb11952 100644 --- a/cadence/tests/flow_evm_bridge_tests.cdc +++ b/cadence/tests/flow_evm_bridge_tests.cdc @@ -139,11 +139,43 @@ fun setup() { arguments: [] ) Test.expect(err, Test.beNil()) + // Deploy registry + let registryDeploymentResult = executeTransaction( + "../transactions/evm/deploy.cdc", + [getRegistryBytecode(), 15_000_000, 0.0], + bridgeAccount + ) + Test.expect(registryDeploymentResult, Test.beSucceeded()) + // Deploy ERC20Deployer + let erc20DeployerDeploymentResult = executeTransaction( + "../transactions/evm/deploy.cdc", + [getERC20DeployerBytecode(), 15_000_000, 0.0], + bridgeAccount + ) + Test.expect(erc20DeployerDeploymentResult, Test.beSucceeded()) + // Deploy ERC721Deployer + let erc721DeployerDeploymentResult = executeTransaction( + "../transactions/evm/deploy.cdc", + [getERC721DeployerBytecode(), 15_000_000, 0.0], + bridgeAccount + ) + Test.expect(erc721DeployerDeploymentResult, Test.beSucceeded()) err = Test.deployContract( name: "FlowEVMBridgeUtils", path: "../contracts/bridge/FlowEVMBridgeUtils.cdc", arguments: [getCompiledFactoryBytecode()] ) + // Set factory as registrar in registry + let setRegistrarResult = executeTransaction( + "../transactions/evm/set_registrar.cdc", + [registryDeploymentResult.events[0].data as! Address], + bridgeAccount + ) + // Set registry as registry in factory + // Set factory as delegatedDeployer in erc20Deployer + // Set factory as delegatedDeployer in erc721Deployer + // add erc20Deployer under "ERC20" tag to factory + // add erc721Deployer under "ERC721" tag to factory Test.expect(err, Test.beNil()) err = Test.deployContract( name: "FlowEVMBridgeNFTEscrow", @@ -216,7 +248,7 @@ fun setup() { Test.expect(err, Test.beNil()) let claimAccessorResult = executeTransaction( - "../transactions/bridge/admin/evm/claim_accessor_capability_and_save_router.cdc", + "../transactions/bridge/admin/evm-integration/claim_accessor_capability_and_save_router.cdc", ["FlowEVMBridgeAccessor", bridgeAccount.address], serviceAccount ) diff --git a/cadence/tests/scripts/type_at.cdc b/cadence/tests/scripts/type_at.cdc new file mode 100644 index 00000000..0fcbef1f --- /dev/null +++ b/cadence/tests/scripts/type_at.cdc @@ -0,0 +1,4 @@ +access(all) +fun main(addr: Address, sp: StoragePath): Type? { + return getAuthAccount(addr).storage.borrow<&AnyResource>(from: sp)?.getType() ?? nil +} \ No newline at end of file diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc index a339013a..47908810 100644 --- a/cadence/tests/test_helpers.cdc +++ b/cadence/tests/test_helpers.cdc @@ -14,7 +14,13 @@ access(all) let metadataViewsUpdateCode = "696d706f72742046756e6769626c65546f6b6 access(all) let evmUpdateCode = "696d706f72742043727970746f0a696d706f7274204e6f6e46756e6769626c65546f6b656e2066726f6d203078303030303030303030303030303030310a696d706f72742046756e6769626c65546f6b656e2066726f6d203078303030303030303030303030303030320a696d706f727420466c6f77546f6b656e2066726f6d203078303030303030303030303030303030330a0a61636365737328616c6c290a636f6e74726163742045564d207b0a0a202020202f2f20456e7469746c656d656e747320656e61626c696e672066696e65722d6772616e65642061636365737320636f6e74726f6c206f6e206120436164656e63654f776e65644163636f756e740a2020202061636365737328616c6c2920656e7469746c656d656e742056616c69646174650a2020202061636365737328616c6c2920656e7469746c656d656e742057697468647261770a2020202061636365737328616c6c2920656e7469746c656d656e742043616c6c0a2020202061636365737328616c6c2920656e7469746c656d656e74204465706c6f790a2020202061636365737328616c6c2920656e7469746c656d656e74204f776e65720a2020202061636365737328616c6c2920656e7469746c656d656e74204272696467650a0a2020202061636365737328616c6c290a202020206576656e7420436164656e63654f776e65644163636f756e7443726561746564286164647265737342797465733a205b55496e74383b2032305d290a0a202020202f2f2f20464c4f57546f6b656e734465706f736974656420697320656d6974746564207768656e20464c4f5720746f6b656e7320697320627269646765640a202020202f2f2f20696e746f207468652045564d20656e7669726f6e6d656e742e204e6f746520746861742074686973206576656e74206973206e6f7420656d69747465640a202020202f2f2f20666f72207472616e73666572206f6620666c6f7720746f6b656e73206265747765656e2074776f2045564d206164647265737365732e0a2020202061636365737328616c6c290a202020206576656e7420464c4f57546f6b656e734465706f7369746564286164647265737342797465733a205b55496e74383b2032305d2c20616d6f756e743a20554669783634290a0a202020202f2f2f20464c4f57546f6b656e7357697468647261776e20697320656d6974746564207768656e20464c4f5720746f6b656e732061726520627269646765640a202020202f2f2f206f7574206f66207468652045564d20656e7669726f6e6d656e742e204e6f746520746861742074686973206576656e74206973206e6f7420656d69747465640a202020202f2f2f20666f72207472616e73666572206f6620666c6f7720746f6b656e73206265747765656e2074776f2045564d206164647265737365732e0a2020202061636365737328616c6c290a202020206576656e7420464c4f57546f6b656e7357697468647261776e286164647265737342797465733a205b55496e74383b2032305d2c20616d6f756e743a20554669783634290a0a202020202f2f2f204272696467654163636573736f725570646174656420697320656d6974746564207768656e20746865204272696467654163636573736f72204361706162696c6974790a202020202f2f2f206973207570646174656420696e207468652073746f72656420427269646765526f7574657220616c6f6e672077697468206964656e74696679696e670a202020202f2f2f20696e666f726d6174696f6e2061626f757420626f74682e0a2020202061636365737328616c6c290a202020206576656e74204272696467654163636573736f7255706461746564280a2020202020202020726f75746572547970653a20547970652c0a2020202020202020726f75746572555549443a2055496e7436342c0a2020202020202020726f75746572416464726573733a20416464726573732c0a20202020202020206163636573736f72547970653a20547970652c0a20202020202020206163636573736f72555549443a2055496e7436342c0a20202020202020206163636573736f72416464726573733a20416464726573730a20202020290a0a202020202f2f2f2045564d4164647265737320697320616e2045564d2d636f6d70617469626c6520616464726573730a2020202061636365737328616c6c290a202020207374727563742045564d41646472657373207b0a0a20202020202020202f2f2f204279746573206f662074686520616464726573730a202020202020202061636365737328616c6c290a20202020202020206c65742062797465733a205b55496e74383b2032305d0a0a20202020202020202f2f2f20436f6e737472756374732061206e65772045564d20616464726573732066726f6d2074686520676976656e206279746520726570726573656e746174696f6e0a20202020202020207669657720696e69742862797465733a205b55496e74383b2032305d29207b0a20202020202020202020202073656c662e6279746573203d2062797465730a20202020202020207d0a0a20202020202020202f2f2f2042616c616e6365206f662074686520616464726573730a202020202020202061636365737328616c6c290a2020202020202020766965772066756e2062616c616e636528293a2042616c616e6365207b0a2020202020202020202020206c65742062616c616e6365203d20496e7465726e616c45564d2e62616c616e6365280a20202020202020202020202020202020616464726573733a2073656c662e62797465730a202020202020202020202020290a20202020202020202020202072657475726e2042616c616e6365286174746f666c6f773a2062616c616e6365290a20202020202020207d0a0a20202020202020202f2f2f204e6f6e6365206f662074686520616464726573730a202020202020202061636365737328616c6c290a202020202020202066756e206e6f6e636528293a2055496e743634207b0a20202020202020202020202072657475726e20496e7465726e616c45564d2e6e6f6e6365280a20202020202020202020202020202020616464726573733a2073656c662e62797465730a202020202020202020202020290a20202020202020207d0a0a20202020202020202f2f2f20436f6465206f662074686520616464726573730a202020202020202061636365737328616c6c290a202020202020202066756e20636f646528293a205b55496e74385d207b0a20202020202020202020202072657475726e20496e7465726e616c45564d2e636f6465280a20202020202020202020202020202020616464726573733a2073656c662e62797465730a202020202020202020202020290a20202020202020207d0a0a20202020202020202f2f2f20436f646548617368206f662074686520616464726573730a202020202020202061636365737328616c6c290a202020202020202066756e20636f64654861736828293a205b55496e74385d207b0a20202020202020202020202072657475726e20496e7465726e616c45564d2e636f646548617368280a20202020202020202020202020202020616464726573733a2073656c662e62797465730a202020202020202020202020290a20202020202020207d0a0a20202020202020202f2f2f204465706f736974732074686520676976656e207661756c7420696e746f207468652045564d206163636f756e7420776974682074686520676976656e20616464726573730a202020202020202061636365737328616c6c290a202020202020202066756e206465706f7369742866726f6d3a2040466c6f77546f6b656e2e5661756c7429207b0a2020202020202020202020206c657420616d6f756e74203d2066726f6d2e62616c616e63650a202020202020202020202020696620616d6f756e74203d3d20302e30207b0a2020202020202020202020202020202070616e6963282263616c6c696e67206465706f7369742066756e6374696f6e207769746820616e20656d707479207661756c74206973206e6f7420616c6c6f77656422290a2020202020202020202020207d0a202020202020202020202020496e7465726e616c45564d2e6465706f736974280a2020202020202020202020202020202066726f6d3a203c2d66726f6d2c0a20202020202020202020202020202020746f3a2073656c662e62797465730a202020202020202020202020290a202020202020202020202020656d697420464c4f57546f6b656e734465706f7369746564286164647265737342797465733a2073656c662e62797465732c20616d6f756e743a20616d6f756e74290a20202020202020207d0a202020207d0a0a2020202061636365737328616c6c290a202020207374727563742042616c616e6365207b0a0a20202020202020202f2f2f205468652062616c616e636520696e206174746f2d464c4f570a20202020202020202f2f2f204174746f2d464c4f572069732074686520736d616c6c6573742064656e6f6d696e6174696f6e206f6620464c4f5720283165313820464c4f57290a20202020202020202f2f2f2074686174206973207573656420746f2073746f7265206163636f756e742062616c616e63657320696e736964652045564d0a20202020202020202f2f2f2073696d696c617220746f207468652077617920574549206973207573656420746f2073746f72652045544820646976697369626c6520746f20313820646563696d616c20706c616365732e0a202020202020202061636365737328616c6c290a2020202020202020766172206174746f666c6f773a2055496e740a0a20202020202020202f2f2f20436f6e737472756374732061206e65772062616c616e63650a202020202020202061636365737328616c6c290a20202020202020207669657720696e6974286174746f666c6f773a2055496e7429207b0a20202020202020202020202073656c662e6174746f666c6f77203d206174746f666c6f770a20202020202020207d0a0a20202020202020202f2f2f2053657473207468652062616c616e636520627920612055466978363420283820646563696d616c20706f696e7473292c2074686520666f726d61740a20202020202020202f2f2f2074686174206973207573656420696e20436164656e636520746f2073746f726520464c4f5720746f6b656e732e0a202020202020202061636365737328616c6c290a202020202020202066756e20736574464c4f5728666c6f773a20554669783634297b0a20202020202020202020202073656c662e6174746f666c6f77203d20496e7465726e616c45564d2e63617374546f4174746f464c4f572862616c616e63653a20666c6f77290a20202020202020207d0a0a20202020202020202f2f2f204361737473207468652062616c616e636520746f2061205546697836342028726f756e64696e6720646f776e290a20202020202020202f2f2f205761726e696e67212063617374696e6720612062616c616e636520746f20612055466978363420776869636820737570706f7274732061206c6f776572206c6576656c206f6620707265636973696f6e0a20202020202020202f2f2f20283820646563696d616c20706f696e747320696e20636f6d7061726520746f20313829206d6967687420726573756c7420696e20726f756e64696e6720646f776e206572726f722e0a20202020202020202f2f2f205573652074686520746f4174746f466c6f772066756e6374696f6e20696620796f752063617265206e656564206d6f72652061636375726163792e0a202020202020202061636365737328616c6c290a2020202020202020766965772066756e20696e464c4f5728293a20554669783634207b0a20202020202020202020202072657475726e20496e7465726e616c45564d2e63617374546f464c4f572862616c616e63653a2073656c662e6174746f666c6f77290a20202020202020207d0a0a20202020202020202f2f2f2052657475726e73207468652062616c616e636520696e204174746f2d464c4f570a202020202020202061636365737328616c6c290a2020202020202020766965772066756e20696e4174746f464c4f5728293a2055496e74207b0a20202020202020202020202072657475726e2073656c662e6174746f666c6f770a20202020202020207d0a0a20202020202020202f2f2f2052657475726e732074727565206966207468652062616c616e6365206973207a65726f0a202020202020202061636365737328616c6c290a202020202020202066756e2069735a65726f28293a20426f6f6c207b0a20202020202020202020202072657475726e2073656c662e6174746f666c6f77203d3d20300a20202020202020207d0a202020207d0a0a202020202f2f2f207265706f7274732074686520737461747573206f662065766d20657865637574696f6e2e0a2020202061636365737328616c6c2920656e756d205374617475733a2055496e7438207b0a20202020202020202f2f2f2069732028726172656c79292072657475726e6564207768656e2073746174757320697320756e6b6e6f776e0a20202020202020202f2f2f20616e6420736f6d657468696e672068617320676f6e6520766572792077726f6e672e0a202020202020202061636365737328616c6c29206361736520756e6b6e6f776e0a0a20202020202020202f2f2f2069732072657475726e6564207768656e20657865637574696f6e206f6620616e2065766d207472616e73616374696f6e2f63616c6c0a20202020202020202f2f2f20686173206661696c6564206174207468652076616c69646174696f6e20737465702028652e672e206e6f6e6365206d69736d61746368292e0a20202020202020202f2f2f20416e20696e76616c6964207472616e73616374696f6e2f63616c6c2069732072656a656374656420746f2062652065786563757465640a20202020202020202f2f2f206f7220626520696e636c7564656420696e206120626c6f636b2e0a202020202020202061636365737328616c6c29206361736520696e76616c69640a0a20202020202020202f2f2f2069732072657475726e6564207768656e20657865637574696f6e206f6620616e2065766d207472616e73616374696f6e2f63616c6c0a20202020202020202f2f2f20686173206265656e207375636365737366756c206275742074686520766d20686173207265706f7274656420616e206572726f722061730a20202020202020202f2f2f20746865206f7574636f6d65206f6620657865637574696f6e2028652e672e2072756e6e696e67206f7574206f6620676173292e0a20202020202020202f2f2f2041206661696c65642074782f63616c6c20697320696e636c7564656420696e206120626c6f636b2e0a20202020202020202f2f2f204e6f746520746861742072657375626d697373696f6e206f662061206661696c6564207472616e73616374696f6e20776f756c640a20202020202020202f2f2f20726573756c7420696e20696e76616c69642073746174757320696e20746865207365636f6e6420617474656d70742c20676976656e0a20202020202020202f2f2f20746865206e6f6e636520776f756c6420626520636f6d6520696e76616c69642e0a202020202020202061636365737328616c6c292063617365206661696c65640a0a20202020202020202f2f2f2069732072657475726e6564207768656e20657865637574696f6e206f6620616e2065766d207472616e73616374696f6e2f63616c6c0a20202020202020202f2f2f20686173206265656e207375636365737366756c20616e64206e6f206572726f72206973207265706f727465642062792074686520766d2e0a202020202020202061636365737328616c6c292063617365207375636365737366756c0a202020207d0a0a202020202f2f2f207265706f72747320746865206f7574636f6d65206f662065766d207472616e73616374696f6e2f63616c6c20657865637574696f6e20617474656d70740a2020202061636365737328616c6c292073747275637420526573756c74207b0a20202020202020202f2f2f20737461747573206f662074686520657865637574696f6e0a202020202020202061636365737328616c6c290a20202020202020206c6574207374617475733a205374617475730a0a20202020202020202f2f2f206572726f7220636f646520286572726f7220636f6465207a65726f206d65616e73206e6f206572726f72290a202020202020202061636365737328616c6c290a20202020202020206c6574206572726f72436f64653a2055496e7436340a0a20202020202020202f2f2f2072657475726e732074686520616d6f756e74206f6620676173206d65746572656420647572696e670a20202020202020202f2f2f2065766d20657865637574696f6e0a202020202020202061636365737328616c6c290a20202020202020206c657420676173557365643a2055496e7436340a0a20202020202020202f2f2f2072657475726e7320746865206461746120746861742069732072657475726e65642066726f6d0a20202020202020202f2f2f207468652065766d20666f72207468652063616c6c2e20466f7220636f612e6465706c6f790a20202020202020202f2f2f2063616c6c732069742072657475726e73207468652061646472657373206279746573206f66207468650a20202020202020202f2f2f206e65776c79206465706c6f79656420636f6e74726163742e0a202020202020202061636365737328616c6c290a20202020202020206c657420646174613a205b55496e74385d0a0a2020202020202020696e6974280a2020202020202020202020207374617475733a205374617475732c0a2020202020202020202020206572726f72436f64653a2055496e7436342c0a202020202020202020202020676173557365643a2055496e7436342c0a202020202020202020202020646174613a205b55496e74385d0a202020202020202029207b0a20202020202020202020202073656c662e737461747573203d207374617475730a20202020202020202020202073656c662e6572726f72436f6465203d206572726f72436f64650a20202020202020202020202073656c662e67617355736564203d20676173557365640a20202020202020202020202073656c662e64617461203d20646174610a20202020202020207d0a202020207d0a0a2020202061636365737328616c6c290a202020207265736f7572636520696e74657266616365204164647265737361626c65207b0a20202020202020202f2f2f205468652045564d20616464726573730a202020202020202061636365737328616c6c290a2020202020202020766965772066756e206164647265737328293a2045564d416464726573730a202020207d0a0a2020202061636365737328616c6c290a202020207265736f7572636520436164656e63654f776e65644163636f756e743a204164647265737361626c65207b0a0a20202020202020206163636573732873656c66290a2020202020202020766172206164647265737342797465733a205b55496e74383b2032305d0a0a2020202020202020696e69742829207b0a2020202020202020202020202f2f206164647265737320697320696e697469616c6c792073657420746f207a65726f0a2020202020202020202020202f2f206275742075706461746564207468726f75676820696e697441646472657373206c617465720a2020202020202020202020202f2f207765206861766520746f20646f20746869732073696e6365207765206e656564207265736f75726365206964202875756964290a2020202020202020202020202f2f20746f2063616c63756c617465207468652045564d206164647265737320666f72207468697320636164656e6365206f776e6564206163636f756e740a20202020202020202020202073656c662e616464726573734279746573203d205b302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20302c20305d0a20202020202020207d0a0a202020202020202061636365737328636f6e7472616374290a202020202020202066756e20696e697441646472657373286164647265737342797465733a205b55496e74383b2032305d29207b0a20202020202020202020202f2f206f6e6c7920616c6c6f7720736574206164647265737320666f72207468652066697273742074696d650a20202020202020202020202f2f20636865636b206164647265737320697320656d7074790a202020202020202020202020666f72206974656d20696e2073656c662e616464726573734279746573207b0a20202020202020202020202020202020617373657274286974656d203d3d20302c206d6573736167653a2022616464726573732062797465206973206e6f7420656d70747922290a2020202020202020202020207d0a202020202020202020202073656c662e616464726573734279746573203d206164647265737342797465730a20202020202020207d0a0a20202020202020202f2f2f205468652045564d2061646472657373206f662074686520636164656e6365206f776e6564206163636f756e740a202020202020202061636365737328616c6c290a2020202020202020766965772066756e206164647265737328293a2045564d41646472657373207b0a2020202020202020202020202f2f20416c77617973206372656174652061206e65772045564d4164647265737320696e7374616e63650a20202020202020202020202072657475726e2045564d416464726573732862797465733a2073656c662e616464726573734279746573290a20202020202020207d0a0a20202020202020202f2f2f204765742062616c616e6365206f662074686520636164656e6365206f776e6564206163636f756e740a202020202020202061636365737328616c6c290a2020202020202020766965772066756e2062616c616e636528293a2042616c616e6365207b0a20202020202020202020202072657475726e2073656c662e6164647265737328292e62616c616e636528290a20202020202020207d0a0a20202020202020202f2f2f204465706f736974732074686520676976656e207661756c7420696e746f2074686520636164656e6365206f776e6564206163636f756e7427732062616c616e63650a202020202020202061636365737328616c6c290a202020202020202066756e206465706f7369742866726f6d3a2040466c6f77546f6b656e2e5661756c7429207b0a20202020202020202020202073656c662e6164647265737328292e6465706f7369742866726f6d3a203c2d66726f6d290a20202020202020207d0a0a20202020202020202f2f2f205468652045564d2061646472657373206f662074686520636164656e6365206f776e6564206163636f756e7420626568696e6420616e20656e7469746c656d656e742c20616374696e672061732070726f6f66206f66206163636573730a2020202020202020616363657373284f776e6572207c2056616c6964617465290a2020202020202020766965772066756e2070726f7465637465644164647265737328293a2045564d41646472657373207b0a20202020202020202020202072657475726e2073656c662e6164647265737328290a20202020202020207d0a0a20202020202020202f2f2f20576974686472617773207468652062616c616e63652066726f6d2074686520636164656e6365206f776e6564206163636f756e7427732062616c616e63650a20202020202020202f2f2f204e6f7465207468617420616d6f756e747320736d616c6c6572207468616e2031306e4620283130652d38292063616e27742062652077697468647261776e0a20202020202020202f2f2f20676976656e207468617420466c6f7720546f6b656e205661756c747320757365205546697836347320746f2073746f72652062616c616e6365732e0a20202020202020202f2f2f2049662074686520676976656e2062616c616e636520636f6e76657273696f6e20746f2055466978363420726573756c747320696e0a20202020202020202f2f2f20726f756e64696e67206572726f722c20746869732066756e6374696f6e20776f756c64206661696c2e0a2020202020202020616363657373284f776e6572207c205769746864726177290a202020202020202066756e2077697468647261772862616c616e63653a2042616c616e6365293a2040466c6f77546f6b656e2e5661756c74207b0a20202020202020202020202069662062616c616e63652e69735a65726f2829207b0a2020202020202020202020202020202070616e6963282263616c6c696e672077697468647261772066756e6374696f6e2077697468207a65726f2062616c616e6365206973206e6f7420616c6c6f77656422290a2020202020202020202020207d0a2020202020202020202020206c6574207661756c74203c2d20496e7465726e616c45564d2e7769746864726177280a2020202020202020202020202020202066726f6d3a2073656c662e6164647265737342797465732c0a20202020202020202020202020202020616d6f756e743a2062616c616e63652e6174746f666c6f770a20202020202020202020202029206173212040466c6f77546f6b656e2e5661756c740a202020202020202020202020656d697420464c4f57546f6b656e7357697468647261776e286164647265737342797465733a2073656c662e6164647265737342797465732c20616d6f756e743a2062616c616e63652e696e464c4f572829290a20202020202020202020202072657475726e203c2d7661756c740a20202020202020207d0a0a20202020202020202f2f2f204465706c6f7973206120636f6e747261637420746f207468652045564d20656e7669726f6e6d656e742e0a20202020202020202f2f2f2052657475726e73207468652061646472657373206f6620746865206e65776c79206465706c6f79656420636f6e74726163740a2020202020202020616363657373284f776e6572207c204465706c6f79290a202020202020202066756e206465706c6f79280a202020202020202020202020636f64653a205b55496e74385d2c0a2020202020202020202020206761734c696d69743a2055496e7436342c0a20202020202020202020202076616c75653a2042616c616e63650a2020202020202020293a2045564d41646472657373207b0a2020202020202020202020206c657420616464726573734279746573203d20496e7465726e616c45564d2e6465706c6f79280a2020202020202020202020202020202066726f6d3a2073656c662e6164647265737342797465732c0a20202020202020202020202020202020636f64653a20636f64652c0a202020202020202020202020202020206761734c696d69743a206761734c696d69742c0a2020202020202020202020202020202076616c75653a2076616c75652e6174746f666c6f770a202020202020202020202020290a20202020202020202020202072657475726e2045564d416464726573732862797465733a20616464726573734279746573290a20202020202020207d0a0a20202020202020202f2f2f2043616c6c7320612066756e6374696f6e20776974682074686520676976656e20646174612e0a20202020202020202f2f2f2054686520657865637574696f6e206973206c696d697465642062792074686520676976656e20616d6f756e74206f66206761730a2020202020202020616363657373284f776e6572207c2043616c6c290a202020202020202066756e2063616c6c280a202020202020202020202020746f3a2045564d416464726573732c0a202020202020202020202020646174613a205b55496e74385d2c0a2020202020202020202020206761734c696d69743a2055496e7436342c0a20202020202020202020202076616c75653a2042616c616e63650a2020202020202020293a20526573756c74207b0a20202020202020202020202072657475726e20496e7465726e616c45564d2e63616c6c280a2020202020202020202020202020202066726f6d3a2073656c662e6164647265737342797465732c0a20202020202020202020202020202020746f3a20746f2e62797465732c0a20202020202020202020202020202020646174613a20646174612c0a202020202020202020202020202020206761734c696d69743a206761734c696d69742c0a2020202020202020202020202020202076616c75653a2076616c75652e6174746f666c6f770a202020202020202020202020292061732120526573756c740a20202020202020207d0a0a20202020202020202f2f2f20427269646765732074686520676976656e204e465420746f207468652045564d20656e7669726f6e6d656e742c20726571756972696e6720612050726f76696465722066726f6d20776869636820746f20776974686472617720612066656520746f2066756c66696c6c0a20202020202020202f2f2f207468652062726964676520726571756573740a202020202020202061636365737328616c6c290a202020202020202066756e206465706f7369744e4654280a2020202020202020202020206e66743a20407b4e6f6e46756e6769626c65546f6b656e2e4e46547d2c0a20202020202020202020202066656550726f76696465723a20617574682846756e6769626c65546f6b656e2e57697468647261772920267b46756e6769626c65546f6b656e2e50726f76696465727d0a202020202020202029207b0a20202020202020202020202045564d2e626f72726f774272696467654163636573736f7228292e6465706f7369744e4654286e66743a203c2d6e66742c20746f3a2073656c662e6164647265737328292c2066656550726f76696465723a2066656550726f7669646572290a20202020202020207d0a0a20202020202020202f2f2f20427269646765732074686520676976656e204e46542066726f6d207468652045564d20656e7669726f6e6d656e742c20726571756972696e6720612050726f76696465722066726f6d20776869636820746f20776974686472617720612066656520746f2066756c66696c6c0a20202020202020202f2f2f207468652062726964676520726571756573742e204e6f74653a207468652063616c6c65722073686f756c64206f776e2074686520726571756573746564204e465420696e2045564d0a2020202020202020616363657373284f776e6572207c20427269646765290a202020202020202066756e2077697468647261774e4654280a202020202020202020202020747970653a20547970652c0a20202020202020202020202069643a2055496e743235362c0a20202020202020202020202066656550726f76696465723a20617574682846756e6769626c65546f6b656e2e57697468647261772920267b46756e6769626c65546f6b656e2e50726f76696465727d0a2020202020202020293a20407b4e6f6e46756e6769626c65546f6b656e2e4e46547d207b0a20202020202020202020202072657475726e203c2d2045564d2e626f72726f774272696467654163636573736f7228292e77697468647261774e4654280a2020202020202020202020202020202063616c6c65723a202673656c6620617320617574682843616c6c292026436164656e63654f776e65644163636f756e742c0a20202020202020202020202020202020747970653a20747970652c0a2020202020202020202020202020202069643a2069642c0a2020202020202020202020202020202066656550726f76696465723a2066656550726f76696465720a202020202020202020202020290a20202020202020207d0a0a20202020202020202f2f2f20427269646765732074686520676976656e205661756c7420746f207468652045564d20656e7669726f6e6d656e742c20726571756972696e6720612050726f76696465722066726f6d20776869636820746f20776974686472617720612066656520746f2066756c66696c6c0a20202020202020202f2f2f207468652062726964676520726571756573740a202020202020202061636365737328616c6c290a202020202020202066756e206465706f736974546f6b656e73280a2020202020202020202020207661756c743a20407b46756e6769626c65546f6b656e2e5661756c747d2c0a20202020202020202020202066656550726f76696465723a20617574682846756e6769626c65546f6b656e2e57697468647261772920267b46756e6769626c65546f6b656e2e50726f76696465727d0a202020202020202029207b0a20202020202020202020202045564d2e626f72726f774272696467654163636573736f7228292e6465706f736974546f6b656e73287661756c743a203c2d7661756c742c20746f3a2073656c662e6164647265737328292c2066656550726f76696465723a2066656550726f7669646572290a20202020202020207d0a0a20202020202020202f2f2f20427269646765732074686520676976656e2066756e6769626c6520746f6b656e732066726f6d207468652045564d20656e7669726f6e6d656e742c20726571756972696e6720612050726f76696465722066726f6d20776869636820746f20776974686472617720610a20202020202020202f2f2f2066656520746f2066756c66696c6c207468652062726964676520726571756573742e204e6f74653a207468652063616c6c65722073686f756c64206f776e207468652072657175657374656420746f6b656e7320262073756666696369656e742062616c616e6365206f660a20202020202020202f2f2f2072657175657374656420746f6b656e7320696e2045564d0a2020202020202020616363657373284f776e6572207c20427269646765290a202020202020202066756e207769746864726177546f6b656e73280a202020202020202020202020747970653a20547970652c0a202020202020202020202020616d6f756e743a2055496e743235362c0a20202020202020202020202066656550726f76696465723a20617574682846756e6769626c65546f6b656e2e57697468647261772920267b46756e6769626c65546f6b656e2e50726f76696465727d0a2020202020202020293a20407b46756e6769626c65546f6b656e2e5661756c747d207b0a20202020202020202020202072657475726e203c2d2045564d2e626f72726f774272696467654163636573736f7228292e7769746864726177546f6b656e73280a2020202020202020202020202020202063616c6c65723a202673656c6620617320617574682843616c6c292026436164656e63654f776e65644163636f756e742c0a20202020202020202020202020202020747970653a20747970652c0a20202020202020202020202020202020616d6f756e743a20616d6f756e742c0a2020202020202020202020202020202066656550726f76696465723a2066656550726f76696465720a202020202020202020202020290a20202020202020207d0a202020207d0a0a202020202f2f2f20437265617465732061206e657720636164656e6365206f776e6564206163636f756e740a2020202061636365737328616c6c290a2020202066756e20637265617465436164656e63654f776e65644163636f756e7428293a2040436164656e63654f776e65644163636f756e74207b0a20202020202020206c657420616363203c2d63726561746520436164656e63654f776e65644163636f756e7428290a20202020202020206c65742061646472203d20496e7465726e616c45564d2e637265617465436164656e63654f776e65644163636f756e7428757569643a206163632e75756964290a20202020202020206163632e696e697441646472657373286164647265737342797465733a2061646472290a2020202020202020656d697420436164656e63654f776e65644163636f756e7443726561746564286164647265737342797465733a2061646472290a202020202020202072657475726e203c2d6163630a202020207d0a0a202020202f2f2f2052756e7320616e206120524c502d656e636f6465642045564d207472616e73616374696f6e2c2064656475637473207468652067617320666565732c0a202020202f2f2f20616e64206465706f736974732074686520676173206665657320696e746f207468652070726f766964656420636f696e6261736520616464726573732e0a2020202061636365737328616c6c290a2020202066756e2072756e2874783a205b55496e74385d2c20636f696e626173653a2045564d41646472657373293a20526573756c74207b0a202020202020202072657475726e20496e7465726e616c45564d2e72756e280a2020202020202020202020202020202074783a2074782c0a20202020202020202020202020202020636f696e626173653a20636f696e626173652e62797465730a2020202020202020292061732120526573756c740a202020207d0a0a202020202f2f2f206d75737452756e2072756e7320746865207472616e73616374696f6e207573696e672045564d2e72756e207965742069740a202020202f2f2f20726f6c6c6261636b2069662074686520747820657865637574696f6e2073746174757320697320756e6b6e6f776e206f7220696e76616c69642e0a202020202f2f2f204e6f746520746861742074686973206d6574686f6420646f6573206e6f7420726f6c6c6261636b206966207472616e73616374696f6e0a202020202f2f2f2069732065786563757465642062757420616e20766d206572726f72206973207265706f7274656420617320746865206f7574636f6d650a202020202f2f2f206f662074686520657865637574696f6e20287374617475733a206661696c6564292e0a2020202061636365737328616c6c290a2020202066756e206d75737452756e2874783a205b55496e74385d2c20636f696e626173653a2045564d41646472657373293a20526573756c74207b0a20202020202020206c65742072756e526573756c74203d2073656c662e72756e2874783a2074782c20636f696e626173653a20636f696e62617365290a2020202020202020617373657274280a20202020202020202020202072756e526573756c742e737461747573203d3d205374617475732e6661696c6564207c7c2072756e526573756c742e737461747573203d3d205374617475732e7375636365737366756c2c0a2020202020202020202020206d6573736167653a20227478206973206e6f742076616c696420666f7220657865637574696f6e220a2020202020202020290a202020202020202072657475726e2072756e526573756c740a202020207d0a0a2020202061636365737328616c6c290a2020202066756e20656e636f6465414249285f2076616c7565733a205b416e795374727563745d293a205b55496e74385d207b0a202020202020202072657475726e20496e7465726e616c45564d2e656e636f64654142492876616c756573290a202020207d0a0a2020202061636365737328616c6c290a2020202066756e206465636f64654142492874797065733a205b547970655d2c20646174613a205b55496e74385d293a205b416e795374727563745d207b0a202020202020202072657475726e20496e7465726e616c45564d2e6465636f64654142492874797065733a2074797065732c20646174613a2064617461290a202020207d0a0a2020202061636365737328616c6c290a2020202066756e20656e636f6465414249576974685369676e6174757265280a20202020202020205f207369676e61747572653a20537472696e672c0a20202020202020205f2076616c7565733a205b416e795374727563745d0a20202020293a205b55496e74385d207b0a20202020202020206c6574206d6574686f644944203d2048617368416c676f726974686d2e4b454343414b5f3235362e68617368280a2020202020202020202020207369676e61747572652e757466380a2020202020202020292e736c6963652866726f6d3a20302c207570546f3a2034290a20202020202020206c657420617267756d656e7473203d20496e7465726e616c45564d2e656e636f64654142492876616c756573290a0a202020202020202072657475726e206d6574686f6449442e636f6e63617428617267756d656e7473290a202020207d0a0a2020202061636365737328616c6c290a2020202066756e206465636f6465414249576974685369676e6174757265280a20202020202020205f207369676e61747572653a20537472696e672c0a202020202020202074797065733a205b547970655d2c0a2020202020202020646174613a205b55496e74385d0a20202020293a205b416e795374727563745d207b0a20202020202020206c6574206d6574686f644944203d2048617368416c676f726974686d2e4b454343414b5f3235362e68617368280a2020202020202020202020207369676e61747572652e757466380a2020202020202020292e736c6963652866726f6d3a20302c207570546f3a2034290a0a2020202020202020666f72206279746520696e206d6574686f644944207b0a2020202020202020202020206966206279746520213d20646174612e72656d6f766546697273742829207b0a2020202020202020202020202020202070616e696328227369676e6174757265206d69736d6174636822290a2020202020202020202020207d0a20202020202020207d0a0a202020202020202072657475726e20496e7465726e616c45564d2e6465636f64654142492874797065733a2074797065732c20646174613a2064617461290a202020207d0a0a202020202f2f2f2056616c69646174696f6e526573756c742072657475726e732074686520726573756c74206f6620434f41206f776e6572736869702070726f6f662076616c69646174696f6e0a2020202061636365737328616c6c290a202020207374727563742056616c69646174696f6e526573756c74207b0a202020202020202061636365737328616c6c290a20202020202020206c657420697356616c69643a20426f6f6c0a0a202020202020202061636365737328616c6c290a20202020202020206c65742070726f626c656d3a20537472696e673f0a0a2020202020202020696e697428697356616c69643a20426f6f6c2c2070726f626c656d3a20537472696e673f29207b0a20202020202020202020202073656c662e697356616c6964203d20697356616c69640a20202020202020202020202073656c662e70726f626c656d203d2070726f626c656d0a20202020202020207d0a202020207d0a0a202020202f2f2f2076616c6964617465434f414f776e65727368697050726f6f662076616c696461746573206120434f41206f776e6572736869702070726f6f660a2020202061636365737328616c6c290a2020202066756e2076616c6964617465434f414f776e65727368697050726f6f66280a2020202020202020616464726573733a20416464726573732c0a2020202020202020706174683a205075626c6963506174682c0a20202020202020207369676e6564446174613a205b55496e74385d2c0a20202020202020206b6579496e64696365733a205b55496e7436345d2c0a20202020202020207369676e6174757265733a205b5b55496e74385d5d2c0a202020202020202065766d416464726573733a205b55496e74383b2032305d0a20202020293a2056616c69646174696f6e526573756c74207b0a0a20202020202020202f2f206d616b65207369676e6174757265207365742066697273740a20202020202020202f2f20636865636b206e756d626572206f66207369676e617475726573206d617463686573206e756d626572206f66206b657920696e64696365730a20202020202020206966206b6579496e64696365732e6c656e67746820213d207369676e6174757265732e6c656e677468207b0a20202020202020202020202072657475726e2056616c69646174696f6e526573756c74280a20202020202020202020202020202020697356616c69643a2066616c73652c0a2020202020202020202020202020202070726f626c656d3a20226b657920696e64696365732073697a6520646f65736e2774206d6174636820746865207369676e617475726573220a202020202020202020202020290a20202020202020207d0a0a2020202020202020766172207369676e61747572655365743a205b43727970746f2e4b65794c6973745369676e61747572655d203d205b5d0a2020202020202020666f72207369676e6174757265496e6465782c207369676e617475726520696e207369676e6174757265737b0a2020202020202020202020207369676e61747572655365742e617070656e642843727970746f2e4b65794c6973745369676e6174757265280a202020202020202020202020202020206b6579496e6465783a20496e74286b6579496e64696365735b7369676e6174757265496e6465785d292c0a202020202020202020202020202020207369676e61747572653a207369676e61747572650a20202020202020202020202029290a20202020202020207d0a0a20202020202020202f2f206665746368206163636f756e740a20202020202020206c657420616363203d206765744163636f756e742861646472657373290a0a20202020202020202f2f20636f6e737472756374696e67206b6579206c6973740a20202020202020206c6574206b65794c697374203d2043727970746f2e4b65794c69737428290a2020202020202020666f72207369676e617475726520696e207369676e6174757265536574207b0a2020202020202020202020206c6574206b6579203d206163632e6b6579732e676574286b6579496e6465783a207369676e61747572652e6b6579496e64657829210a20202020202020202020202061737365727428216b65792e69735265766f6b65642c206d6573736167653a20227265766f6b6564206b6579206973207573656422290a2020202020202020202020206b65794c6973742e616464280a20202020202020202020202020206b65792e7075626c69634b65792c0a202020202020202020202020202068617368416c676f726974686d3a206b65792e68617368416c676f726974686d2c0a20202020202020202020202020207765696768743a206b65792e7765696768742c0a2020202020202020202020290a20202020202020207d0a0a20202020202020206c657420697356616c6964203d206b65794c6973742e766572696679280a2020202020202020202020207369676e61747572655365743a207369676e61747572655365742c0a2020202020202020202020207369676e6564446174613a207369676e6564446174612c0a202020202020202020202020646f6d61696e53657061726174696f6e5461673a2022464c4f572d56302e302d75736572220a2020202020202020290a0a202020202020202069662021697356616c69647b0a20202020202020202020202072657475726e2056616c69646174696f6e526573756c74280a20202020202020202020202020202020697356616c69643a2066616c73652c0a2020202020202020202020202020202070726f626c656d3a202274686520676976656e207369676e61747572657320617265206e6f742076616c6964206f722070726f7669646520656e6f75676820776569676874220a202020202020202020202020290a20202020202020207d0a0a20202020202020206c657420636f61526566203d206163632e6361706162696c69746965732e626f72726f773c2645564d2e436164656e63654f776e65644163636f756e743e2870617468290a2020202020202020696620636f61526566203d3d206e696c207b0a2020202020202020202020202072657475726e2056616c69646174696f6e526573756c74280a2020202020202020202020202020202020697356616c69643a2066616c73652c0a202020202020202020202020202020202070726f626c656d3a2022636f756c64206e6f7420626f72726f7720627269646765206163636f756e742773207265736f75726365220a20202020202020202020202020290a20202020202020207d0a0a20202020202020202f2f207665726966792065766d2061646472657373206d61746368696e670a20202020202020207661722061646472203d20636f61526566212e6164647265737328290a2020202020202020666f7220696e6465782c206974656d20696e20636f61526566212e6164647265737328292e6279746573207b0a2020202020202020202020206966206974656d20213d2065766d416464726573735b696e6465785d207b0a2020202020202020202020202020202072657475726e2056616c69646174696f6e526573756c74280a2020202020202020202020202020202020202020697356616c69643a2066616c73652c0a202020202020202020202020202020202020202070726f626c656d3a202265766d2061646472657373206d69736d61746368220a20202020202020202020202020202020290a2020202020202020202020207d0a20202020202020207d0a0a202020202020202072657475726e2056616c69646174696f6e526573756c74280a202020202020202020202020697356616c69643a20747275652c0a20202020202020202020202070726f626c656d3a206e696c0a2020202020202020290a202020207d0a0a202020202f2f2f20426c6f636b2072657475726e7320696e666f726d6174696f6e2061626f757420746865206c617465737420657865637574656420626c6f636b2e0a2020202061636365737328616c6c290a202020207374727563742045564d426c6f636b207b0a202020202020202061636365737328616c6c290a20202020202020206c6574206865696768743a2055496e7436340a0a202020202020202061636365737328616c6c290a20202020202020206c657420686173683a20537472696e670a0a202020202020202061636365737328616c6c290a20202020202020206c657420746f74616c537570706c793a20496e740a0a2020202020202020696e6974286865696768743a2055496e7436342c20686173683a20537472696e672c20746f74616c537570706c793a20496e7429207b0a20202020202020202020202073656c662e686569676874203d206865696768740a20202020202020202020202073656c662e68617368203d20686173680a20202020202020202020202073656c662e746f74616c537570706c79203d20746f74616c537570706c790a20202020202020207d0a202020207d0a0a202020202f2f2f2052657475726e7320746865206c617465737420657865637574656420626c6f636b2e0a2020202061636365737328616c6c290a2020202066756e206765744c6174657374426c6f636b28293a2045564d426c6f636b207b0a202020202020202072657475726e20496e7465726e616c45564d2e6765744c6174657374426c6f636b2829206173212045564d426c6f636b0a202020207d0a0a202020202f2f2f20496e7465726661636520666f722061207265736f75726365207768696368206163747320617320616e20656e747279706f696e7420746f2074686520564d206272696467650a2020202061636365737328616c6c290a202020207265736f7572636520696e74657266616365204272696467654163636573736f72207b0a0a20202020202020202f2f2f20456e64706f696e7420656e61626c696e6720746865206272696467696e67206f6620616e204e465420746f2045564d0a202020202020202061636365737328427269646765290a202020202020202066756e206465706f7369744e4654280a2020202020202020202020206e66743a20407b4e6f6e46756e6769626c65546f6b656e2e4e46547d2c0a202020202020202020202020746f3a2045564d416464726573732c0a20202020202020202020202066656550726f76696465723a20617574682846756e6769626c65546f6b656e2e57697468647261772920267b46756e6769626c65546f6b656e2e50726f76696465727d0a2020202020202020290a0a20202020202020202f2f2f20456e64706f696e7420656e61626c696e6720746865206272696467696e67206f6620616e204e46542066726f6d2045564d0a202020202020202061636365737328427269646765290a202020202020202066756e2077697468647261774e4654280a20202020202020202020202063616c6c65723a20617574682843616c6c292026436164656e63654f776e65644163636f756e742c0a202020202020202020202020747970653a20547970652c0a20202020202020202020202069643a2055496e743235362c0a20202020202020202020202066656550726f76696465723a20617574682846756e6769626c65546f6b656e2e57697468647261772920267b46756e6769626c65546f6b656e2e50726f76696465727d0a2020202020202020293a20407b4e6f6e46756e6769626c65546f6b656e2e4e46547d0a0a20202020202020202f2f2f20456e64706f696e7420656e61626c696e6720746865206272696467696e67206f6620612066756e6769626c6520746f6b656e207661756c7420746f2045564d0a202020202020202061636365737328427269646765290a202020202020202066756e206465706f736974546f6b656e73280a2020202020202020202020207661756c743a20407b46756e6769626c65546f6b656e2e5661756c747d2c0a202020202020202020202020746f3a2045564d416464726573732c0a20202020202020202020202066656550726f76696465723a20617574682846756e6769626c65546f6b656e2e57697468647261772920267b46756e6769626c65546f6b656e2e50726f76696465727d0a2020202020202020290a0a20202020202020202f2f2f20456e64706f696e7420656e61626c696e6720746865206272696467696e67206f662066756e6769626c6520746f6b656e732066726f6d2045564d0a202020202020202061636365737328427269646765290a202020202020202066756e207769746864726177546f6b656e73280a20202020202020202020202063616c6c65723a20617574682843616c6c292026436164656e63654f776e65644163636f756e742c0a202020202020202020202020747970653a20547970652c0a202020202020202020202020616d6f756e743a2055496e743235362c0a20202020202020202020202066656550726f76696465723a20617574682846756e6769626c65546f6b656e2e57697468647261772920267b46756e6769626c65546f6b656e2e50726f76696465727d0a2020202020202020293a20407b46756e6769626c65546f6b656e2e5661756c747d0a202020207d0a0a202020202f2f2f20496e746572666163652077686963682063617074757265732061204361706162696c69747920746f2074686520627269646765204163636573736f722c20736176696e672069742077697468696e2074686520427269646765526f75746572207265736f757263650a2020202061636365737328616c6c290a202020207265736f7572636520696e7465726661636520427269646765526f75746572207b0a0a20202020202020202f2f2f2052657475726e732061207265666572656e636520746f20746865204272696467654163636573736f722064657369676e6174656420666f7220696e7465726e616c206272696467652072657175657374730a2020202020202020616363657373284272696467652920766965772066756e20626f72726f774272696467654163636573736f7228293a2061757468284272696467652920267b4272696467654163636573736f727d0a0a20202020202020202f2f2f205365747320746865204272696467654163636573736f72204361706162696c69747920696e2074686520427269646765526f757465720a202020202020202061636365737328427269646765292066756e207365744272696467654163636573736f72285f206163636573736f723a204361706162696c6974793c61757468284272696467652920267b4272696467654163636573736f727d3e29207b0a202020202020202020202020707265207b0a202020202020202020202020202020206163636573736f722e636865636b28293a2022496e76616c6964204272696467654163636573736f72204361706162696c6974792070726f7669646564220a20202020202020202020202020202020656d6974204272696467654163636573736f7255706461746564280a2020202020202020202020202020202020202020726f75746572547970653a2073656c662e6765745479706528292c0a2020202020202020202020202020202020202020726f75746572555549443a2073656c662e757569642c0a2020202020202020202020202020202020202020726f75746572416464726573733a2073656c662e6f776e65723f2e61646472657373203f3f2070616e69632822526f75746572206d757374206861766520616e206f776e657220746f206265206964656e74696669656422292c0a20202020202020202020202020202020202020206163636573736f72547970653a206163636573736f722e626f72726f772829212e6765745479706528292c0a20202020202020202020202020202020202020206163636573736f72555549443a206163636573736f722e626f72726f772829212e757569642c0a20202020202020202020202020202020202020206163636573736f72416464726573733a206163636573736f722e616464726573730a20202020202020202020202020202020290a2020202020202020202020207d0a20202020202020207d0a202020207d0a0a202020202f2f2f2052657475726e732061207265666572656e636520746f20746865204272696467654163636573736f722064657369676e6174656420666f7220696e7465726e616c206272696467652072657175657374730a202020206163636573732873656c66290a20202020766965772066756e20626f72726f774272696467654163636573736f7228293a2061757468284272696467652920267b4272696467654163636573736f727d207b0a202020202020202072657475726e2073656c662e6163636f756e742e73746f726167652e626f72726f773c61757468284272696467652920267b427269646765526f757465727d3e2866726f6d3a202f73746f726167652f65766d427269646765526f75746572290a2020202020202020202020203f2e626f72726f774272696467654163636573736f7228290a2020202020202020202020203f3f2070616e69632822436f756c64206e6f7420626f72726f77207265666572656e636520746f207468652045564d2062726964676522290a202020207d0a7d0a" -access(all) let compiledFactoryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61484a806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000c35760003560e01c8063715018a6116200007a578063715018a6146200018f5780638da5cb5b146200019b578063d56e0ccf14620001ad578063daa09e5414620001e4578063f2fde38b14620001fb578063f93241dd146200021257600080fd5b806304433bbc14620000c85780630a2c0ce914620000fc578063263e0c1b1462000122578063335f4c76146200014a57806340f8d42b146200016157806361a169051462000178575b600080fd5b620000df620000d936600462000c0a565b62000229565b6040516001600160a01b0390911681526020015b60405180910390f35b620001136200010d36600462000c4b565b6200025c565b604051620000f3919062000cd1565b620001396200013336600462000c4b565b62000310565b6040519015158152602001620000f3565b620001396200015b36600462000c4b565b62000724565b620000df6200017236600462000ce6565b62000752565b620000df6200018936600462000ce6565b62000853565b6200019962000942565b005b6000546001600160a01b0316620000df565b620000df620001be36600462000c0a565b80516020818301810180516001825292820191909301209152546001600160a01b031681565b62000139620001f536600462000c4b565b6200095a565b620001996200020c36600462000c4b565b620009da565b620001136200022336600462000c4b565b62000a22565b60006001826040516200023d919062000dc8565b908152604051908190036020019020546001600160a01b031692915050565b6001600160a01b0381166000908152600260205260409020805460609190620002859062000de6565b80601f0160208091040260200160405190810160405280929190818152602001828054620002b39062000de6565b8015620003045780601f10620002d85761010080835404028352916020019162000304565b820191906000526020600020905b815481529060010190602001808311620002e657829003601f168201915b50505050509050919050565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169162000358919062000dc8565b600060405180830381855afa9150503d806000811462000395576040519150601f19603f3d011682016040523d82523d6000602084013e6200039a565b606091505b5091509150811580620003ac57508051155b15620003bc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b179052516200040b919062000dc8565b600060405180830381855afa9150503d806000811462000448576040519150601f19603f3d011682016040523d82523d6000602084013e6200044d565b606091505b5090925090508115806200046057508051155b1562000470575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b17905251620004c6919062000dc8565b600060405180830381855afa9150503d806000811462000503576040519150601f19603f3d011682016040523d82523d6000602084013e62000508565b606091505b5090925090508115806200051b57508051155b156200052b575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b038616916200056b9162000dc8565b600060405180830381855afa9150503d8060008114620005a8576040519150601f19603f3d011682016040523d82523d6000602084013e620005ad565b606091505b509092509050811580620005c057508051155b15620005d0575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b03861691620006109162000dc8565b600060405180830381855afa9150503d80600081146200064d576040519150601f19603f3d011682016040523d82523d6000602084013e62000652565b606091505b5090925090508115806200066557508051155b1562000675575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b03861691620006b59162000dc8565b600060405180830381855afa9150503d8060008114620006f2576040519150601f19603f3d011682016040523d82523d6000602084013e620006f7565b606091505b5090925090508115806200070a57508051155b156200071a575060009392505050565b5060019392505050565b6001600160a01b03811660009081526002602052604081208054620007499062000de6565b15159392505050565b60006200075e62000ac4565b600080546001600160a01b031687878787876040516200077e9062000b43565b6200078f9695949392919062000e22565b604051809103906000f080158015620007ac573d6000803e3d6000fd5b50905080600185604051620007c2919062000dc8565b908152604080516020928190038301902080546001600160a01b0319166001600160a01b03948516179055918316600090815260029091522062000807858262000f00565b507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee81888888886040516200084195949392919062000fcd565b60405180910390a19695505050505050565b60006200085f62000ac4565b600080546001600160a01b031687878787876040516200087f9062000b51565b620008909695949392919062000e22565b604051809103906000f080158015620008ad573d6000803e3d6000fd5b50905080600185604051620008c3919062000dc8565b908152604080516020928190038301902080546001600160a01b0319166001600160a01b03948516179055918316600090815260029091522062000908858262000f00565b507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f081888888886040516200084195949392919062000fcd565b6200094c62000ac4565b62000958600062000af3565b565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015620009c7575060408051601f3d908101601f19168201909252620009c4918101906200103f565b60015b620009d457506000919050565b92915050565b620009e462000ac4565b6001600160a01b03811662000a1457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b62000a1f8162000af3565b50565b6002602052600090815260409020805462000a3d9062000de6565b80601f016020809104026020016040519081016040528092919081815260200182805462000a6b9062000de6565b801562000abc5780601f1062000a905761010080835404028352916020019162000abc565b820191906000526020600020905b81548152906001019060200180831162000a9e57829003601f168201915b505050505081565b6000546001600160a01b03163314620009585760405163118cdaa760e01b815233600482015260240162000a0b565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200106483390190565b611eb7806200295e83390190565b634e487b7160e01b600052604160045260246000fd5b600082601f83011262000b8757600080fd5b813567ffffffffffffffff8082111562000ba55762000ba562000b5f565b604051601f8301601f19908116603f0116810190828211818310171562000bd05762000bd062000b5f565b8160405283815286602085880101111562000bea57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121562000c1d57600080fd5b813567ffffffffffffffff81111562000c3557600080fd5b62000c438482850162000b75565b949350505050565b60006020828403121562000c5e57600080fd5b81356001600160a01b038116811462000c7657600080fd5b9392505050565b60005b8381101562000c9a57818101518382015260200162000c80565b50506000910152565b6000815180845262000cbd81602086016020860162000c7d565b601f01601f19169290920160200192915050565b60208152600062000c76602083018462000ca3565b600080600080600060a0868803121562000cff57600080fd5b853567ffffffffffffffff8082111562000d1857600080fd5b62000d2689838a0162000b75565b9650602088013591508082111562000d3d57600080fd5b62000d4b89838a0162000b75565b9550604088013591508082111562000d6257600080fd5b62000d7089838a0162000b75565b9450606088013591508082111562000d8757600080fd5b62000d9589838a0162000b75565b9350608088013591508082111562000dac57600080fd5b5062000dbb8882890162000b75565b9150509295509295909350565b6000825162000ddc81846020870162000c7d565b9190910192915050565b600181811c9082168062000dfb57607f821691505b60208210810362000e1c57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b038716815260c06020820181905260009062000e489083018862000ca3565b828103604084015262000e5c818862000ca3565b9050828103606084015262000e72818762000ca3565b9050828103608084015262000e88818662000ca3565b905082810360a084015262000e9e818562000ca3565b9998505050505050505050565b601f82111562000efb576000816000526020600020601f850160051c8101602086101562000ed65750805b601f850160051c820191505b8181101562000ef75782815560010162000ee2565b5050505b505050565b815167ffffffffffffffff81111562000f1d5762000f1d62000b5f565b62000f358162000f2e845462000de6565b8462000eab565b602080601f83116001811462000f6d576000841562000f545750858301515b600019600386901b1c1916600185901b17855562000ef7565b600085815260208120601f198616915b8281101562000f9e5788860151825594840194600190910190840162000f7d565b508582101562000fbd5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b038616815260a06020820181905260009062000ff39083018762000ca3565b828103604084015262001007818762000ca3565b905082810360608401526200101d818662000ca3565b9050828103608084015262001033818562000ca3565b98975050505050505050565b6000602082840312156200105257600080fd5b8151801515811462000c7657600080fdfe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212200fea5736ecebd6f4f71e77a0743e7169bb21209a84517a64d4e0a6b0313817b864736f6c6343000817003360806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212206ff38700c73b602455dbb7964f2d3281f62efc77263f0f3bdb67f5e4ee5d4f3f64736f6c63430008170033a2646970667358221220d058cf8dfb17169ff3320b4ba2cb9665d5f875cda19c5c22351f341d783cad4064736f6c63430008170033" +access(all) let compiledFactoryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6113cd806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004610fe2565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d610138366004611034565b6102bc565b005b61015261014d366004611034565b6102ef565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004610fe2565b6106df565b61013d610710565b61013d61019c366004610fe2565b610724565b6000546001600160a01b031661010d565b61013d6101c0366004611051565b610826565b6101d86101d3366004611034565b61093f565b60405161012191906110f3565b61013d6101f3366004611051565b6109b2565b610152610206366004611034565b610a83565b61010d610219366004611106565b610af9565b61015261022c366004611034565b610bce565b61013d61023f366004611034565b610c3d565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc906102759085906004016110f3565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b691906111fb565b92915050565b6102c4610c7b565b6102cd81610ca8565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b038616916103359190611218565b600060405180830381855afa9150503d8060008114610370576040519150601f19603f3d011682016040523d82523d6000602084013e610375565b606091505b509150915081158061038657508051155b15610395575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b179052516103e29190611218565b600060405180830381855afa9150503d806000811461041d576040519150601f19603f3d011682016040523d82523d6000602084013e610422565b606091505b50909250905081158061043457508051155b15610443575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104979190611218565b600060405180830381855afa9150503d80600081146104d2576040519150601f19603f3d011682016040523d82523d6000602084013e6104d7565b606091505b5090925090508115806104e957508051155b156104f8575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161053691611218565b600060405180830381855afa9150503d8060008114610571576040519150601f19603f3d011682016040523d82523d6000602084013e610576565b606091505b50909250905081158061058857508051155b15610597575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b038616916105d591611218565b600060405180830381855afa9150503d8060008114610610576040519150601f19603f3d011682016040523d82523d6000602084013e610615565b606091505b50909250905081158061062757508051155b15610636575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b0386169161067491611218565b600060405180830381855afa9150503d80600081146106af576040519150601f19603f3d011682016040523d82523d6000602084013e6106b4565b606091505b5090925090508115806106c657508051155b156106d5575060009392505050565b5060019392505050565b60006002826040516106f19190611218565b908152604051908190036020019020546001600160a01b031692915050565b610718610c7b565b6107226000610d1a565b565b61072c610c7b565b600060028260405161073e9190611218565b908152604051908190036020019020546001600160a01b03169050806107be5760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b6002826040516107ce9190611218565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b9061081a9084908490611234565b60405180910390a15050565b61082e610c7b565b61083781610d6a565b60006001600160a01b03166002836040516108529190611218565b908152604051908190036020019020546001600160a01b0316146108cf5760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107b5565b806002836040516108e09190611218565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f9061081a9084908490611234565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa15801561098a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b6919081019061125e565b6109ba610c7b565b6109c381610d6a565b60006002836040516109d59190611218565b908152604051908190036020019020546001600160a01b0316905080610a04576109ff8383610826565b505050565b81600284604051610a159190611218565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610a76908590849086906112d5565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610aed575060408051601f3d908101601f19168201909252610aea91810190611308565b60015b6102b657506000919050565b6000610b03610c7b565b6000600288604051610b159190611218565b908152604051908190036020019020546001600160a01b03169050610b3981610d6a565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610b72908c908c908c908c908c9060040161132a565b6020604051808303816000875af1158015610b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb591906111fb565b9050610bc18682610ddc565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611308565b610c45610c7b565b6001600160a01b038116610c6f57604051631e4fbdf760e01b8152600060048201526024016107b5565b610c7881610d1a565b50565b6000546001600160a01b031633146107225760405163118cdaa760e01b81523360048201526024016107b5565b610cb181610e47565b610cc28163976998cb60e01b610e9d565b610c785760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107b5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610d7381610e47565b610d848163476d399760e01b610e9d565b610c785760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107b5565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e109086908690600401611234565b600060405180830381600087803b158015610e2a57600080fd5b505af1158015610e3e573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610c785760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107b5565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f0a575060408051601f3d908101601f19168201909252610f0791810190611308565b60015b610f16575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610f5c57610f5c610f1d565b604052919050565b600067ffffffffffffffff821115610f7e57610f7e610f1d565b50601f01601f191660200190565b600082601f830112610f9d57600080fd5b8135610fb0610fab82610f64565b610f33565b818152846020838601011115610fc557600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215610ff457600080fd5b813567ffffffffffffffff81111561100b57600080fd5b61101784828501610f8c565b949350505050565b6001600160a01b0381168114610c7857600080fd5b60006020828403121561104657600080fd5b8135610f168161101f565b6000806040838503121561106457600080fd5b823567ffffffffffffffff81111561107b57600080fd5b61108785828601610f8c565b92505060208301356110988161101f565b809150509250929050565b60005b838110156110be5781810151838201526020016110a6565b50506000910152565b600081518084526110df8160208601602086016110a3565b601f01601f19169290920160200192915050565b602081526000610f1660208301846110c7565b60008060008060008060c0878903121561111f57600080fd5b863567ffffffffffffffff8082111561113757600080fd5b6111438a838b01610f8c565b9750602089013591508082111561115957600080fd5b6111658a838b01610f8c565b9650604089013591508082111561117b57600080fd5b6111878a838b01610f8c565b9550606089013591508082111561119d57600080fd5b6111a98a838b01610f8c565b945060808901359150808211156111bf57600080fd5b6111cb8a838b01610f8c565b935060a08901359150808211156111e157600080fd5b506111ee89828a01610f8c565b9150509295509295509295565b60006020828403121561120d57600080fd5b8151610f168161101f565b6000825161122a8184602087016110a3565b9190910192915050565b60408152600061124760408301856110c7565b905060018060a01b03831660208301529392505050565b60006020828403121561127057600080fd5b815167ffffffffffffffff81111561128757600080fd5b8201601f8101841361129857600080fd5b80516112a6610fab82610f64565b8181528560208385010111156112bb57600080fd5b6112cc8260208301602086016110a3565b95945050505050565b6060815260006112e860608301866110c7565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561131a57600080fd5b81518015158114610f1657600080fd5b60a08152600061133d60a08301886110c7565b828103602084015261134f81886110c7565b9050828103604084015261136381876110c7565b9050828103606084015261137781866110c7565b9050828103608084015261138b81856110c7565b9897505050505050505056fea264697066735822122091fccc6734718ef21c20a3579176410521061d6cceb595794bd2fe0fecbff25f64736f6c63430008170033" + +access(all) let erc20DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212202d573cf4820d94ed241f7d0352db0bcd8eb3161e4cecdd44be2ef4266796a2ed64736f6c63430008170033a26469706673582212207e3abd727ba0dcf3a95051385c15199c608b02d4bd6f0ebea00574a2d1e370df64736f6c63430008170033" + +access(all) let erc721DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612657806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d3660046200043c565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c93660046200051a565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a7565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005fc565b620002bf565b6200010662000142366004620005fc565b6200036b565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b031633146200020b576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a204f6e60448201527f6c792064656c656761746564206465706c6f7965722063616e206465706c6f7960648201526084015b60405180910390fd5b600080546001600160a01b031687878787876040516200022b906200042e565b6200023c969594939291906200066f565b604051809103906000f08015801562000259573d6000803e3d6000fd5b5090507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f0818888888860405162000295959493929190620006f8565b60405180910390a19695505050505050565b620002b1620003af565b620002bd6000620003de565b565b620002c9620003af565b6001600160a01b03811662000349576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a20496e60448201527f76616c69642064656c656761746564206465706c6f7965722061646472657373606482015260840162000202565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000375620003af565b6001600160a01b038116620003a157604051631e4fbdf760e01b81526000600482015260240162000202565b620003ac81620003de565b50565b6000546001600160a01b03163314620002bd5760405163118cdaa760e01b815233600482015260240162000202565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611eb7806200076b83390190565b6000602082840312156200044f57600080fd5b81356001600160e01b0319811681146200046857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049757600080fd5b813567ffffffffffffffff80821115620004b557620004b56200046f565b604051601f8301601f19908116603f01168101908282118183101715620004e057620004e06200046f565b81604052838152866020858801011115620004fa57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200053357600080fd5b853567ffffffffffffffff808211156200054c57600080fd5b6200055a89838a0162000485565b965060208801359150808211156200057157600080fd5b6200057f89838a0162000485565b955060408801359150808211156200059657600080fd5b620005a489838a0162000485565b94506060880135915080821115620005bb57600080fd5b620005c989838a0162000485565b93506080880135915080821115620005e057600080fd5b50620005ef8882890162000485565b9150509295509295909350565b6000602082840312156200060f57600080fd5b81356001600160a01b03811681146200046857600080fd5b6000815180845260005b818110156200064f5760208185018101518683018201520162000631565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006959083018862000627565b8281036040840152620006a9818862000627565b90508281036060840152620006bf818762000627565b90508281036080840152620006d5818662000627565b905082810360a0840152620006eb818562000627565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071e9083018762000627565b828103604084015262000732818762000627565b9050828103606084015262000748818662000627565b905082810360808401526200075e818562000627565b9897505050505050505056fe60806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea2646970667358221220e5b8da7e9f5a8ba0772457fe42d9f13eb90dec0ad70a92e30ac8d5ecd317e92f64736f6c63430008170033a2646970667358221220185b564932a6fb2d0066082694692d9d4ee875e9f7e2bfe408bdf1b3079817e764736f6c63430008170033" + +access(all) let registryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610058565b50600080546001600160a01b031916331790556100aa565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6108a5806100b96000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063862119ae11610071578063862119ae146101315780638da5cb5b14610144578063a6de610514610155578063b3d5dbdc14610168578063f2fde38b14610188578063faab9d391461019b57600080fd5b806301ffc9a7146100ae57806304433bbc146100d65780632b20e39714610101578063522791d114610114578063715018a614610129575b600080fd5b6100c16100bc36600461051c565b6101ae565b60405190151581526020015b60405180910390f35b6100e96100e43660046105f0565b6101e5565b6040516001600160a01b0390911681526020016100cd565b6000546100e9906001600160a01b031681565b610127610122366004610649565b610216565b005b6101276102b7565b6100c161013f3660046105f0565b6102cb565b6003546001600160a01b03166100e9565b6100c1610163366004610697565b610308565b61017b610176366004610697565b610334565b6040516100cd91906106d6565b610127610196366004610697565b6103e0565b6101276101a9366004610697565b61041e565b60006001600160e01b0319821663976998cb60e01b14806101df57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60006001826040516101f79190610709565b908152604051908190036020019020546001600160a01b031692915050565b6000546001600160a01b031633146102a95760405162461bcd60e51b815260206004820152604560248201527f466c6f774272696467654465706c6f796d656e7452656769737472793a204f6e60448201527f6c79207265676973747261722063616e207265676973746572206173736f636960648201526430ba34b7b760d91b608482015260a4015b60405180910390fd5b6102b38282610444565b5050565b6102bf61049d565b6102c960006104ca565b565b6000806001600160a01b03166001836040516102e79190610709565b908152604051908190036020019020546001600160a01b0316141592915050565b6001600160a01b0381166000908152600260205260408120805461032b90610725565b15159392505050565b6001600160a01b038116600090815260026020526040902080546060919061035b90610725565b80601f016020809104026020016040519081016040528092919081815260200182805461038790610725565b80156103d45780601f106103a9576101008083540402835291602001916103d4565b820191906000526020600020905b8154815290600101906020018083116103b757829003601f168201915b50505050509050919050565b6103e861049d565b6001600160a01b03811661041257604051631e4fbdf760e01b8152600060048201526024016102a0565b61041b816104ca565b50565b61042661049d565b600080546001600160a01b0319166001600160a01b03831617905550565b806001836040516104559190610709565b908152604080516020928190038301902080546001600160a01b0319166001600160a01b03948516179055918316600090815260029091522061049883826107af565b505050565b6003546001600160a01b031633146102c95760405163118cdaa760e01b81523360048201526024016102a0565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006020828403121561052e57600080fd5b81356001600160e01b03198116811461054657600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261057457600080fd5b813567ffffffffffffffff8082111561058f5761058f61054d565b604051601f8301601f19908116603f011681019082821181831017156105b7576105b761054d565b816040528381528660208588010111156105d057600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561060257600080fd5b813567ffffffffffffffff81111561061957600080fd5b61062584828501610563565b949350505050565b80356001600160a01b038116811461064457600080fd5b919050565b6000806040838503121561065c57600080fd5b823567ffffffffffffffff81111561067357600080fd5b61067f85828601610563565b92505061068e6020840161062d565b90509250929050565b6000602082840312156106a957600080fd5b6105468261062d565b60005b838110156106cd5781810151838201526020016106b5565b50506000910152565b60208152600082518060208401526106f58160408501602087016106b2565b601f01601f19169190910160400192915050565b6000825161071b8184602087016106b2565b9190910192915050565b600181811c9082168061073957607f821691505b60208210810361075957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610498576000816000526020600020601f850160051c810160208610156107885750805b601f850160051c820191505b818110156107a757828155600101610794565b505050505050565b815167ffffffffffffffff8111156107c9576107c961054d565b6107dd816107d78454610725565b8461075f565b602080601f83116001811461081257600084156107fa5750858301515b600019600386901b1c1916600185901b1785556107a7565b600085815260208120601f198616915b8281101561084157888601518255948401946001909101908401610822565b508582101561085f5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212204229c8738eb6a99e2fe8a2cd0be82f006719cf059ff7c5b2f748353eb7c5da4c64736f6c63430008170033" access(all) let compiledERC721Bytecode = "60806040523480156200001157600080fd5b5033604051806040016040528060048152602001634e414d4560e01b8152506040518060400160405280600681526020016514d6535093d360d21b8152508160009081620000609190620001ac565b5060016200006f8282620001ac565b5050506001600160a01b038116620000a157604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b620000ac81620000b3565b5062000278565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200013057607f821691505b6020821081036200015157634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620001a7576000816000526020600020601f850160051c81016020861015620001825750805b601f850160051c820191505b81811015620001a3578281556001016200018e565b5050505b505050565b81516001600160401b03811115620001c857620001c862000105565b620001e081620001d984546200011b565b8462000157565b602080601f831160018114620002185760008415620001ff5750858301515b600019600386901b1c1916600185901b178555620001a3565b600085815260208120601f198616915b82811015620002495788860151825594840194600190910190840162000228565b5085821015620002685787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61143080620002886000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c8063715018a6116100a2578063b88d4fde11610071578063b88d4fde14610239578063c87b56dd1461024c578063cd279c7c1461025f578063e985e9c514610272578063f2fde38b1461028557600080fd5b8063715018a6146102055780638da5cb5b1461020d57806395d89b411461021e578063a22cb4651461022657600080fd5b806323b872dd116100e957806323b872dd1461019857806342842e0e146101ab57806342966c68146101be5780636352211e146101d157806370a08231146101e457600080fd5b806301ffc9a71461011b57806306fdde0314610143578063081812fc14610158578063095ea7b314610183575b600080fd5b61012e610129366004610f0f565b610298565b60405190151581526020015b60405180910390f35b61014b6102a9565b60405161013a9190610f7c565b61016b610166366004610f8f565b61033b565b6040516001600160a01b03909116815260200161013a565b610196610191366004610fc4565b610364565b005b6101966101a6366004610fee565b610373565b6101966101b9366004610fee565b610403565b6101966101cc366004610f8f565b610423565b61016b6101df366004610f8f565b61042f565b6101f76101f236600461102a565b61043a565b60405190815260200161013a565b610196610482565b6007546001600160a01b031661016b565b61014b610496565b610196610234366004611045565b6104a5565b61019661024736600461110d565b6104b0565b61014b61025a366004610f8f565b6104c7565b61019661026d366004611189565b6104d2565b61012e6102803660046111f4565b6104ee565b61019661029336600461102a565b61051c565b60006102a38261055a565b92915050565b6060600080546102b890611227565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611227565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b5050505050905090565b60006103468261057f565b506000828152600460205260409020546001600160a01b03166102a3565b61036f8282336105b8565b5050565b6001600160a01b0382166103a257604051633250574960e11b8152600060048201526024015b60405180910390fd5b60006103af8383336105c5565b9050836001600160a01b0316816001600160a01b0316146103fd576040516364283d7b60e01b81526001600160a01b0380861660048301526024820184905282166044820152606401610399565b50505050565b61041e838383604051806020016040528060008152506104b0565b505050565b61036f600082336105c5565b60006102a38261057f565b60006001600160a01b038216610466576040516322718ad960e21b815260006004820152602401610399565b506001600160a01b031660009081526003602052604090205490565b61048a6106be565b61049460006106eb565b565b6060600180546102b890611227565b61036f33838361073d565b6104bb848484610373565b6103fd848484846107dc565b60606102a382610905565b6104da6106be565b6104e48383610a16565b61041e8282610a30565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6105246106be565b6001600160a01b03811661054e57604051631e4fbdf760e01b815260006004820152602401610399565b610557816106eb565b50565b60006001600160e01b03198216632483248360e11b14806102a357506102a382610a80565b6000818152600260205260408120546001600160a01b0316806102a357604051637e27328960e01b815260048101849052602401610399565b61041e8383836001610ad0565b6000828152600260205260408120546001600160a01b03908116908316156105f2576105f2818486610bd6565b6001600160a01b038116156106305761060f600085600080610ad0565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b0385161561065f576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6007546001600160a01b031633146104945760405163118cdaa760e01b8152336004820152602401610399565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03821661076f57604051630b61174360e31b81526001600160a01b0383166004820152602401610399565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b156103fd57604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061081e903390889087908790600401611261565b6020604051808303816000875af1925050508015610859575060408051601f3d908101601f191682019092526108569181019061129e565b60015b6108c2573d808015610887576040519150601f19603f3d011682016040523d82523d6000602084013e61088c565b606091505b5080516000036108ba57604051633250574960e11b81526001600160a01b0385166004820152602401610399565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b146108fe57604051633250574960e11b81526001600160a01b0385166004820152602401610399565b5050505050565b60606109108261057f565b506000828152600660205260408120805461092a90611227565b80601f016020809104026020016040519081016040528092919081815260200182805461095690611227565b80156109a35780601f10610978576101008083540402835291602001916109a3565b820191906000526020600020905b81548152906001019060200180831161098657829003601f168201915b5050505050905060006109c160408051602081019091526000815290565b905080516000036109d3575092915050565b815115610a055780826040516020016109ed9291906112bb565b60405160208183030381529060405292505050919050565b610a0e84610c3a565b949350505050565b61036f828260405180602001604052806000815250610caf565b6000828152600660205260409020610a48828261133a565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b60006001600160e01b031982166380ac58cd60e01b1480610ab157506001600160e01b03198216635b5e139f60e01b145b806102a357506301ffc9a760e01b6001600160e01b03198316146102a3565b8080610ae457506001600160a01b03821615155b15610ba6576000610af48461057f565b90506001600160a01b03831615801590610b205750826001600160a01b0316816001600160a01b031614155b8015610b335750610b3181846104ee565b155b15610b5c5760405163a9fbf51f60e01b81526001600160a01b0384166004820152602401610399565b8115610ba45783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b610be1838383610cc6565b61041e576001600160a01b038316610c0f57604051637e27328960e01b815260048101829052602401610399565b60405163177e802f60e01b81526001600160a01b038316600482015260248101829052604401610399565b6060610c458261057f565b506000610c5d60408051602081019091526000815290565b90506000815111610c7d5760405180602001604052806000815250610ca8565b80610c8784610d29565b604051602001610c989291906112bb565b6040516020818303038152906040525b9392505050565b610cb98383610dbc565b61041e60008484846107dc565b60006001600160a01b03831615801590610a0e5750826001600160a01b0316846001600160a01b03161480610d005750610d0084846104ee565b80610a0e5750506000908152600460205260409020546001600160a01b03908116911614919050565b60606000610d3683610e21565b600101905060008167ffffffffffffffff811115610d5657610d56611081565b6040519080825280601f01601f191660200182016040528015610d80576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610d8a57509392505050565b6001600160a01b038216610de657604051633250574960e11b815260006004820152602401610399565b6000610df4838360006105c5565b90506001600160a01b0381161561041e576040516339e3563760e11b815260006004820152602401610399565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610e605772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610e8c576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610eaa57662386f26fc10000830492506010015b6305f5e1008310610ec2576305f5e100830492506008015b6127108310610ed657612710830492506004015b60648310610ee8576064830492506002015b600a83106102a35760010192915050565b6001600160e01b03198116811461055757600080fd5b600060208284031215610f2157600080fd5b8135610ca881610ef9565b60005b83811015610f47578181015183820152602001610f2f565b50506000910152565b60008151808452610f68816020860160208601610f2c565b601f01601f19169290920160200192915050565b602081526000610ca86020830184610f50565b600060208284031215610fa157600080fd5b5035919050565b80356001600160a01b0381168114610fbf57600080fd5b919050565b60008060408385031215610fd757600080fd5b610fe083610fa8565b946020939093013593505050565b60008060006060848603121561100357600080fd5b61100c84610fa8565b925061101a60208501610fa8565b9150604084013590509250925092565b60006020828403121561103c57600080fd5b610ca882610fa8565b6000806040838503121561105857600080fd5b61106183610fa8565b91506020830135801515811461107657600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156110b2576110b2611081565b604051601f8501601f19908116603f011681019082821181831017156110da576110da611081565b816040528093508581528686860111156110f357600080fd5b858560208301376000602087830101525050509392505050565b6000806000806080858703121561112357600080fd5b61112c85610fa8565b935061113a60208601610fa8565b925060408501359150606085013567ffffffffffffffff81111561115d57600080fd5b8501601f8101871361116e57600080fd5b61117d87823560208401611097565b91505092959194509250565b60008060006060848603121561119e57600080fd5b6111a784610fa8565b925060208401359150604084013567ffffffffffffffff8111156111ca57600080fd5b8401601f810186136111db57600080fd5b6111ea86823560208401611097565b9150509250925092565b6000806040838503121561120757600080fd5b61121083610fa8565b915061121e60208401610fa8565b90509250929050565b600181811c9082168061123b57607f821691505b60208210810361125b57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061129490830184610f50565b9695505050505050565b6000602082840312156112b057600080fd5b8151610ca881610ef9565b600083516112cd818460208801610f2c565b8351908301906112e1818360208801610f2c565b01949350505050565b601f82111561041e576000816000526020600020601f850160051c810160208610156113135750805b601f850160051c820191505b818110156113325782815560010161131f565b505050505050565b815167ffffffffffffffff81111561135457611354611081565b611368816113628454611227565b846112ea565b602080601f83116001811461139d57600084156113855750858301515b600019600386901b1c1916600185901b178555611332565b600085815260208120601f198616915b828110156113cc578886015182559484019460019091019084016113ad565b50858210156113ea5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea264697066735822122046da1d9cfc7c225e4655204f464e2ecbb316a6284c51c9c338433a1abb5919f864736f6c63430008170033" @@ -89,6 +95,21 @@ fun getCompiledFactoryBytecode(): String { return compiledFactoryBytecode } +access(all) +fun getERC20DeployerBytecode(): String { + return erc20DeployerBytecode +} + +access(all) +fun getERC721DeployerBytecode(): String { + return erc721DeployerBytecode +} + +access(all) +fun getRegistryBytecode(): String { + return registryBytecode +} + access(all) fun getCompiledERC721Bytecode(): String { return compiledERC721Bytecode diff --git a/cadence/transactions/bridge/admin/evm/claim_accessor_capability_and_save_router.cdc b/cadence/transactions/bridge/admin/evm-integration/claim_accessor_capability_and_save_router.cdc similarity index 100% rename from cadence/transactions/bridge/admin/evm/claim_accessor_capability_and_save_router.cdc rename to cadence/transactions/bridge/admin/evm-integration/claim_accessor_capability_and_save_router.cdc diff --git a/cadence/transactions/bridge/admin/evm/set_registrar.cdc b/cadence/transactions/bridge/admin/evm/set_registrar.cdc new file mode 100644 index 00000000..7b7fe326 --- /dev/null +++ b/cadence/transactions/bridge/admin/evm/set_registrar.cdc @@ -0,0 +1,36 @@ +import "EVM" + +import "EVMUtils" + +/// Sets the registrar address for the provided FlowBridgeDeploymentRegistry address. Should be called by the owner of +/// the registry contract. +/// +/// @param registryEVMAddressHex The EVM address of the FlowBridgeDeploymentRegistry contract. +/// @param registrarEVMAddressHex The EVM address of the registrar contract. +/// +transaction(registryEVMAddressHex: String, registrarEVMAddressHex: String) { + + let coa: auth(Call) &CadenceOwnedAccount + + prepare(signer: auth(BorrowValue) &Account) { + self.coa = signer.storage.borrow(from: /storage/evm) + ?? panic("Could not borrow COA from provided gateway address") + } + + execute { + let registryEVMAddress = EVMUtils.getEVMAddressFromHexString(address: registryEVMAddressHex) + ?? panic("Could not convert registry address to EVM address") + let registrarEVMAddress = EVMUtils.getEVMAddressFromHexString(address: registrarEVMAddressHex) + ?? panic("Could not convert registrar address to EVM address") + + self.coa.call( + to: registryEVMAddress, + data: EVM.encodeABIWithSignature( + "setRegistrar(address)", + [registrarEVMAddress] + ), + gasLimit: 15_000_000, + value: EVM.Balance(attoflow: 0) + ) + } +} diff --git a/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol b/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol index c30e57ca..f4e18a0b 100644 --- a/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol +++ b/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol @@ -56,9 +56,9 @@ abstract contract FlowEVMDeploymentRegistry is IFlowEVMDeploymentRegistry, ERC16 /** * @dev Check if a contract address is a registered deployment * - * @param contractAddr The address of the deployed contract in question + * @param cadenceIdentifier The Cadence type identifier in question * - * @return True if the contract address is associated with a Cadence type identifier + * @return True if the contract address is associated with a Cadence type identifier as a registered deployment */ function isRegisteredDeployment(string memory cadenceIdentifier) external view returns (bool) { return cadenceIdentifierToContract[cadenceIdentifier] != address(0); @@ -69,7 +69,7 @@ abstract contract FlowEVMDeploymentRegistry is IFlowEVMDeploymentRegistry, ERC16 * * @param contractAddr The address of the contract in question * - * @return True if the contract address is associated with a Cadence type identifier + * @return True if the contract address is associated with a Cadence type identifier as a registered deployment */ function isRegisteredDeployment(address contractAddr) external view returns (bool) { return bytes(contractToCadenceIdentifier[contractAddr]).length != 0; From 15d1a454d4e26d9a5549be77b17cab49c1fe67cd Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 3 May 2024 19:47:41 -0500 Subject: [PATCH 04/18] add .sol integration Cadence txns & add to bridge test setup --- cadence/tests/flow_evm_bridge_tests.cdc | 70 ++++++++++++++++--- .../bridge/admin/evm/add_deployer.cdc | 30 ++++++++ .../admin/evm/set_delegated_deployer.cdc | 30 ++++++++ .../admin/evm/set_deployment_registry.cdc | 30 ++++++++ .../bridge/admin/evm/set_registrar.cdc | 11 ++- solidity/src/FlowBridgeFactory.sol | 5 +- 6 files changed, 159 insertions(+), 17 deletions(-) create mode 100644 cadence/transactions/bridge/admin/evm/add_deployer.cdc create mode 100644 cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc create mode 100644 cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc diff --git a/cadence/tests/flow_evm_bridge_tests.cdc b/cadence/tests/flow_evm_bridge_tests.cdc index ff81b13f..28a7a290 100644 --- a/cadence/tests/flow_evm_bridge_tests.cdc +++ b/cadence/tests/flow_evm_bridge_tests.cdc @@ -28,6 +28,11 @@ access(all) var mintedNFTID: UInt64 = 0 access(all) let exampleTokenIdentifier = "A.0000000000000010.ExampleToken.Vault" access(all) let exampleTokenMintAmount = 100.0 +// Bridge-related EVM contract values +access(all) var registryAddressHex: String = "" +access(all) var erc20DeployerAddressHex: String = "" +access(all) var erc721DeployerAddressHex: String = "" + // ERC721 values access(all) var erc721AddressHex: String = "" access(all) let erc721Name = "NAME" @@ -127,40 +132,55 @@ fun setup() { arguments: [] ) Test.expect(err, Test.beNil()) + // Deploy registry let registryDeploymentResult = executeTransaction( "../transactions/evm/deploy.cdc", - [getRegistryBytecode(), 15_000_000, 0.0], + [getRegistryBytecode(), UInt64(15_000_000), 0.0], bridgeAccount ) Test.expect(registryDeploymentResult, Test.beSucceeded()) // Deploy ERC20Deployer let erc20DeployerDeploymentResult = executeTransaction( "../transactions/evm/deploy.cdc", - [getERC20DeployerBytecode(), 15_000_000, 0.0], + [getERC20DeployerBytecode(), UInt64(15_000_000), 0.0], bridgeAccount ) Test.expect(erc20DeployerDeploymentResult, Test.beSucceeded()) // Deploy ERC721Deployer let erc721DeployerDeploymentResult = executeTransaction( "../transactions/evm/deploy.cdc", - [getERC721DeployerBytecode(), 15_000_000, 0.0], + [getERC721DeployerBytecode(), UInt64(15_000_000), 0.0], bridgeAccount ) Test.expect(erc721DeployerDeploymentResult, Test.beSucceeded()) + // Assign contract addresses var evts = Test.eventsOfType(Type()) - Test.assertEqual(2, evts.length) + Test.assertEqual(5, evts.length) + let registryDeploymentEvent = evts[2] as! EVM.TransactionExecuted + let erc20DeployerDeploymentEvent = evts[3] as! EVM.TransactionExecuted + let erc721DeployerDeploymentEvent = evts[4] as! EVM.TransactionExecuted + registryAddressHex = registryDeploymentEvent.contractAddress.slice(from: 2, upTo: registryDeploymentEvent.contractAddress.length).toLower() + erc20DeployerAddressHex = erc20DeployerDeploymentEvent.contractAddress.slice(from: 2, upTo: erc20DeployerDeploymentEvent.contractAddress.length).toLower() + erc721DeployerAddressHex = erc721DeployerDeploymentEvent.contractAddress.slice(from: 2, upTo: erc721DeployerDeploymentEvent.contractAddress.length).toLower() + Test.assertEqual(registryAddressHex.length, 40) + Test.assertEqual(erc20DeployerAddressHex.length, 40) + Test.assertEqual(erc721DeployerAddressHex.length, 40) + + // Deploy factory let deploymentResult = executeTransaction( "../transactions/evm/deploy.cdc", [getCompiledFactoryBytecode(), UInt64(15_000_000), 0.0], bridgeAccount ) Test.expect(deploymentResult, Test.beSucceeded()) + // Assign the factory contract address evts = Test.eventsOfType(Type()) - Test.assertEqual(3, evts.length) - let factoryDeploymentEvent = evts[2] as! EVM.TransactionExecuted + Test.assertEqual(6, evts.length) + let factoryDeploymentEvent = evts[5] as! EVM.TransactionExecuted + let factoryAddressHex = factoryDeploymentEvent.contractAddress.slice(from: 2, upTo: factoryDeploymentEvent.contractAddress.length).toLower() + Test.assertEqual(factoryAddressHex.length, 40) - let factoryAddressHex = factoryDeploymentEvent.contractAddress err = Test.deployContract( name: "FlowEVMBridgeUtils", path: "../contracts/bridge/FlowEVMBridgeUtils.cdc", @@ -168,16 +188,46 @@ fun setup() { ) // Set factory as registrar in registry let setRegistrarResult = executeTransaction( - "../transactions/evm/set_registrar.cdc", - [registryDeploymentResult.events[0].data as! Address], + "../transactions/bridge/admin/evm/set_registrar.cdc", + [registryAddressHex, factoryAddressHex], bridgeAccount ) + Test.expect(setRegistrarResult, Test.beSucceeded()) // Set registry as registry in factory + let setRegistryResult = executeTransaction( + "../transactions/bridge/admin/evm/set_deployment_registry.cdc", + [registryAddressHex], + bridgeAccount + ) + Test.expect(setRegistryResult, Test.beSucceeded()) // Set factory as delegatedDeployer in erc20Deployer + var setDelegatedDeployerResult = executeTransaction( + "../transactions/bridge/admin/evm/set_delegated_deployer.cdc", + [erc20DeployerAddressHex], + bridgeAccount + ) + Test.expect(setDelegatedDeployerResult, Test.beSucceeded()) // Set factory as delegatedDeployer in erc721Deployer + setDelegatedDeployerResult = executeTransaction( + "../transactions/bridge/admin/evm/set_delegated_deployer.cdc", + [erc721DeployerAddressHex], + bridgeAccount + ) + Test.expect(setDelegatedDeployerResult, Test.beSucceeded()) // add erc20Deployer under "ERC20" tag to factory + var addDeployerResult = executeTransaction( + "../transactions/bridge/admin/evm/add_deployer.cdc", + ["ERC20", erc20DeployerAddressHex], + bridgeAccount + ) + Test.expect(addDeployerResult, Test.beSucceeded()) // add erc721Deployer under "ERC721" tag to factory - Test.expect(err, Test.beNil()) + addDeployerResult = executeTransaction( + "../transactions/bridge/admin/evm/add_deployer.cdc", + ["ERC721", erc721DeployerAddressHex], + bridgeAccount + ) + Test.expect(addDeployerResult, Test.beSucceeded()) err = Test.deployContract( name: "FlowEVMBridgeNFTEscrow", path: "../contracts/bridge/FlowEVMBridgeNFTEscrow.cdc", diff --git a/cadence/transactions/bridge/admin/evm/add_deployer.cdc b/cadence/transactions/bridge/admin/evm/add_deployer.cdc new file mode 100644 index 00000000..0987524c --- /dev/null +++ b/cadence/transactions/bridge/admin/evm/add_deployer.cdc @@ -0,0 +1,30 @@ +import "EVM" + +import "EVMUtils" +import "FlowEVMBridgeUtils" + +transaction(deployerTag: String, deployerEVMAddressHex: String) { + + let coa: auth(Call) &CadenceOwnedAccount + + prepare(signer: auth(BorrowValue) &Account) { + self.coa = signer.storage.borrow(from: /storage/evm) + ?? panic("Could not borrow COA from provided gateway address") + } + + execute { + let deployerEVMAddress = EVMUtils.getEVMAddressFromHexString(address: deployerEVMAddressHex) + ?? panic("Could not convert deployer contract address to EVM address") + + let callResult = self.coa.call( + to: FlowEVMBridgeUtils.bridgeFactoryEVMAddress, + data: EVM.encodeABIWithSignature( + "addDeployer(string, address)", + [deployerTag, deployerEVMAddress] + ), + gasLimit: 15_000_000, + value: EVM.Balance(attoflow: 0) + ) + assert(callResult.success == EVM.Status.successful, message: "Failed to add deployer") + } +} diff --git a/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc b/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc new file mode 100644 index 00000000..1f0448d6 --- /dev/null +++ b/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc @@ -0,0 +1,30 @@ +import "EVM" + +import "EVMUtils" +import "FlowEVMBridgeUtils" + +transaction(deployerEVMAddressHex: String, delegatedEVMAddressHex: String) { + + let coa: auth(Call) &CadenceOwnedAccount + + prepare(signer: auth(BorrowValue) &Account) { + self.coa = signer.storage.borrow(from: /storage/evm) + ?? panic("Could not borrow COA from provided gateway address") + } + + execute { + let deployerEVMAddress = EVMUtils.getEVMAddressFromHexString(address: deployerEVMAddressHex) + ?? panic("Could not convert deployer contract address to EVM address") + + let callResult = self.coa.call( + to: deployerEVMAddress, + data: EVM.encodeABIWithSignature( + "setDelegatedDeployer(address)", + [FlowEVMBridgeUtils.bridgeFactoryEVMAddress] + ), + gasLimit: 15_000_000, + value: EVM.Balance(attoflow: 0) + ) + assert(callResult.success == EVM.Status.successful, message: "Failed to set delegated deployer") + } +} diff --git a/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc b/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc new file mode 100644 index 00000000..e4067987 --- /dev/null +++ b/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc @@ -0,0 +1,30 @@ +import "EVM" + +import "EVMUtils" +import "FlowEVMBridgeUtils" + +transaction(registryEVMAddressHex: String) { + + let coa: auth(Call) &CadenceOwnedAccount + + prepare(signer: auth(BorrowValue) &Account) { + self.coa = signer.storage.borrow(from: /storage/evm) + ?? panic("Could not borrow COA from provided gateway address") + } + + execute { + let registryEVMAddress = EVMUtils.getEVMAddressFromHexString(address: registryEVMAddressHex) + ?? panic("Could not convert registry address to EVM address") + + let callResult = self.coa.call( + to: FlowEVMBridgeUtils.bridgeFactoryEVMAddress, + data: EVM.encodeABIWithSignature( + "setDeploymentRegistry(address)", + [registryEVMAddress] + ), + gasLimit: 15_000_000, + value: EVM.Balance(attoflow: 0) + ) + assert(callResult.success == EVM.Status.successful, message: "Failed to set delegated deployer") + } +} diff --git a/cadence/transactions/bridge/admin/evm/set_registrar.cdc b/cadence/transactions/bridge/admin/evm/set_registrar.cdc index 7b7fe326..c727b61c 100644 --- a/cadence/transactions/bridge/admin/evm/set_registrar.cdc +++ b/cadence/transactions/bridge/admin/evm/set_registrar.cdc @@ -1,14 +1,14 @@ import "EVM" import "EVMUtils" +import "FlowEVMBridgeUtils" /// Sets the registrar address for the provided FlowBridgeDeploymentRegistry address. Should be called by the owner of /// the registry contract. /// /// @param registryEVMAddressHex The EVM address of the FlowBridgeDeploymentRegistry contract. -/// @param registrarEVMAddressHex The EVM address of the registrar contract. /// -transaction(registryEVMAddressHex: String, registrarEVMAddressHex: String) { +transaction(registryEVMAddressHex: String) { let coa: auth(Call) &CadenceOwnedAccount @@ -20,17 +20,16 @@ transaction(registryEVMAddressHex: String, registrarEVMAddressHex: String) { execute { let registryEVMAddress = EVMUtils.getEVMAddressFromHexString(address: registryEVMAddressHex) ?? panic("Could not convert registry address to EVM address") - let registrarEVMAddress = EVMUtils.getEVMAddressFromHexString(address: registrarEVMAddressHex) - ?? panic("Could not convert registrar address to EVM address") - self.coa.call( + let callResult = self.coa.call( to: registryEVMAddress, data: EVM.encodeABIWithSignature( "setRegistrar(address)", - [registrarEVMAddress] + [FlowEVMBridgeUtils.bridgeFactoryEVMAddress] ), gasLimit: 15_000_000, value: EVM.Balance(attoflow: 0) ) + assert(callResult.success == EVM.Status.successful, message: "Failed to set delegated deployer") } } diff --git a/solidity/src/FlowBridgeFactory.sol b/solidity/src/FlowBridgeFactory.sol index 8cd8e92c..c1e487a3 100644 --- a/solidity/src/FlowBridgeFactory.sol +++ b/solidity/src/FlowBridgeFactory.sol @@ -34,7 +34,7 @@ contract FlowBridgeFactory is Ownable { /** * @dev Emitted when the deployment registry is updated */ - event DeploymentRegistryUpdated(address registryAddress); + event DeploymentRegistryUpdated(address oldAddress, address newAddress); constructor() Ownable(msg.sender) {} @@ -183,6 +183,9 @@ contract FlowBridgeFactory is Ownable { */ function setDeploymentRegistry(address _deploymentRegistry) public onlyOwner { _requireIsValidRegistry(_deploymentRegistry); + + DeploymentRegistryUpdated(deploymentRegistry, _deploymentRegistry); + deploymentRegistry = _deploymentRegistry; } From 85224f49c81e761bc5d3ab8f1745194336906827 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 3 May 2024 20:05:44 -0500 Subject: [PATCH 05/18] fix failing transactions --- cadence/tests/flow_evm_bridge_tests.cdc | 1685 +++++++++-------- .../bridge/admin/evm/add_deployer.cdc | 4 +- .../admin/evm/set_delegated_deployer.cdc | 6 +- .../admin/evm/set_deployment_registry.cdc | 4 +- .../bridge/admin/evm/set_registrar.cdc | 4 +- 5 files changed, 856 insertions(+), 847 deletions(-) diff --git a/cadence/tests/flow_evm_bridge_tests.cdc b/cadence/tests/flow_evm_bridge_tests.cdc index 28a7a290..f1902011 100644 --- a/cadence/tests/flow_evm_bridge_tests.cdc +++ b/cadence/tests/flow_evm_bridge_tests.cdc @@ -181,15 +181,21 @@ fun setup() { let factoryAddressHex = factoryDeploymentEvent.contractAddress.slice(from: 2, upTo: factoryDeploymentEvent.contractAddress.length).toLower() Test.assertEqual(factoryAddressHex.length, 40) + log(factoryAddressHex) + err = Test.deployContract( name: "FlowEVMBridgeUtils", path: "../contracts/bridge/FlowEVMBridgeUtils.cdc", - arguments: [factoryAddressHex.slice(from: 2, upTo: factoryAddressHex.length).toLower()] + arguments: [factoryAddressHex] ) + Test.expect(err, Test.beNil()) + + /* Integrate EVM bridge contract */ + // Set factory as registrar in registry let setRegistrarResult = executeTransaction( "../transactions/bridge/admin/evm/set_registrar.cdc", - [registryAddressHex, factoryAddressHex], + [registryAddressHex], bridgeAccount ) Test.expect(setRegistrarResult, Test.beSucceeded()) @@ -228,6 +234,9 @@ fun setup() { bridgeAccount ) Test.expect(addDeployerResult, Test.beSucceeded()) + + /* End EVM bridge integration txns */ + err = Test.deployContract( name: "FlowEVMBridgeNFTEscrow", path: "../contracts/bridge/FlowEVMBridgeNFTEscrow.cdc", @@ -325,849 +334,849 @@ fun setup() { /* --- ASSET & ACCOUNT SETUP - Configure test accounts with assets to bridge --- */ -access(all) -fun testDeployERC721Succeeds() { - let erc721DeployResult = executeTransaction( - "../transactions/evm/deploy.cdc", - [getCompiledERC721Bytecode(), UInt64(15_000_000), 0.0], - exampleERCAccount - ) - Test.expect(erc721DeployResult, Test.beSucceeded()) +// access(all) +// fun testDeployERC721Succeeds() { +// let erc721DeployResult = executeTransaction( +// "../transactions/evm/deploy.cdc", +// [getCompiledERC721Bytecode(), UInt64(15_000_000), 0.0], +// exampleERCAccount +// ) +// Test.expect(erc721DeployResult, Test.beSucceeded()) - // Get ERC721 & ERC20 deployed contract addresses - let evts = Test.eventsOfType(Type()) - Test.assertEqual(6, evts.length) +// // Get ERC721 & ERC20 deployed contract addresses +// let evts = Test.eventsOfType(Type()) +// Test.assertEqual(6, evts.length) - let erc721DeploymentEvent = evts[5] as! EVM.TransactionExecuted - erc721AddressHex = erc721DeploymentEvent.contractAddress.slice(from: 2, upTo: erc721DeploymentEvent.contractAddress.length).toLower() +// let erc721DeploymentEvent = evts[5] as! EVM.TransactionExecuted +// erc721AddressHex = erc721DeploymentEvent.contractAddress.slice(from: 2, upTo: erc721DeploymentEvent.contractAddress.length).toLower() - Test.assertEqual(40, erc721AddressHex.length) - - log("ERC721 Address: ".concat(erc721AddressHex)) -} - -access(all) -fun testDeployERC20Succeeds() { - let erc20DeployResult = executeTransaction( - "../transactions/evm/deploy.cdc", - [getCompiledERC20Bytecode(), UInt64(15_000_000), 0.0], - exampleERCAccount - ) - Test.expect(erc20DeployResult, Test.beSucceeded()) +// Test.assertEqual(40, erc721AddressHex.length) + +// log("ERC721 Address: ".concat(erc721AddressHex)) +// } + +// access(all) +// fun testDeployERC20Succeeds() { +// let erc20DeployResult = executeTransaction( +// "../transactions/evm/deploy.cdc", +// [getCompiledERC20Bytecode(), UInt64(15_000_000), 0.0], +// exampleERCAccount +// ) +// Test.expect(erc20DeployResult, Test.beSucceeded()) - // Get ERC721 & ERC20 deployed contract addresses - let evts = Test.eventsOfType(Type()) - Test.assertEqual(7, evts.length) +// // Get ERC721 & ERC20 deployed contract addresses +// let evts = Test.eventsOfType(Type()) +// Test.assertEqual(7, evts.length) - let erc20DeploymentEvent = evts[6] as! EVM.TransactionExecuted - erc20AddressHex = erc20DeploymentEvent.contractAddress.slice(from: 2, upTo: erc20DeploymentEvent.contractAddress.length).toLower() +// let erc20DeploymentEvent = evts[6] as! EVM.TransactionExecuted +// erc20AddressHex = erc20DeploymentEvent.contractAddress.slice(from: 2, upTo: erc20DeploymentEvent.contractAddress.length).toLower() - Test.assertEqual(40, erc20AddressHex.length) +// Test.assertEqual(40, erc20AddressHex.length) - log("ERC20 Address: ".concat(erc20AddressHex)) -} - -access(all) -fun testCreateCOASucceeds() { - transferFlow(signer: serviceAccount, recipient: alice.address, amount: 1_000.0) - createCOA(signer: alice, fundingAmount: 100.0) - - let coaAddressHex = getCOAAddressHex(atFlowAddress: alice.address) -} - -access(all) -fun testBridgeFlowToEVMSucceeds() { - // Get $FLOW balances before, making assertions based on values from previous case - let cadenceBalanceBefore = getBalance(ownerAddr: alice.address, storagePathIdentifier: "flowTokenVault") - ?? panic("Problem getting $FLOW balance") - Test.assertEqual(900.0, cadenceBalanceBefore) - - // Get EVM $FLOW balance before - var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - let evmBalanceBefore = getEVMFlowBalance(of: aliceCOAAddressHex) - Test.assertEqual(100.0, evmBalanceBefore) - - // Execute bridge to EVM - let bridgeAmount = 100.0 - bridgeTokensToEVM( - signer: alice, - contractAddr: Address(0x03), - contractName: "FlowToken", - amount: bridgeAmount, - beFailed: false - ) - - // Confirm Alice's token balance is now 0.0 - let cadenceBalanceAfter = getBalance(ownerAddr: alice.address, storagePathIdentifier: "flowTokenVault") - ?? panic("Problem getting $FLOW balance") - Test.assertEqual(cadenceBalanceBefore - bridgeAmount, cadenceBalanceAfter) - - // Confirm balance on EVM side has been updated - let evmBalanceAfter = getEVMFlowBalance(of: aliceCOAAddressHex) - Test.assertEqual(evmBalanceBefore + bridgeAmount, evmBalanceAfter) -} - -access(all) -fun testMintExampleNFTSucceeds() { - let setupCollectionResult = executeTransaction( - "../transactions/example-assets/example-nft/setup_collection.cdc", - [], - alice - ) - Test.expect(setupCollectionResult, Test.beSucceeded()) - - let mintExampleNFTResult = executeTransaction( - "../transactions/example-assets/example-nft/mint_nft.cdc", - [alice.address, exampleNFTTokenName, exampleNFTTokenDescription, exampleNFTTokenThumbnail, [], [], []], - exampleNFTAccount - ) - Test.expect(mintExampleNFTResult, Test.beSucceeded()) - - let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") - Test.assertEqual(1, aliceOwnedIDs.length) - - let events = Test.eventsOfType(Type()) - Test.assertEqual(1, events.length) - let evt = events[0] as! NonFungibleToken.Deposited - mintedNFTID = evt.id - - Test.assertEqual(aliceOwnedIDs[0], mintedNFTID) -} - -access(all) -fun testMintExampleTokenSucceeds() { - let setupVaultResult = executeTransaction( - "../transactions/example-assets/example-token/setup_vault.cdc", - [], - alice - ) - Test.expect(setupVaultResult, Test.beSucceeded()) - - let mintExampleTokenResult = executeTransaction( - "../transactions/example-assets/example-token/mint_tokens.cdc", - [alice.address, exampleTokenMintAmount], - exampleTokenAccount - ) - Test.expect(mintExampleTokenResult, Test.beSucceeded()) - - let aliceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") - ?? panic("Problem getting ExampleToken balance") - Test.assertEqual(exampleTokenMintAmount, aliceBalance) - - let events = Test.eventsOfType(Type()) - let evt = events[events.length - 1] as! FungibleToken.Deposited - - Test.assertEqual(aliceBalance, evt.amount) -} - -access(all) -fun testMintERC721Succeeds() { - let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - Test.assertEqual(40, erc721AddressHex.length) - - let mintERC721Result = executeTransaction( - "../transactions/example-assets/evm-assets/safe_mint_erc721.cdc", - [aliceCOAAddressHex, erc721ID, erc721URI, erc721AddressHex, UInt64(200_000)], - exampleERCAccount - ) - Test.expect(mintERC721Result, Test.beSucceeded()) - - let aliceIsOwner = isOwner(of: erc721ID, ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: erc721AddressHex) - Test.assertEqual(true, aliceIsOwner) -} - -access(all) -fun testMintERC20Succeeds() { - let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - let mintERC20Result = executeTransaction( - "../transactions/example-assets/evm-assets/mint_erc20.cdc", - [aliceCOAAddressHex, erc20MintAmount, erc20AddressHex, UInt64(200_000)], - exampleERCAccount - ) - Test.expect(mintERC20Result, Test.beSucceeded()) - - let aliceBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) - Test.assertEqual(erc20MintAmount, aliceBalance) -} - -access(all) -fun testUpdateBridgeFeesSucceeds() { - fun getFee(feeType: String): UFix64 { - let feeResult = executeScript( - "../scripts/config/get_".concat(feeType).concat(".cdc"), - [] - ) - Test.expect(feeResult, Test.beSucceeded()) - return feeResult.returnValue as! UFix64? ?? panic("Problem getting fee: ".concat(feeType)) - } - - fun calculateBridgeFee(bytesUsed: UInt64): UFix64 { - let calculatedResult = executeScript( - "../scripts/bridge/calculate_bridge_fee.cdc", - [bytesUsed] - ) - Test.expect(calculatedResult, Test.beSucceeded()) - return calculatedResult.returnValue as! UFix64? ?? panic("Problem getting calculated fee") - } - - let bytesUsed: UInt64 = 1024 - let expectedFinalFee = FlowStorageFees.storageCapacityToFlow( - FlowStorageFees.convertUInt64StorageBytesToUFix64Megabytes(bytesUsed) - ) + expectedBaseFee - - // Validate the initialized values are set to 0.0 - var actualOnboardFee = getFee(feeType: "onboard_fee") - var actualBaseFee = getFee(feeType: "base_fee") - - Test.assertEqual(0.0, actualOnboardFee) - Test.assertEqual(0.0, actualBaseFee) - - var actualCalculated = calculateBridgeFee(bytesUsed: bytesUsed) - Test.assertEqual(0.0, actualCalculated) - - // Set the fees to new values - let updateOnboardFeeResult = executeTransaction( - "../transactions/bridge/admin/fee/update_onboard_fee.cdc", - [expectedOnboardFee], - bridgeAccount - ) - Test.expect(updateOnboardFeeResult, Test.beSucceeded()) - let updateBaseFeeResult = executeTransaction( - "../transactions/bridge/admin/fee/update_base_fee.cdc", - [expectedBaseFee], - bridgeAccount - ) - Test.expect(updateBaseFeeResult, Test.beSucceeded()) - - // Validate the values have been updated - actualOnboardFee = getFee(feeType: "onboard_fee") - actualBaseFee = getFee(feeType: "base_fee") - - Test.assertEqual(expectedOnboardFee, actualOnboardFee) - Test.assertEqual(expectedBaseFee, actualBaseFee) - - actualCalculated = calculateBridgeFee(bytesUsed: bytesUsed) - Test.assertEqual(expectedFinalFee, actualCalculated) -} - -/* --- ONBOARDING - Test asset onboarding to the bridge --- */ - -access(all) -fun testOnboardNFTByTypeSucceeds() { - snapshot = getCurrentBlockHeight() - - var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(true, requiresOnboarding) - - var onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", - [exampleNFTIdentifier], - alice - ) - Test.expect(onboardingResult, Test.beSucceeded()) - - requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(false, requiresOnboarding) - - onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", - [exampleNFTIdentifier], - alice - ) - Test.expect(onboardingResult, Test.beFailed()) -} - -access(all) -fun testOnboardAndBridgeNFTToEVMSucceeds() { - // Revert to state before ExampleNFT was onboarded - Test.reset(to: snapshot) - - var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - Test.assertEqual(40, aliceCOAAddressHex.length) - var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") - Test.assertEqual(1, aliceOwnedIDs.length) - let aliceID = aliceOwnedIDs[0] - - var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(true, requiresOnboarding) +// log("ERC20 Address: ".concat(erc20AddressHex)) +// } + +// access(all) +// fun testCreateCOASucceeds() { +// transferFlow(signer: serviceAccount, recipient: alice.address, amount: 1_000.0) +// createCOA(signer: alice, fundingAmount: 100.0) + +// let coaAddressHex = getCOAAddressHex(atFlowAddress: alice.address) +// } + +// access(all) +// fun testBridgeFlowToEVMSucceeds() { +// // Get $FLOW balances before, making assertions based on values from previous case +// let cadenceBalanceBefore = getBalance(ownerAddr: alice.address, storagePathIdentifier: "flowTokenVault") +// ?? panic("Problem getting $FLOW balance") +// Test.assertEqual(900.0, cadenceBalanceBefore) + +// // Get EVM $FLOW balance before +// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// let evmBalanceBefore = getEVMFlowBalance(of: aliceCOAAddressHex) +// Test.assertEqual(100.0, evmBalanceBefore) + +// // Execute bridge to EVM +// let bridgeAmount = 100.0 +// bridgeTokensToEVM( +// signer: alice, +// contractAddr: Address(0x03), +// contractName: "FlowToken", +// amount: bridgeAmount, +// beFailed: false +// ) + +// // Confirm Alice's token balance is now 0.0 +// let cadenceBalanceAfter = getBalance(ownerAddr: alice.address, storagePathIdentifier: "flowTokenVault") +// ?? panic("Problem getting $FLOW balance") +// Test.assertEqual(cadenceBalanceBefore - bridgeAmount, cadenceBalanceAfter) + +// // Confirm balance on EVM side has been updated +// let evmBalanceAfter = getEVMFlowBalance(of: aliceCOAAddressHex) +// Test.assertEqual(evmBalanceBefore + bridgeAmount, evmBalanceAfter) +// } + +// access(all) +// fun testMintExampleNFTSucceeds() { +// let setupCollectionResult = executeTransaction( +// "../transactions/example-assets/example-nft/setup_collection.cdc", +// [], +// alice +// ) +// Test.expect(setupCollectionResult, Test.beSucceeded()) + +// let mintExampleNFTResult = executeTransaction( +// "../transactions/example-assets/example-nft/mint_nft.cdc", +// [alice.address, exampleNFTTokenName, exampleNFTTokenDescription, exampleNFTTokenThumbnail, [], [], []], +// exampleNFTAccount +// ) +// Test.expect(mintExampleNFTResult, Test.beSucceeded()) + +// let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") +// Test.assertEqual(1, aliceOwnedIDs.length) + +// let events = Test.eventsOfType(Type()) +// Test.assertEqual(1, events.length) +// let evt = events[0] as! NonFungibleToken.Deposited +// mintedNFTID = evt.id + +// Test.assertEqual(aliceOwnedIDs[0], mintedNFTID) +// } + +// access(all) +// fun testMintExampleTokenSucceeds() { +// let setupVaultResult = executeTransaction( +// "../transactions/example-assets/example-token/setup_vault.cdc", +// [], +// alice +// ) +// Test.expect(setupVaultResult, Test.beSucceeded()) + +// let mintExampleTokenResult = executeTransaction( +// "../transactions/example-assets/example-token/mint_tokens.cdc", +// [alice.address, exampleTokenMintAmount], +// exampleTokenAccount +// ) +// Test.expect(mintExampleTokenResult, Test.beSucceeded()) + +// let aliceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") +// ?? panic("Problem getting ExampleToken balance") +// Test.assertEqual(exampleTokenMintAmount, aliceBalance) + +// let events = Test.eventsOfType(Type()) +// let evt = events[events.length - 1] as! FungibleToken.Deposited + +// Test.assertEqual(aliceBalance, evt.amount) +// } + +// access(all) +// fun testMintERC721Succeeds() { +// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// Test.assertEqual(40, erc721AddressHex.length) + +// let mintERC721Result = executeTransaction( +// "../transactions/example-assets/evm-assets/safe_mint_erc721.cdc", +// [aliceCOAAddressHex, erc721ID, erc721URI, erc721AddressHex, UInt64(200_000)], +// exampleERCAccount +// ) +// Test.expect(mintERC721Result, Test.beSucceeded()) + +// let aliceIsOwner = isOwner(of: erc721ID, ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: erc721AddressHex) +// Test.assertEqual(true, aliceIsOwner) +// } + +// access(all) +// fun testMintERC20Succeeds() { +// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// let mintERC20Result = executeTransaction( +// "../transactions/example-assets/evm-assets/mint_erc20.cdc", +// [aliceCOAAddressHex, erc20MintAmount, erc20AddressHex, UInt64(200_000)], +// exampleERCAccount +// ) +// Test.expect(mintERC20Result, Test.beSucceeded()) + +// let aliceBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) +// Test.assertEqual(erc20MintAmount, aliceBalance) +// } + +// access(all) +// fun testUpdateBridgeFeesSucceeds() { +// fun getFee(feeType: String): UFix64 { +// let feeResult = executeScript( +// "../scripts/config/get_".concat(feeType).concat(".cdc"), +// [] +// ) +// Test.expect(feeResult, Test.beSucceeded()) +// return feeResult.returnValue as! UFix64? ?? panic("Problem getting fee: ".concat(feeType)) +// } + +// fun calculateBridgeFee(bytesUsed: UInt64): UFix64 { +// let calculatedResult = executeScript( +// "../scripts/bridge/calculate_bridge_fee.cdc", +// [bytesUsed] +// ) +// Test.expect(calculatedResult, Test.beSucceeded()) +// return calculatedResult.returnValue as! UFix64? ?? panic("Problem getting calculated fee") +// } + +// let bytesUsed: UInt64 = 1024 +// let expectedFinalFee = FlowStorageFees.storageCapacityToFlow( +// FlowStorageFees.convertUInt64StorageBytesToUFix64Megabytes(bytesUsed) +// ) + expectedBaseFee + +// // Validate the initialized values are set to 0.0 +// var actualOnboardFee = getFee(feeType: "onboard_fee") +// var actualBaseFee = getFee(feeType: "base_fee") + +// Test.assertEqual(0.0, actualOnboardFee) +// Test.assertEqual(0.0, actualBaseFee) + +// var actualCalculated = calculateBridgeFee(bytesUsed: bytesUsed) +// Test.assertEqual(0.0, actualCalculated) + +// // Set the fees to new values +// let updateOnboardFeeResult = executeTransaction( +// "../transactions/bridge/admin/fee/update_onboard_fee.cdc", +// [expectedOnboardFee], +// bridgeAccount +// ) +// Test.expect(updateOnboardFeeResult, Test.beSucceeded()) +// let updateBaseFeeResult = executeTransaction( +// "../transactions/bridge/admin/fee/update_base_fee.cdc", +// [expectedBaseFee], +// bridgeAccount +// ) +// Test.expect(updateBaseFeeResult, Test.beSucceeded()) + +// // Validate the values have been updated +// actualOnboardFee = getFee(feeType: "onboard_fee") +// actualBaseFee = getFee(feeType: "base_fee") + +// Test.assertEqual(expectedOnboardFee, actualOnboardFee) +// Test.assertEqual(expectedBaseFee, actualBaseFee) + +// actualCalculated = calculateBridgeFee(bytesUsed: bytesUsed) +// Test.assertEqual(expectedFinalFee, actualCalculated) +// } + +// /* --- ONBOARDING - Test asset onboarding to the bridge --- */ + +// access(all) +// fun testOnboardNFTByTypeSucceeds() { +// snapshot = getCurrentBlockHeight() + +// var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(true, requiresOnboarding) + +// var onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", +// [exampleNFTIdentifier], +// alice +// ) +// Test.expect(onboardingResult, Test.beSucceeded()) + +// requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(false, requiresOnboarding) + +// onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", +// [exampleNFTIdentifier], +// alice +// ) +// Test.expect(onboardingResult, Test.beFailed()) +// } + +// access(all) +// fun testOnboardAndBridgeNFTToEVMSucceeds() { +// // Revert to state before ExampleNFT was onboarded +// Test.reset(to: snapshot) + +// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) +// Test.assertEqual(40, aliceCOAAddressHex.length) +// var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") +// Test.assertEqual(1, aliceOwnedIDs.length) +// let aliceID = aliceOwnedIDs[0] + +// var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(true, requiresOnboarding) - // Execute bridge NFT to EVM - should also onboard the NFT type - bridgeNFTToEVM( - signer: alice, - contractAddr: exampleNFTAccount.address, - contractName: "ExampleNFT", - nftID: aliceID, - bridgeAccountAddr: bridgeAccount.address, - beFailed: false - ) - - requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(false, requiresOnboarding) - - let onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", - [exampleNFTIdentifier], - alice - ) - Test.expect(onboardingResult, Test.beFailed()) - - let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) - Test.assertEqual(40, associatedEVMAddressHex.length) - - // Confirm the NFT is no longer in Alice's Collection - aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") - Test.assertEqual(0, aliceOwnedIDs.length) - - // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation - let isOwnerResult = executeScript( - "../scripts/utils/is_owner.cdc", - [UInt256(mintedNFTID), aliceCOAAddressHex, associatedEVMAddressHex] - ) - Test.expect(isOwnerResult, Test.beSucceeded()) - Test.assertEqual(true, isOwnerResult.returnValue as! Bool? ?? panic("Problem getting owner status")) -} - - -access(all) -fun testOnboardTokenByTypeSucceeds() { - var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(true, requiresOnboarding) - - var onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", - [exampleTokenIdentifier], - alice - ) - Test.expect(onboardingResult, Test.beSucceeded()) - - requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(false, requiresOnboarding) - - onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", - [exampleTokenIdentifier], - alice - ) - Test.expect(onboardingResult, Test.beFailed()) -} - -access(all) -fun testOnboardAndBridgeTokensToEVMSucceeds() { - // Revert to state before ExampleNFT was onboarded - Test.reset(to: snapshot) +// // Execute bridge NFT to EVM - should also onboard the NFT type +// bridgeNFTToEVM( +// signer: alice, +// contractAddr: exampleNFTAccount.address, +// contractName: "ExampleNFT", +// nftID: aliceID, +// bridgeAccountAddr: bridgeAccount.address, +// beFailed: false +// ) + +// requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(false, requiresOnboarding) + +// let onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", +// [exampleNFTIdentifier], +// alice +// ) +// Test.expect(onboardingResult, Test.beFailed()) + +// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) +// Test.assertEqual(40, associatedEVMAddressHex.length) + +// // Confirm the NFT is no longer in Alice's Collection +// aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") +// Test.assertEqual(0, aliceOwnedIDs.length) + +// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation +// let isOwnerResult = executeScript( +// "../scripts/utils/is_owner.cdc", +// [UInt256(mintedNFTID), aliceCOAAddressHex, associatedEVMAddressHex] +// ) +// Test.expect(isOwnerResult, Test.beSucceeded()) +// Test.assertEqual(true, isOwnerResult.returnValue as! Bool? ?? panic("Problem getting owner status")) +// } + + +// access(all) +// fun testOnboardTokenByTypeSucceeds() { +// var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(true, requiresOnboarding) + +// var onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", +// [exampleTokenIdentifier], +// alice +// ) +// Test.expect(onboardingResult, Test.beSucceeded()) + +// requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(false, requiresOnboarding) + +// onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", +// [exampleTokenIdentifier], +// alice +// ) +// Test.expect(onboardingResult, Test.beFailed()) +// } + +// access(all) +// fun testOnboardAndBridgeTokensToEVMSucceeds() { +// // Revert to state before ExampleNFT was onboarded +// Test.reset(to: snapshot) - var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - Test.assertEqual(40, aliceCOAAddressHex.length) - var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") - ?? panic("Could not get ExampleToken balance") - - var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(true, requiresOnboarding) - - // Execute bridge to EVM - should also onboard the token type - bridgeTokensToEVM( - signer: alice, - contractAddr: exampleTokenAccount.address, - contractName: "ExampleToken", - amount: cadenceBalance, - beFailed: false - ) - - requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(false, requiresOnboarding) - - let onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", - [exampleTokenIdentifier], - alice - ) - Test.expect(onboardingResult, Test.beFailed()) - - let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) - Test.assertEqual(40, associatedEVMAddressHex.length) - - // Confirm Alice's token balance is now 0.0 - cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") - ?? panic("Problem getting ExampleToken balance") - Test.assertEqual(0.0, cadenceBalance) - - // Confirm balance on EVM side has been updated - let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) - let expectedEVMBalance = ufix64ToUInt256(exampleTokenMintAmount, decimals: decimals) - let evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) - Test.assertEqual(expectedEVMBalance, evmBalance) -} - -access(all) -fun testBatchOnboardByTypeSucceeds() { - Test.assert(snapshot != 0, message: "Expected snapshot to be taken before onboarding any types") - Test.reset(to: snapshot) - - let nftRequiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(true, nftRequiresOnboarding) - let tokenRequiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) - ?? panic("Problem getting onboarding status for type") - Test.assertEqual(true, tokenRequiresOnboarding) - - let exampleNFTType = Type<@ExampleNFT.NFT>() - let exampleTokenType = Type<@ExampleToken.Vault>() - var onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/batch_onboard_by_type.cdc", - [[exampleNFTType, exampleTokenType]], - alice - ) - Test.expect(onboardingResult, Test.beSucceeded()) - - let expectedBatchOnboardingRequired: {Type: Bool?} = { - exampleNFTType: false, - exampleTokenType: false - } - let batchOnboardingRequiredResult = executeScript( - "../scripts/bridge/batch_type_requires_onboarding.cdc", - [[exampleNFTType, exampleTokenType]] - ) - Test.expect(batchOnboardingRequiredResult, Test.beSucceeded()) - let batchRequiresOnboarding = batchOnboardingRequiredResult.returnValue as! {Type: Bool?}? ?? panic("Problem getting onboarding requirement") - Test.assertEqual(expectedBatchOnboardingRequired, batchRequiresOnboarding) - - // Should succeed as batch onboarding skips already onboarded types - onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/batch_onboard_by_type.cdc", - [[exampleNFTType, exampleTokenType]], - alice - ) - Test.expect(onboardingResult, Test.beSucceeded()) -} - -access(all) -fun testOnboardERC721ByEVMAddressSucceeds() { - snapshot = getCurrentBlockHeight() - - - var requiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) - ?? panic("Problem getting onboarding requirement") - Test.assertEqual(true, requiresOnboarding) - - var onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", - [erc721AddressHex], - alice - ) - Test.expect(onboardingResult, Test.beSucceeded()) - - requiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) - ?? panic("Problem getting onboarding requirement") - Test.assertEqual(false, requiresOnboarding) - - onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", - [erc721AddressHex], - alice - ) - Test.expect(onboardingResult, Test.beFailed()) -} - -access(all) -fun testOnboardERC20ByEVMAddressSucceeds() { - - var requiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) - ?? panic("Problem getting onboarding requirement") - Test.assertEqual(true, requiresOnboarding) - - var onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", - [erc20AddressHex], - alice - ) - Test.expect(onboardingResult, Test.beSucceeded()) - - requiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) - ?? panic("Problem getting onboarding requirement") - Test.assertEqual(false, requiresOnboarding) - - onboardingResult = executeTransaction( - "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", - [erc20AddressHex], - alice - ) - Test.expect(onboardingResult, Test.beFailed()) -} - -access(all) -fun testBatchOnboardByEVMAddressSucceeds() { - Test.assert(snapshot != 0, message: "Expected snapshot to be taken before onboarding any EVM contracts") - Test.reset(to: snapshot) - - - var erc721RequiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) - ?? panic("Problem getting onboarding requirement") - var erc20RequiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) - ?? panic("Problem getting onboarding requirement") - Test.assertEqual(true, erc721RequiresOnboarding) - Test.assertEqual(true, erc20RequiresOnboarding) - - var batchOnboardingResult = executeTransaction( - "../transactions/bridge/onboarding/batch_onboard_by_evm_address.cdc", - [[erc721AddressHex, erc20AddressHex]], - alice - ) - Test.expect(batchOnboardingResult, Test.beSucceeded()) - - let expectedBatchRequiresOnboarding: {String: Bool?} = { - erc721AddressHex: false, - erc20AddressHex: false - } - let batchOnboardingRequiredResult = executeScript( - "../scripts/bridge/batch_evm_address_requires_onboarding.cdc", - [[erc721AddressHex, erc20AddressHex]] - ) - Test.expect(batchOnboardingRequiredResult, Test.beSucceeded()) - let batchRequiresOnboarding = batchOnboardingRequiredResult.returnValue as! {String: Bool?}? ?? panic("Problem getting onboarding requirement") - Test.assertEqual(expectedBatchRequiresOnboarding, batchRequiresOnboarding) - - // Batch onboarding should succeed as it skips already onboarded contracts - batchOnboardingResult = executeTransaction( - "../transactions/bridge/onboarding/batch_onboard_by_evm_address.cdc", - [[erc721AddressHex, erc20AddressHex]], - alice - ) - Test.expect(batchOnboardingResult, Test.beSucceeded()) - -} - -/* --- BRIDGING NFTS - Test bridging both Cadence- & EVM-native NFTs --- */ - -access(all) -fun testPauseBridgeSucceeds() { - // Pause the bridge - let pauseResult = executeTransaction( - "../transactions/bridge/admin/pause/update_bridge_pause_status.cdc", - [true], - bridgeAccount - ) - Test.expect(pauseResult, Test.beSucceeded()) - var isPausedResult = executeScript( - "../scripts/bridge/is_paused.cdc", - [] - ) - Test.expect(isPausedResult, Test.beSucceeded()) - Test.assertEqual(true, isPausedResult.returnValue as! Bool? ?? panic("Problem getting pause status")) - - var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") - Test.assertEqual(1, aliceOwnedIDs.length) - - var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - // Execute bridge to EVM - should fail after pausing - bridgeNFTToEVM( - signer: alice, - contractAddr: exampleNFTAccount.address, - contractName: "ExampleNFT", - nftID: aliceOwnedIDs[0], - bridgeAccountAddr: bridgeAccount.address, - beFailed: true - ) - - // Unpause bridging - let unpauseResult = executeTransaction( - "../transactions/bridge/admin/pause/update_bridge_pause_status.cdc", - [false], - bridgeAccount - ) - Test.expect(unpauseResult, Test.beSucceeded()) - - isPausedResult = executeScript( - "../scripts/bridge/is_paused.cdc", - [] - ) - Test.expect(isPausedResult, Test.beSucceeded()) - Test.assertEqual(false, isPausedResult.returnValue as! Bool? ?? panic("Problem getting pause status")) -} - -access(all) -fun testBridgeCadenceNativeNFTToEVMSucceeds() { - var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") - Test.assertEqual(1, aliceOwnedIDs.length) - - var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - // Execute bridge to EVM - bridgeNFTToEVM( - signer: alice, - contractAddr: exampleNFTAccount.address, - contractName: "ExampleNFT", - nftID: aliceOwnedIDs[0], - bridgeAccountAddr: bridgeAccount.address, - beFailed: false - ) - - let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) - Test.assertEqual(40, associatedEVMAddressHex.length) - - // Confirm the NFT is no longer in Alice's Collection - aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") - Test.assertEqual(0, aliceOwnedIDs.length) - - // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation - let isOwnerResult = executeScript( - "../scripts/utils/is_owner.cdc", - [UInt256(mintedNFTID), aliceCOAAddressHex, associatedEVMAddressHex] - ) - Test.expect(isOwnerResult, Test.beSucceeded()) - Test.assertEqual(true, isOwnerResult.returnValue as! Bool? ?? panic("Problem getting owner status")) -} - -access(all) -fun testBridgeCadenceNativeNFTFromEVMSucceeds() { - let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) - Test.assertEqual(40, associatedEVMAddressHex.length) - - // Assert ownership of the bridged NFT in EVM - var aliceIsOwner = isOwner(of: UInt256(mintedNFTID), ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: associatedEVMAddressHex) - Test.assertEqual(true, aliceIsOwner) - - // Execute bridge from EVM - bridgeNFTFromEVM( - signer: alice, - contractAddr: exampleNFTAccount.address, - contractName: "ExampleNFT", - erc721ID: UInt256(mintedNFTID), - bridgeAccountAddr: bridgeAccount.address, - beFailed: false - ) - - // Assert ownership of the bridged NFT in EVM has transferred - aliceIsOwner = isOwner(of: UInt256(mintedNFTID), ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: associatedEVMAddressHex) - Test.assertEqual(false, aliceIsOwner) - - // Assert the NFT is back in Alice's Collection - let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") - Test.assertEqual(1, aliceOwnedIDs.length) - Test.assertEqual(mintedNFTID, aliceOwnedIDs[0]) -} - -access(all) -fun testBridgeEVMNativeNFTFromEVMSucceeds() { - - let derivedERC721ContractName = deriveBridgedNFTContractName(evmAddressHex: erc721AddressHex) - let bridgedCollectionPathIdentifier = derivedERC721ContractName.concat("Collection") - let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - bridgeNFTFromEVM( - signer: alice, - contractAddr: bridgeAccount.address, - contractName: derivedERC721ContractName, - erc721ID: erc721ID, - bridgeAccountAddr: bridgeAccount.address, - beFailed: false - ) - - let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) - Test.assertEqual(1, aliceOwnedIDs.length) - - let evmIDResult = executeScript( - "../scripts/nft/get_evm_id_from_evm_nft.cdc", - [alice.address, aliceOwnedIDs[0], StoragePath(identifier: bridgedCollectionPathIdentifier)!] - ) - Test.expect(evmIDResult, Test.beSucceeded()) - let evmID = evmIDResult.returnValue as! UInt256? ?? panic("Problem getting EVM ID") - Test.assertEqual(erc721ID, evmID) -} - -access(all) -fun testBridgeEVMNativeNFTToEVMSucceeds() { - - let derivedERC721ContractName = deriveBridgedNFTContractName(evmAddressHex: erc721AddressHex) - let bridgedCollectionPathIdentifier = derivedERC721ContractName.concat("Collection") - let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) - Test.assertEqual(1, aliceOwnedIDs.length) - - bridgeNFTToEVM( - signer: alice, - contractAddr: bridgeAccount.address, - contractName: derivedERC721ContractName, - nftID: aliceOwnedIDs[0], - bridgeAccountAddr: bridgeAccount.address, - beFailed: false - ) - - aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) - Test.assertEqual(0, aliceOwnedIDs.length) - - let aliceIsOwner = isOwner(of: erc721ID, ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: erc721AddressHex) - Test.assertEqual(true, aliceIsOwner) -} - -/* --- BRIDGING FUNGIBLE TOKENS - Test bridging both Cadence- & EVM-native fungible tokens --- */ - -access(all) -fun testBridgeCadenceNativeTokenToEVMSucceeds() { - var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") - ?? panic("Problem getting ExampleToken balance") - Test.assert(cadenceBalance == exampleTokenMintAmount) - - var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - // Execute bridge to EVM - bridgeTokensToEVM( - signer: alice, - contractAddr: exampleTokenAccount.address, - contractName: "ExampleToken", - amount: cadenceBalance, - beFailed: false - ) - - let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) - Test.assertEqual(40, associatedEVMAddressHex.length) - - // Confirm Alice's token balance is now 0.0 - cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") - ?? panic("Problem getting ExampleToken balance") - Test.assertEqual(0.0, cadenceBalance) - - // Confirm balance on EVM side has been updated - let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) - let expectedEVMBalance = ufix64ToUInt256(exampleTokenMintAmount, decimals: decimals) - let evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) - Test.assertEqual(expectedEVMBalance, evmBalance) -} - -access(all) -fun testBridgeCadenceNativeTokenFromEVMSucceeds() { - let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) - Test.assertEqual(40, associatedEVMAddressHex.length) +// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) +// Test.assertEqual(40, aliceCOAAddressHex.length) +// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") +// ?? panic("Could not get ExampleToken balance") + +// var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(true, requiresOnboarding) + +// // Execute bridge to EVM - should also onboard the token type +// bridgeTokensToEVM( +// signer: alice, +// contractAddr: exampleTokenAccount.address, +// contractName: "ExampleToken", +// amount: cadenceBalance, +// beFailed: false +// ) + +// requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(false, requiresOnboarding) + +// let onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", +// [exampleTokenIdentifier], +// alice +// ) +// Test.expect(onboardingResult, Test.beFailed()) + +// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) +// Test.assertEqual(40, associatedEVMAddressHex.length) + +// // Confirm Alice's token balance is now 0.0 +// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") +// ?? panic("Problem getting ExampleToken balance") +// Test.assertEqual(0.0, cadenceBalance) + +// // Confirm balance on EVM side has been updated +// let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) +// let expectedEVMBalance = ufix64ToUInt256(exampleTokenMintAmount, decimals: decimals) +// let evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) +// Test.assertEqual(expectedEVMBalance, evmBalance) +// } + +// access(all) +// fun testBatchOnboardByTypeSucceeds() { +// Test.assert(snapshot != 0, message: "Expected snapshot to be taken before onboarding any types") +// Test.reset(to: snapshot) + +// let nftRequiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(true, nftRequiresOnboarding) +// let tokenRequiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) +// ?? panic("Problem getting onboarding status for type") +// Test.assertEqual(true, tokenRequiresOnboarding) + +// let exampleNFTType = Type<@ExampleNFT.NFT>() +// let exampleTokenType = Type<@ExampleToken.Vault>() +// var onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/batch_onboard_by_type.cdc", +// [[exampleNFTType, exampleTokenType]], +// alice +// ) +// Test.expect(onboardingResult, Test.beSucceeded()) + +// let expectedBatchOnboardingRequired: {Type: Bool?} = { +// exampleNFTType: false, +// exampleTokenType: false +// } +// let batchOnboardingRequiredResult = executeScript( +// "../scripts/bridge/batch_type_requires_onboarding.cdc", +// [[exampleNFTType, exampleTokenType]] +// ) +// Test.expect(batchOnboardingRequiredResult, Test.beSucceeded()) +// let batchRequiresOnboarding = batchOnboardingRequiredResult.returnValue as! {Type: Bool?}? ?? panic("Problem getting onboarding requirement") +// Test.assertEqual(expectedBatchOnboardingRequired, batchRequiresOnboarding) + +// // Should succeed as batch onboarding skips already onboarded types +// onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/batch_onboard_by_type.cdc", +// [[exampleNFTType, exampleTokenType]], +// alice +// ) +// Test.expect(onboardingResult, Test.beSucceeded()) +// } + +// access(all) +// fun testOnboardERC721ByEVMAddressSucceeds() { +// snapshot = getCurrentBlockHeight() + + +// var requiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) +// ?? panic("Problem getting onboarding requirement") +// Test.assertEqual(true, requiresOnboarding) + +// var onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", +// [erc721AddressHex], +// alice +// ) +// Test.expect(onboardingResult, Test.beSucceeded()) + +// requiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) +// ?? panic("Problem getting onboarding requirement") +// Test.assertEqual(false, requiresOnboarding) + +// onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", +// [erc721AddressHex], +// alice +// ) +// Test.expect(onboardingResult, Test.beFailed()) +// } + +// access(all) +// fun testOnboardERC20ByEVMAddressSucceeds() { + +// var requiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) +// ?? panic("Problem getting onboarding requirement") +// Test.assertEqual(true, requiresOnboarding) + +// var onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", +// [erc20AddressHex], +// alice +// ) +// Test.expect(onboardingResult, Test.beSucceeded()) + +// requiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) +// ?? panic("Problem getting onboarding requirement") +// Test.assertEqual(false, requiresOnboarding) + +// onboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", +// [erc20AddressHex], +// alice +// ) +// Test.expect(onboardingResult, Test.beFailed()) +// } + +// access(all) +// fun testBatchOnboardByEVMAddressSucceeds() { +// Test.assert(snapshot != 0, message: "Expected snapshot to be taken before onboarding any EVM contracts") +// Test.reset(to: snapshot) + + +// var erc721RequiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) +// ?? panic("Problem getting onboarding requirement") +// var erc20RequiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) +// ?? panic("Problem getting onboarding requirement") +// Test.assertEqual(true, erc721RequiresOnboarding) +// Test.assertEqual(true, erc20RequiresOnboarding) + +// var batchOnboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/batch_onboard_by_evm_address.cdc", +// [[erc721AddressHex, erc20AddressHex]], +// alice +// ) +// Test.expect(batchOnboardingResult, Test.beSucceeded()) + +// let expectedBatchRequiresOnboarding: {String: Bool?} = { +// erc721AddressHex: false, +// erc20AddressHex: false +// } +// let batchOnboardingRequiredResult = executeScript( +// "../scripts/bridge/batch_evm_address_requires_onboarding.cdc", +// [[erc721AddressHex, erc20AddressHex]] +// ) +// Test.expect(batchOnboardingRequiredResult, Test.beSucceeded()) +// let batchRequiresOnboarding = batchOnboardingRequiredResult.returnValue as! {String: Bool?}? ?? panic("Problem getting onboarding requirement") +// Test.assertEqual(expectedBatchRequiresOnboarding, batchRequiresOnboarding) + +// // Batch onboarding should succeed as it skips already onboarded contracts +// batchOnboardingResult = executeTransaction( +// "../transactions/bridge/onboarding/batch_onboard_by_evm_address.cdc", +// [[erc721AddressHex, erc20AddressHex]], +// alice +// ) +// Test.expect(batchOnboardingResult, Test.beSucceeded()) + +// } + +// /* --- BRIDGING NFTS - Test bridging both Cadence- & EVM-native NFTs --- */ + +// access(all) +// fun testPauseBridgeSucceeds() { +// // Pause the bridge +// let pauseResult = executeTransaction( +// "../transactions/bridge/admin/pause/update_bridge_pause_status.cdc", +// [true], +// bridgeAccount +// ) +// Test.expect(pauseResult, Test.beSucceeded()) +// var isPausedResult = executeScript( +// "../scripts/bridge/is_paused.cdc", +// [] +// ) +// Test.expect(isPausedResult, Test.beSucceeded()) +// Test.assertEqual(true, isPausedResult.returnValue as! Bool? ?? panic("Problem getting pause status")) + +// var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") +// Test.assertEqual(1, aliceOwnedIDs.length) + +// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// // Execute bridge to EVM - should fail after pausing +// bridgeNFTToEVM( +// signer: alice, +// contractAddr: exampleNFTAccount.address, +// contractName: "ExampleNFT", +// nftID: aliceOwnedIDs[0], +// bridgeAccountAddr: bridgeAccount.address, +// beFailed: true +// ) + +// // Unpause bridging +// let unpauseResult = executeTransaction( +// "../transactions/bridge/admin/pause/update_bridge_pause_status.cdc", +// [false], +// bridgeAccount +// ) +// Test.expect(unpauseResult, Test.beSucceeded()) + +// isPausedResult = executeScript( +// "../scripts/bridge/is_paused.cdc", +// [] +// ) +// Test.expect(isPausedResult, Test.beSucceeded()) +// Test.assertEqual(false, isPausedResult.returnValue as! Bool? ?? panic("Problem getting pause status")) +// } + +// access(all) +// fun testBridgeCadenceNativeNFTToEVMSucceeds() { +// var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") +// Test.assertEqual(1, aliceOwnedIDs.length) + +// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// // Execute bridge to EVM +// bridgeNFTToEVM( +// signer: alice, +// contractAddr: exampleNFTAccount.address, +// contractName: "ExampleNFT", +// nftID: aliceOwnedIDs[0], +// bridgeAccountAddr: bridgeAccount.address, +// beFailed: false +// ) + +// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) +// Test.assertEqual(40, associatedEVMAddressHex.length) + +// // Confirm the NFT is no longer in Alice's Collection +// aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") +// Test.assertEqual(0, aliceOwnedIDs.length) + +// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation +// let isOwnerResult = executeScript( +// "../scripts/utils/is_owner.cdc", +// [UInt256(mintedNFTID), aliceCOAAddressHex, associatedEVMAddressHex] +// ) +// Test.expect(isOwnerResult, Test.beSucceeded()) +// Test.assertEqual(true, isOwnerResult.returnValue as! Bool? ?? panic("Problem getting owner status")) +// } + +// access(all) +// fun testBridgeCadenceNativeNFTFromEVMSucceeds() { +// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) +// Test.assertEqual(40, associatedEVMAddressHex.length) + +// // Assert ownership of the bridged NFT in EVM +// var aliceIsOwner = isOwner(of: UInt256(mintedNFTID), ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: associatedEVMAddressHex) +// Test.assertEqual(true, aliceIsOwner) + +// // Execute bridge from EVM +// bridgeNFTFromEVM( +// signer: alice, +// contractAddr: exampleNFTAccount.address, +// contractName: "ExampleNFT", +// erc721ID: UInt256(mintedNFTID), +// bridgeAccountAddr: bridgeAccount.address, +// beFailed: false +// ) + +// // Assert ownership of the bridged NFT in EVM has transferred +// aliceIsOwner = isOwner(of: UInt256(mintedNFTID), ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: associatedEVMAddressHex) +// Test.assertEqual(false, aliceIsOwner) + +// // Assert the NFT is back in Alice's Collection +// let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") +// Test.assertEqual(1, aliceOwnedIDs.length) +// Test.assertEqual(mintedNFTID, aliceOwnedIDs[0]) +// } + +// access(all) +// fun testBridgeEVMNativeNFTFromEVMSucceeds() { + +// let derivedERC721ContractName = deriveBridgedNFTContractName(evmAddressHex: erc721AddressHex) +// let bridgedCollectionPathIdentifier = derivedERC721ContractName.concat("Collection") +// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// bridgeNFTFromEVM( +// signer: alice, +// contractAddr: bridgeAccount.address, +// contractName: derivedERC721ContractName, +// erc721ID: erc721ID, +// bridgeAccountAddr: bridgeAccount.address, +// beFailed: false +// ) + +// let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) +// Test.assertEqual(1, aliceOwnedIDs.length) + +// let evmIDResult = executeScript( +// "../scripts/nft/get_evm_id_from_evm_nft.cdc", +// [alice.address, aliceOwnedIDs[0], StoragePath(identifier: bridgedCollectionPathIdentifier)!] +// ) +// Test.expect(evmIDResult, Test.beSucceeded()) +// let evmID = evmIDResult.returnValue as! UInt256? ?? panic("Problem getting EVM ID") +// Test.assertEqual(erc721ID, evmID) +// } + +// access(all) +// fun testBridgeEVMNativeNFTToEVMSucceeds() { + +// let derivedERC721ContractName = deriveBridgedNFTContractName(evmAddressHex: erc721AddressHex) +// let bridgedCollectionPathIdentifier = derivedERC721ContractName.concat("Collection") +// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) +// Test.assertEqual(1, aliceOwnedIDs.length) + +// bridgeNFTToEVM( +// signer: alice, +// contractAddr: bridgeAccount.address, +// contractName: derivedERC721ContractName, +// nftID: aliceOwnedIDs[0], +// bridgeAccountAddr: bridgeAccount.address, +// beFailed: false +// ) + +// aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) +// Test.assertEqual(0, aliceOwnedIDs.length) + +// let aliceIsOwner = isOwner(of: erc721ID, ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: erc721AddressHex) +// Test.assertEqual(true, aliceIsOwner) +// } + +// /* --- BRIDGING FUNGIBLE TOKENS - Test bridging both Cadence- & EVM-native fungible tokens --- */ + +// access(all) +// fun testBridgeCadenceNativeTokenToEVMSucceeds() { +// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") +// ?? panic("Problem getting ExampleToken balance") +// Test.assert(cadenceBalance == exampleTokenMintAmount) + +// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// // Execute bridge to EVM +// bridgeTokensToEVM( +// signer: alice, +// contractAddr: exampleTokenAccount.address, +// contractName: "ExampleToken", +// amount: cadenceBalance, +// beFailed: false +// ) + +// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) +// Test.assertEqual(40, associatedEVMAddressHex.length) + +// // Confirm Alice's token balance is now 0.0 +// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") +// ?? panic("Problem getting ExampleToken balance") +// Test.assertEqual(0.0, cadenceBalance) + +// // Confirm balance on EVM side has been updated +// let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) +// let expectedEVMBalance = ufix64ToUInt256(exampleTokenMintAmount, decimals: decimals) +// let evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) +// Test.assertEqual(expectedEVMBalance, evmBalance) +// } + +// access(all) +// fun testBridgeCadenceNativeTokenFromEVMSucceeds() { +// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) +// Test.assertEqual(40, associatedEVMAddressHex.length) - var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - // Confirm Alice is starting with 0.0 balance in their Cadence Vault - var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") - ?? panic("Problem getting ExampleToken balance") - Test.assertEqual(0.0, cadenceBalance) - - // Get Alice's ERC20 balance & convert to UFix64 - var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) - let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) - let ufixValue = uint256ToUFix64(evmBalance, decimals: decimals) - // Assert the converted balance is equal to the originally minted amount that was bridged in the previous step - Test.assertEqual(exampleTokenMintAmount, ufixValue) - - // Execute bridge from EVM - bridgeTokensFromEVM( - signer: alice, - contractAddr: exampleTokenAccount.address, - contractName: "ExampleToken", - amount: evmBalance, - beFailed: false - ) - - // Confirm ExampleToken balance has been bridged back to Alice's Cadence vault - cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") - ?? panic("Problem getting ExampleToken balance") - Test.assertEqual(ufixValue, cadenceBalance) - - // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation - evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) - Test.assertEqual(UInt256(0), evmBalance) -} - -access(all) -fun testBridgeEVMNativeTokenFromEVMSucceeds() { - - let derivedERC20ContractName = deriveBridgedTokenContractName(evmAddressHex: erc20AddressHex) - let bridgedVaultPathIdentifier = derivedERC20ContractName.concat("Vault") - let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation - var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) - Test.assertEqual(erc20MintAmount, evmBalance) - - // Confirm Alice does not yet have a bridged Vault configured - var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) - Test.assertEqual(nil, cadenceBalance) - - // Execute bridge from EVM - bridgeTokensFromEVM( - signer: alice, - contractAddr: bridgeAccount.address, - contractName: derivedERC20ContractName, - amount: evmBalance, - beFailed: false - ) - - // Confirm EVM balance is no 0 - evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) - Test.assertEqual(UInt256(0), evmBalance) - - // Confirm the Cadence Vault is now configured and contains the bridged balance - cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) - ?? panic("Bridged token Vault was not found in Alice's account after bridging") - let decimals = getTokenDecimals(erc20AddressHex: erc20AddressHex) - let expectedCadenceBalance = uint256ToUFix64(erc20MintAmount, decimals: decimals) - Test.assertEqual(expectedCadenceBalance, cadenceBalance!) - - // With the bridge executed, confirm the bridge COA escrows the ERC20 tokens - let bridgeCOAAddressHex = getCOAAddressHex(atFlowAddress: bridgeAccount.address) - let bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) - Test.assertEqual(erc20MintAmount, bridgeCOAEscrowBalance) -} - -access(all) -fun testBridgeEVMNativeTokenToEVMSucceeds() { - - let derivedERC20ContractName = deriveBridgedTokenContractName(evmAddressHex: erc20AddressHex) - let bridgedVaultPathIdentifier = derivedERC20ContractName.concat("Vault") - let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - - // Confirm Cadence Vault has the expected balance - var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) - ?? panic("Bridged token Vault was not found in Alice's account after bridging") - let decimals = getTokenDecimals(erc20AddressHex: erc20AddressHex) - let expectedCadenceBalance = uint256ToUFix64(erc20MintAmount, decimals: decimals) - Test.assertEqual(expectedCadenceBalance, cadenceBalance) - - // Confirm EVM balance is 0 - var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) - Test.assertEqual(UInt256(0), evmBalance) - - // Confirm the bridge COA currently escrows the ERC20 tokens we will be bridging - let bridgeCOAAddressHex = getCOAAddressHex(atFlowAddress: bridgeAccount.address) - var bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) - Test.assertEqual(erc20MintAmount, bridgeCOAEscrowBalance) - - // Execute bridge from EVM - bridgeTokensToEVM( - signer: alice, - contractAddr: bridgeAccount.address, - contractName: derivedERC20ContractName, - amount: cadenceBalance, - beFailed: false - ) - - // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation - evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) - Test.assertEqual(erc20MintAmount, evmBalance) - - cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) - ?? panic("Bridged token Vault was not found in Alice's account after bridging") - Test.assertEqual(0.0, cadenceBalance) - - // Confirm the bridge COA no longer escrows the ERC20 tokens - bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) - Test.assertEqual(UInt256(0), bridgeCOAEscrowBalance) -} +// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// // Confirm Alice is starting with 0.0 balance in their Cadence Vault +// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") +// ?? panic("Problem getting ExampleToken balance") +// Test.assertEqual(0.0, cadenceBalance) + +// // Get Alice's ERC20 balance & convert to UFix64 +// var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) +// let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) +// let ufixValue = uint256ToUFix64(evmBalance, decimals: decimals) +// // Assert the converted balance is equal to the originally minted amount that was bridged in the previous step +// Test.assertEqual(exampleTokenMintAmount, ufixValue) + +// // Execute bridge from EVM +// bridgeTokensFromEVM( +// signer: alice, +// contractAddr: exampleTokenAccount.address, +// contractName: "ExampleToken", +// amount: evmBalance, +// beFailed: false +// ) + +// // Confirm ExampleToken balance has been bridged back to Alice's Cadence vault +// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") +// ?? panic("Problem getting ExampleToken balance") +// Test.assertEqual(ufixValue, cadenceBalance) + +// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation +// evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) +// Test.assertEqual(UInt256(0), evmBalance) +// } + +// access(all) +// fun testBridgeEVMNativeTokenFromEVMSucceeds() { + +// let derivedERC20ContractName = deriveBridgedTokenContractName(evmAddressHex: erc20AddressHex) +// let bridgedVaultPathIdentifier = derivedERC20ContractName.concat("Vault") +// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation +// var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) +// Test.assertEqual(erc20MintAmount, evmBalance) + +// // Confirm Alice does not yet have a bridged Vault configured +// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) +// Test.assertEqual(nil, cadenceBalance) + +// // Execute bridge from EVM +// bridgeTokensFromEVM( +// signer: alice, +// contractAddr: bridgeAccount.address, +// contractName: derivedERC20ContractName, +// amount: evmBalance, +// beFailed: false +// ) + +// // Confirm EVM balance is no 0 +// evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) +// Test.assertEqual(UInt256(0), evmBalance) + +// // Confirm the Cadence Vault is now configured and contains the bridged balance +// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) +// ?? panic("Bridged token Vault was not found in Alice's account after bridging") +// let decimals = getTokenDecimals(erc20AddressHex: erc20AddressHex) +// let expectedCadenceBalance = uint256ToUFix64(erc20MintAmount, decimals: decimals) +// Test.assertEqual(expectedCadenceBalance, cadenceBalance!) + +// // With the bridge executed, confirm the bridge COA escrows the ERC20 tokens +// let bridgeCOAAddressHex = getCOAAddressHex(atFlowAddress: bridgeAccount.address) +// let bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) +// Test.assertEqual(erc20MintAmount, bridgeCOAEscrowBalance) +// } + +// access(all) +// fun testBridgeEVMNativeTokenToEVMSucceeds() { + +// let derivedERC20ContractName = deriveBridgedTokenContractName(evmAddressHex: erc20AddressHex) +// let bridgedVaultPathIdentifier = derivedERC20ContractName.concat("Vault") +// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + +// // Confirm Cadence Vault has the expected balance +// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) +// ?? panic("Bridged token Vault was not found in Alice's account after bridging") +// let decimals = getTokenDecimals(erc20AddressHex: erc20AddressHex) +// let expectedCadenceBalance = uint256ToUFix64(erc20MintAmount, decimals: decimals) +// Test.assertEqual(expectedCadenceBalance, cadenceBalance) + +// // Confirm EVM balance is 0 +// var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) +// Test.assertEqual(UInt256(0), evmBalance) + +// // Confirm the bridge COA currently escrows the ERC20 tokens we will be bridging +// let bridgeCOAAddressHex = getCOAAddressHex(atFlowAddress: bridgeAccount.address) +// var bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) +// Test.assertEqual(erc20MintAmount, bridgeCOAEscrowBalance) + +// // Execute bridge from EVM +// bridgeTokensToEVM( +// signer: alice, +// contractAddr: bridgeAccount.address, +// contractName: derivedERC20ContractName, +// amount: cadenceBalance, +// beFailed: false +// ) + +// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation +// evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) +// Test.assertEqual(erc20MintAmount, evmBalance) + +// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) +// ?? panic("Bridged token Vault was not found in Alice's account after bridging") +// Test.assertEqual(0.0, cadenceBalance) + +// // Confirm the bridge COA no longer escrows the ERC20 tokens +// bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) +// Test.assertEqual(UInt256(0), bridgeCOAEscrowBalance) +// } diff --git a/cadence/transactions/bridge/admin/evm/add_deployer.cdc b/cadence/transactions/bridge/admin/evm/add_deployer.cdc index 0987524c..0d592023 100644 --- a/cadence/transactions/bridge/admin/evm/add_deployer.cdc +++ b/cadence/transactions/bridge/admin/evm/add_deployer.cdc @@ -5,7 +5,7 @@ import "FlowEVMBridgeUtils" transaction(deployerTag: String, deployerEVMAddressHex: String) { - let coa: auth(Call) &CadenceOwnedAccount + let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount prepare(signer: auth(BorrowValue) &Account) { self.coa = signer.storage.borrow(from: /storage/evm) @@ -25,6 +25,6 @@ transaction(deployerTag: String, deployerEVMAddressHex: String) { gasLimit: 15_000_000, value: EVM.Balance(attoflow: 0) ) - assert(callResult.success == EVM.Status.successful, message: "Failed to add deployer") + assert(callResult.status == EVM.Status.successful, message: "Failed to add deployer") } } diff --git a/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc b/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc index 1f0448d6..ed4c20ab 100644 --- a/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc +++ b/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc @@ -3,9 +3,9 @@ import "EVM" import "EVMUtils" import "FlowEVMBridgeUtils" -transaction(deployerEVMAddressHex: String, delegatedEVMAddressHex: String) { +transaction(deployerEVMAddressHex: String) { - let coa: auth(Call) &CadenceOwnedAccount + let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount prepare(signer: auth(BorrowValue) &Account) { self.coa = signer.storage.borrow(from: /storage/evm) @@ -25,6 +25,6 @@ transaction(deployerEVMAddressHex: String, delegatedEVMAddressHex: String) { gasLimit: 15_000_000, value: EVM.Balance(attoflow: 0) ) - assert(callResult.success == EVM.Status.successful, message: "Failed to set delegated deployer") + assert(callResult.status == EVM.Status.successful, message: "Failed to set delegated deployer") } } diff --git a/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc b/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc index e4067987..43b943f0 100644 --- a/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc +++ b/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc @@ -5,7 +5,7 @@ import "FlowEVMBridgeUtils" transaction(registryEVMAddressHex: String) { - let coa: auth(Call) &CadenceOwnedAccount + let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount prepare(signer: auth(BorrowValue) &Account) { self.coa = signer.storage.borrow(from: /storage/evm) @@ -25,6 +25,6 @@ transaction(registryEVMAddressHex: String) { gasLimit: 15_000_000, value: EVM.Balance(attoflow: 0) ) - assert(callResult.success == EVM.Status.successful, message: "Failed to set delegated deployer") + assert(callResult.status == EVM.Status.successful, message: "Failed to set delegated deployer") } } diff --git a/cadence/transactions/bridge/admin/evm/set_registrar.cdc b/cadence/transactions/bridge/admin/evm/set_registrar.cdc index c727b61c..baf5db3f 100644 --- a/cadence/transactions/bridge/admin/evm/set_registrar.cdc +++ b/cadence/transactions/bridge/admin/evm/set_registrar.cdc @@ -10,7 +10,7 @@ import "FlowEVMBridgeUtils" /// transaction(registryEVMAddressHex: String) { - let coa: auth(Call) &CadenceOwnedAccount + let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount prepare(signer: auth(BorrowValue) &Account) { self.coa = signer.storage.borrow(from: /storage/evm) @@ -30,6 +30,6 @@ transaction(registryEVMAddressHex: String) { gasLimit: 15_000_000, value: EVM.Balance(attoflow: 0) ) - assert(callResult.success == EVM.Status.successful, message: "Failed to set delegated deployer") + assert(callResult.status == EVM.Status.successful, message: "Failed to set registrar") } } From 34665f917fca9f37323d6f179a79ec66c3f198f5 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Mon, 6 May 2024 15:39:05 -0500 Subject: [PATCH 06/18] fix factory event emission --- cadence/args/deploy-factory-args.json | 2 +- solidity/src/FlowBridgeFactory.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cadence/args/deploy-factory-args.json b/cadence/args/deploy-factory-args.json index bee7f760..9bb00ea0 100644 --- a/cadence/args/deploy-factory-args.json +++ b/cadence/args/deploy-factory-args.json @@ -1,7 +1,7 @@ [ { "type": "String", - "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61484a806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000c35760003560e01c8063715018a6116200007a578063715018a6146200018f5780638da5cb5b146200019b578063d56e0ccf14620001ad578063daa09e5414620001e4578063f2fde38b14620001fb578063f93241dd146200021257600080fd5b806304433bbc14620000c85780630a2c0ce914620000fc578063263e0c1b1462000122578063335f4c76146200014a57806340f8d42b146200016157806361a169051462000178575b600080fd5b620000df620000d936600462000c0a565b62000229565b6040516001600160a01b0390911681526020015b60405180910390f35b620001136200010d36600462000c4b565b6200025c565b604051620000f3919062000cd1565b620001396200013336600462000c4b565b62000310565b6040519015158152602001620000f3565b620001396200015b36600462000c4b565b62000724565b620000df6200017236600462000ce6565b62000752565b620000df6200018936600462000ce6565b62000853565b6200019962000942565b005b6000546001600160a01b0316620000df565b620000df620001be36600462000c0a565b80516020818301810180516001825292820191909301209152546001600160a01b031681565b62000139620001f536600462000c4b565b6200095a565b620001996200020c36600462000c4b565b620009da565b620001136200022336600462000c4b565b62000a22565b60006001826040516200023d919062000dc8565b908152604051908190036020019020546001600160a01b031692915050565b6001600160a01b0381166000908152600260205260409020805460609190620002859062000de6565b80601f0160208091040260200160405190810160405280929190818152602001828054620002b39062000de6565b8015620003045780601f10620002d85761010080835404028352916020019162000304565b820191906000526020600020905b815481529060010190602001808311620002e657829003601f168201915b50505050509050919050565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169162000358919062000dc8565b600060405180830381855afa9150503d806000811462000395576040519150601f19603f3d011682016040523d82523d6000602084013e6200039a565b606091505b5091509150811580620003ac57508051155b15620003bc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b179052516200040b919062000dc8565b600060405180830381855afa9150503d806000811462000448576040519150601f19603f3d011682016040523d82523d6000602084013e6200044d565b606091505b5090925090508115806200046057508051155b1562000470575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b17905251620004c6919062000dc8565b600060405180830381855afa9150503d806000811462000503576040519150601f19603f3d011682016040523d82523d6000602084013e62000508565b606091505b5090925090508115806200051b57508051155b156200052b575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b038616916200056b9162000dc8565b600060405180830381855afa9150503d8060008114620005a8576040519150601f19603f3d011682016040523d82523d6000602084013e620005ad565b606091505b509092509050811580620005c057508051155b15620005d0575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b03861691620006109162000dc8565b600060405180830381855afa9150503d80600081146200064d576040519150601f19603f3d011682016040523d82523d6000602084013e62000652565b606091505b5090925090508115806200066557508051155b1562000675575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b03861691620006b59162000dc8565b600060405180830381855afa9150503d8060008114620006f2576040519150601f19603f3d011682016040523d82523d6000602084013e620006f7565b606091505b5090925090508115806200070a57508051155b156200071a575060009392505050565b5060019392505050565b6001600160a01b03811660009081526002602052604081208054620007499062000de6565b15159392505050565b60006200075e62000ac4565b600080546001600160a01b031687878787876040516200077e9062000b43565b6200078f9695949392919062000e22565b604051809103906000f080158015620007ac573d6000803e3d6000fd5b50905080600185604051620007c2919062000dc8565b908152604080516020928190038301902080546001600160a01b0319166001600160a01b03948516179055918316600090815260029091522062000807858262000f00565b507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee81888888886040516200084195949392919062000fcd565b60405180910390a19695505050505050565b60006200085f62000ac4565b600080546001600160a01b031687878787876040516200087f9062000b51565b620008909695949392919062000e22565b604051809103906000f080158015620008ad573d6000803e3d6000fd5b50905080600185604051620008c3919062000dc8565b908152604080516020928190038301902080546001600160a01b0319166001600160a01b03948516179055918316600090815260029091522062000908858262000f00565b507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f081888888886040516200084195949392919062000fcd565b6200094c62000ac4565b62000958600062000af3565b565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015620009c7575060408051601f3d908101601f19168201909252620009c4918101906200103f565b60015b620009d457506000919050565b92915050565b620009e462000ac4565b6001600160a01b03811662000a1457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b62000a1f8162000af3565b50565b6002602052600090815260409020805462000a3d9062000de6565b80601f016020809104026020016040519081016040528092919081815260200182805462000a6b9062000de6565b801562000abc5780601f1062000a905761010080835404028352916020019162000abc565b820191906000526020600020905b81548152906001019060200180831162000a9e57829003601f168201915b505050505081565b6000546001600160a01b03163314620009585760405163118cdaa760e01b815233600482015260240162000a0b565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200106483390190565b611eb7806200295e83390190565b634e487b7160e01b600052604160045260246000fd5b600082601f83011262000b8757600080fd5b813567ffffffffffffffff8082111562000ba55762000ba562000b5f565b604051601f8301601f19908116603f0116810190828211818310171562000bd05762000bd062000b5f565b8160405283815286602085880101111562000bea57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121562000c1d57600080fd5b813567ffffffffffffffff81111562000c3557600080fd5b62000c438482850162000b75565b949350505050565b60006020828403121562000c5e57600080fd5b81356001600160a01b038116811462000c7657600080fd5b9392505050565b60005b8381101562000c9a57818101518382015260200162000c80565b50506000910152565b6000815180845262000cbd81602086016020860162000c7d565b601f01601f19169290920160200192915050565b60208152600062000c76602083018462000ca3565b600080600080600060a0868803121562000cff57600080fd5b853567ffffffffffffffff8082111562000d1857600080fd5b62000d2689838a0162000b75565b9650602088013591508082111562000d3d57600080fd5b62000d4b89838a0162000b75565b9550604088013591508082111562000d6257600080fd5b62000d7089838a0162000b75565b9450606088013591508082111562000d8757600080fd5b62000d9589838a0162000b75565b9350608088013591508082111562000dac57600080fd5b5062000dbb8882890162000b75565b9150509295509295909350565b6000825162000ddc81846020870162000c7d565b9190910192915050565b600181811c9082168062000dfb57607f821691505b60208210810362000e1c57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b038716815260c06020820181905260009062000e489083018862000ca3565b828103604084015262000e5c818862000ca3565b9050828103606084015262000e72818762000ca3565b9050828103608084015262000e88818662000ca3565b905082810360a084015262000e9e818562000ca3565b9998505050505050505050565b601f82111562000efb576000816000526020600020601f850160051c8101602086101562000ed65750805b601f850160051c820191505b8181101562000ef75782815560010162000ee2565b5050505b505050565b815167ffffffffffffffff81111562000f1d5762000f1d62000b5f565b62000f358162000f2e845462000de6565b8462000eab565b602080601f83116001811462000f6d576000841562000f545750858301515b600019600386901b1c1916600185901b17855562000ef7565b600085815260208120601f198616915b8281101562000f9e5788860151825594840194600190910190840162000f7d565b508582101562000fbd5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b038616815260a06020820181905260009062000ff39083018762000ca3565b828103604084015262001007818762000ca3565b905082810360608401526200101d818662000ca3565b9050828103608084015262001033818562000ca3565b98975050505050505050565b6000602082840312156200105257600080fd5b8151801515811462000c7657600080fdfe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212205a8199658d4eaad2b10696323e0bc0215d35ed43fe73c3637316e44e6d8ca31864736f6c6343000817003360806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212206ebc33968f0bb2aac75fa88729c43c34a634938367a10e417cf26ce7e65b108764736f6c63430008170033a2646970667358221220a26f238ed62e7e34bbbb8acd7b64f9737843d19754822adfb4ce059e7e1743e064736f6c63430008170033" + "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611414806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004611029565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d61013836600461107b565b6102bc565b005b61015261014d36600461107b565b610336565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004611029565b610726565b61013d610757565b61013d61019c366004611029565b61076b565b6000546001600160a01b031661010d565b61013d6101c0366004611098565b61086d565b6101d86101d336600461107b565b610986565b604051610121919061113a565b61013d6101f3366004611098565b6109f9565b61015261020636600461107b565b610aca565b61010d61021936600461114d565b610b40565b61015261022c36600461107b565b610c15565b61013d61023f36600461107b565b610c84565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc9061027590859060040161113a565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611242565b92915050565b6102c4610cc2565b6102cd81610cef565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161037c919061125f565b600060405180830381855afa9150503d80600081146103b7576040519150601f19603f3d011682016040523d82523d6000602084013e6103bc565b606091505b50915091508115806103cd57508051155b156103dc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610429919061125f565b600060405180830381855afa9150503d8060008114610464576040519150601f19603f3d011682016040523d82523d6000602084013e610469565b606091505b50909250905081158061047b57508051155b1561048a575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104de919061125f565b600060405180830381855afa9150503d8060008114610519576040519150601f19603f3d011682016040523d82523d6000602084013e61051e565b606091505b50909250905081158061053057508051155b1561053f575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161057d9161125f565b600060405180830381855afa9150503d80600081146105b8576040519150601f19603f3d011682016040523d82523d6000602084013e6105bd565b606091505b5090925090508115806105cf57508051155b156105de575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161061c9161125f565b600060405180830381855afa9150503d8060008114610657576040519150601f19603f3d011682016040523d82523d6000602084013e61065c565b606091505b50909250905081158061066e57508051155b1561067d575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106bb9161125f565b600060405180830381855afa9150503d80600081146106f6576040519150601f19603f3d011682016040523d82523d6000602084013e6106fb565b606091505b50909250905081158061070d57508051155b1561071c575060009392505050565b5060019392505050565b6000600282604051610738919061125f565b908152604051908190036020019020546001600160a01b031692915050565b61075f610cc2565b6107696000610d61565b565b610773610cc2565b6000600282604051610785919061125f565b908152604051908190036020019020546001600160a01b03169050806108055760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610815919061125f565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b90610861908490849061127b565b60405180910390a15050565b610875610cc2565b61087e81610db1565b60006001600160a01b0316600283604051610899919061125f565b908152604051908190036020019020546001600160a01b0316146109165760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107fc565b80600283604051610927919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f90610861908490849061127b565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b691908101906112a5565b610a01610cc2565b610a0a81610db1565b6000600283604051610a1c919061125f565b908152604051908190036020019020546001600160a01b0316905080610a4b57610a46838361086d565b505050565b81600284604051610a5c919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610abd9085908490869061131c565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b34575060408051601f3d908101601f19168201909252610b319181019061134f565b60015b6102b657506000919050565b6000610b4a610cc2565b6000600288604051610b5c919061125f565b908152604051908190036020019020546001600160a01b03169050610b8081610db1565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bb9908c908c908c908c908c90600401611371565b6020604051808303816000875af1158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611242565b9050610c088682610e23565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061134f565b610c8c610cc2565b6001600160a01b038116610cb657604051631e4fbdf760e01b8152600060048201526024016107fc565b610cbf81610d61565b50565b6000546001600160a01b031633146107695760405163118cdaa760e01b81523360048201526024016107fc565b610cf881610e8e565b610d098163976998cb60e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107fc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610dba81610e8e565b610dcb8163476d399760e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107fc565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e57908690869060040161127b565b600060405180830381600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cbf5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107fc565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f51575060408051601f3d908101601f19168201909252610f4e9181019061134f565b60015b610f5d575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa357610fa3610f64565b604052919050565b600067ffffffffffffffff821115610fc557610fc5610f64565b50601f01601f191660200190565b600082601f830112610fe457600080fd5b8135610ff7610ff282610fab565b610f7a565b81815284602083860101111561100c57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561103b57600080fd5b813567ffffffffffffffff81111561105257600080fd5b61105e84828501610fd3565b949350505050565b6001600160a01b0381168114610cbf57600080fd5b60006020828403121561108d57600080fd5b8135610f5d81611066565b600080604083850312156110ab57600080fd5b823567ffffffffffffffff8111156110c257600080fd5b6110ce85828601610fd3565b92505060208301356110df81611066565b809150509250929050565b60005b838110156111055781810151838201526020016110ed565b50506000910152565b600081518084526111268160208601602086016110ea565b601f01601f19169290920160200192915050565b602081526000610f5d602083018461110e565b60008060008060008060c0878903121561116657600080fd5b863567ffffffffffffffff8082111561117e57600080fd5b61118a8a838b01610fd3565b975060208901359150808211156111a057600080fd5b6111ac8a838b01610fd3565b965060408901359150808211156111c257600080fd5b6111ce8a838b01610fd3565b955060608901359150808211156111e457600080fd5b6111f08a838b01610fd3565b9450608089013591508082111561120657600080fd5b6112128a838b01610fd3565b935060a089013591508082111561122857600080fd5b5061123589828a01610fd3565b9150509295509295509295565b60006020828403121561125457600080fd5b8151610f5d81611066565b600082516112718184602087016110ea565b9190910192915050565b60408152600061128e604083018561110e565b905060018060a01b03831660208301529392505050565b6000602082840312156112b757600080fd5b815167ffffffffffffffff8111156112ce57600080fd5b8201601f810184136112df57600080fd5b80516112ed610ff282610fab565b81815285602083850101111561130257600080fd5b6113138260208301602086016110ea565b95945050505050565b60608152600061132f606083018661110e565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561136157600080fd5b81518015158114610f5d57600080fd5b60a08152600061138460a083018861110e565b8281036020840152611396818861110e565b905082810360408401526113aa818761110e565b905082810360608401526113be818661110e565b905082810360808401526113d2818561110e565b9897505050505050505056fea2646970667358221220b05065a8bb324fb253b0370f16d886e6b31389df606099d521bff6670967c17464736f6c63430008170033" }, { "type": "UInt64", diff --git a/solidity/src/FlowBridgeFactory.sol b/solidity/src/FlowBridgeFactory.sol index c1e487a3..f3c2c295 100644 --- a/solidity/src/FlowBridgeFactory.sol +++ b/solidity/src/FlowBridgeFactory.sol @@ -184,7 +184,7 @@ contract FlowBridgeFactory is Ownable { function setDeploymentRegistry(address _deploymentRegistry) public onlyOwner { _requireIsValidRegistry(_deploymentRegistry); - DeploymentRegistryUpdated(deploymentRegistry, _deploymentRegistry); + emit DeploymentRegistryUpdated(deploymentRegistry, _deploymentRegistry); deploymentRegistry = _deploymentRegistry; } From 5977bcfc47dad047cbd6cae94a3514c8c007d1ba Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Mon, 6 May 2024 15:40:34 -0500 Subject: [PATCH 07/18] integrate updated solidity contracts --- .../contracts/bridge/FlowEVMBridgeUtils.cdc | 8 +- .../tests/flow_evm_bridge_handler_tests.cdc | 12 +- cadence/tests/flow_evm_bridge_tests.cdc | 1680 ++++++++--------- cadence/tests/test_helpers.cdc | 23 +- .../bridge/admin/evm/add_deployer.cdc | 2 +- 5 files changed, 859 insertions(+), 866 deletions(-) diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index 0a442258..3974f693 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -188,7 +188,7 @@ contract FlowEVMBridgeUtils { fun isEVMContractBridgeOwned(evmContractAddress: EVM.EVMAddress): Bool { // Ask the bridge factory if the given contract address was deployed by the bridge let callResult = self.call( - signature: "isFactoryDeployed(address)", + signature: "isBridgeDeployed(address)", targetEVMAddress: self.bridgeFactoryEVMAddress, args: [evmContractAddress], gasLimit: 60000, @@ -1241,11 +1241,11 @@ contract FlowEVMBridgeUtils { contractURI: String, isERC721: Bool ): EVM.EVMAddress { - let signature = isERC721 ? "deployERC721(string,string,string,string,string)" : "deployERC20(string,string,string,string,string)" + let deployerTag = isERC721 ? "ERC721" : "ERC20" let deployResult: EVM.Result = self.call( - signature: signature, + signature: "deploy(string,string,string,string,string,string)", targetEVMAddress: self.bridgeFactoryEVMAddress, - args: [name, symbol, cadenceAddress.toString(), flowIdentifier, contractURI], + args: [deployerTag, name, symbol, cadenceAddress.toString(), flowIdentifier, contractURI], gasLimit: 15000000, value: 0.0 ) diff --git a/cadence/tests/flow_evm_bridge_handler_tests.cdc b/cadence/tests/flow_evm_bridge_handler_tests.cdc index dfca249c..3cf54d27 100644 --- a/cadence/tests/flow_evm_bridge_handler_tests.cdc +++ b/cadence/tests/flow_evm_bridge_handler_tests.cdc @@ -125,13 +125,12 @@ fun setup() { // Get the deployed contract address from the latest EVM event let evts = Test.eventsOfType(Type()) Test.assertEqual(2, evts.length) - let factoryDeploymentEvent = evts[0] as! EVM.TransactionExecuted - let factoryAddressHex = factoryDeploymentEvent.contractAddress + let factoryAddressHex = getEVMAddressHexFromEvents(evts, idx: 0) err = Test.deployContract( name: "FlowEVMBridgeUtils", path: "../contracts/bridge/FlowEVMBridgeUtils.cdc", - arguments: [factoryAddressHex.slice(from: 2, upTo: factoryAddressHex.length)] + arguments: [factoryAddressHex] ) Test.expect(err, Test.beNil()) err = Test.deployContract( @@ -345,12 +344,7 @@ fun testDeployERC20Succeeds() { let evts = Test.eventsOfType(Type()) Test.assertEqual(7, evts.length) - let erc20DeploymentEvent = evts[6] as! EVM.TransactionExecuted - // remove 0x prefix - erc20AddressHex = erc20DeploymentEvent.contractAddress.slice( - from: 2, - upTo: erc20DeploymentEvent.contractAddress.length - ).toLower() + erc20AddressHex = getEVMAddressHexFromEvents(evts, idx: 6) } // Set the TokenHandler's targetEVMAddress to the deployed ERC20 contract address diff --git a/cadence/tests/flow_evm_bridge_tests.cdc b/cadence/tests/flow_evm_bridge_tests.cdc index f1902011..de469faa 100644 --- a/cadence/tests/flow_evm_bridge_tests.cdc +++ b/cadence/tests/flow_evm_bridge_tests.cdc @@ -157,15 +157,9 @@ fun setup() { // Assign contract addresses var evts = Test.eventsOfType(Type()) Test.assertEqual(5, evts.length) - let registryDeploymentEvent = evts[2] as! EVM.TransactionExecuted - let erc20DeployerDeploymentEvent = evts[3] as! EVM.TransactionExecuted - let erc721DeployerDeploymentEvent = evts[4] as! EVM.TransactionExecuted - registryAddressHex = registryDeploymentEvent.contractAddress.slice(from: 2, upTo: registryDeploymentEvent.contractAddress.length).toLower() - erc20DeployerAddressHex = erc20DeployerDeploymentEvent.contractAddress.slice(from: 2, upTo: erc20DeployerDeploymentEvent.contractAddress.length).toLower() - erc721DeployerAddressHex = erc721DeployerDeploymentEvent.contractAddress.slice(from: 2, upTo: erc721DeployerDeploymentEvent.contractAddress.length).toLower() - Test.assertEqual(registryAddressHex.length, 40) - Test.assertEqual(erc20DeployerAddressHex.length, 40) - Test.assertEqual(erc721DeployerAddressHex.length, 40) + registryAddressHex = getEVMAddressHexFromEvents(evts, idx: 2) + erc20DeployerAddressHex = getEVMAddressHexFromEvents(evts, idx: 3) + erc721DeployerAddressHex = getEVMAddressHexFromEvents(evts, idx: 4) // Deploy factory let deploymentResult = executeTransaction( @@ -177,12 +171,9 @@ fun setup() { // Assign the factory contract address evts = Test.eventsOfType(Type()) Test.assertEqual(6, evts.length) - let factoryDeploymentEvent = evts[5] as! EVM.TransactionExecuted - let factoryAddressHex = factoryDeploymentEvent.contractAddress.slice(from: 2, upTo: factoryDeploymentEvent.contractAddress.length).toLower() + let factoryAddressHex = getEVMAddressHexFromEvents(evts, idx: 5) Test.assertEqual(factoryAddressHex.length, 40) - log(factoryAddressHex) - err = Test.deployContract( name: "FlowEVMBridgeUtils", path: "../contracts/bridge/FlowEVMBridgeUtils.cdc", @@ -334,849 +325,838 @@ fun setup() { /* --- ASSET & ACCOUNT SETUP - Configure test accounts with assets to bridge --- */ -// access(all) -// fun testDeployERC721Succeeds() { -// let erc721DeployResult = executeTransaction( -// "../transactions/evm/deploy.cdc", -// [getCompiledERC721Bytecode(), UInt64(15_000_000), 0.0], -// exampleERCAccount -// ) -// Test.expect(erc721DeployResult, Test.beSucceeded()) +access(all) +fun testDeployERC721Succeeds() { + let erc721DeployResult = executeTransaction( + "../transactions/evm/deploy.cdc", + [getCompiledERC721Bytecode(), UInt64(15_000_000), 0.0], + exampleERCAccount + ) + Test.expect(erc721DeployResult, Test.beSucceeded()) -// // Get ERC721 & ERC20 deployed contract addresses -// let evts = Test.eventsOfType(Type()) -// Test.assertEqual(6, evts.length) + // Get ERC721 & ERC20 deployed contract addresses + let evts = Test.eventsOfType(Type()) + Test.assertEqual(15, evts.length) + erc721AddressHex = getEVMAddressHexFromEvents(evts, idx: 14) -// let erc721DeploymentEvent = evts[5] as! EVM.TransactionExecuted -// erc721AddressHex = erc721DeploymentEvent.contractAddress.slice(from: 2, upTo: erc721DeploymentEvent.contractAddress.length).toLower() +} + +access(all) +fun testDeployERC20Succeeds() { + let erc20DeployResult = executeTransaction( + "../transactions/evm/deploy.cdc", + [getCompiledERC20Bytecode(), UInt64(15_000_000), 0.0], + exampleERCAccount + ) + Test.expect(erc20DeployResult, Test.beSucceeded()) -// Test.assertEqual(40, erc721AddressHex.length) - -// log("ERC721 Address: ".concat(erc721AddressHex)) -// } - -// access(all) -// fun testDeployERC20Succeeds() { -// let erc20DeployResult = executeTransaction( -// "../transactions/evm/deploy.cdc", -// [getCompiledERC20Bytecode(), UInt64(15_000_000), 0.0], -// exampleERCAccount -// ) -// Test.expect(erc20DeployResult, Test.beSucceeded()) + // Get ERC721 & ERC20 deployed contract addresses + let evts = Test.eventsOfType(Type()) + Test.assertEqual(16, evts.length) + erc20AddressHex = getEVMAddressHexFromEvents(evts, idx: 15) -// // Get ERC721 & ERC20 deployed contract addresses -// let evts = Test.eventsOfType(Type()) -// Test.assertEqual(7, evts.length) +} -// let erc20DeploymentEvent = evts[6] as! EVM.TransactionExecuted -// erc20AddressHex = erc20DeploymentEvent.contractAddress.slice(from: 2, upTo: erc20DeploymentEvent.contractAddress.length).toLower() +access(all) +fun testCreateCOASucceeds() { + transferFlow(signer: serviceAccount, recipient: alice.address, amount: 1_000.0) + createCOA(signer: alice, fundingAmount: 100.0) -// Test.assertEqual(40, erc20AddressHex.length) - -// log("ERC20 Address: ".concat(erc20AddressHex)) -// } - -// access(all) -// fun testCreateCOASucceeds() { -// transferFlow(signer: serviceAccount, recipient: alice.address, amount: 1_000.0) -// createCOA(signer: alice, fundingAmount: 100.0) - -// let coaAddressHex = getCOAAddressHex(atFlowAddress: alice.address) -// } - -// access(all) -// fun testBridgeFlowToEVMSucceeds() { -// // Get $FLOW balances before, making assertions based on values from previous case -// let cadenceBalanceBefore = getBalance(ownerAddr: alice.address, storagePathIdentifier: "flowTokenVault") -// ?? panic("Problem getting $FLOW balance") -// Test.assertEqual(900.0, cadenceBalanceBefore) - -// // Get EVM $FLOW balance before -// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// let evmBalanceBefore = getEVMFlowBalance(of: aliceCOAAddressHex) -// Test.assertEqual(100.0, evmBalanceBefore) - -// // Execute bridge to EVM -// let bridgeAmount = 100.0 -// bridgeTokensToEVM( -// signer: alice, -// contractAddr: Address(0x03), -// contractName: "FlowToken", -// amount: bridgeAmount, -// beFailed: false -// ) - -// // Confirm Alice's token balance is now 0.0 -// let cadenceBalanceAfter = getBalance(ownerAddr: alice.address, storagePathIdentifier: "flowTokenVault") -// ?? panic("Problem getting $FLOW balance") -// Test.assertEqual(cadenceBalanceBefore - bridgeAmount, cadenceBalanceAfter) - -// // Confirm balance on EVM side has been updated -// let evmBalanceAfter = getEVMFlowBalance(of: aliceCOAAddressHex) -// Test.assertEqual(evmBalanceBefore + bridgeAmount, evmBalanceAfter) -// } - -// access(all) -// fun testMintExampleNFTSucceeds() { -// let setupCollectionResult = executeTransaction( -// "../transactions/example-assets/example-nft/setup_collection.cdc", -// [], -// alice -// ) -// Test.expect(setupCollectionResult, Test.beSucceeded()) - -// let mintExampleNFTResult = executeTransaction( -// "../transactions/example-assets/example-nft/mint_nft.cdc", -// [alice.address, exampleNFTTokenName, exampleNFTTokenDescription, exampleNFTTokenThumbnail, [], [], []], -// exampleNFTAccount -// ) -// Test.expect(mintExampleNFTResult, Test.beSucceeded()) - -// let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") -// Test.assertEqual(1, aliceOwnedIDs.length) - -// let events = Test.eventsOfType(Type()) -// Test.assertEqual(1, events.length) -// let evt = events[0] as! NonFungibleToken.Deposited -// mintedNFTID = evt.id - -// Test.assertEqual(aliceOwnedIDs[0], mintedNFTID) -// } - -// access(all) -// fun testMintExampleTokenSucceeds() { -// let setupVaultResult = executeTransaction( -// "../transactions/example-assets/example-token/setup_vault.cdc", -// [], -// alice -// ) -// Test.expect(setupVaultResult, Test.beSucceeded()) - -// let mintExampleTokenResult = executeTransaction( -// "../transactions/example-assets/example-token/mint_tokens.cdc", -// [alice.address, exampleTokenMintAmount], -// exampleTokenAccount -// ) -// Test.expect(mintExampleTokenResult, Test.beSucceeded()) - -// let aliceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") -// ?? panic("Problem getting ExampleToken balance") -// Test.assertEqual(exampleTokenMintAmount, aliceBalance) - -// let events = Test.eventsOfType(Type()) -// let evt = events[events.length - 1] as! FungibleToken.Deposited - -// Test.assertEqual(aliceBalance, evt.amount) -// } - -// access(all) -// fun testMintERC721Succeeds() { -// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// Test.assertEqual(40, erc721AddressHex.length) - -// let mintERC721Result = executeTransaction( -// "../transactions/example-assets/evm-assets/safe_mint_erc721.cdc", -// [aliceCOAAddressHex, erc721ID, erc721URI, erc721AddressHex, UInt64(200_000)], -// exampleERCAccount -// ) -// Test.expect(mintERC721Result, Test.beSucceeded()) - -// let aliceIsOwner = isOwner(of: erc721ID, ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: erc721AddressHex) -// Test.assertEqual(true, aliceIsOwner) -// } - -// access(all) -// fun testMintERC20Succeeds() { -// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// let mintERC20Result = executeTransaction( -// "../transactions/example-assets/evm-assets/mint_erc20.cdc", -// [aliceCOAAddressHex, erc20MintAmount, erc20AddressHex, UInt64(200_000)], -// exampleERCAccount -// ) -// Test.expect(mintERC20Result, Test.beSucceeded()) - -// let aliceBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) -// Test.assertEqual(erc20MintAmount, aliceBalance) -// } - -// access(all) -// fun testUpdateBridgeFeesSucceeds() { -// fun getFee(feeType: String): UFix64 { -// let feeResult = executeScript( -// "../scripts/config/get_".concat(feeType).concat(".cdc"), -// [] -// ) -// Test.expect(feeResult, Test.beSucceeded()) -// return feeResult.returnValue as! UFix64? ?? panic("Problem getting fee: ".concat(feeType)) -// } - -// fun calculateBridgeFee(bytesUsed: UInt64): UFix64 { -// let calculatedResult = executeScript( -// "../scripts/bridge/calculate_bridge_fee.cdc", -// [bytesUsed] -// ) -// Test.expect(calculatedResult, Test.beSucceeded()) -// return calculatedResult.returnValue as! UFix64? ?? panic("Problem getting calculated fee") -// } - -// let bytesUsed: UInt64 = 1024 -// let expectedFinalFee = FlowStorageFees.storageCapacityToFlow( -// FlowStorageFees.convertUInt64StorageBytesToUFix64Megabytes(bytesUsed) -// ) + expectedBaseFee - -// // Validate the initialized values are set to 0.0 -// var actualOnboardFee = getFee(feeType: "onboard_fee") -// var actualBaseFee = getFee(feeType: "base_fee") - -// Test.assertEqual(0.0, actualOnboardFee) -// Test.assertEqual(0.0, actualBaseFee) - -// var actualCalculated = calculateBridgeFee(bytesUsed: bytesUsed) -// Test.assertEqual(0.0, actualCalculated) - -// // Set the fees to new values -// let updateOnboardFeeResult = executeTransaction( -// "../transactions/bridge/admin/fee/update_onboard_fee.cdc", -// [expectedOnboardFee], -// bridgeAccount -// ) -// Test.expect(updateOnboardFeeResult, Test.beSucceeded()) -// let updateBaseFeeResult = executeTransaction( -// "../transactions/bridge/admin/fee/update_base_fee.cdc", -// [expectedBaseFee], -// bridgeAccount -// ) -// Test.expect(updateBaseFeeResult, Test.beSucceeded()) - -// // Validate the values have been updated -// actualOnboardFee = getFee(feeType: "onboard_fee") -// actualBaseFee = getFee(feeType: "base_fee") - -// Test.assertEqual(expectedOnboardFee, actualOnboardFee) -// Test.assertEqual(expectedBaseFee, actualBaseFee) - -// actualCalculated = calculateBridgeFee(bytesUsed: bytesUsed) -// Test.assertEqual(expectedFinalFee, actualCalculated) -// } - -// /* --- ONBOARDING - Test asset onboarding to the bridge --- */ - -// access(all) -// fun testOnboardNFTByTypeSucceeds() { -// snapshot = getCurrentBlockHeight() - -// var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(true, requiresOnboarding) - -// var onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", -// [exampleNFTIdentifier], -// alice -// ) -// Test.expect(onboardingResult, Test.beSucceeded()) - -// requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(false, requiresOnboarding) - -// onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", -// [exampleNFTIdentifier], -// alice -// ) -// Test.expect(onboardingResult, Test.beFailed()) -// } - -// access(all) -// fun testOnboardAndBridgeNFTToEVMSucceeds() { -// // Revert to state before ExampleNFT was onboarded -// Test.reset(to: snapshot) - -// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) -// Test.assertEqual(40, aliceCOAAddressHex.length) -// var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") -// Test.assertEqual(1, aliceOwnedIDs.length) -// let aliceID = aliceOwnedIDs[0] - -// var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(true, requiresOnboarding) + let coaAddressHex = getCOAAddressHex(atFlowAddress: alice.address) +} + +access(all) +fun testBridgeFlowToEVMSucceeds() { + // Get $FLOW balances before, making assertions based on values from previous case + let cadenceBalanceBefore = getBalance(ownerAddr: alice.address, storagePathIdentifier: "flowTokenVault") + ?? panic("Problem getting $FLOW balance") + Test.assertEqual(900.0, cadenceBalanceBefore) + + // Get EVM $FLOW balance before + var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + let evmBalanceBefore = getEVMFlowBalance(of: aliceCOAAddressHex) + Test.assertEqual(100.0, evmBalanceBefore) + + // Execute bridge to EVM + let bridgeAmount = 100.0 + bridgeTokensToEVM( + signer: alice, + contractAddr: Address(0x03), + contractName: "FlowToken", + amount: bridgeAmount, + beFailed: false + ) + + // Confirm Alice's token balance is now 0.0 + let cadenceBalanceAfter = getBalance(ownerAddr: alice.address, storagePathIdentifier: "flowTokenVault") + ?? panic("Problem getting $FLOW balance") + Test.assertEqual(cadenceBalanceBefore - bridgeAmount, cadenceBalanceAfter) + + // Confirm balance on EVM side has been updated + let evmBalanceAfter = getEVMFlowBalance(of: aliceCOAAddressHex) + Test.assertEqual(evmBalanceBefore + bridgeAmount, evmBalanceAfter) +} + +access(all) +fun testMintExampleNFTSucceeds() { + let setupCollectionResult = executeTransaction( + "../transactions/example-assets/example-nft/setup_collection.cdc", + [], + alice + ) + Test.expect(setupCollectionResult, Test.beSucceeded()) + + let mintExampleNFTResult = executeTransaction( + "../transactions/example-assets/example-nft/mint_nft.cdc", + [alice.address, exampleNFTTokenName, exampleNFTTokenDescription, exampleNFTTokenThumbnail, [], [], []], + exampleNFTAccount + ) + Test.expect(mintExampleNFTResult, Test.beSucceeded()) + + let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") + Test.assertEqual(1, aliceOwnedIDs.length) + + let events = Test.eventsOfType(Type()) + Test.assertEqual(1, events.length) + let evt = events[0] as! NonFungibleToken.Deposited + mintedNFTID = evt.id + + Test.assertEqual(aliceOwnedIDs[0], mintedNFTID) +} + +access(all) +fun testMintExampleTokenSucceeds() { + let setupVaultResult = executeTransaction( + "../transactions/example-assets/example-token/setup_vault.cdc", + [], + alice + ) + Test.expect(setupVaultResult, Test.beSucceeded()) + + let mintExampleTokenResult = executeTransaction( + "../transactions/example-assets/example-token/mint_tokens.cdc", + [alice.address, exampleTokenMintAmount], + exampleTokenAccount + ) + Test.expect(mintExampleTokenResult, Test.beSucceeded()) + + let aliceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") + ?? panic("Problem getting ExampleToken balance") + Test.assertEqual(exampleTokenMintAmount, aliceBalance) + + let events = Test.eventsOfType(Type()) + let evt = events[events.length - 1] as! FungibleToken.Deposited + + Test.assertEqual(aliceBalance, evt.amount) +} + +access(all) +fun testMintERC721Succeeds() { + let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + Test.assertEqual(40, erc721AddressHex.length) + + let mintERC721Result = executeTransaction( + "../transactions/example-assets/evm-assets/safe_mint_erc721.cdc", + [aliceCOAAddressHex, erc721ID, erc721URI, erc721AddressHex, UInt64(200_000)], + exampleERCAccount + ) + Test.expect(mintERC721Result, Test.beSucceeded()) + + let aliceIsOwner = isOwner(of: erc721ID, ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: erc721AddressHex) + Test.assertEqual(true, aliceIsOwner) +} + +access(all) +fun testMintERC20Succeeds() { + let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + let mintERC20Result = executeTransaction( + "../transactions/example-assets/evm-assets/mint_erc20.cdc", + [aliceCOAAddressHex, erc20MintAmount, erc20AddressHex, UInt64(200_000)], + exampleERCAccount + ) + Test.expect(mintERC20Result, Test.beSucceeded()) + + let aliceBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) + Test.assertEqual(erc20MintAmount, aliceBalance) +} + +access(all) +fun testUpdateBridgeFeesSucceeds() { + fun getFee(feeType: String): UFix64 { + let feeResult = executeScript( + "../scripts/config/get_".concat(feeType).concat(".cdc"), + [] + ) + Test.expect(feeResult, Test.beSucceeded()) + return feeResult.returnValue as! UFix64? ?? panic("Problem getting fee: ".concat(feeType)) + } + + fun calculateBridgeFee(bytesUsed: UInt64): UFix64 { + let calculatedResult = executeScript( + "../scripts/bridge/calculate_bridge_fee.cdc", + [bytesUsed] + ) + Test.expect(calculatedResult, Test.beSucceeded()) + return calculatedResult.returnValue as! UFix64? ?? panic("Problem getting calculated fee") + } + + let bytesUsed: UInt64 = 1024 + let expectedFinalFee = FlowStorageFees.storageCapacityToFlow( + FlowStorageFees.convertUInt64StorageBytesToUFix64Megabytes(bytesUsed) + ) + expectedBaseFee + + // Validate the initialized values are set to 0.0 + var actualOnboardFee = getFee(feeType: "onboard_fee") + var actualBaseFee = getFee(feeType: "base_fee") + + Test.assertEqual(0.0, actualOnboardFee) + Test.assertEqual(0.0, actualBaseFee) + + var actualCalculated = calculateBridgeFee(bytesUsed: bytesUsed) + Test.assertEqual(0.0, actualCalculated) + + // Set the fees to new values + let updateOnboardFeeResult = executeTransaction( + "../transactions/bridge/admin/fee/update_onboard_fee.cdc", + [expectedOnboardFee], + bridgeAccount + ) + Test.expect(updateOnboardFeeResult, Test.beSucceeded()) + let updateBaseFeeResult = executeTransaction( + "../transactions/bridge/admin/fee/update_base_fee.cdc", + [expectedBaseFee], + bridgeAccount + ) + Test.expect(updateBaseFeeResult, Test.beSucceeded()) + + // Validate the values have been updated + actualOnboardFee = getFee(feeType: "onboard_fee") + actualBaseFee = getFee(feeType: "base_fee") + + Test.assertEqual(expectedOnboardFee, actualOnboardFee) + Test.assertEqual(expectedBaseFee, actualBaseFee) + + actualCalculated = calculateBridgeFee(bytesUsed: bytesUsed) + Test.assertEqual(expectedFinalFee, actualCalculated) +} + +/* --- ONBOARDING - Test asset onboarding to the bridge --- */ + +access(all) +fun testOnboardNFTByTypeSucceeds() { + snapshot = getCurrentBlockHeight() + + var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(true, requiresOnboarding) + + var onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", + [exampleNFTIdentifier], + alice + ) + Test.expect(onboardingResult, Test.beSucceeded()) + + requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(false, requiresOnboarding) + + onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", + [exampleNFTIdentifier], + alice + ) + Test.expect(onboardingResult, Test.beFailed()) +} + +access(all) +fun testOnboardAndBridgeNFTToEVMSucceeds() { + // Revert to state before ExampleNFT was onboarded + Test.reset(to: snapshot) + + var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + Test.assertEqual(40, aliceCOAAddressHex.length) + var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") + Test.assertEqual(1, aliceOwnedIDs.length) + let aliceID = aliceOwnedIDs[0] + + var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(true, requiresOnboarding) -// // Execute bridge NFT to EVM - should also onboard the NFT type -// bridgeNFTToEVM( -// signer: alice, -// contractAddr: exampleNFTAccount.address, -// contractName: "ExampleNFT", -// nftID: aliceID, -// bridgeAccountAddr: bridgeAccount.address, -// beFailed: false -// ) - -// requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(false, requiresOnboarding) - -// let onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", -// [exampleNFTIdentifier], -// alice -// ) -// Test.expect(onboardingResult, Test.beFailed()) - -// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) -// Test.assertEqual(40, associatedEVMAddressHex.length) - -// // Confirm the NFT is no longer in Alice's Collection -// aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") -// Test.assertEqual(0, aliceOwnedIDs.length) - -// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation -// let isOwnerResult = executeScript( -// "../scripts/utils/is_owner.cdc", -// [UInt256(mintedNFTID), aliceCOAAddressHex, associatedEVMAddressHex] -// ) -// Test.expect(isOwnerResult, Test.beSucceeded()) -// Test.assertEqual(true, isOwnerResult.returnValue as! Bool? ?? panic("Problem getting owner status")) -// } - - -// access(all) -// fun testOnboardTokenByTypeSucceeds() { -// var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(true, requiresOnboarding) - -// var onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", -// [exampleTokenIdentifier], -// alice -// ) -// Test.expect(onboardingResult, Test.beSucceeded()) - -// requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(false, requiresOnboarding) - -// onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", -// [exampleTokenIdentifier], -// alice -// ) -// Test.expect(onboardingResult, Test.beFailed()) -// } - -// access(all) -// fun testOnboardAndBridgeTokensToEVMSucceeds() { -// // Revert to state before ExampleNFT was onboarded -// Test.reset(to: snapshot) + // Execute bridge NFT to EVM - should also onboard the NFT type + bridgeNFTToEVM( + signer: alice, + contractAddr: exampleNFTAccount.address, + contractName: "ExampleNFT", + nftID: aliceID, + bridgeAccountAddr: bridgeAccount.address, + beFailed: false + ) + + requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(false, requiresOnboarding) + + let onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", + [exampleNFTIdentifier], + alice + ) + Test.expect(onboardingResult, Test.beFailed()) + + let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) + Test.assertEqual(40, associatedEVMAddressHex.length) + + // Confirm the NFT is no longer in Alice's Collection + aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") + Test.assertEqual(0, aliceOwnedIDs.length) + + // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation + let isOwnerResult = executeScript( + "../scripts/utils/is_owner.cdc", + [UInt256(mintedNFTID), aliceCOAAddressHex, associatedEVMAddressHex] + ) + Test.expect(isOwnerResult, Test.beSucceeded()) + Test.assertEqual(true, isOwnerResult.returnValue as! Bool? ?? panic("Problem getting owner status")) +} + + +access(all) +fun testOnboardTokenByTypeSucceeds() { + var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(true, requiresOnboarding) + + var onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", + [exampleTokenIdentifier], + alice + ) + Test.expect(onboardingResult, Test.beSucceeded()) + + requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(false, requiresOnboarding) + + onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", + [exampleTokenIdentifier], + alice + ) + Test.expect(onboardingResult, Test.beFailed()) +} + +access(all) +fun testOnboardAndBridgeTokensToEVMSucceeds() { + // Revert to state before ExampleNFT was onboarded + Test.reset(to: snapshot) -// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) -// Test.assertEqual(40, aliceCOAAddressHex.length) -// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") -// ?? panic("Could not get ExampleToken balance") - -// var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(true, requiresOnboarding) - -// // Execute bridge to EVM - should also onboard the token type -// bridgeTokensToEVM( -// signer: alice, -// contractAddr: exampleTokenAccount.address, -// contractName: "ExampleToken", -// amount: cadenceBalance, -// beFailed: false -// ) - -// requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(false, requiresOnboarding) - -// let onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", -// [exampleTokenIdentifier], -// alice -// ) -// Test.expect(onboardingResult, Test.beFailed()) - -// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) -// Test.assertEqual(40, associatedEVMAddressHex.length) - -// // Confirm Alice's token balance is now 0.0 -// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") -// ?? panic("Problem getting ExampleToken balance") -// Test.assertEqual(0.0, cadenceBalance) - -// // Confirm balance on EVM side has been updated -// let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) -// let expectedEVMBalance = ufix64ToUInt256(exampleTokenMintAmount, decimals: decimals) -// let evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) -// Test.assertEqual(expectedEVMBalance, evmBalance) -// } - -// access(all) -// fun testBatchOnboardByTypeSucceeds() { -// Test.assert(snapshot != 0, message: "Expected snapshot to be taken before onboarding any types") -// Test.reset(to: snapshot) - -// let nftRequiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(true, nftRequiresOnboarding) -// let tokenRequiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) -// ?? panic("Problem getting onboarding status for type") -// Test.assertEqual(true, tokenRequiresOnboarding) - -// let exampleNFTType = Type<@ExampleNFT.NFT>() -// let exampleTokenType = Type<@ExampleToken.Vault>() -// var onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/batch_onboard_by_type.cdc", -// [[exampleNFTType, exampleTokenType]], -// alice -// ) -// Test.expect(onboardingResult, Test.beSucceeded()) - -// let expectedBatchOnboardingRequired: {Type: Bool?} = { -// exampleNFTType: false, -// exampleTokenType: false -// } -// let batchOnboardingRequiredResult = executeScript( -// "../scripts/bridge/batch_type_requires_onboarding.cdc", -// [[exampleNFTType, exampleTokenType]] -// ) -// Test.expect(batchOnboardingRequiredResult, Test.beSucceeded()) -// let batchRequiresOnboarding = batchOnboardingRequiredResult.returnValue as! {Type: Bool?}? ?? panic("Problem getting onboarding requirement") -// Test.assertEqual(expectedBatchOnboardingRequired, batchRequiresOnboarding) - -// // Should succeed as batch onboarding skips already onboarded types -// onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/batch_onboard_by_type.cdc", -// [[exampleNFTType, exampleTokenType]], -// alice -// ) -// Test.expect(onboardingResult, Test.beSucceeded()) -// } - -// access(all) -// fun testOnboardERC721ByEVMAddressSucceeds() { -// snapshot = getCurrentBlockHeight() - - -// var requiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) -// ?? panic("Problem getting onboarding requirement") -// Test.assertEqual(true, requiresOnboarding) - -// var onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", -// [erc721AddressHex], -// alice -// ) -// Test.expect(onboardingResult, Test.beSucceeded()) - -// requiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) -// ?? panic("Problem getting onboarding requirement") -// Test.assertEqual(false, requiresOnboarding) - -// onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", -// [erc721AddressHex], -// alice -// ) -// Test.expect(onboardingResult, Test.beFailed()) -// } - -// access(all) -// fun testOnboardERC20ByEVMAddressSucceeds() { - -// var requiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) -// ?? panic("Problem getting onboarding requirement") -// Test.assertEqual(true, requiresOnboarding) - -// var onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", -// [erc20AddressHex], -// alice -// ) -// Test.expect(onboardingResult, Test.beSucceeded()) - -// requiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) -// ?? panic("Problem getting onboarding requirement") -// Test.assertEqual(false, requiresOnboarding) - -// onboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", -// [erc20AddressHex], -// alice -// ) -// Test.expect(onboardingResult, Test.beFailed()) -// } - -// access(all) -// fun testBatchOnboardByEVMAddressSucceeds() { -// Test.assert(snapshot != 0, message: "Expected snapshot to be taken before onboarding any EVM contracts") -// Test.reset(to: snapshot) - - -// var erc721RequiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) -// ?? panic("Problem getting onboarding requirement") -// var erc20RequiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) -// ?? panic("Problem getting onboarding requirement") -// Test.assertEqual(true, erc721RequiresOnboarding) -// Test.assertEqual(true, erc20RequiresOnboarding) - -// var batchOnboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/batch_onboard_by_evm_address.cdc", -// [[erc721AddressHex, erc20AddressHex]], -// alice -// ) -// Test.expect(batchOnboardingResult, Test.beSucceeded()) - -// let expectedBatchRequiresOnboarding: {String: Bool?} = { -// erc721AddressHex: false, -// erc20AddressHex: false -// } -// let batchOnboardingRequiredResult = executeScript( -// "../scripts/bridge/batch_evm_address_requires_onboarding.cdc", -// [[erc721AddressHex, erc20AddressHex]] -// ) -// Test.expect(batchOnboardingRequiredResult, Test.beSucceeded()) -// let batchRequiresOnboarding = batchOnboardingRequiredResult.returnValue as! {String: Bool?}? ?? panic("Problem getting onboarding requirement") -// Test.assertEqual(expectedBatchRequiresOnboarding, batchRequiresOnboarding) - -// // Batch onboarding should succeed as it skips already onboarded contracts -// batchOnboardingResult = executeTransaction( -// "../transactions/bridge/onboarding/batch_onboard_by_evm_address.cdc", -// [[erc721AddressHex, erc20AddressHex]], -// alice -// ) -// Test.expect(batchOnboardingResult, Test.beSucceeded()) - -// } - -// /* --- BRIDGING NFTS - Test bridging both Cadence- & EVM-native NFTs --- */ - -// access(all) -// fun testPauseBridgeSucceeds() { -// // Pause the bridge -// let pauseResult = executeTransaction( -// "../transactions/bridge/admin/pause/update_bridge_pause_status.cdc", -// [true], -// bridgeAccount -// ) -// Test.expect(pauseResult, Test.beSucceeded()) -// var isPausedResult = executeScript( -// "../scripts/bridge/is_paused.cdc", -// [] -// ) -// Test.expect(isPausedResult, Test.beSucceeded()) -// Test.assertEqual(true, isPausedResult.returnValue as! Bool? ?? panic("Problem getting pause status")) - -// var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") -// Test.assertEqual(1, aliceOwnedIDs.length) - -// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// // Execute bridge to EVM - should fail after pausing -// bridgeNFTToEVM( -// signer: alice, -// contractAddr: exampleNFTAccount.address, -// contractName: "ExampleNFT", -// nftID: aliceOwnedIDs[0], -// bridgeAccountAddr: bridgeAccount.address, -// beFailed: true -// ) - -// // Unpause bridging -// let unpauseResult = executeTransaction( -// "../transactions/bridge/admin/pause/update_bridge_pause_status.cdc", -// [false], -// bridgeAccount -// ) -// Test.expect(unpauseResult, Test.beSucceeded()) - -// isPausedResult = executeScript( -// "../scripts/bridge/is_paused.cdc", -// [] -// ) -// Test.expect(isPausedResult, Test.beSucceeded()) -// Test.assertEqual(false, isPausedResult.returnValue as! Bool? ?? panic("Problem getting pause status")) -// } - -// access(all) -// fun testBridgeCadenceNativeNFTToEVMSucceeds() { -// var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") -// Test.assertEqual(1, aliceOwnedIDs.length) - -// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// // Execute bridge to EVM -// bridgeNFTToEVM( -// signer: alice, -// contractAddr: exampleNFTAccount.address, -// contractName: "ExampleNFT", -// nftID: aliceOwnedIDs[0], -// bridgeAccountAddr: bridgeAccount.address, -// beFailed: false -// ) - -// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) -// Test.assertEqual(40, associatedEVMAddressHex.length) - -// // Confirm the NFT is no longer in Alice's Collection -// aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") -// Test.assertEqual(0, aliceOwnedIDs.length) - -// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation -// let isOwnerResult = executeScript( -// "../scripts/utils/is_owner.cdc", -// [UInt256(mintedNFTID), aliceCOAAddressHex, associatedEVMAddressHex] -// ) -// Test.expect(isOwnerResult, Test.beSucceeded()) -// Test.assertEqual(true, isOwnerResult.returnValue as! Bool? ?? panic("Problem getting owner status")) -// } - -// access(all) -// fun testBridgeCadenceNativeNFTFromEVMSucceeds() { -// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) -// Test.assertEqual(40, associatedEVMAddressHex.length) - -// // Assert ownership of the bridged NFT in EVM -// var aliceIsOwner = isOwner(of: UInt256(mintedNFTID), ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: associatedEVMAddressHex) -// Test.assertEqual(true, aliceIsOwner) - -// // Execute bridge from EVM -// bridgeNFTFromEVM( -// signer: alice, -// contractAddr: exampleNFTAccount.address, -// contractName: "ExampleNFT", -// erc721ID: UInt256(mintedNFTID), -// bridgeAccountAddr: bridgeAccount.address, -// beFailed: false -// ) - -// // Assert ownership of the bridged NFT in EVM has transferred -// aliceIsOwner = isOwner(of: UInt256(mintedNFTID), ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: associatedEVMAddressHex) -// Test.assertEqual(false, aliceIsOwner) - -// // Assert the NFT is back in Alice's Collection -// let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") -// Test.assertEqual(1, aliceOwnedIDs.length) -// Test.assertEqual(mintedNFTID, aliceOwnedIDs[0]) -// } - -// access(all) -// fun testBridgeEVMNativeNFTFromEVMSucceeds() { - -// let derivedERC721ContractName = deriveBridgedNFTContractName(evmAddressHex: erc721AddressHex) -// let bridgedCollectionPathIdentifier = derivedERC721ContractName.concat("Collection") -// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// bridgeNFTFromEVM( -// signer: alice, -// contractAddr: bridgeAccount.address, -// contractName: derivedERC721ContractName, -// erc721ID: erc721ID, -// bridgeAccountAddr: bridgeAccount.address, -// beFailed: false -// ) - -// let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) -// Test.assertEqual(1, aliceOwnedIDs.length) - -// let evmIDResult = executeScript( -// "../scripts/nft/get_evm_id_from_evm_nft.cdc", -// [alice.address, aliceOwnedIDs[0], StoragePath(identifier: bridgedCollectionPathIdentifier)!] -// ) -// Test.expect(evmIDResult, Test.beSucceeded()) -// let evmID = evmIDResult.returnValue as! UInt256? ?? panic("Problem getting EVM ID") -// Test.assertEqual(erc721ID, evmID) -// } - -// access(all) -// fun testBridgeEVMNativeNFTToEVMSucceeds() { - -// let derivedERC721ContractName = deriveBridgedNFTContractName(evmAddressHex: erc721AddressHex) -// let bridgedCollectionPathIdentifier = derivedERC721ContractName.concat("Collection") -// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) -// Test.assertEqual(1, aliceOwnedIDs.length) - -// bridgeNFTToEVM( -// signer: alice, -// contractAddr: bridgeAccount.address, -// contractName: derivedERC721ContractName, -// nftID: aliceOwnedIDs[0], -// bridgeAccountAddr: bridgeAccount.address, -// beFailed: false -// ) - -// aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) -// Test.assertEqual(0, aliceOwnedIDs.length) - -// let aliceIsOwner = isOwner(of: erc721ID, ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: erc721AddressHex) -// Test.assertEqual(true, aliceIsOwner) -// } - -// /* --- BRIDGING FUNGIBLE TOKENS - Test bridging both Cadence- & EVM-native fungible tokens --- */ - -// access(all) -// fun testBridgeCadenceNativeTokenToEVMSucceeds() { -// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") -// ?? panic("Problem getting ExampleToken balance") -// Test.assert(cadenceBalance == exampleTokenMintAmount) - -// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// // Execute bridge to EVM -// bridgeTokensToEVM( -// signer: alice, -// contractAddr: exampleTokenAccount.address, -// contractName: "ExampleToken", -// amount: cadenceBalance, -// beFailed: false -// ) - -// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) -// Test.assertEqual(40, associatedEVMAddressHex.length) - -// // Confirm Alice's token balance is now 0.0 -// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") -// ?? panic("Problem getting ExampleToken balance") -// Test.assertEqual(0.0, cadenceBalance) - -// // Confirm balance on EVM side has been updated -// let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) -// let expectedEVMBalance = ufix64ToUInt256(exampleTokenMintAmount, decimals: decimals) -// let evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) -// Test.assertEqual(expectedEVMBalance, evmBalance) -// } - -// access(all) -// fun testBridgeCadenceNativeTokenFromEVMSucceeds() { -// let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) -// Test.assertEqual(40, associatedEVMAddressHex.length) + var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + Test.assertEqual(40, aliceCOAAddressHex.length) + var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") + ?? panic("Could not get ExampleToken balance") + + var requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(true, requiresOnboarding) + + // Execute bridge to EVM - should also onboard the token type + bridgeTokensToEVM( + signer: alice, + contractAddr: exampleTokenAccount.address, + contractName: "ExampleToken", + amount: cadenceBalance, + beFailed: false + ) + + requiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(false, requiresOnboarding) + + let onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_type_identifier.cdc", + [exampleTokenIdentifier], + alice + ) + Test.expect(onboardingResult, Test.beFailed()) + + let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) + Test.assertEqual(40, associatedEVMAddressHex.length) + + // Confirm Alice's token balance is now 0.0 + cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") + ?? panic("Problem getting ExampleToken balance") + Test.assertEqual(0.0, cadenceBalance) + + // Confirm balance on EVM side has been updated + let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) + let expectedEVMBalance = ufix64ToUInt256(exampleTokenMintAmount, decimals: decimals) + let evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) + Test.assertEqual(expectedEVMBalance, evmBalance) +} + +access(all) +fun testBatchOnboardByTypeSucceeds() { + Test.assert(snapshot != 0, message: "Expected snapshot to be taken before onboarding any types") + Test.reset(to: snapshot) + + let nftRequiresOnboarding = typeRequiresOnboardingByIdentifier(exampleNFTIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(true, nftRequiresOnboarding) + let tokenRequiresOnboarding = typeRequiresOnboardingByIdentifier(exampleTokenIdentifier) + ?? panic("Problem getting onboarding status for type") + Test.assertEqual(true, tokenRequiresOnboarding) + + let exampleNFTType = Type<@ExampleNFT.NFT>() + let exampleTokenType = Type<@ExampleToken.Vault>() + var onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/batch_onboard_by_type.cdc", + [[exampleNFTType, exampleTokenType]], + alice + ) + Test.expect(onboardingResult, Test.beSucceeded()) + + let expectedBatchOnboardingRequired: {Type: Bool?} = { + exampleNFTType: false, + exampleTokenType: false + } + let batchOnboardingRequiredResult = executeScript( + "../scripts/bridge/batch_type_requires_onboarding.cdc", + [[exampleNFTType, exampleTokenType]] + ) + Test.expect(batchOnboardingRequiredResult, Test.beSucceeded()) + let batchRequiresOnboarding = batchOnboardingRequiredResult.returnValue as! {Type: Bool?}? ?? panic("Problem getting onboarding requirement") + Test.assertEqual(expectedBatchOnboardingRequired, batchRequiresOnboarding) + + // Should succeed as batch onboarding skips already onboarded types + onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/batch_onboard_by_type.cdc", + [[exampleNFTType, exampleTokenType]], + alice + ) + Test.expect(onboardingResult, Test.beSucceeded()) +} + +access(all) +fun testOnboardERC721ByEVMAddressSucceeds() { + snapshot = getCurrentBlockHeight() + + + var requiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) + ?? panic("Problem getting onboarding requirement") + Test.assertEqual(true, requiresOnboarding) + + var onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", + [erc721AddressHex], + alice + ) + Test.expect(onboardingResult, Test.beSucceeded()) + + requiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) + ?? panic("Problem getting onboarding requirement") + Test.assertEqual(false, requiresOnboarding) + + onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", + [erc721AddressHex], + alice + ) + Test.expect(onboardingResult, Test.beFailed()) +} + +access(all) +fun testOnboardERC20ByEVMAddressSucceeds() { + + var requiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) + ?? panic("Problem getting onboarding requirement") + Test.assertEqual(true, requiresOnboarding) + + var onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", + [erc20AddressHex], + alice + ) + Test.expect(onboardingResult, Test.beSucceeded()) + + requiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) + ?? panic("Problem getting onboarding requirement") + Test.assertEqual(false, requiresOnboarding) + + onboardingResult = executeTransaction( + "../transactions/bridge/onboarding/onboard_by_evm_address.cdc", + [erc20AddressHex], + alice + ) + Test.expect(onboardingResult, Test.beFailed()) +} + +access(all) +fun testBatchOnboardByEVMAddressSucceeds() { + Test.assert(snapshot != 0, message: "Expected snapshot to be taken before onboarding any EVM contracts") + Test.reset(to: snapshot) + + var erc721RequiresOnboarding = evmAddressRequiresOnboarding(erc721AddressHex) + ?? panic("Problem getting onboarding requirement") + var erc20RequiresOnboarding = evmAddressRequiresOnboarding(erc20AddressHex) + ?? panic("Problem getting onboarding requirement") + Test.assertEqual(true, erc721RequiresOnboarding) + Test.assertEqual(true, erc20RequiresOnboarding) + + var batchOnboardingResult = executeTransaction( + "../transactions/bridge/onboarding/batch_onboard_by_evm_address.cdc", + [[erc721AddressHex, erc20AddressHex]], + alice + ) + Test.expect(batchOnboardingResult, Test.beSucceeded()) + + let expectedBatchRequiresOnboarding: {String: Bool?} = { + erc721AddressHex: false, + erc20AddressHex: false + } + let batchOnboardingRequiredResult = executeScript( + "../scripts/bridge/batch_evm_address_requires_onboarding.cdc", + [[erc721AddressHex, erc20AddressHex]] + ) + Test.expect(batchOnboardingRequiredResult, Test.beSucceeded()) + let batchRequiresOnboarding = batchOnboardingRequiredResult.returnValue as! {String: Bool?}? ?? panic("Problem getting onboarding requirement") + Test.assertEqual(expectedBatchRequiresOnboarding, batchRequiresOnboarding) + + // Batch onboarding should succeed as it skips already onboarded contracts + batchOnboardingResult = executeTransaction( + "../transactions/bridge/onboarding/batch_onboard_by_evm_address.cdc", + [[erc721AddressHex, erc20AddressHex]], + alice + ) + Test.expect(batchOnboardingResult, Test.beSucceeded()) + +} + +/* --- BRIDGING NFTS - Test bridging both Cadence- & EVM-native NFTs --- */ + +access(all) +fun testPauseBridgeSucceeds() { + // Pause the bridge + let pauseResult = executeTransaction( + "../transactions/bridge/admin/pause/update_bridge_pause_status.cdc", + [true], + bridgeAccount + ) + Test.expect(pauseResult, Test.beSucceeded()) + var isPausedResult = executeScript( + "../scripts/bridge/is_paused.cdc", + [] + ) + Test.expect(isPausedResult, Test.beSucceeded()) + Test.assertEqual(true, isPausedResult.returnValue as! Bool? ?? panic("Problem getting pause status")) + + var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") + Test.assertEqual(1, aliceOwnedIDs.length) + + var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + // Execute bridge to EVM - should fail after pausing + bridgeNFTToEVM( + signer: alice, + contractAddr: exampleNFTAccount.address, + contractName: "ExampleNFT", + nftID: aliceOwnedIDs[0], + bridgeAccountAddr: bridgeAccount.address, + beFailed: true + ) + + // Unpause bridging + let unpauseResult = executeTransaction( + "../transactions/bridge/admin/pause/update_bridge_pause_status.cdc", + [false], + bridgeAccount + ) + Test.expect(unpauseResult, Test.beSucceeded()) + + isPausedResult = executeScript( + "../scripts/bridge/is_paused.cdc", + [] + ) + Test.expect(isPausedResult, Test.beSucceeded()) + Test.assertEqual(false, isPausedResult.returnValue as! Bool? ?? panic("Problem getting pause status")) +} + +access(all) +fun testBridgeCadenceNativeNFTToEVMSucceeds() { + var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") + Test.assertEqual(1, aliceOwnedIDs.length) + + var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + // Execute bridge to EVM + bridgeNFTToEVM( + signer: alice, + contractAddr: exampleNFTAccount.address, + contractName: "ExampleNFT", + nftID: aliceOwnedIDs[0], + bridgeAccountAddr: bridgeAccount.address, + beFailed: false + ) + + let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) + Test.assertEqual(40, associatedEVMAddressHex.length) + + // Confirm the NFT is no longer in Alice's Collection + aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") + Test.assertEqual(0, aliceOwnedIDs.length) + + // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation + let isOwnerResult = executeScript( + "../scripts/utils/is_owner.cdc", + [UInt256(mintedNFTID), aliceCOAAddressHex, associatedEVMAddressHex] + ) + Test.expect(isOwnerResult, Test.beSucceeded()) + Test.assertEqual(true, isOwnerResult.returnValue as! Bool? ?? panic("Problem getting owner status")) +} + +access(all) +fun testBridgeCadenceNativeNFTFromEVMSucceeds() { + let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleNFTIdentifier) + Test.assertEqual(40, associatedEVMAddressHex.length) + + // Assert ownership of the bridged NFT in EVM + var aliceIsOwner = isOwner(of: UInt256(mintedNFTID), ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: associatedEVMAddressHex) + Test.assertEqual(true, aliceIsOwner) + + // Execute bridge from EVM + bridgeNFTFromEVM( + signer: alice, + contractAddr: exampleNFTAccount.address, + contractName: "ExampleNFT", + erc721ID: UInt256(mintedNFTID), + bridgeAccountAddr: bridgeAccount.address, + beFailed: false + ) + + // Assert ownership of the bridged NFT in EVM has transferred + aliceIsOwner = isOwner(of: UInt256(mintedNFTID), ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: associatedEVMAddressHex) + Test.assertEqual(false, aliceIsOwner) + + // Assert the NFT is back in Alice's Collection + let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: "cadenceExampleNFTCollection") + Test.assertEqual(1, aliceOwnedIDs.length) + Test.assertEqual(mintedNFTID, aliceOwnedIDs[0]) +} + +access(all) +fun testBridgeEVMNativeNFTFromEVMSucceeds() { + + let derivedERC721ContractName = deriveBridgedNFTContractName(evmAddressHex: erc721AddressHex) + let bridgedCollectionPathIdentifier = derivedERC721ContractName.concat("Collection") + let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + bridgeNFTFromEVM( + signer: alice, + contractAddr: bridgeAccount.address, + contractName: derivedERC721ContractName, + erc721ID: erc721ID, + bridgeAccountAddr: bridgeAccount.address, + beFailed: false + ) + + let aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) + Test.assertEqual(1, aliceOwnedIDs.length) + + let evmIDResult = executeScript( + "../scripts/nft/get_evm_id_from_evm_nft.cdc", + [alice.address, aliceOwnedIDs[0], StoragePath(identifier: bridgedCollectionPathIdentifier)!] + ) + Test.expect(evmIDResult, Test.beSucceeded()) + let evmID = evmIDResult.returnValue as! UInt256? ?? panic("Problem getting EVM ID") + Test.assertEqual(erc721ID, evmID) +} + +access(all) +fun testBridgeEVMNativeNFTToEVMSucceeds() { + + let derivedERC721ContractName = deriveBridgedNFTContractName(evmAddressHex: erc721AddressHex) + let bridgedCollectionPathIdentifier = derivedERC721ContractName.concat("Collection") + let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + var aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) + Test.assertEqual(1, aliceOwnedIDs.length) + + bridgeNFTToEVM( + signer: alice, + contractAddr: bridgeAccount.address, + contractName: derivedERC721ContractName, + nftID: aliceOwnedIDs[0], + bridgeAccountAddr: bridgeAccount.address, + beFailed: false + ) + + aliceOwnedIDs = getIDs(ownerAddr: alice.address, storagePathIdentifier: bridgedCollectionPathIdentifier) + Test.assertEqual(0, aliceOwnedIDs.length) + + let aliceIsOwner = isOwner(of: erc721ID, ownerEVMAddrHex: aliceCOAAddressHex, erc721AddressHex: erc721AddressHex) + Test.assertEqual(true, aliceIsOwner) +} + +/* --- BRIDGING FUNGIBLE TOKENS - Test bridging both Cadence- & EVM-native fungible tokens --- */ + +access(all) +fun testBridgeCadenceNativeTokenToEVMSucceeds() { + var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") + ?? panic("Problem getting ExampleToken balance") + Test.assert(cadenceBalance == exampleTokenMintAmount) + + var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + // Execute bridge to EVM + bridgeTokensToEVM( + signer: alice, + contractAddr: exampleTokenAccount.address, + contractName: "ExampleToken", + amount: cadenceBalance, + beFailed: false + ) + + let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) + Test.assertEqual(40, associatedEVMAddressHex.length) + + // Confirm Alice's token balance is now 0.0 + cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") + ?? panic("Problem getting ExampleToken balance") + Test.assertEqual(0.0, cadenceBalance) + + // Confirm balance on EVM side has been updated + let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) + let expectedEVMBalance = ufix64ToUInt256(exampleTokenMintAmount, decimals: decimals) + let evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) + Test.assertEqual(expectedEVMBalance, evmBalance) +} + +access(all) +fun testBridgeCadenceNativeTokenFromEVMSucceeds() { + let associatedEVMAddressHex = getAssociatedEVMAddressHex(with: exampleTokenIdentifier) + Test.assertEqual(40, associatedEVMAddressHex.length) -// var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// // Confirm Alice is starting with 0.0 balance in their Cadence Vault -// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") -// ?? panic("Problem getting ExampleToken balance") -// Test.assertEqual(0.0, cadenceBalance) - -// // Get Alice's ERC20 balance & convert to UFix64 -// var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) -// let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) -// let ufixValue = uint256ToUFix64(evmBalance, decimals: decimals) -// // Assert the converted balance is equal to the originally minted amount that was bridged in the previous step -// Test.assertEqual(exampleTokenMintAmount, ufixValue) - -// // Execute bridge from EVM -// bridgeTokensFromEVM( -// signer: alice, -// contractAddr: exampleTokenAccount.address, -// contractName: "ExampleToken", -// amount: evmBalance, -// beFailed: false -// ) - -// // Confirm ExampleToken balance has been bridged back to Alice's Cadence vault -// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") -// ?? panic("Problem getting ExampleToken balance") -// Test.assertEqual(ufixValue, cadenceBalance) - -// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation -// evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) -// Test.assertEqual(UInt256(0), evmBalance) -// } - -// access(all) -// fun testBridgeEVMNativeTokenFromEVMSucceeds() { - -// let derivedERC20ContractName = deriveBridgedTokenContractName(evmAddressHex: erc20AddressHex) -// let bridgedVaultPathIdentifier = derivedERC20ContractName.concat("Vault") -// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation -// var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) -// Test.assertEqual(erc20MintAmount, evmBalance) - -// // Confirm Alice does not yet have a bridged Vault configured -// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) -// Test.assertEqual(nil, cadenceBalance) - -// // Execute bridge from EVM -// bridgeTokensFromEVM( -// signer: alice, -// contractAddr: bridgeAccount.address, -// contractName: derivedERC20ContractName, -// amount: evmBalance, -// beFailed: false -// ) - -// // Confirm EVM balance is no 0 -// evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) -// Test.assertEqual(UInt256(0), evmBalance) - -// // Confirm the Cadence Vault is now configured and contains the bridged balance -// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) -// ?? panic("Bridged token Vault was not found in Alice's account after bridging") -// let decimals = getTokenDecimals(erc20AddressHex: erc20AddressHex) -// let expectedCadenceBalance = uint256ToUFix64(erc20MintAmount, decimals: decimals) -// Test.assertEqual(expectedCadenceBalance, cadenceBalance!) - -// // With the bridge executed, confirm the bridge COA escrows the ERC20 tokens -// let bridgeCOAAddressHex = getCOAAddressHex(atFlowAddress: bridgeAccount.address) -// let bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) -// Test.assertEqual(erc20MintAmount, bridgeCOAEscrowBalance) -// } - -// access(all) -// fun testBridgeEVMNativeTokenToEVMSucceeds() { - -// let derivedERC20ContractName = deriveBridgedTokenContractName(evmAddressHex: erc20AddressHex) -// let bridgedVaultPathIdentifier = derivedERC20ContractName.concat("Vault") -// let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) - -// // Confirm Cadence Vault has the expected balance -// var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) -// ?? panic("Bridged token Vault was not found in Alice's account after bridging") -// let decimals = getTokenDecimals(erc20AddressHex: erc20AddressHex) -// let expectedCadenceBalance = uint256ToUFix64(erc20MintAmount, decimals: decimals) -// Test.assertEqual(expectedCadenceBalance, cadenceBalance) - -// // Confirm EVM balance is 0 -// var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) -// Test.assertEqual(UInt256(0), evmBalance) - -// // Confirm the bridge COA currently escrows the ERC20 tokens we will be bridging -// let bridgeCOAAddressHex = getCOAAddressHex(atFlowAddress: bridgeAccount.address) -// var bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) -// Test.assertEqual(erc20MintAmount, bridgeCOAEscrowBalance) - -// // Execute bridge from EVM -// bridgeTokensToEVM( -// signer: alice, -// contractAddr: bridgeAccount.address, -// contractName: derivedERC20ContractName, -// amount: cadenceBalance, -// beFailed: false -// ) - -// // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation -// evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) -// Test.assertEqual(erc20MintAmount, evmBalance) - -// cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) -// ?? panic("Bridged token Vault was not found in Alice's account after bridging") -// Test.assertEqual(0.0, cadenceBalance) - -// // Confirm the bridge COA no longer escrows the ERC20 tokens -// bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) -// Test.assertEqual(UInt256(0), bridgeCOAEscrowBalance) -// } + var aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + // Confirm Alice is starting with 0.0 balance in their Cadence Vault + var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") + ?? panic("Problem getting ExampleToken balance") + Test.assertEqual(0.0, cadenceBalance) + + // Get Alice's ERC20 balance & convert to UFix64 + var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) + let decimals = getTokenDecimals(erc20AddressHex: associatedEVMAddressHex) + let ufixValue = uint256ToUFix64(evmBalance, decimals: decimals) + // Assert the converted balance is equal to the originally minted amount that was bridged in the previous step + Test.assertEqual(exampleTokenMintAmount, ufixValue) + + // Execute bridge from EVM + bridgeTokensFromEVM( + signer: alice, + contractAddr: exampleTokenAccount.address, + contractName: "ExampleToken", + amount: evmBalance, + beFailed: false + ) + + // Confirm ExampleToken balance has been bridged back to Alice's Cadence vault + cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: "exampleTokenVault") + ?? panic("Problem getting ExampleToken balance") + Test.assertEqual(ufixValue, cadenceBalance) + + // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation + evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: associatedEVMAddressHex) + Test.assertEqual(UInt256(0), evmBalance) +} + +access(all) +fun testBridgeEVMNativeTokenFromEVMSucceeds() { + + let derivedERC20ContractName = deriveBridgedTokenContractName(evmAddressHex: erc20AddressHex) + let bridgedVaultPathIdentifier = derivedERC20ContractName.concat("Vault") + let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation + var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) + Test.assertEqual(erc20MintAmount, evmBalance) + + // Confirm Alice does not yet have a bridged Vault configured + var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) + Test.assertEqual(nil, cadenceBalance) + + // Execute bridge from EVM + bridgeTokensFromEVM( + signer: alice, + contractAddr: bridgeAccount.address, + contractName: derivedERC20ContractName, + amount: evmBalance, + beFailed: false + ) + + // Confirm EVM balance is no 0 + evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) + Test.assertEqual(UInt256(0), evmBalance) + + // Confirm the Cadence Vault is now configured and contains the bridged balance + cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) + ?? panic("Bridged token Vault was not found in Alice's account after bridging") + let decimals = getTokenDecimals(erc20AddressHex: erc20AddressHex) + let expectedCadenceBalance = uint256ToUFix64(erc20MintAmount, decimals: decimals) + Test.assertEqual(expectedCadenceBalance, cadenceBalance!) + + // With the bridge executed, confirm the bridge COA escrows the ERC20 tokens + let bridgeCOAAddressHex = getCOAAddressHex(atFlowAddress: bridgeAccount.address) + let bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) + Test.assertEqual(erc20MintAmount, bridgeCOAEscrowBalance) +} + +access(all) +fun testBridgeEVMNativeTokenToEVMSucceeds() { + + let derivedERC20ContractName = deriveBridgedTokenContractName(evmAddressHex: erc20AddressHex) + let bridgedVaultPathIdentifier = derivedERC20ContractName.concat("Vault") + let aliceCOAAddressHex = getCOAAddressHex(atFlowAddress: alice.address) + + // Confirm Cadence Vault has the expected balance + var cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) + ?? panic("Bridged token Vault was not found in Alice's account after bridging") + let decimals = getTokenDecimals(erc20AddressHex: erc20AddressHex) + let expectedCadenceBalance = uint256ToUFix64(erc20MintAmount, decimals: decimals) + Test.assertEqual(expectedCadenceBalance, cadenceBalance) + + // Confirm EVM balance is 0 + var evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) + Test.assertEqual(UInt256(0), evmBalance) + + // Confirm the bridge COA currently escrows the ERC20 tokens we will be bridging + let bridgeCOAAddressHex = getCOAAddressHex(atFlowAddress: bridgeAccount.address) + var bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) + Test.assertEqual(erc20MintAmount, bridgeCOAEscrowBalance) + + // Execute bridge from EVM + bridgeTokensToEVM( + signer: alice, + contractAddr: bridgeAccount.address, + contractName: derivedERC20ContractName, + amount: cadenceBalance, + beFailed: false + ) + + // Confirm ownership on EVM side with Alice COA as owner of ERC721 representation + evmBalance = balanceOf(evmAddressHex: aliceCOAAddressHex, erc20AddressHex: erc20AddressHex) + Test.assertEqual(erc20MintAmount, evmBalance) + + cadenceBalance = getBalance(ownerAddr: alice.address, storagePathIdentifier: bridgedVaultPathIdentifier) + ?? panic("Bridged token Vault was not found in Alice's account after bridging") + Test.assertEqual(0.0, cadenceBalance) + + // Confirm the bridge COA no longer escrows the ERC20 tokens + bridgeCOAEscrowBalance = balanceOf(evmAddressHex: bridgeCOAAddressHex, erc20AddressHex: erc20AddressHex) + Test.assertEqual(UInt256(0), bridgeCOAEscrowBalance) +} diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc index 52d6b9ac..3931788b 100644 --- a/cadence/tests/test_helpers.cdc +++ b/cadence/tests/test_helpers.cdc @@ -5,14 +5,15 @@ import "NonFungibleToken" import "ExampleNFT" import "ExampleToken" import "FlowStorageFees" +import "EVM" /// This file contains constants for contract code which is used for bridge suite configuration. /// See the python util `get_code_hex.py` to retrieve the hex-encoded Cadence either with or /// without a separator (`{{CONTRACT_NAME}}` used in templates to "chunk" template code). -access(all) let compiledFactoryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6113cd806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004610fe2565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d610138366004611034565b6102bc565b005b61015261014d366004611034565b6102ef565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004610fe2565b6106df565b61013d610710565b61013d61019c366004610fe2565b610724565b6000546001600160a01b031661010d565b61013d6101c0366004611051565b610826565b6101d86101d3366004611034565b61093f565b60405161012191906110f3565b61013d6101f3366004611051565b6109b2565b610152610206366004611034565b610a83565b61010d610219366004611106565b610af9565b61015261022c366004611034565b610bce565b61013d61023f366004611034565b610c3d565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc906102759085906004016110f3565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b691906111fb565b92915050565b6102c4610c7b565b6102cd81610ca8565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b038616916103359190611218565b600060405180830381855afa9150503d8060008114610370576040519150601f19603f3d011682016040523d82523d6000602084013e610375565b606091505b509150915081158061038657508051155b15610395575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b179052516103e29190611218565b600060405180830381855afa9150503d806000811461041d576040519150601f19603f3d011682016040523d82523d6000602084013e610422565b606091505b50909250905081158061043457508051155b15610443575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104979190611218565b600060405180830381855afa9150503d80600081146104d2576040519150601f19603f3d011682016040523d82523d6000602084013e6104d7565b606091505b5090925090508115806104e957508051155b156104f8575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161053691611218565b600060405180830381855afa9150503d8060008114610571576040519150601f19603f3d011682016040523d82523d6000602084013e610576565b606091505b50909250905081158061058857508051155b15610597575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b038616916105d591611218565b600060405180830381855afa9150503d8060008114610610576040519150601f19603f3d011682016040523d82523d6000602084013e610615565b606091505b50909250905081158061062757508051155b15610636575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b0386169161067491611218565b600060405180830381855afa9150503d80600081146106af576040519150601f19603f3d011682016040523d82523d6000602084013e6106b4565b606091505b5090925090508115806106c657508051155b156106d5575060009392505050565b5060019392505050565b60006002826040516106f19190611218565b908152604051908190036020019020546001600160a01b031692915050565b610718610c7b565b6107226000610d1a565b565b61072c610c7b565b600060028260405161073e9190611218565b908152604051908190036020019020546001600160a01b03169050806107be5760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b6002826040516107ce9190611218565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b9061081a9084908490611234565b60405180910390a15050565b61082e610c7b565b61083781610d6a565b60006001600160a01b03166002836040516108529190611218565b908152604051908190036020019020546001600160a01b0316146108cf5760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107b5565b806002836040516108e09190611218565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f9061081a9084908490611234565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa15801561098a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b6919081019061125e565b6109ba610c7b565b6109c381610d6a565b60006002836040516109d59190611218565b908152604051908190036020019020546001600160a01b0316905080610a04576109ff8383610826565b505050565b81600284604051610a159190611218565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610a76908590849086906112d5565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610aed575060408051601f3d908101601f19168201909252610aea91810190611308565b60015b6102b657506000919050565b6000610b03610c7b565b6000600288604051610b159190611218565b908152604051908190036020019020546001600160a01b03169050610b3981610d6a565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610b72908c908c908c908c908c9060040161132a565b6020604051808303816000875af1158015610b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb591906111fb565b9050610bc18682610ddc565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611308565b610c45610c7b565b6001600160a01b038116610c6f57604051631e4fbdf760e01b8152600060048201526024016107b5565b610c7881610d1a565b50565b6000546001600160a01b031633146107225760405163118cdaa760e01b81523360048201526024016107b5565b610cb181610e47565b610cc28163976998cb60e01b610e9d565b610c785760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107b5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610d7381610e47565b610d848163476d399760e01b610e9d565b610c785760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107b5565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e109086908690600401611234565b600060405180830381600087803b158015610e2a57600080fd5b505af1158015610e3e573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610c785760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107b5565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f0a575060408051601f3d908101601f19168201909252610f0791810190611308565b60015b610f16575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610f5c57610f5c610f1d565b604052919050565b600067ffffffffffffffff821115610f7e57610f7e610f1d565b50601f01601f191660200190565b600082601f830112610f9d57600080fd5b8135610fb0610fab82610f64565b610f33565b818152846020838601011115610fc557600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215610ff457600080fd5b813567ffffffffffffffff81111561100b57600080fd5b61101784828501610f8c565b949350505050565b6001600160a01b0381168114610c7857600080fd5b60006020828403121561104657600080fd5b8135610f168161101f565b6000806040838503121561106457600080fd5b823567ffffffffffffffff81111561107b57600080fd5b61108785828601610f8c565b92505060208301356110988161101f565b809150509250929050565b60005b838110156110be5781810151838201526020016110a6565b50506000910152565b600081518084526110df8160208601602086016110a3565b601f01601f19169290920160200192915050565b602081526000610f1660208301846110c7565b60008060008060008060c0878903121561111f57600080fd5b863567ffffffffffffffff8082111561113757600080fd5b6111438a838b01610f8c565b9750602089013591508082111561115957600080fd5b6111658a838b01610f8c565b9650604089013591508082111561117b57600080fd5b6111878a838b01610f8c565b9550606089013591508082111561119d57600080fd5b6111a98a838b01610f8c565b945060808901359150808211156111bf57600080fd5b6111cb8a838b01610f8c565b935060a08901359150808211156111e157600080fd5b506111ee89828a01610f8c565b9150509295509295509295565b60006020828403121561120d57600080fd5b8151610f168161101f565b6000825161122a8184602087016110a3565b9190910192915050565b60408152600061124760408301856110c7565b905060018060a01b03831660208301529392505050565b60006020828403121561127057600080fd5b815167ffffffffffffffff81111561128757600080fd5b8201601f8101841361129857600080fd5b80516112a6610fab82610f64565b8181528560208385010111156112bb57600080fd5b6112cc8260208301602086016110a3565b95945050505050565b6060815260006112e860608301866110c7565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561131a57600080fd5b81518015158114610f1657600080fd5b60a08152600061133d60a08301886110c7565b828103602084015261134f81886110c7565b9050828103604084015261136381876110c7565b9050828103606084015261137781866110c7565b9050828103608084015261138b81856110c7565b9897505050505050505056fea264697066735822122091fccc6734718ef21c20a3579176410521061d6cceb595794bd2fe0fecbff25f64736f6c63430008170033" +access(all) let compiledFactoryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611414806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004611029565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d61013836600461107b565b6102bc565b005b61015261014d36600461107b565b610336565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004611029565b610726565b61013d610757565b61013d61019c366004611029565b61076b565b6000546001600160a01b031661010d565b61013d6101c0366004611098565b61086d565b6101d86101d336600461107b565b610986565b604051610121919061113a565b61013d6101f3366004611098565b6109f9565b61015261020636600461107b565b610aca565b61010d61021936600461114d565b610b40565b61015261022c36600461107b565b610c15565b61013d61023f36600461107b565b610c84565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc9061027590859060040161113a565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611242565b92915050565b6102c4610cc2565b6102cd81610cef565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161037c919061125f565b600060405180830381855afa9150503d80600081146103b7576040519150601f19603f3d011682016040523d82523d6000602084013e6103bc565b606091505b50915091508115806103cd57508051155b156103dc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610429919061125f565b600060405180830381855afa9150503d8060008114610464576040519150601f19603f3d011682016040523d82523d6000602084013e610469565b606091505b50909250905081158061047b57508051155b1561048a575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104de919061125f565b600060405180830381855afa9150503d8060008114610519576040519150601f19603f3d011682016040523d82523d6000602084013e61051e565b606091505b50909250905081158061053057508051155b1561053f575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161057d9161125f565b600060405180830381855afa9150503d80600081146105b8576040519150601f19603f3d011682016040523d82523d6000602084013e6105bd565b606091505b5090925090508115806105cf57508051155b156105de575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161061c9161125f565b600060405180830381855afa9150503d8060008114610657576040519150601f19603f3d011682016040523d82523d6000602084013e61065c565b606091505b50909250905081158061066e57508051155b1561067d575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106bb9161125f565b600060405180830381855afa9150503d80600081146106f6576040519150601f19603f3d011682016040523d82523d6000602084013e6106fb565b606091505b50909250905081158061070d57508051155b1561071c575060009392505050565b5060019392505050565b6000600282604051610738919061125f565b908152604051908190036020019020546001600160a01b031692915050565b61075f610cc2565b6107696000610d61565b565b610773610cc2565b6000600282604051610785919061125f565b908152604051908190036020019020546001600160a01b03169050806108055760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610815919061125f565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b90610861908490849061127b565b60405180910390a15050565b610875610cc2565b61087e81610db1565b60006001600160a01b0316600283604051610899919061125f565b908152604051908190036020019020546001600160a01b0316146109165760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107fc565b80600283604051610927919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f90610861908490849061127b565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b691908101906112a5565b610a01610cc2565b610a0a81610db1565b6000600283604051610a1c919061125f565b908152604051908190036020019020546001600160a01b0316905080610a4b57610a46838361086d565b505050565b81600284604051610a5c919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610abd9085908490869061131c565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b34575060408051601f3d908101601f19168201909252610b319181019061134f565b60015b6102b657506000919050565b6000610b4a610cc2565b6000600288604051610b5c919061125f565b908152604051908190036020019020546001600160a01b03169050610b8081610db1565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bb9908c908c908c908c908c90600401611371565b6020604051808303816000875af1158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611242565b9050610c088682610e23565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061134f565b610c8c610cc2565b6001600160a01b038116610cb657604051631e4fbdf760e01b8152600060048201526024016107fc565b610cbf81610d61565b50565b6000546001600160a01b031633146107695760405163118cdaa760e01b81523360048201526024016107fc565b610cf881610e8e565b610d098163976998cb60e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107fc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610dba81610e8e565b610dcb8163476d399760e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107fc565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e57908690869060040161127b565b600060405180830381600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cbf5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107fc565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f51575060408051601f3d908101601f19168201909252610f4e9181019061134f565b60015b610f5d575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa357610fa3610f64565b604052919050565b600067ffffffffffffffff821115610fc557610fc5610f64565b50601f01601f191660200190565b600082601f830112610fe457600080fd5b8135610ff7610ff282610fab565b610f7a565b81815284602083860101111561100c57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561103b57600080fd5b813567ffffffffffffffff81111561105257600080fd5b61105e84828501610fd3565b949350505050565b6001600160a01b0381168114610cbf57600080fd5b60006020828403121561108d57600080fd5b8135610f5d81611066565b600080604083850312156110ab57600080fd5b823567ffffffffffffffff8111156110c257600080fd5b6110ce85828601610fd3565b92505060208301356110df81611066565b809150509250929050565b60005b838110156111055781810151838201526020016110ed565b50506000910152565b600081518084526111268160208601602086016110ea565b601f01601f19169290920160200192915050565b602081526000610f5d602083018461110e565b60008060008060008060c0878903121561116657600080fd5b863567ffffffffffffffff8082111561117e57600080fd5b61118a8a838b01610fd3565b975060208901359150808211156111a057600080fd5b6111ac8a838b01610fd3565b965060408901359150808211156111c257600080fd5b6111ce8a838b01610fd3565b955060608901359150808211156111e457600080fd5b6111f08a838b01610fd3565b9450608089013591508082111561120657600080fd5b6112128a838b01610fd3565b935060a089013591508082111561122857600080fd5b5061123589828a01610fd3565b9150509295509295509295565b60006020828403121561125457600080fd5b8151610f5d81611066565b600082516112718184602087016110ea565b9190910192915050565b60408152600061128e604083018561110e565b905060018060a01b03831660208301529392505050565b6000602082840312156112b757600080fd5b815167ffffffffffffffff8111156112ce57600080fd5b8201601f810184136112df57600080fd5b80516112ed610ff282610fab565b81815285602083850101111561130257600080fd5b6113138260208301602086016110ea565b95945050505050565b60608152600061132f606083018661110e565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561136157600080fd5b81518015158114610f5d57600080fd5b60a08152600061138460a083018861110e565b8281036020840152611396818861110e565b905082810360408401526113aa818761110e565b905082810360608401526113be818661110e565b905082810360808401526113d2818561110e565b9897505050505050505056fea2646970667358221220b05065a8bb324fb253b0370f16d886e6b31389df606099d521bff6670967c17464736f6c63430008170033" -access(all) let erc20DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212202d573cf4820d94ed241f7d0352db0bcd8eb3161e4cecdd44be2ef4266796a2ed64736f6c63430008170033a26469706673582212207e3abd727ba0dcf3a95051385c15199c608b02d4bd6f0ebea00574a2d1e370df64736f6c63430008170033" +access(all) let erc20DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212202d573cf4820d94ed241f7d0352db0bcd8eb3161e4cecdd44be2ef4266796a2ed64736f6c63430008170033a26469706673582212207f13a0f8d5cef31961e368d802a69dfbafd5e77501cf88fc6c92ecf5c57a9f1064736f6c63430008170033" access(all) let erc721DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612657806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d3660046200043c565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c93660046200051a565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a7565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005fc565b620002bf565b6200010662000142366004620005fc565b6200036b565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b031633146200020b576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a204f6e60448201527f6c792064656c656761746564206465706c6f7965722063616e206465706c6f7960648201526084015b60405180910390fd5b600080546001600160a01b031687878787876040516200022b906200042e565b6200023c969594939291906200066f565b604051809103906000f08015801562000259573d6000803e3d6000fd5b5090507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f0818888888860405162000295959493929190620006f8565b60405180910390a19695505050505050565b620002b1620003af565b620002bd6000620003de565b565b620002c9620003af565b6001600160a01b03811662000349576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a20496e60448201527f76616c69642064656c656761746564206465706c6f7965722061646472657373606482015260840162000202565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000375620003af565b6001600160a01b038116620003a157604051631e4fbdf760e01b81526000600482015260240162000202565b620003ac81620003de565b50565b6000546001600160a01b03163314620002bd5760405163118cdaa760e01b815233600482015260240162000202565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611eb7806200076b83390190565b6000602082840312156200044f57600080fd5b81356001600160e01b0319811681146200046857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049757600080fd5b813567ffffffffffffffff80821115620004b557620004b56200046f565b604051601f8301601f19908116603f01168101908282118183101715620004e057620004e06200046f565b81604052838152866020858801011115620004fa57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200053357600080fd5b853567ffffffffffffffff808211156200054c57600080fd5b6200055a89838a0162000485565b965060208801359150808211156200057157600080fd5b6200057f89838a0162000485565b955060408801359150808211156200059657600080fd5b620005a489838a0162000485565b94506060880135915080821115620005bb57600080fd5b620005c989838a0162000485565b93506080880135915080821115620005e057600080fd5b50620005ef8882890162000485565b9150509295509295909350565b6000602082840312156200060f57600080fd5b81356001600160a01b03811681146200046857600080fd5b6000815180845260005b818110156200064f5760208185018101518683018201520162000631565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006959083018862000627565b8281036040840152620006a9818862000627565b90508281036060840152620006bf818762000627565b90508281036080840152620006d5818662000627565b905082810360a0840152620006eb818562000627565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071e9083018762000627565b828103604084015262000732818762000627565b9050828103606084015262000748818662000627565b905082810360808401526200075e818562000627565b9897505050505050505056fe60806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea2646970667358221220e5b8da7e9f5a8ba0772457fe42d9f13eb90dec0ad70a92e30ac8d5ecd317e92f64736f6c63430008170033a2646970667358221220185b564932a6fb2d0066082694692d9d4ee875e9f7e2bfe408bdf1b3079817e764736f6c63430008170033" @@ -74,6 +75,8 @@ access(all) let bridgedTokenCodeChunks = [ "2e5661756c743e28292c20776974683a2073656c662e65766d546f6b656e436f6e747261637441646472657373290a2020202020202020466c6f7745564d427269646765546f6b656e457363726f772e696e697469616c697a65457363726f77280a202020202020202020202020776974683a203c2d637265617465205661756c742862616c616e63653a20302e30292c0a2020202020202020202020206e616d653a206e616d652c0a20202020202020202020202073796d626f6c3a2073796d626f6c2c0a202020202020202020202020646563696d616c733a20646563696d616c732c0a20202020202020202020202065766d546f6b656e416464726573733a2073656c662e65766d546f6b656e436f6e7472616374416464726573730a2020202020202020290a202020207d0a7d0a" ] +/* --- Bytecode Getters --- */ + access(all) fun getCompiledFactoryBytecode(): String { return compiledFactoryBytecode @@ -119,6 +122,22 @@ fun getBridgedTokenCodeChunks(): [String] { return bridgedTokenCodeChunks } +/* --- Event Value Helpers --- */ + +access(all) +fun getEVMAddressHexFromEvents(_ evts: [AnyStruct], idx: Int): String { + Test.assert(evts.length > idx, message: "Event index out of bounds") + + let evt = evts[idx] as? EVM.TransactionExecuted + ?? panic("Event at index ".concat(idx.toString()).concat(" is not a TransactionExecuted event")) + let emittedAddress = evt.contractAddress + Test.assert(emittedAddress.length != 0, message: "Emitted .contractAddress value is empty") + + let hexAddress = emittedAddress.slice(from: 2, upTo: emittedAddress.length).toLower() + Test.assertEqual(40, hexAddress.length) + return hexAddress +} + /* --- Script Helpers --- */ access(all) diff --git a/cadence/transactions/bridge/admin/evm/add_deployer.cdc b/cadence/transactions/bridge/admin/evm/add_deployer.cdc index 0d592023..804fdd30 100644 --- a/cadence/transactions/bridge/admin/evm/add_deployer.cdc +++ b/cadence/transactions/bridge/admin/evm/add_deployer.cdc @@ -19,7 +19,7 @@ transaction(deployerTag: String, deployerEVMAddressHex: String) { let callResult = self.coa.call( to: FlowEVMBridgeUtils.bridgeFactoryEVMAddress, data: EVM.encodeABIWithSignature( - "addDeployer(string, address)", + "addDeployer(string,address)", [deployerTag, deployerEVMAddress] ), gasLimit: 15_000_000, From e3c90b50c3aeed6670944003e707aa782a377549 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Mon, 6 May 2024 16:12:49 -0500 Subject: [PATCH 08/18] update solidity import patterns & compiled bytecode --- cadence/args/deploy-erc20-deployer-args.json | 14 ++++++++++++++ cadence/args/deploy-erc721-deployer-args.json | 14 ++++++++++++++ cadence/args/deploy-factory-args.json | 2 +- cadence/tests/test_helpers.cdc | 6 +++--- cadence/transactions/evm/create_account.cdc | 1 - solidity/src/FlowBridgeDeploymentRegistry.sol | 6 +++--- solidity/src/FlowBridgeFactory.sol | 7 ++++++- solidity/src/FlowEVMBridgedERC20Deployer.sol | 12 ++++++------ solidity/src/FlowEVMBridgedERC721Deployer.sol | 12 ++++++------ solidity/src/interfaces/BridgePermissions.sol | 6 +++--- .../src/interfaces/FlowEVMDeploymentRegistry.sol | 8 ++++---- solidity/src/interfaces/IBridgePermissions.sol | 7 +++---- solidity/src/interfaces/IFlowEVMBridgeDeployer.sol | 2 +- .../src/interfaces/IFlowEVMDeploymentRegistry.sol | 2 +- solidity/src/templates/FlowEVMBridgedERC20.sol | 8 ++++---- solidity/src/templates/FlowEVMBridgedERC721.sol | 10 +++++----- 16 files changed, 74 insertions(+), 43 deletions(-) create mode 100644 cadence/args/deploy-erc20-deployer-args.json create mode 100644 cadence/args/deploy-erc721-deployer-args.json diff --git a/cadence/args/deploy-erc20-deployer-args.json b/cadence/args/deploy-erc20-deployer-args.json new file mode 100644 index 00000000..58400869 --- /dev/null +++ b/cadence/args/deploy-erc20-deployer-args.json @@ -0,0 +1,14 @@ +[ + { + "type": "String", + "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206fb41458119173f9f1d07720d0b22fbfacf4726505008b5c43816c9902cd0fc464736f6c63430008170033a2646970667358221220fbaaee74b0e14c12923bfbdc4701408031af759f454cf27df9e8defc7658e96264736f6c63430008170033" + }, + { + "type": "UInt64", + "value": "12000000" + }, + { + "type": "UFix64", + "value": "0.0" + } +] \ No newline at end of file diff --git a/cadence/args/deploy-erc721-deployer-args.json b/cadence/args/deploy-erc721-deployer-args.json new file mode 100644 index 00000000..8230383c --- /dev/null +++ b/cadence/args/deploy-erc721-deployer-args.json @@ -0,0 +1,14 @@ +[ + { + "type": "String", + "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612657806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d3660046200043c565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c93660046200051a565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a7565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005fc565b620002bf565b6200010662000142366004620005fc565b6200036b565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b031633146200020b576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a204f6e60448201527f6c792064656c656761746564206465706c6f7965722063616e206465706c6f7960648201526084015b60405180910390fd5b600080546001600160a01b031687878787876040516200022b906200042e565b6200023c969594939291906200066f565b604051809103906000f08015801562000259573d6000803e3d6000fd5b5090507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f0818888888860405162000295959493929190620006f8565b60405180910390a19695505050505050565b620002b1620003af565b620002bd6000620003de565b565b620002c9620003af565b6001600160a01b03811662000349576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a20496e60448201527f76616c69642064656c656761746564206465706c6f7965722061646472657373606482015260840162000202565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000375620003af565b6001600160a01b038116620003a157604051631e4fbdf760e01b81526000600482015260240162000202565b620003ac81620003de565b50565b6000546001600160a01b03163314620002bd5760405163118cdaa760e01b815233600482015260240162000202565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611eb7806200076b83390190565b6000602082840312156200044f57600080fd5b81356001600160e01b0319811681146200046857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049757600080fd5b813567ffffffffffffffff80821115620004b557620004b56200046f565b604051601f8301601f19908116603f01168101908282118183101715620004e057620004e06200046f565b81604052838152866020858801011115620004fa57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200053357600080fd5b853567ffffffffffffffff808211156200054c57600080fd5b6200055a89838a0162000485565b965060208801359150808211156200057157600080fd5b6200057f89838a0162000485565b955060408801359150808211156200059657600080fd5b620005a489838a0162000485565b94506060880135915080821115620005bb57600080fd5b620005c989838a0162000485565b93506080880135915080821115620005e057600080fd5b50620005ef8882890162000485565b9150509295509295909350565b6000602082840312156200060f57600080fd5b81356001600160a01b03811681146200046857600080fd5b6000815180845260005b818110156200064f5760208185018101518683018201520162000631565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006959083018862000627565b8281036040840152620006a9818862000627565b90508281036060840152620006bf818762000627565b90508281036080840152620006d5818662000627565b905082810360a0840152620006eb818562000627565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071e9083018762000627565b828103604084015262000732818762000627565b9050828103606084015262000748818662000627565b905082810360808401526200075e818562000627565b9897505050505050505056fe60806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122074d34aec07c0da793ce5cac74069bf4177b7594babf4fede87db849ea2f57b3764736f6c63430008170033a264697066735822122064104e4f6458f9ff9e5aca71c897aa1948c1b57434e9d83b5f4ce4a9ab5d328564736f6c63430008170033" + }, + { + "type": "UInt64", + "value": "12000000" + }, + { + "type": "UFix64", + "value": "0.0" + } +] \ No newline at end of file diff --git a/cadence/args/deploy-factory-args.json b/cadence/args/deploy-factory-args.json index 9bb00ea0..b89fe17c 100644 --- a/cadence/args/deploy-factory-args.json +++ b/cadence/args/deploy-factory-args.json @@ -1,7 +1,7 @@ [ { "type": "String", - "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611414806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004611029565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d61013836600461107b565b6102bc565b005b61015261014d36600461107b565b610336565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004611029565b610726565b61013d610757565b61013d61019c366004611029565b61076b565b6000546001600160a01b031661010d565b61013d6101c0366004611098565b61086d565b6101d86101d336600461107b565b610986565b604051610121919061113a565b61013d6101f3366004611098565b6109f9565b61015261020636600461107b565b610aca565b61010d61021936600461114d565b610b40565b61015261022c36600461107b565b610c15565b61013d61023f36600461107b565b610c84565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc9061027590859060040161113a565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611242565b92915050565b6102c4610cc2565b6102cd81610cef565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161037c919061125f565b600060405180830381855afa9150503d80600081146103b7576040519150601f19603f3d011682016040523d82523d6000602084013e6103bc565b606091505b50915091508115806103cd57508051155b156103dc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610429919061125f565b600060405180830381855afa9150503d8060008114610464576040519150601f19603f3d011682016040523d82523d6000602084013e610469565b606091505b50909250905081158061047b57508051155b1561048a575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104de919061125f565b600060405180830381855afa9150503d8060008114610519576040519150601f19603f3d011682016040523d82523d6000602084013e61051e565b606091505b50909250905081158061053057508051155b1561053f575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161057d9161125f565b600060405180830381855afa9150503d80600081146105b8576040519150601f19603f3d011682016040523d82523d6000602084013e6105bd565b606091505b5090925090508115806105cf57508051155b156105de575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161061c9161125f565b600060405180830381855afa9150503d8060008114610657576040519150601f19603f3d011682016040523d82523d6000602084013e61065c565b606091505b50909250905081158061066e57508051155b1561067d575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106bb9161125f565b600060405180830381855afa9150503d80600081146106f6576040519150601f19603f3d011682016040523d82523d6000602084013e6106fb565b606091505b50909250905081158061070d57508051155b1561071c575060009392505050565b5060019392505050565b6000600282604051610738919061125f565b908152604051908190036020019020546001600160a01b031692915050565b61075f610cc2565b6107696000610d61565b565b610773610cc2565b6000600282604051610785919061125f565b908152604051908190036020019020546001600160a01b03169050806108055760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610815919061125f565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b90610861908490849061127b565b60405180910390a15050565b610875610cc2565b61087e81610db1565b60006001600160a01b0316600283604051610899919061125f565b908152604051908190036020019020546001600160a01b0316146109165760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107fc565b80600283604051610927919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f90610861908490849061127b565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b691908101906112a5565b610a01610cc2565b610a0a81610db1565b6000600283604051610a1c919061125f565b908152604051908190036020019020546001600160a01b0316905080610a4b57610a46838361086d565b505050565b81600284604051610a5c919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610abd9085908490869061131c565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b34575060408051601f3d908101601f19168201909252610b319181019061134f565b60015b6102b657506000919050565b6000610b4a610cc2565b6000600288604051610b5c919061125f565b908152604051908190036020019020546001600160a01b03169050610b8081610db1565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bb9908c908c908c908c908c90600401611371565b6020604051808303816000875af1158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611242565b9050610c088682610e23565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061134f565b610c8c610cc2565b6001600160a01b038116610cb657604051631e4fbdf760e01b8152600060048201526024016107fc565b610cbf81610d61565b50565b6000546001600160a01b031633146107695760405163118cdaa760e01b81523360048201526024016107fc565b610cf881610e8e565b610d098163976998cb60e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107fc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610dba81610e8e565b610dcb8163476d399760e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107fc565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e57908690869060040161127b565b600060405180830381600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cbf5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107fc565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f51575060408051601f3d908101601f19168201909252610f4e9181019061134f565b60015b610f5d575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa357610fa3610f64565b604052919050565b600067ffffffffffffffff821115610fc557610fc5610f64565b50601f01601f191660200190565b600082601f830112610fe457600080fd5b8135610ff7610ff282610fab565b610f7a565b81815284602083860101111561100c57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561103b57600080fd5b813567ffffffffffffffff81111561105257600080fd5b61105e84828501610fd3565b949350505050565b6001600160a01b0381168114610cbf57600080fd5b60006020828403121561108d57600080fd5b8135610f5d81611066565b600080604083850312156110ab57600080fd5b823567ffffffffffffffff8111156110c257600080fd5b6110ce85828601610fd3565b92505060208301356110df81611066565b809150509250929050565b60005b838110156111055781810151838201526020016110ed565b50506000910152565b600081518084526111268160208601602086016110ea565b601f01601f19169290920160200192915050565b602081526000610f5d602083018461110e565b60008060008060008060c0878903121561116657600080fd5b863567ffffffffffffffff8082111561117e57600080fd5b61118a8a838b01610fd3565b975060208901359150808211156111a057600080fd5b6111ac8a838b01610fd3565b965060408901359150808211156111c257600080fd5b6111ce8a838b01610fd3565b955060608901359150808211156111e457600080fd5b6111f08a838b01610fd3565b9450608089013591508082111561120657600080fd5b6112128a838b01610fd3565b935060a089013591508082111561122857600080fd5b5061123589828a01610fd3565b9150509295509295509295565b60006020828403121561125457600080fd5b8151610f5d81611066565b600082516112718184602087016110ea565b9190910192915050565b60408152600061128e604083018561110e565b905060018060a01b03831660208301529392505050565b6000602082840312156112b757600080fd5b815167ffffffffffffffff8111156112ce57600080fd5b8201601f810184136112df57600080fd5b80516112ed610ff282610fab565b81815285602083850101111561130257600080fd5b6113138260208301602086016110ea565b95945050505050565b60608152600061132f606083018661110e565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561136157600080fd5b81518015158114610f5d57600080fd5b60a08152600061138460a083018861110e565b8281036020840152611396818861110e565b905082810360408401526113aa818761110e565b905082810360608401526113be818661110e565b905082810360808401526113d2818561110e565b9897505050505050505056fea2646970667358221220b05065a8bb324fb253b0370f16d886e6b31389df606099d521bff6670967c17464736f6c63430008170033" + "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611414806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004611029565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d61013836600461107b565b6102bc565b005b61015261014d36600461107b565b610336565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004611029565b610726565b61013d610757565b61013d61019c366004611029565b61076b565b6000546001600160a01b031661010d565b61013d6101c0366004611098565b61086d565b6101d86101d336600461107b565b610986565b604051610121919061113a565b61013d6101f3366004611098565b6109f9565b61015261020636600461107b565b610aca565b61010d61021936600461114d565b610b40565b61015261022c36600461107b565b610c15565b61013d61023f36600461107b565b610c84565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc9061027590859060040161113a565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611242565b92915050565b6102c4610cc2565b6102cd81610cef565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161037c919061125f565b600060405180830381855afa9150503d80600081146103b7576040519150601f19603f3d011682016040523d82523d6000602084013e6103bc565b606091505b50915091508115806103cd57508051155b156103dc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610429919061125f565b600060405180830381855afa9150503d8060008114610464576040519150601f19603f3d011682016040523d82523d6000602084013e610469565b606091505b50909250905081158061047b57508051155b1561048a575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104de919061125f565b600060405180830381855afa9150503d8060008114610519576040519150601f19603f3d011682016040523d82523d6000602084013e61051e565b606091505b50909250905081158061053057508051155b1561053f575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161057d9161125f565b600060405180830381855afa9150503d80600081146105b8576040519150601f19603f3d011682016040523d82523d6000602084013e6105bd565b606091505b5090925090508115806105cf57508051155b156105de575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161061c9161125f565b600060405180830381855afa9150503d8060008114610657576040519150601f19603f3d011682016040523d82523d6000602084013e61065c565b606091505b50909250905081158061066e57508051155b1561067d575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106bb9161125f565b600060405180830381855afa9150503d80600081146106f6576040519150601f19603f3d011682016040523d82523d6000602084013e6106fb565b606091505b50909250905081158061070d57508051155b1561071c575060009392505050565b5060019392505050565b6000600282604051610738919061125f565b908152604051908190036020019020546001600160a01b031692915050565b61075f610cc2565b6107696000610d61565b565b610773610cc2565b6000600282604051610785919061125f565b908152604051908190036020019020546001600160a01b03169050806108055760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610815919061125f565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b90610861908490849061127b565b60405180910390a15050565b610875610cc2565b61087e81610db1565b60006001600160a01b0316600283604051610899919061125f565b908152604051908190036020019020546001600160a01b0316146109165760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107fc565b80600283604051610927919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f90610861908490849061127b565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b691908101906112a5565b610a01610cc2565b610a0a81610db1565b6000600283604051610a1c919061125f565b908152604051908190036020019020546001600160a01b0316905080610a4b57610a46838361086d565b505050565b81600284604051610a5c919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610abd9085908490869061131c565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b34575060408051601f3d908101601f19168201909252610b319181019061134f565b60015b6102b657506000919050565b6000610b4a610cc2565b6000600288604051610b5c919061125f565b908152604051908190036020019020546001600160a01b03169050610b8081610db1565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bb9908c908c908c908c908c90600401611371565b6020604051808303816000875af1158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611242565b9050610c088682610e23565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061134f565b610c8c610cc2565b6001600160a01b038116610cb657604051631e4fbdf760e01b8152600060048201526024016107fc565b610cbf81610d61565b50565b6000546001600160a01b031633146107695760405163118cdaa760e01b81523360048201526024016107fc565b610cf881610e8e565b610d098163976998cb60e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107fc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610dba81610e8e565b610dcb8163476d399760e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107fc565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e57908690869060040161127b565b600060405180830381600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cbf5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107fc565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f51575060408051601f3d908101601f19168201909252610f4e9181019061134f565b60015b610f5d575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa357610fa3610f64565b604052919050565b600067ffffffffffffffff821115610fc557610fc5610f64565b50601f01601f191660200190565b600082601f830112610fe457600080fd5b8135610ff7610ff282610fab565b610f7a565b81815284602083860101111561100c57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561103b57600080fd5b813567ffffffffffffffff81111561105257600080fd5b61105e84828501610fd3565b949350505050565b6001600160a01b0381168114610cbf57600080fd5b60006020828403121561108d57600080fd5b8135610f5d81611066565b600080604083850312156110ab57600080fd5b823567ffffffffffffffff8111156110c257600080fd5b6110ce85828601610fd3565b92505060208301356110df81611066565b809150509250929050565b60005b838110156111055781810151838201526020016110ed565b50506000910152565b600081518084526111268160208601602086016110ea565b601f01601f19169290920160200192915050565b602081526000610f5d602083018461110e565b60008060008060008060c0878903121561116657600080fd5b863567ffffffffffffffff8082111561117e57600080fd5b61118a8a838b01610fd3565b975060208901359150808211156111a057600080fd5b6111ac8a838b01610fd3565b965060408901359150808211156111c257600080fd5b6111ce8a838b01610fd3565b955060608901359150808211156111e457600080fd5b6111f08a838b01610fd3565b9450608089013591508082111561120657600080fd5b6112128a838b01610fd3565b935060a089013591508082111561122857600080fd5b5061123589828a01610fd3565b9150509295509295509295565b60006020828403121561125457600080fd5b8151610f5d81611066565b600082516112718184602087016110ea565b9190910192915050565b60408152600061128e604083018561110e565b905060018060a01b03831660208301529392505050565b6000602082840312156112b757600080fd5b815167ffffffffffffffff8111156112ce57600080fd5b8201601f810184136112df57600080fd5b80516112ed610ff282610fab565b81815285602083850101111561130257600080fd5b6113138260208301602086016110ea565b95945050505050565b60608152600061132f606083018661110e565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561136157600080fd5b81518015158114610f5d57600080fd5b60a08152600061138460a083018861110e565b8281036020840152611396818861110e565b905082810360408401526113aa818761110e565b905082810360608401526113be818661110e565b905082810360808401526113d2818561110e565b9897505050505050505056fea2646970667358221220f24c72179ae52649db9edfc49327676600f6548bf80be2ac1838fbfaf00f29af64736f6c63430008170033" }, { "type": "UInt64", diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc index 3931788b..e71ffe2e 100644 --- a/cadence/tests/test_helpers.cdc +++ b/cadence/tests/test_helpers.cdc @@ -11,11 +11,11 @@ import "EVM" /// See the python util `get_code_hex.py` to retrieve the hex-encoded Cadence either with or /// without a separator (`{{CONTRACT_NAME}}` used in templates to "chunk" template code). -access(all) let compiledFactoryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611414806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004611029565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d61013836600461107b565b6102bc565b005b61015261014d36600461107b565b610336565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004611029565b610726565b61013d610757565b61013d61019c366004611029565b61076b565b6000546001600160a01b031661010d565b61013d6101c0366004611098565b61086d565b6101d86101d336600461107b565b610986565b604051610121919061113a565b61013d6101f3366004611098565b6109f9565b61015261020636600461107b565b610aca565b61010d61021936600461114d565b610b40565b61015261022c36600461107b565b610c15565b61013d61023f36600461107b565b610c84565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc9061027590859060040161113a565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611242565b92915050565b6102c4610cc2565b6102cd81610cef565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161037c919061125f565b600060405180830381855afa9150503d80600081146103b7576040519150601f19603f3d011682016040523d82523d6000602084013e6103bc565b606091505b50915091508115806103cd57508051155b156103dc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610429919061125f565b600060405180830381855afa9150503d8060008114610464576040519150601f19603f3d011682016040523d82523d6000602084013e610469565b606091505b50909250905081158061047b57508051155b1561048a575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104de919061125f565b600060405180830381855afa9150503d8060008114610519576040519150601f19603f3d011682016040523d82523d6000602084013e61051e565b606091505b50909250905081158061053057508051155b1561053f575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161057d9161125f565b600060405180830381855afa9150503d80600081146105b8576040519150601f19603f3d011682016040523d82523d6000602084013e6105bd565b606091505b5090925090508115806105cf57508051155b156105de575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161061c9161125f565b600060405180830381855afa9150503d8060008114610657576040519150601f19603f3d011682016040523d82523d6000602084013e61065c565b606091505b50909250905081158061066e57508051155b1561067d575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106bb9161125f565b600060405180830381855afa9150503d80600081146106f6576040519150601f19603f3d011682016040523d82523d6000602084013e6106fb565b606091505b50909250905081158061070d57508051155b1561071c575060009392505050565b5060019392505050565b6000600282604051610738919061125f565b908152604051908190036020019020546001600160a01b031692915050565b61075f610cc2565b6107696000610d61565b565b610773610cc2565b6000600282604051610785919061125f565b908152604051908190036020019020546001600160a01b03169050806108055760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610815919061125f565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b90610861908490849061127b565b60405180910390a15050565b610875610cc2565b61087e81610db1565b60006001600160a01b0316600283604051610899919061125f565b908152604051908190036020019020546001600160a01b0316146109165760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107fc565b80600283604051610927919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f90610861908490849061127b565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b691908101906112a5565b610a01610cc2565b610a0a81610db1565b6000600283604051610a1c919061125f565b908152604051908190036020019020546001600160a01b0316905080610a4b57610a46838361086d565b505050565b81600284604051610a5c919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610abd9085908490869061131c565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b34575060408051601f3d908101601f19168201909252610b319181019061134f565b60015b6102b657506000919050565b6000610b4a610cc2565b6000600288604051610b5c919061125f565b908152604051908190036020019020546001600160a01b03169050610b8081610db1565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bb9908c908c908c908c908c90600401611371565b6020604051808303816000875af1158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611242565b9050610c088682610e23565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061134f565b610c8c610cc2565b6001600160a01b038116610cb657604051631e4fbdf760e01b8152600060048201526024016107fc565b610cbf81610d61565b50565b6000546001600160a01b031633146107695760405163118cdaa760e01b81523360048201526024016107fc565b610cf881610e8e565b610d098163976998cb60e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107fc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610dba81610e8e565b610dcb8163476d399760e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107fc565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e57908690869060040161127b565b600060405180830381600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cbf5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107fc565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f51575060408051601f3d908101601f19168201909252610f4e9181019061134f565b60015b610f5d575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa357610fa3610f64565b604052919050565b600067ffffffffffffffff821115610fc557610fc5610f64565b50601f01601f191660200190565b600082601f830112610fe457600080fd5b8135610ff7610ff282610fab565b610f7a565b81815284602083860101111561100c57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561103b57600080fd5b813567ffffffffffffffff81111561105257600080fd5b61105e84828501610fd3565b949350505050565b6001600160a01b0381168114610cbf57600080fd5b60006020828403121561108d57600080fd5b8135610f5d81611066565b600080604083850312156110ab57600080fd5b823567ffffffffffffffff8111156110c257600080fd5b6110ce85828601610fd3565b92505060208301356110df81611066565b809150509250929050565b60005b838110156111055781810151838201526020016110ed565b50506000910152565b600081518084526111268160208601602086016110ea565b601f01601f19169290920160200192915050565b602081526000610f5d602083018461110e565b60008060008060008060c0878903121561116657600080fd5b863567ffffffffffffffff8082111561117e57600080fd5b61118a8a838b01610fd3565b975060208901359150808211156111a057600080fd5b6111ac8a838b01610fd3565b965060408901359150808211156111c257600080fd5b6111ce8a838b01610fd3565b955060608901359150808211156111e457600080fd5b6111f08a838b01610fd3565b9450608089013591508082111561120657600080fd5b6112128a838b01610fd3565b935060a089013591508082111561122857600080fd5b5061123589828a01610fd3565b9150509295509295509295565b60006020828403121561125457600080fd5b8151610f5d81611066565b600082516112718184602087016110ea565b9190910192915050565b60408152600061128e604083018561110e565b905060018060a01b03831660208301529392505050565b6000602082840312156112b757600080fd5b815167ffffffffffffffff8111156112ce57600080fd5b8201601f810184136112df57600080fd5b80516112ed610ff282610fab565b81815285602083850101111561130257600080fd5b6113138260208301602086016110ea565b95945050505050565b60608152600061132f606083018661110e565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561136157600080fd5b81518015158114610f5d57600080fd5b60a08152600061138460a083018861110e565b8281036020840152611396818861110e565b905082810360408401526113aa818761110e565b905082810360608401526113be818661110e565b905082810360808401526113d2818561110e565b9897505050505050505056fea2646970667358221220b05065a8bb324fb253b0370f16d886e6b31389df606099d521bff6670967c17464736f6c63430008170033" +access(all) let compiledFactoryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611414806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004611029565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d61013836600461107b565b6102bc565b005b61015261014d36600461107b565b610336565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004611029565b610726565b61013d610757565b61013d61019c366004611029565b61076b565b6000546001600160a01b031661010d565b61013d6101c0366004611098565b61086d565b6101d86101d336600461107b565b610986565b604051610121919061113a565b61013d6101f3366004611098565b6109f9565b61015261020636600461107b565b610aca565b61010d61021936600461114d565b610b40565b61015261022c36600461107b565b610c15565b61013d61023f36600461107b565b610c84565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc9061027590859060040161113a565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611242565b92915050565b6102c4610cc2565b6102cd81610cef565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161037c919061125f565b600060405180830381855afa9150503d80600081146103b7576040519150601f19603f3d011682016040523d82523d6000602084013e6103bc565b606091505b50915091508115806103cd57508051155b156103dc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610429919061125f565b600060405180830381855afa9150503d8060008114610464576040519150601f19603f3d011682016040523d82523d6000602084013e610469565b606091505b50909250905081158061047b57508051155b1561048a575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104de919061125f565b600060405180830381855afa9150503d8060008114610519576040519150601f19603f3d011682016040523d82523d6000602084013e61051e565b606091505b50909250905081158061053057508051155b1561053f575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161057d9161125f565b600060405180830381855afa9150503d80600081146105b8576040519150601f19603f3d011682016040523d82523d6000602084013e6105bd565b606091505b5090925090508115806105cf57508051155b156105de575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161061c9161125f565b600060405180830381855afa9150503d8060008114610657576040519150601f19603f3d011682016040523d82523d6000602084013e61065c565b606091505b50909250905081158061066e57508051155b1561067d575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106bb9161125f565b600060405180830381855afa9150503d80600081146106f6576040519150601f19603f3d011682016040523d82523d6000602084013e6106fb565b606091505b50909250905081158061070d57508051155b1561071c575060009392505050565b5060019392505050565b6000600282604051610738919061125f565b908152604051908190036020019020546001600160a01b031692915050565b61075f610cc2565b6107696000610d61565b565b610773610cc2565b6000600282604051610785919061125f565b908152604051908190036020019020546001600160a01b03169050806108055760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610815919061125f565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b90610861908490849061127b565b60405180910390a15050565b610875610cc2565b61087e81610db1565b60006001600160a01b0316600283604051610899919061125f565b908152604051908190036020019020546001600160a01b0316146109165760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107fc565b80600283604051610927919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f90610861908490849061127b565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b691908101906112a5565b610a01610cc2565b610a0a81610db1565b6000600283604051610a1c919061125f565b908152604051908190036020019020546001600160a01b0316905080610a4b57610a46838361086d565b505050565b81600284604051610a5c919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610abd9085908490869061131c565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b34575060408051601f3d908101601f19168201909252610b319181019061134f565b60015b6102b657506000919050565b6000610b4a610cc2565b6000600288604051610b5c919061125f565b908152604051908190036020019020546001600160a01b03169050610b8081610db1565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bb9908c908c908c908c908c90600401611371565b6020604051808303816000875af1158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611242565b9050610c088682610e23565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061134f565b610c8c610cc2565b6001600160a01b038116610cb657604051631e4fbdf760e01b8152600060048201526024016107fc565b610cbf81610d61565b50565b6000546001600160a01b031633146107695760405163118cdaa760e01b81523360048201526024016107fc565b610cf881610e8e565b610d098163976998cb60e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107fc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610dba81610e8e565b610dcb8163476d399760e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107fc565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e57908690869060040161127b565b600060405180830381600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cbf5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107fc565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f51575060408051601f3d908101601f19168201909252610f4e9181019061134f565b60015b610f5d575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa357610fa3610f64565b604052919050565b600067ffffffffffffffff821115610fc557610fc5610f64565b50601f01601f191660200190565b600082601f830112610fe457600080fd5b8135610ff7610ff282610fab565b610f7a565b81815284602083860101111561100c57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561103b57600080fd5b813567ffffffffffffffff81111561105257600080fd5b61105e84828501610fd3565b949350505050565b6001600160a01b0381168114610cbf57600080fd5b60006020828403121561108d57600080fd5b8135610f5d81611066565b600080604083850312156110ab57600080fd5b823567ffffffffffffffff8111156110c257600080fd5b6110ce85828601610fd3565b92505060208301356110df81611066565b809150509250929050565b60005b838110156111055781810151838201526020016110ed565b50506000910152565b600081518084526111268160208601602086016110ea565b601f01601f19169290920160200192915050565b602081526000610f5d602083018461110e565b60008060008060008060c0878903121561116657600080fd5b863567ffffffffffffffff8082111561117e57600080fd5b61118a8a838b01610fd3565b975060208901359150808211156111a057600080fd5b6111ac8a838b01610fd3565b965060408901359150808211156111c257600080fd5b6111ce8a838b01610fd3565b955060608901359150808211156111e457600080fd5b6111f08a838b01610fd3565b9450608089013591508082111561120657600080fd5b6112128a838b01610fd3565b935060a089013591508082111561122857600080fd5b5061123589828a01610fd3565b9150509295509295509295565b60006020828403121561125457600080fd5b8151610f5d81611066565b600082516112718184602087016110ea565b9190910192915050565b60408152600061128e604083018561110e565b905060018060a01b03831660208301529392505050565b6000602082840312156112b757600080fd5b815167ffffffffffffffff8111156112ce57600080fd5b8201601f810184136112df57600080fd5b80516112ed610ff282610fab565b81815285602083850101111561130257600080fd5b6113138260208301602086016110ea565b95945050505050565b60608152600061132f606083018661110e565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561136157600080fd5b81518015158114610f5d57600080fd5b60a08152600061138460a083018861110e565b8281036020840152611396818861110e565b905082810360408401526113aa818761110e565b905082810360608401526113be818661110e565b905082810360808401526113d2818561110e565b9897505050505050505056fea2646970667358221220f24c72179ae52649db9edfc49327676600f6548bf80be2ac1838fbfaf00f29af64736f6c63430008170033" -access(all) let erc20DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212202d573cf4820d94ed241f7d0352db0bcd8eb3161e4cecdd44be2ef4266796a2ed64736f6c63430008170033a26469706673582212207f13a0f8d5cef31961e368d802a69dfbafd5e77501cf88fc6c92ecf5c57a9f1064736f6c63430008170033" +access(all) let erc20DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206fb41458119173f9f1d07720d0b22fbfacf4726505008b5c43816c9902cd0fc464736f6c63430008170033a2646970667358221220fbaaee74b0e14c12923bfbdc4701408031af759f454cf27df9e8defc7658e96264736f6c63430008170033" -access(all) let erc721DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612657806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d3660046200043c565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c93660046200051a565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a7565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005fc565b620002bf565b6200010662000142366004620005fc565b6200036b565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b031633146200020b576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a204f6e60448201527f6c792064656c656761746564206465706c6f7965722063616e206465706c6f7960648201526084015b60405180910390fd5b600080546001600160a01b031687878787876040516200022b906200042e565b6200023c969594939291906200066f565b604051809103906000f08015801562000259573d6000803e3d6000fd5b5090507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f0818888888860405162000295959493929190620006f8565b60405180910390a19695505050505050565b620002b1620003af565b620002bd6000620003de565b565b620002c9620003af565b6001600160a01b03811662000349576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a20496e60448201527f76616c69642064656c656761746564206465706c6f7965722061646472657373606482015260840162000202565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000375620003af565b6001600160a01b038116620003a157604051631e4fbdf760e01b81526000600482015260240162000202565b620003ac81620003de565b50565b6000546001600160a01b03163314620002bd5760405163118cdaa760e01b815233600482015260240162000202565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611eb7806200076b83390190565b6000602082840312156200044f57600080fd5b81356001600160e01b0319811681146200046857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049757600080fd5b813567ffffffffffffffff80821115620004b557620004b56200046f565b604051601f8301601f19908116603f01168101908282118183101715620004e057620004e06200046f565b81604052838152866020858801011115620004fa57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200053357600080fd5b853567ffffffffffffffff808211156200054c57600080fd5b6200055a89838a0162000485565b965060208801359150808211156200057157600080fd5b6200057f89838a0162000485565b955060408801359150808211156200059657600080fd5b620005a489838a0162000485565b94506060880135915080821115620005bb57600080fd5b620005c989838a0162000485565b93506080880135915080821115620005e057600080fd5b50620005ef8882890162000485565b9150509295509295909350565b6000602082840312156200060f57600080fd5b81356001600160a01b03811681146200046857600080fd5b6000815180845260005b818110156200064f5760208185018101518683018201520162000631565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006959083018862000627565b8281036040840152620006a9818862000627565b90508281036060840152620006bf818762000627565b90508281036080840152620006d5818662000627565b905082810360a0840152620006eb818562000627565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071e9083018762000627565b828103604084015262000732818762000627565b9050828103606084015262000748818662000627565b905082810360808401526200075e818562000627565b9897505050505050505056fe60806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea2646970667358221220e5b8da7e9f5a8ba0772457fe42d9f13eb90dec0ad70a92e30ac8d5ecd317e92f64736f6c63430008170033a2646970667358221220185b564932a6fb2d0066082694692d9d4ee875e9f7e2bfe408bdf1b3079817e764736f6c63430008170033" +access(all) let erc721DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612657806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d3660046200043c565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c93660046200051a565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a7565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005fc565b620002bf565b6200010662000142366004620005fc565b6200036b565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b031633146200020b576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a204f6e60448201527f6c792064656c656761746564206465706c6f7965722063616e206465706c6f7960648201526084015b60405180910390fd5b600080546001600160a01b031687878787876040516200022b906200042e565b6200023c969594939291906200066f565b604051809103906000f08015801562000259573d6000803e3d6000fd5b5090507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f0818888888860405162000295959493929190620006f8565b60405180910390a19695505050505050565b620002b1620003af565b620002bd6000620003de565b565b620002c9620003af565b6001600160a01b03811662000349576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a20496e60448201527f76616c69642064656c656761746564206465706c6f7965722061646472657373606482015260840162000202565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000375620003af565b6001600160a01b038116620003a157604051631e4fbdf760e01b81526000600482015260240162000202565b620003ac81620003de565b50565b6000546001600160a01b03163314620002bd5760405163118cdaa760e01b815233600482015260240162000202565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611eb7806200076b83390190565b6000602082840312156200044f57600080fd5b81356001600160e01b0319811681146200046857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049757600080fd5b813567ffffffffffffffff80821115620004b557620004b56200046f565b604051601f8301601f19908116603f01168101908282118183101715620004e057620004e06200046f565b81604052838152866020858801011115620004fa57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200053357600080fd5b853567ffffffffffffffff808211156200054c57600080fd5b6200055a89838a0162000485565b965060208801359150808211156200057157600080fd5b6200057f89838a0162000485565b955060408801359150808211156200059657600080fd5b620005a489838a0162000485565b94506060880135915080821115620005bb57600080fd5b620005c989838a0162000485565b93506080880135915080821115620005e057600080fd5b50620005ef8882890162000485565b9150509295509295909350565b6000602082840312156200060f57600080fd5b81356001600160a01b03811681146200046857600080fd5b6000815180845260005b818110156200064f5760208185018101518683018201520162000631565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006959083018862000627565b8281036040840152620006a9818862000627565b90508281036060840152620006bf818762000627565b90508281036080840152620006d5818662000627565b905082810360a0840152620006eb818562000627565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071e9083018762000627565b828103604084015262000732818762000627565b9050828103606084015262000748818662000627565b905082810360808401526200075e818562000627565b9897505050505050505056fe60806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122074d34aec07c0da793ce5cac74069bf4177b7594babf4fede87db849ea2f57b3764736f6c63430008170033a264697066735822122064104e4f6458f9ff9e5aca71c897aa1948c1b57434e9d83b5f4ce4a9ab5d328564736f6c63430008170033" access(all) let registryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610058565b50600080546001600160a01b031916331790556100aa565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6108a5806100b96000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063862119ae11610071578063862119ae146101315780638da5cb5b14610144578063a6de610514610155578063b3d5dbdc14610168578063f2fde38b14610188578063faab9d391461019b57600080fd5b806301ffc9a7146100ae57806304433bbc146100d65780632b20e39714610101578063522791d114610114578063715018a614610129575b600080fd5b6100c16100bc36600461051c565b6101ae565b60405190151581526020015b60405180910390f35b6100e96100e43660046105f0565b6101e5565b6040516001600160a01b0390911681526020016100cd565b6000546100e9906001600160a01b031681565b610127610122366004610649565b610216565b005b6101276102b7565b6100c161013f3660046105f0565b6102cb565b6003546001600160a01b03166100e9565b6100c1610163366004610697565b610308565b61017b610176366004610697565b610334565b6040516100cd91906106d6565b610127610196366004610697565b6103e0565b6101276101a9366004610697565b61041e565b60006001600160e01b0319821663976998cb60e01b14806101df57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60006001826040516101f79190610709565b908152604051908190036020019020546001600160a01b031692915050565b6000546001600160a01b031633146102a95760405162461bcd60e51b815260206004820152604560248201527f466c6f774272696467654465706c6f796d656e7452656769737472793a204f6e60448201527f6c79207265676973747261722063616e207265676973746572206173736f636960648201526430ba34b7b760d91b608482015260a4015b60405180910390fd5b6102b38282610444565b5050565b6102bf61049d565b6102c960006104ca565b565b6000806001600160a01b03166001836040516102e79190610709565b908152604051908190036020019020546001600160a01b0316141592915050565b6001600160a01b0381166000908152600260205260408120805461032b90610725565b15159392505050565b6001600160a01b038116600090815260026020526040902080546060919061035b90610725565b80601f016020809104026020016040519081016040528092919081815260200182805461038790610725565b80156103d45780601f106103a9576101008083540402835291602001916103d4565b820191906000526020600020905b8154815290600101906020018083116103b757829003601f168201915b50505050509050919050565b6103e861049d565b6001600160a01b03811661041257604051631e4fbdf760e01b8152600060048201526024016102a0565b61041b816104ca565b50565b61042661049d565b600080546001600160a01b0319166001600160a01b03831617905550565b806001836040516104559190610709565b908152604080516020928190038301902080546001600160a01b0319166001600160a01b03948516179055918316600090815260029091522061049883826107af565b505050565b6003546001600160a01b031633146102c95760405163118cdaa760e01b81523360048201526024016102a0565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006020828403121561052e57600080fd5b81356001600160e01b03198116811461054657600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261057457600080fd5b813567ffffffffffffffff8082111561058f5761058f61054d565b604051601f8301601f19908116603f011681019082821181831017156105b7576105b761054d565b816040528381528660208588010111156105d057600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561060257600080fd5b813567ffffffffffffffff81111561061957600080fd5b61062584828501610563565b949350505050565b80356001600160a01b038116811461064457600080fd5b919050565b6000806040838503121561065c57600080fd5b823567ffffffffffffffff81111561067357600080fd5b61067f85828601610563565b92505061068e6020840161062d565b90509250929050565b6000602082840312156106a957600080fd5b6105468261062d565b60005b838110156106cd5781810151838201526020016106b5565b50506000910152565b60208152600082518060208401526106f58160408501602087016106b2565b601f01601f19169190910160400192915050565b6000825161071b8184602087016106b2565b9190910192915050565b600181811c9082168061073957607f821691505b60208210810361075957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610498576000816000526020600020601f850160051c810160208610156107885750805b601f850160051c820191505b818110156107a757828155600101610794565b505050505050565b815167ffffffffffffffff8111156107c9576107c961054d565b6107dd816107d78454610725565b8461075f565b602080601f83116001811461081257600084156107fa5750858301515b600019600386901b1c1916600185901b1785556107a7565b600085815260208120601f198616915b8281101561084157888601518255948401946001909101908401610822565b508582101561085f5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212204229c8738eb6a99e2fe8a2cd0be82f006719cf059ff7c5b2f748353eb7c5da4c64736f6c63430008170033" diff --git a/cadence/transactions/evm/create_account.cdc b/cadence/transactions/evm/create_account.cdc index fe389d56..57d31241 100644 --- a/cadence/transactions/evm/create_account.cdc +++ b/cadence/transactions/evm/create_account.cdc @@ -21,7 +21,6 @@ transaction(amount: UFix64) { let coa <- EVM.createCadenceOwnedAccount() coa.deposit(from: <-self.sentVault) - log(coa.balance().inFLOW()) let storagePath = StoragePath(identifier: "evm")! let publicPath = PublicPath(identifier: "evm")! self.auth.storage.save<@EVM.CadenceOwnedAccount>(<-coa, to: storagePath) diff --git a/solidity/src/FlowBridgeDeploymentRegistry.sol b/solidity/src/FlowBridgeDeploymentRegistry.sol index 940377b8..4ca79495 100644 --- a/solidity/src/FlowBridgeDeploymentRegistry.sol +++ b/solidity/src/FlowBridgeDeploymentRegistry.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import "./interfaces/FlowEVMDeploymentRegistry.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {FlowEVMDeploymentRegistry} from "./interfaces/FlowEVMDeploymentRegistry.sol"; /** * @title FlowBridgeDeploymentRegistry diff --git a/solidity/src/FlowBridgeFactory.sol b/solidity/src/FlowBridgeFactory.sol index f3c2c295..d817e3c3 100644 --- a/solidity/src/FlowBridgeFactory.sol +++ b/solidity/src/FlowBridgeFactory.sol @@ -11,7 +11,12 @@ import {FlowEVMDeploymentRegistry} from "./interfaces/FlowEVMDeploymentRegistry. /** * @title FlowBridgeFactory - * @dev Factory contract to deploy new FlowEVM bridge contracts, defining Cadence-native assets in EVM + * @dev Factory contract to deploy new FlowEVM bridge contracts, defining Cadence-native assets in EVM. Cadence & EVM + * contract associations are maintained in a deployment registry. This factory is enabled to deploy contracts via + * registered deployer implementations, each of which handle the deployment of a single templated contract indexed by + * a human-readable deployer tag. This setup modularizes each key component of the EVM side of the Flow EVM VM bridge, + * allowing new asset types to be added by simply adding a new deployer implementation or updated factory contract + * to be swapped out without affecting the underlying associations between Cadence and EVM contracts. */ contract FlowBridgeFactory is Ownable { // Address of the deployment registry where deployed contract associations are registered diff --git a/solidity/src/FlowEVMBridgedERC20Deployer.sol b/solidity/src/FlowEVMBridgedERC20Deployer.sol index cd444344..5bfeb013 100644 --- a/solidity/src/FlowEVMBridgedERC20Deployer.sol +++ b/solidity/src/FlowEVMBridgedERC20Deployer.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import "./interfaces/IFlowEVMBridgeDeployer.sol"; -import "./templates/FlowEVMBridgedERC20.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {IFlowEVMBridgeDeployer} from "./interfaces/IFlowEVMBridgeDeployer.sol"; +import {FlowEVMBridgedERC20} from "./templates/FlowEVMBridgedERC20.sol"; /** * @title FlowEVMBridgedERC20Deployer @@ -16,7 +16,7 @@ import "./templates/FlowEVMBridgedERC20.sol"; contract FlowEVMBridgedERC20Deployer is IFlowEVMBridgeDeployer, ERC165, Ownable { // The address of the delegated deployer who can deploy new contracts address public delegatedDeployer; - + /** * @dev Event emitted when a new ERC20 contract is deployed via this deployer */ diff --git a/solidity/src/FlowEVMBridgedERC721Deployer.sol b/solidity/src/FlowEVMBridgedERC721Deployer.sol index ff7753f9..86e0c1fb 100644 --- a/solidity/src/FlowEVMBridgedERC721Deployer.sol +++ b/solidity/src/FlowEVMBridgedERC721Deployer.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import "./interfaces/IFlowEVMBridgeDeployer.sol"; -import "./templates/FlowEVMBridgedERC721.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {IFlowEVMBridgeDeployer} from "./interfaces/IFlowEVMBridgeDeployer.sol"; +import {FlowEVMBridgedERC721} from "./templates/FlowEVMBridgedERC721.sol"; /** * @title FlowEVMBridgedERC721Deployer diff --git a/solidity/src/interfaces/BridgePermissions.sol b/solidity/src/interfaces/BridgePermissions.sol index a3504990..92069ac3 100644 --- a/solidity/src/interfaces/BridgePermissions.sol +++ b/solidity/src/interfaces/BridgePermissions.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import "./IBridgePermissions.sol"; +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {IBridgePermissions} from "./IBridgePermissions.sol"; /** * @dev Contract for which implementation is checked by the Flow VM bridge as an opt-out mechanism diff --git a/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol b/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol index f4e18a0b..dcdfd7f8 100644 --- a/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol +++ b/solidity/src/interfaces/FlowEVMDeploymentRegistry.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import "./IFlowEVMDeploymentRegistry.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {IFlowEVMDeploymentRegistry} from "./IFlowEVMDeploymentRegistry.sol"; /** * @title FlowEVMDeploymentRegistry diff --git a/solidity/src/interfaces/IBridgePermissions.sol b/solidity/src/interfaces/IBridgePermissions.sol index ea8eed18..ccce6404 100644 --- a/solidity/src/interfaces/IBridgePermissions.sol +++ b/solidity/src/interfaces/IBridgePermissions.sol @@ -1,17 +1,16 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface IBridgePermissions is IERC165 { - /** * @dev Emitted when the permissions for the contract are updated. */ event PermissionsUpdated(bool newPermissions); - + /** * @dev Returns true if the contract allows bridging of its assets. */ function allowsBridging() external view returns (bool); -} \ No newline at end of file +} diff --git a/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol b/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol index 247afad0..6e65236a 100644 --- a/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol +++ b/solidity/src/interfaces/IFlowEVMBridgeDeployer.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /** * @title IFlowEVMBridgeDeployer diff --git a/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol b/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol index c6cbc18e..110f8a0f 100644 --- a/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol +++ b/solidity/src/interfaces/IFlowEVMDeploymentRegistry.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /** * @title IFlowEVMDeploymentRegistry diff --git a/solidity/src/templates/FlowEVMBridgedERC20.sol b/solidity/src/templates/FlowEVMBridgedERC20.sol index 1ddc8941..fca09940 100644 --- a/solidity/src/templates/FlowEVMBridgedERC20.sol +++ b/solidity/src/templates/FlowEVMBridgedERC20.sol @@ -2,10 +2,10 @@ // Compatible with OpenZeppelin Contracts ^5.0.0 pragma solidity ^0.8.17; -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import {ERC20Burnable} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; contract FlowEVMBridgedERC20 is ERC20, ERC20Burnable, Ownable, ERC20Permit { string public flowTokenAddress; diff --git a/solidity/src/templates/FlowEVMBridgedERC721.sol b/solidity/src/templates/FlowEVMBridgedERC721.sol index 597dc8da..a9ff920c 100644 --- a/solidity/src/templates/FlowEVMBridgedERC721.sol +++ b/solidity/src/templates/FlowEVMBridgedERC721.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; -import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; +import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import {ERC721URIStorage} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; +import {ERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import {ERC721Burnable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; contract FlowEVMBridgedERC721 is ERC721, ERC721URIStorage, ERC721Burnable, ERC721Enumerable, Ownable { string public flowNFTAddress; From c41711981752b6a5788ce9a61de3321d10e6f059 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Mon, 6 May 2024 16:25:12 -0500 Subject: [PATCH 09/18] remove unused test import --- solidity/test/FlowBridgeFactory.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/solidity/test/FlowBridgeFactory.t.sol b/solidity/test/FlowBridgeFactory.t.sol index b34dcc5e..477d6f96 100644 --- a/solidity/test/FlowBridgeFactory.t.sol +++ b/solidity/test/FlowBridgeFactory.t.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.17; import {Test} from "forge-std/Test.sol"; -import {console} from "forge-std/console.sol"; import {FlowBridgeDeploymentRegistry} from "../src/FlowBridgeDeploymentRegistry.sol"; import {FlowEVMBridgedERC721Deployer} from "../src/FlowEVMBridgedERC721Deployer.sol"; From e2a5662ba70bc7459cf33718ba7a7784fdaab175 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Mon, 6 May 2024 16:36:46 -0500 Subject: [PATCH 10/18] add Cadence transaction comments --- cadence/tests/scripts/type_at.cdc | 4 ---- cadence/transactions/bridge/admin/evm/add_deployer.cdc | 6 ++++++ .../bridge/admin/evm/set_delegated_deployer.cdc | 5 +++++ .../bridge/admin/evm/set_deployment_registry.cdc | 9 +++++++++ cadence/transactions/bridge/admin/evm/set_registrar.cdc | 4 ++-- 5 files changed, 22 insertions(+), 6 deletions(-) delete mode 100644 cadence/tests/scripts/type_at.cdc diff --git a/cadence/tests/scripts/type_at.cdc b/cadence/tests/scripts/type_at.cdc deleted file mode 100644 index 0fcbef1f..00000000 --- a/cadence/tests/scripts/type_at.cdc +++ /dev/null @@ -1,4 +0,0 @@ -access(all) -fun main(addr: Address, sp: StoragePath): Type? { - return getAuthAccount(addr).storage.borrow<&AnyResource>(from: sp)?.getType() ?? nil -} \ No newline at end of file diff --git a/cadence/transactions/bridge/admin/evm/add_deployer.cdc b/cadence/transactions/bridge/admin/evm/add_deployer.cdc index 804fdd30..47ad13e7 100644 --- a/cadence/transactions/bridge/admin/evm/add_deployer.cdc +++ b/cadence/transactions/bridge/admin/evm/add_deployer.cdc @@ -3,6 +3,12 @@ import "EVM" import "EVMUtils" import "FlowEVMBridgeUtils" +/// This transaction adds the given EVM address as a deployer in the bridge factory contract, indexed on the +/// provided tag. +/// +/// @param deployerTag: The tag to index the deployer with - e.g. ERC20, ERC721, etc. +/// @param deployerEVMAddressHex: The EVM address of the deployer contract as a hex string, without the '0x' prefix +/// transaction(deployerTag: String, deployerEVMAddressHex: String) { let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount diff --git a/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc b/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc index ed4c20ab..945f00d7 100644 --- a/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc +++ b/cadence/transactions/bridge/admin/evm/set_delegated_deployer.cdc @@ -3,6 +3,11 @@ import "EVM" import "EVMUtils" import "FlowEVMBridgeUtils" +/// Sets the bridge factory contract address as a delegated deployer in the provided deployer contract. This enables the +/// factory contract to deploy new contracts via the deployer contract. +/// +/// @param deployerEVMAddressHex The EVM address of the deployer contract as a hex string without the '0x' prefix +/// transaction(deployerEVMAddressHex: String) { let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount diff --git a/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc b/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc index 43b943f0..cfd8c79a 100644 --- a/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc +++ b/cadence/transactions/bridge/admin/evm/set_deployment_registry.cdc @@ -3,6 +3,15 @@ import "EVM" import "EVMUtils" import "FlowEVMBridgeUtils" +/// This transaction sets the address of the registry contract in the bridge factory contract. The registry contract +/// is tasked with maintaining associations between bridge-deployed EVM contracts and their corresponding Cadence +/// implementations. +/// +/// NOTE: This is a sensitive operation as the registry contract serves as the source of truth for bridge-deployed +/// contracts. +/// +/// @param registryEVMAddressHex The EVM address of the registry contract as a hex string without the '0x' prefix. +/// transaction(registryEVMAddressHex: String) { let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount diff --git a/cadence/transactions/bridge/admin/evm/set_registrar.cdc b/cadence/transactions/bridge/admin/evm/set_registrar.cdc index baf5db3f..25158e2e 100644 --- a/cadence/transactions/bridge/admin/evm/set_registrar.cdc +++ b/cadence/transactions/bridge/admin/evm/set_registrar.cdc @@ -3,8 +3,8 @@ import "EVM" import "EVMUtils" import "FlowEVMBridgeUtils" -/// Sets the registrar address for the provided FlowBridgeDeploymentRegistry address. Should be called by the owner of -/// the registry contract. +/// Sets the bridge factory contract address as the registrar for the provided FlowBridgeDeploymentRegistry address. +/// Should be called by the owner of the registry contract. /// /// @param registryEVMAddressHex The EVM address of the FlowBridgeDeploymentRegistry contract. /// From d57c62bf2b4a411c6a2ab0075e71f68c55c93375 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Mon, 6 May 2024 16:38:40 -0500 Subject: [PATCH 11/18] remove unused forge script --- solidity/script/Counter.s.sol | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 solidity/script/Counter.s.sol diff --git a/solidity/script/Counter.s.sol b/solidity/script/Counter.s.sol deleted file mode 100644 index 29938afe..00000000 --- a/solidity/script/Counter.s.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.17; - -import {Script, console2} from "forge-std/Script.sol"; - -contract CounterScript is Script { - function setUp() public {} - - function run() public { - vm.broadcast(); - } -} From 6add503ce5679a1a16cf121df1db46e818678c43 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Mon, 6 May 2024 19:27:00 -0500 Subject: [PATCH 12/18] add uint256 to ufix64 conversion fixes thanks to @bluesign --- .../contracts/bridge/FlowEVMBridgeUtils.cdc | 79 ++++++++++-------- cadence/tests/flow_evm_bridge_utils_tests.cdc | 81 ++++++++++++++++++- 2 files changed, 126 insertions(+), 34 deletions(-) diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index 3974f693..52560131 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -811,26 +811,6 @@ contract FlowEVMBridgeUtils { return r } - /// Converts a UInt256 to a UFix64 - /// - access(all) - view fun uint256ToUFix64(value: UInt256, decimals: UInt8): UFix64 { - // Calculate scale factors for the integer and fractional parts - let absoluteScaleFactor = self.pow(base: 10, exponent: decimals) - - // Separate the integer and fractional parts of the value - let scaledValue = value / absoluteScaleFactor - var fractional = value % absoluteScaleFactor - let scaledFractional = self.uint256FractionalToScaledUFix64Decimals(value: fractional, decimals: decimals) - - assert( - scaledValue < UInt256(UFix64.max), - message: "Scaled integer value ".concat(value.toString()).concat(" exceeds max UFix64 value") - ) - - return UFix64(scaledValue) + scaledFractional - } - /// Converts a UFix64 to a UInt256 // access(all) @@ -852,6 +832,32 @@ contract FlowEVMBridgeUtils { return integer * integerMultiplier + UInt256(fractional) * fractionalMultiplier } + /// Converts a UInt256 to a UFix64 + /// + access(all) + view fun uint256ToUFix64(value: UInt256, decimals: UInt8): UFix64 { + // Calculate scale factors for the integer and fractional parts + let absoluteScaleFactor = self.pow(base: 10, exponent: decimals) + + // Separate the integer and fractional parts of the value + let scaledValue = value / absoluteScaleFactor + var fractional = value % absoluteScaleFactor + // Scale the fractional part + let scaledFractional = self.uint256FractionalToScaledUFix64Decimals(value: fractional, decimals: decimals) + + // Ensure the parts do not exceed the max UFix64 value + assert( + scaledValue <= UInt256(UFix64.max), + message: "Scaled integer value ".concat(value.toString()).concat(" exceeds max UFix64 value") + ) + assert( + scaledValue == UInt256(UFix64.max) ? scaledFractional < 0.09551616 : true, + message: "Scaled integer value ".concat(value.toString()).concat(" exceeds max UFix64 value") + ) + + return UFix64(scaledValue) + scaledFractional + } + /// Converts a UInt256 fractional value with the given decimal places to a scaled UFix64. Note that UFix64 has /// decimal precision of 8 places so converted values may lose precision and be rounded down. /// @@ -861,16 +867,8 @@ contract FlowEVMBridgeUtils { result < 1.0: "Scaled fractional exceeds 1.0" } var fractional = value - // Reduce fractional values with trailing zeros - var e: UInt8 = 0 - while fractional > 0 { - if fractional % 10 == 0 { - fractional = fractional / 10 - e = e + 1 - } else { - break - } - } + var digits = self.getNumberOfDigits(value) + let leadingZeros = decimals - digits // fractional is too long - since UFix64 has 8 decimal places, truncate to maintain only the first 8 digis var fractionalReduction: UInt8 = 0 @@ -880,13 +878,15 @@ contract FlowEVMBridgeUtils { } // Scale the fractional part - let fractionalMultiplier = self.ufixPow(base: 0.1, exponent: decimals - e - fractionalReduction) - let scaledFractional = UFix64(fractional) * fractionalMultiplier + let fractionalMultiplier = self.ufixPow(base: 0.1, exponent: decimals < 8 ? decimals : 8) + var scaledFractional = UFix64(fractional) * fractionalMultiplier + if leadingZeros > 0 && decimals >= 8 { + scaledFractional = scaledFractional * self.ufixPow(base: 0.1, exponent: leadingZeros) + } return scaledFractional } - /// Returns the value as a UInt64 if it fits, otherwise panics /// access(all) @@ -894,6 +894,19 @@ contract FlowEVMBridgeUtils { return value <= UInt256(UInt64.max) ? UInt64(value) : panic("Value too large to fit into UInt64") } + /// Returns the number of digits in the given UInt256 + /// + access(all) + view fun getNumberOfDigits(_ value: UInt256): UInt8 { + var tmp = value + var digits: UInt8 = 0 + while tmp > 0 { + tmp = tmp / 10 + digits = digits + 1 + } + return digits + } + /*************************** Type Identifier Utils ***************************/ diff --git a/cadence/tests/flow_evm_bridge_utils_tests.cdc b/cadence/tests/flow_evm_bridge_utils_tests.cdc index 0b33c935..a4ca6687 100644 --- a/cadence/tests/flow_evm_bridge_utils_tests.cdc +++ b/cadence/tests/flow_evm_bridge_utils_tests.cdc @@ -115,6 +115,15 @@ fun testReducedPrecisionUInt256ToUFix64Succeeds() { Test.assertEqual(ufixAmount, actualUFixAmount) } +access(all) +fun testReducedPrecisionUInt256SmallChangeToUFix64Succeeds() { + let uintAmount: UInt256 = 24_244_814_000_020 + let ufixAmount: UFix64 = 24_244_814.000020 + + let actualUFixAmount = uint256ToUFix64(uintAmount, decimals: 6) + Test.assertEqual(ufixAmount, actualUFixAmount) +} + // Converting from UFix64 to UInt256 with reduced point precision (6 vs. 8) should round down access(all) fun testReducedPrecisionUFix64ToUInt256Succeeds() { @@ -190,12 +199,82 @@ fun testLargeFractionalUInt256ToUFix64Succeeds() { Test.assertEqual(largeFractionalUFixAmount, actualUFixAmount) } +access(all) +fun testLargeFractionalTrailingZerosUInt256ToUFix64Succeeds() { + let largeFractionalUFixAmount: UFix64 = 1.99785982 + let largeFractionalUIntAmount: UInt256 = 1_997_859_829_999_000_000 + + let actualUFixAmount = uint256ToUFix64(largeFractionalUIntAmount, decimals: 18) + Test.assertEqual(largeFractionalUFixAmount, actualUFixAmount) +} + access(all) fun testlargeFractionalUFix64ToUInt256Succeeds() { let largeFractionalUFixAmount: UFix64 = 1.99785982 let largeFractionalUIntAmount: UInt256 = 1_997_859_820_000_000_000 - // let largeFractionalUIntAmount: UInt256 = 1,997,859,820,000,000,000 let actualUIntAmount = ufix64ToUInt256(largeFractionalUFixAmount, decimals: 18) Test.assertEqual(largeFractionalUIntAmount, actualUIntAmount) } + +access(all) +fun testIntegerAndLeadingZeroFractionalUInt256ToUFix64Succeeds() { + let ufixAmount: UFix64 = 100.00000500 + let uintAmount: UInt256 = 100_000_005_000_000_888_999 + + let actualUFixAmount = uint256ToUFix64(uintAmount, decimals: 18) + Test.assertEqual(ufixAmount, actualUFixAmount) +} + +access(all) +fun testIntegerAndLeadingZeroFractionalUFix64ToUInt256Succeeds() { + let ufixAmount: UFix64 = 100.00000500 + let uintAmount: UInt256 = 100_000_005_000_000_000_000 + + let actualUIntAmount = ufix64ToUInt256(ufixAmount, decimals: 18) + Test.assertEqual(uintAmount, actualUIntAmount) +} + +access(all) +fun testMaxUFix64ToUInt256Succeeds() { + let ufixAmount: UFix64 = UFix64.max + let uintAmount: UInt256 = 184467440737_095516150000000000 + + let actualUIntAmount = ufix64ToUInt256(ufixAmount, decimals: 18) + + Test.assertEqual(uintAmount, actualUIntAmount) +} + +access(all) +fun testMaxUFix64AsUInt256ToUFix64Succeds() { + let ufixAmount: UFix64 = UFix64.max + var uintAmount: UInt256 = 184467440737_095516150000000000 + + let actualUFixAmount = uint256ToUFix64(uintAmount, decimals: 18) + + Test.assertEqual(ufixAmount, actualUFixAmount) +} + +access(all) +fun testFractionalPartMaxUFix64AsUInt256ToUFix64Fails() { + let ufixAmount: UFix64 = UFix64.max + var uintAmount: UInt256 = 184467440737_095_516_150_000_000_000 + 10_000_000_000 + + let convertedResult = executeScript( + "../scripts/utils/uint256_to_ufix64.cdc", + [uintAmount, UInt8(18)] + ) + Test.expect(convertedResult, Test.beFailed()) +} + +access(all) +fun testIntegerPartMaxUFix64AsUInt256ToUFix64Fails() { + let ufixAmount: UFix64 = UFix64.max + var uintAmount: UInt256 = 184467440737_095_516_150_000_000_000 + 100_000_000_000_000_000_000_000 + + let convertedResult = executeScript( + "../scripts/utils/uint256_to_ufix64.cdc", + [uintAmount, UInt8(18)] + ) + Test.expect(convertedResult, Test.beFailed()) +} From ed541ed42d17f068ddc294ad5ae1386204f41d64 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Mon, 6 May 2024 20:07:24 -0500 Subject: [PATCH 13/18] simplify uint256FractionalToScaledUFix64Decimals --- .../contracts/bridge/FlowEVMBridgeUtils.cdc | 28 +++---------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index 52560131..958712a3 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -866,23 +866,16 @@ contract FlowEVMBridgeUtils { post { result < 1.0: "Scaled fractional exceeds 1.0" } + var fractional = value - var digits = self.getNumberOfDigits(value) - let leadingZeros = decimals - digits - - // fractional is too long - since UFix64 has 8 decimal places, truncate to maintain only the first 8 digis - var fractionalReduction: UInt8 = 0 - while fractional > 99999999 { - fractional = fractional / 10 - fractionalReduction = fractionalReduction + 1 + // Truncate fractional to the first 8 decimal places + if decimals >= 8 { + fractional = fractional / self.pow(base: 10, exponent: decimals - 8) } // Scale the fractional part let fractionalMultiplier = self.ufixPow(base: 0.1, exponent: decimals < 8 ? decimals : 8) var scaledFractional = UFix64(fractional) * fractionalMultiplier - if leadingZeros > 0 && decimals >= 8 { - scaledFractional = scaledFractional * self.ufixPow(base: 0.1, exponent: leadingZeros) - } return scaledFractional } @@ -894,19 +887,6 @@ contract FlowEVMBridgeUtils { return value <= UInt256(UInt64.max) ? UInt64(value) : panic("Value too large to fit into UInt64") } - /// Returns the number of digits in the given UInt256 - /// - access(all) - view fun getNumberOfDigits(_ value: UInt256): UInt8 { - var tmp = value - var digits: UInt8 = 0 - while tmp > 0 { - tmp = tmp / 10 - digits = digits + 1 - } - return digits - } - /*************************** Type Identifier Utils ***************************/ From 343c3faa864bfc77bca42e930d047aff3f3aa527 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Mon, 6 May 2024 20:13:00 -0500 Subject: [PATCH 14/18] add pre-check in uint256FractionalToScaledUFix64Decimals --- cadence/contracts/bridge/FlowEVMBridgeUtils.cdc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index 958712a3..97f7a48a 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -863,6 +863,9 @@ contract FlowEVMBridgeUtils { /// access(all) view fun uint256FractionalToScaledUFix64Decimals(value: UInt256, decimals: UInt8): UFix64 { + pre { + self.getNumberOfDigits(value) <= decimals: "Fractional exceeds decimal places" + } post { result < 1.0: "Scaled fractional exceeds 1.0" } @@ -887,6 +890,19 @@ contract FlowEVMBridgeUtils { return value <= UInt256(UInt64.max) ? UInt64(value) : panic("Value too large to fit into UInt64") } + /// Returns the number of digits in the given UInt256 + /// + access(all) + view fun getNumberOfDigits(_ value: UInt256): UInt8 { + var tmp = value + var digits: UInt8 = 0 + while tmp > 0 { + tmp = tmp / 10 + digits = digits + 1 + } + return digits + } + /*************************** Type Identifier Utils ***************************/ From 24e2451cabf8ed56f2dea02824e2633d742d6dbd Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Tue, 7 May 2024 16:11:05 -0500 Subject: [PATCH 15/18] update contract comments --- cadence/contracts/bridge/FlowEVMBridgeUtils.cdc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index 97f7a48a..ed3522d9 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -845,7 +845,7 @@ contract FlowEVMBridgeUtils { // Scale the fractional part let scaledFractional = self.uint256FractionalToScaledUFix64Decimals(value: fractional, decimals: decimals) - // Ensure the parts do not exceed the max UFix64 value + // Ensure the parts do not exceed the max UFix64 value before conversion assert( scaledValue <= UInt256(UFix64.max), message: "Scaled integer value ".concat(value.toString()).concat(" exceeds max UFix64 value") @@ -864,23 +864,25 @@ contract FlowEVMBridgeUtils { access(all) view fun uint256FractionalToScaledUFix64Decimals(value: UInt256, decimals: UInt8): UFix64 { pre { - self.getNumberOfDigits(value) <= decimals: "Fractional exceeds decimal places" + self.getNumberOfDigits(value) <= decimals: "Fractional digits exceed the defined decimal places" } post { - result < 1.0: "Scaled fractional exceeds 1.0" + result < 1.0: "Resulting scaled fractional exceeds 1.0" } var fractional = value - // Truncate fractional to the first 8 decimal places + // Truncate fractional to the first 8 decimal places which is the max precision for UFix64 if decimals >= 8 { fractional = fractional / self.pow(base: 10, exponent: decimals - 8) } + // Return early if the truncated fractional part is now 0 + if fractional == 0 { + return 0.0 + } // Scale the fractional part let fractionalMultiplier = self.ufixPow(base: 0.1, exponent: decimals < 8 ? decimals : 8) - var scaledFractional = UFix64(fractional) * fractionalMultiplier - - return scaledFractional + return UFix64(fractional) * fractionalMultiplier } /// Returns the value as a UInt64 if it fits, otherwise panics From 142c0b50c4be70900b81a167919985219152afab Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Tue, 7 May 2024 17:06:07 -0500 Subject: [PATCH 16/18] add EVM asset validation util to factory & implement --- cadence/args/deploy-factory-args.json | 2 +- .../contracts/bridge/FlowEVMBridgeUtils.cdc | 15 +++++++++++---- cadence/tests/flow_evm_bridge_utils_tests.cdc | 5 ++--- cadence/tests/test_helpers.cdc | 2 +- solidity/src/FlowBridgeFactory.sol | 18 +++++++++++++++++- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/cadence/args/deploy-factory-args.json b/cadence/args/deploy-factory-args.json index b89fe17c..512e101b 100644 --- a/cadence/args/deploy-factory-args.json +++ b/cadence/args/deploy-factory-args.json @@ -1,7 +1,7 @@ [ { "type": "String", - "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611414806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004611029565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d61013836600461107b565b6102bc565b005b61015261014d36600461107b565b610336565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004611029565b610726565b61013d610757565b61013d61019c366004611029565b61076b565b6000546001600160a01b031661010d565b61013d6101c0366004611098565b61086d565b6101d86101d336600461107b565b610986565b604051610121919061113a565b61013d6101f3366004611098565b6109f9565b61015261020636600461107b565b610aca565b61010d61021936600461114d565b610b40565b61015261022c36600461107b565b610c15565b61013d61023f36600461107b565b610c84565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc9061027590859060040161113a565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611242565b92915050565b6102c4610cc2565b6102cd81610cef565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161037c919061125f565b600060405180830381855afa9150503d80600081146103b7576040519150601f19603f3d011682016040523d82523d6000602084013e6103bc565b606091505b50915091508115806103cd57508051155b156103dc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610429919061125f565b600060405180830381855afa9150503d8060008114610464576040519150601f19603f3d011682016040523d82523d6000602084013e610469565b606091505b50909250905081158061047b57508051155b1561048a575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104de919061125f565b600060405180830381855afa9150503d8060008114610519576040519150601f19603f3d011682016040523d82523d6000602084013e61051e565b606091505b50909250905081158061053057508051155b1561053f575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161057d9161125f565b600060405180830381855afa9150503d80600081146105b8576040519150601f19603f3d011682016040523d82523d6000602084013e6105bd565b606091505b5090925090508115806105cf57508051155b156105de575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161061c9161125f565b600060405180830381855afa9150503d8060008114610657576040519150601f19603f3d011682016040523d82523d6000602084013e61065c565b606091505b50909250905081158061066e57508051155b1561067d575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106bb9161125f565b600060405180830381855afa9150503d80600081146106f6576040519150601f19603f3d011682016040523d82523d6000602084013e6106fb565b606091505b50909250905081158061070d57508051155b1561071c575060009392505050565b5060019392505050565b6000600282604051610738919061125f565b908152604051908190036020019020546001600160a01b031692915050565b61075f610cc2565b6107696000610d61565b565b610773610cc2565b6000600282604051610785919061125f565b908152604051908190036020019020546001600160a01b03169050806108055760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610815919061125f565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b90610861908490849061127b565b60405180910390a15050565b610875610cc2565b61087e81610db1565b60006001600160a01b0316600283604051610899919061125f565b908152604051908190036020019020546001600160a01b0316146109165760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107fc565b80600283604051610927919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f90610861908490849061127b565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b691908101906112a5565b610a01610cc2565b610a0a81610db1565b6000600283604051610a1c919061125f565b908152604051908190036020019020546001600160a01b0316905080610a4b57610a46838361086d565b505050565b81600284604051610a5c919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610abd9085908490869061131c565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b34575060408051601f3d908101601f19168201909252610b319181019061134f565b60015b6102b657506000919050565b6000610b4a610cc2565b6000600288604051610b5c919061125f565b908152604051908190036020019020546001600160a01b03169050610b8081610db1565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bb9908c908c908c908c908c90600401611371565b6020604051808303816000875af1158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611242565b9050610c088682610e23565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061134f565b610c8c610cc2565b6001600160a01b038116610cb657604051631e4fbdf760e01b8152600060048201526024016107fc565b610cbf81610d61565b50565b6000546001600160a01b031633146107695760405163118cdaa760e01b81523360048201526024016107fc565b610cf881610e8e565b610d098163976998cb60e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107fc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610dba81610e8e565b610dcb8163476d399760e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107fc565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e57908690869060040161127b565b600060405180830381600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cbf5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107fc565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f51575060408051601f3d908101601f19168201909252610f4e9181019061134f565b60015b610f5d575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa357610fa3610f64565b604052919050565b600067ffffffffffffffff821115610fc557610fc5610f64565b50601f01601f191660200190565b600082601f830112610fe457600080fd5b8135610ff7610ff282610fab565b610f7a565b81815284602083860101111561100c57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561103b57600080fd5b813567ffffffffffffffff81111561105257600080fd5b61105e84828501610fd3565b949350505050565b6001600160a01b0381168114610cbf57600080fd5b60006020828403121561108d57600080fd5b8135610f5d81611066565b600080604083850312156110ab57600080fd5b823567ffffffffffffffff8111156110c257600080fd5b6110ce85828601610fd3565b92505060208301356110df81611066565b809150509250929050565b60005b838110156111055781810151838201526020016110ed565b50506000910152565b600081518084526111268160208601602086016110ea565b601f01601f19169290920160200192915050565b602081526000610f5d602083018461110e565b60008060008060008060c0878903121561116657600080fd5b863567ffffffffffffffff8082111561117e57600080fd5b61118a8a838b01610fd3565b975060208901359150808211156111a057600080fd5b6111ac8a838b01610fd3565b965060408901359150808211156111c257600080fd5b6111ce8a838b01610fd3565b955060608901359150808211156111e457600080fd5b6111f08a838b01610fd3565b9450608089013591508082111561120657600080fd5b6112128a838b01610fd3565b935060a089013591508082111561122857600080fd5b5061123589828a01610fd3565b9150509295509295509295565b60006020828403121561125457600080fd5b8151610f5d81611066565b600082516112718184602087016110ea565b9190910192915050565b60408152600061128e604083018561110e565b905060018060a01b03831660208301529392505050565b6000602082840312156112b757600080fd5b815167ffffffffffffffff8111156112ce57600080fd5b8201601f810184136112df57600080fd5b80516112ed610ff282610fab565b81815285602083850101111561130257600080fd5b6113138260208301602086016110ea565b95945050505050565b60608152600061132f606083018661110e565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561136157600080fd5b81518015158114610f5d57600080fd5b60a08152600061138460a083018861110e565b8281036020840152611396818861110e565b905082810360408401526113aa818761110e565b905082810360608401526113be818661110e565b905082810360808401526113d2818561110e565b9897505050505050505056fea2646970667358221220f24c72179ae52649db9edfc49327676600f6548bf80be2ac1838fbfaf00f29af64736f6c63430008170033" + "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611452806100a56000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063aff51c3e11610097578063daa09e5411610066578063daa09e5414610216578063db6d56cd14610229578063dfe1ac361461023c578063f2fde38b1461024f57600080fd5b8063aff51c3e146101bd578063b3d5dbdc146101d0578063cc435bf3146101f0578063d974d2381461020357600080fd5b806366cd5014116100d357806366cd50141461017e578063715018a61461019157806383843c9e146101995780638da5cb5b146101ac57600080fd5b806304433bbc1461010557806314902ad314610135578063263e0c1b1461014a5780635ab1bd531461016d575b600080fd5b610118610113366004611067565b610262565b6040516001600160a01b0390911681526020015b60405180910390f35b6101486101433660046110b9565b6102da565b005b61015d6101583660046110b9565b610354565b604051901515815260200161012c565b6001546001600160a01b0316610118565b61011861018c366004611067565b610744565b610148610775565b6101486101a7366004611067565b610789565b6000546001600160a01b0316610118565b6101486101cb3660046110d6565b61088b565b6101e36101de3660046110b9565b6109a4565b60405161012c9190611178565b61015d6101fe3660046110b9565b610a17565b6101486102113660046110d6565b610a37565b61015d6102243660046110b9565b610b08565b61011861023736600461118b565b610b7e565b61015d61024a3660046110b9565b610c53565b61014861025d3660046110b9565b610cc2565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc90610293908590600401611178565b602060405180830381865afa1580156102b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d49190611280565b92915050565b6102e2610d00565b6102eb81610d2d565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161039a919061129d565b600060405180830381855afa9150503d80600081146103d5576040519150601f19603f3d011682016040523d82523d6000602084013e6103da565b606091505b50915091508115806103eb57508051155b156103fa575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610447919061129d565b600060405180830381855afa9150503d8060008114610482576040519150601f19603f3d011682016040523d82523d6000602084013e610487565b606091505b50909250905081158061049957508051155b156104a8575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104fc919061129d565b600060405180830381855afa9150503d8060008114610537576040519150601f19603f3d011682016040523d82523d6000602084013e61053c565b606091505b50909250905081158061054e57508051155b1561055d575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161059b9161129d565b600060405180830381855afa9150503d80600081146105d6576040519150601f19603f3d011682016040523d82523d6000602084013e6105db565b606091505b5090925090508115806105ed57508051155b156105fc575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161063a9161129d565b600060405180830381855afa9150503d8060008114610675576040519150601f19603f3d011682016040523d82523d6000602084013e61067a565b606091505b50909250905081158061068c57508051155b1561069b575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106d99161129d565b600060405180830381855afa9150503d8060008114610714576040519150601f19603f3d011682016040523d82523d6000602084013e610719565b606091505b50909250905081158061072b57508051155b1561073a575060009392505050565b5060019392505050565b6000600282604051610756919061129d565b908152604051908190036020019020546001600160a01b031692915050565b61077d610d00565b6107876000610d9f565b565b610791610d00565b60006002826040516107a3919061129d565b908152604051908190036020019020546001600160a01b03169050806108235760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610833919061129d565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b9061087f90849084906112b9565b60405180910390a15050565b610893610d00565b61089c81610def565b60006001600160a01b03166002836040516108b7919061129d565b908152604051908190036020019020546001600160a01b0316146109345760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b606482015260840161081a565b80600283604051610945919061129d565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f9061087f90849084906112b9565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109ef573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102d491908101906112e3565b6000610a2282610b08565b1515610a2d83610354565b1515141592915050565b610a3f610d00565b610a4881610def565b6000600283604051610a5a919061129d565b908152604051908190036020019020546001600160a01b0316905080610a8957610a84838361088b565b505050565b81600284604051610a9a919061129d565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610afb9085908490869061135a565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b72575060408051601f3d908101601f19168201909252610b6f9181019061138d565b60015b6102d457506000919050565b6000610b88610d00565b6000600288604051610b9a919061129d565b908152604051908190036020019020546001600160a01b03169050610bbe81610def565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bf7908c908c908c908c908c906004016113af565b6020604051808303816000875af1158015610c16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3a9190611280565b9050610c468682610e61565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c9e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d4919061138d565b610cca610d00565b6001600160a01b038116610cf457604051631e4fbdf760e01b81526000600482015260240161081a565b610cfd81610d9f565b50565b6000546001600160a01b031633146107875760405163118cdaa760e01b815233600482015260240161081a565b610d3681610ecc565b610d478163976998cb60e01b610f22565b610cfd5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b606482015260840161081a565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610df881610ecc565b610e098163476d399760e01b610f22565b610cfd5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b606482015260840161081a565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e9590869086906004016112b9565b600060405180830381600087803b158015610eaf57600080fd5b505af1158015610ec3573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cfd5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f206164647265737300604482015260640161081a565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f8f575060408051601f3d908101601f19168201909252610f8c9181019061138d565b60015b610f9b575060006102d4565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fe157610fe1610fa2565b604052919050565b600067ffffffffffffffff82111561100357611003610fa2565b50601f01601f191660200190565b600082601f83011261102257600080fd5b813561103561103082610fe9565b610fb8565b81815284602083860101111561104a57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561107957600080fd5b813567ffffffffffffffff81111561109057600080fd5b61109c84828501611011565b949350505050565b6001600160a01b0381168114610cfd57600080fd5b6000602082840312156110cb57600080fd5b8135610f9b816110a4565b600080604083850312156110e957600080fd5b823567ffffffffffffffff81111561110057600080fd5b61110c85828601611011565b925050602083013561111d816110a4565b809150509250929050565b60005b8381101561114357818101518382015260200161112b565b50506000910152565b60008151808452611164816020860160208601611128565b601f01601f19169290920160200192915050565b602081526000610f9b602083018461114c565b60008060008060008060c087890312156111a457600080fd5b863567ffffffffffffffff808211156111bc57600080fd5b6111c88a838b01611011565b975060208901359150808211156111de57600080fd5b6111ea8a838b01611011565b9650604089013591508082111561120057600080fd5b61120c8a838b01611011565b9550606089013591508082111561122257600080fd5b61122e8a838b01611011565b9450608089013591508082111561124457600080fd5b6112508a838b01611011565b935060a089013591508082111561126657600080fd5b5061127389828a01611011565b9150509295509295509295565b60006020828403121561129257600080fd5b8151610f9b816110a4565b600082516112af818460208701611128565b9190910192915050565b6040815260006112cc604083018561114c565b905060018060a01b03831660208301529392505050565b6000602082840312156112f557600080fd5b815167ffffffffffffffff81111561130c57600080fd5b8201601f8101841361131d57600080fd5b805161132b61103082610fe9565b81815285602083850101111561134057600080fd5b611351826020830160208601611128565b95945050505050565b60608152600061136d606083018661114c565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561139f57600080fd5b81518015158114610f9b57600080fd5b60a0815260006113c260a083018861114c565b82810360208401526113d4818861114c565b905082810360408401526113e8818761114c565b905082810360608401526113fc818661114c565b90508281036080840152611410818561114c565b9897505050505050505056fea264697066735822122026be7d4ef13534833344abdcc736e8876603e1f9d3463f0047ddca092a98cc2d64736f6c63430008170033" }, { "type": "UInt64", diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index ed3522d9..4d27c2d6 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -256,9 +256,16 @@ contract FlowEVMBridgeUtils { /// access(all) fun isValidEVMAsset(evmContractAddress: EVM.EVMAddress): Bool { - let isERC721 = self.isERC721(evmContractAddress: evmContractAddress) - let isERC20 = self.isERC20(evmContractAddress: evmContractAddress) - return (isERC721 && !isERC20) || (!isERC721 && isERC20) + let callResult = self.call( + signature: "isValidAsset(address)", + targetEVMAddress: self.bridgeFactoryEVMAddress, + args: [evmContractAddress], + gasLimit: 100000, + value: 0.0 + ) + let decodedResult = EVM.decodeABI(types: [Type()], data: callResult.data) + assert(decodedResult.length == 1, message: "Invalid response length") + return decodedResult[0] as! Bool } /// Returns whether the given type is either an NFT or FT exclusively @@ -271,7 +278,7 @@ contract FlowEVMBridgeUtils { view fun isValidFlowAsset(type: Type): Bool { let isFlowNFT = type.isSubtype(of: Type<@{NonFungibleToken.NFT}>()) let isFlowToken = type.isSubtype(of: Type<@{FungibleToken.Vault}>()) - return (isFlowNFT && !isFlowToken) || (!isFlowNFT && isFlowToken) + return isFlowNFT != isFlowToken } /// Retrieves the bridge contract's COA EVMAddress diff --git a/cadence/tests/flow_evm_bridge_utils_tests.cdc b/cadence/tests/flow_evm_bridge_utils_tests.cdc index a4ca6687..aeae6a47 100644 --- a/cadence/tests/flow_evm_bridge_utils_tests.cdc +++ b/cadence/tests/flow_evm_bridge_utils_tests.cdc @@ -96,12 +96,11 @@ fun setup() { ) let evts = Test.eventsOfType(Type()) Test.assertEqual(2, evts.length) - let factoryDeploymentEvent = evts[0] as! EVM.TransactionExecuted - let factoryAddressHex = factoryDeploymentEvent.contractAddress + let factoryAddressHex = getEVMAddressHexFromEvents(evts, idx: 0) err = Test.deployContract( name: "FlowEVMBridgeUtils", path: "../contracts/bridge/FlowEVMBridgeUtils.cdc", - arguments: [factoryAddressHex.slice(from: 2, upTo: factoryAddressHex.length)] + arguments: [factoryAddressHex] ) Test.expect(err, Test.beNil()) } diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc index e71ffe2e..5d732366 100644 --- a/cadence/tests/test_helpers.cdc +++ b/cadence/tests/test_helpers.cdc @@ -11,7 +11,7 @@ import "EVM" /// See the python util `get_code_hex.py` to retrieve the hex-encoded Cadence either with or /// without a separator (`{{CONTRACT_NAME}}` used in templates to "chunk" template code). -access(all) let compiledFactoryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611414806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063daa09e5411610066578063daa09e54146101f8578063db6d56cd1461020b578063dfe1ac361461021e578063f2fde38b1461023157600080fd5b80638da5cb5b146101a1578063aff51c3e146101b2578063b3d5dbdc146101c5578063d974d238146101e557600080fd5b80635ab1bd53116100d35780635ab1bd531461016257806366cd501414610173578063715018a61461018657806383843c9e1461018e57600080fd5b806304433bbc146100fa57806314902ad31461012a578063263e0c1b1461013f575b600080fd5b61010d610108366004611029565b610244565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d61013836600461107b565b6102bc565b005b61015261014d36600461107b565b610336565b6040519015158152602001610121565b6001546001600160a01b031661010d565b61010d610181366004611029565b610726565b61013d610757565b61013d61019c366004611029565b61076b565b6000546001600160a01b031661010d565b61013d6101c0366004611098565b61086d565b6101d86101d336600461107b565b610986565b604051610121919061113a565b61013d6101f3366004611098565b6109f9565b61015261020636600461107b565b610aca565b61010d61021936600461114d565b610b40565b61015261022c36600461107b565b610c15565b61013d61023f36600461107b565b610c84565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc9061027590859060040161113a565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190611242565b92915050565b6102c4610cc2565b6102cd81610cef565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161037c919061125f565b600060405180830381855afa9150503d80600081146103b7576040519150601f19603f3d011682016040523d82523d6000602084013e6103bc565b606091505b50915091508115806103cd57508051155b156103dc575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610429919061125f565b600060405180830381855afa9150503d8060008114610464576040519150601f19603f3d011682016040523d82523d6000602084013e610469565b606091505b50909250905081158061047b57508051155b1561048a575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104de919061125f565b600060405180830381855afa9150503d8060008114610519576040519150601f19603f3d011682016040523d82523d6000602084013e61051e565b606091505b50909250905081158061053057508051155b1561053f575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161057d9161125f565b600060405180830381855afa9150503d80600081146105b8576040519150601f19603f3d011682016040523d82523d6000602084013e6105bd565b606091505b5090925090508115806105cf57508051155b156105de575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161061c9161125f565b600060405180830381855afa9150503d8060008114610657576040519150601f19603f3d011682016040523d82523d6000602084013e61065c565b606091505b50909250905081158061066e57508051155b1561067d575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106bb9161125f565b600060405180830381855afa9150503d80600081146106f6576040519150601f19603f3d011682016040523d82523d6000602084013e6106fb565b606091505b50909250905081158061070d57508051155b1561071c575060009392505050565b5060019392505050565b6000600282604051610738919061125f565b908152604051908190036020019020546001600160a01b031692915050565b61075f610cc2565b6107696000610d61565b565b610773610cc2565b6000600282604051610785919061125f565b908152604051908190036020019020546001600160a01b03169050806108055760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610815919061125f565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b90610861908490849061127b565b60405180910390a15050565b610875610cc2565b61087e81610db1565b60006001600160a01b0316600283604051610899919061125f565b908152604051908190036020019020546001600160a01b0316146109165760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b60648201526084016107fc565b80600283604051610927919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f90610861908490849061127b565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b691908101906112a5565b610a01610cc2565b610a0a81610db1565b6000600283604051610a1c919061125f565b908152604051908190036020019020546001600160a01b0316905080610a4b57610a46838361086d565b505050565b81600284604051610a5c919061125f565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610abd9085908490869061131c565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b34575060408051601f3d908101601f19168201909252610b319181019061134f565b60015b6102b657506000919050565b6000610b4a610cc2565b6000600288604051610b5c919061125f565b908152604051908190036020019020546001600160a01b03169050610b8081610db1565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bb9908c908c908c908c908c90600401611371565b6020604051808303816000875af1158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611242565b9050610c088682610e23565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061134f565b610c8c610cc2565b6001600160a01b038116610cb657604051631e4fbdf760e01b8152600060048201526024016107fc565b610cbf81610d61565b50565b6000546001600160a01b031633146107695760405163118cdaa760e01b81523360048201526024016107fc565b610cf881610e8e565b610d098163976998cb60e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b60648201526084016107fc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610dba81610e8e565b610dcb8163476d399760e01b610ee4565b610cbf5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b60648201526084016107fc565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e57908690869060040161127b565b600060405180830381600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cbf5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f20616464726573730060448201526064016107fc565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f51575060408051601f3d908101601f19168201909252610f4e9181019061134f565b60015b610f5d575060006102b6565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa357610fa3610f64565b604052919050565b600067ffffffffffffffff821115610fc557610fc5610f64565b50601f01601f191660200190565b600082601f830112610fe457600080fd5b8135610ff7610ff282610fab565b610f7a565b81815284602083860101111561100c57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561103b57600080fd5b813567ffffffffffffffff81111561105257600080fd5b61105e84828501610fd3565b949350505050565b6001600160a01b0381168114610cbf57600080fd5b60006020828403121561108d57600080fd5b8135610f5d81611066565b600080604083850312156110ab57600080fd5b823567ffffffffffffffff8111156110c257600080fd5b6110ce85828601610fd3565b92505060208301356110df81611066565b809150509250929050565b60005b838110156111055781810151838201526020016110ed565b50506000910152565b600081518084526111268160208601602086016110ea565b601f01601f19169290920160200192915050565b602081526000610f5d602083018461110e565b60008060008060008060c0878903121561116657600080fd5b863567ffffffffffffffff8082111561117e57600080fd5b61118a8a838b01610fd3565b975060208901359150808211156111a057600080fd5b6111ac8a838b01610fd3565b965060408901359150808211156111c257600080fd5b6111ce8a838b01610fd3565b955060608901359150808211156111e457600080fd5b6111f08a838b01610fd3565b9450608089013591508082111561120657600080fd5b6112128a838b01610fd3565b935060a089013591508082111561122857600080fd5b5061123589828a01610fd3565b9150509295509295509295565b60006020828403121561125457600080fd5b8151610f5d81611066565b600082516112718184602087016110ea565b9190910192915050565b60408152600061128e604083018561110e565b905060018060a01b03831660208301529392505050565b6000602082840312156112b757600080fd5b815167ffffffffffffffff8111156112ce57600080fd5b8201601f810184136112df57600080fd5b80516112ed610ff282610fab565b81815285602083850101111561130257600080fd5b6113138260208301602086016110ea565b95945050505050565b60608152600061132f606083018661110e565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561136157600080fd5b81518015158114610f5d57600080fd5b60a08152600061138460a083018861110e565b8281036020840152611396818861110e565b905082810360408401526113aa818761110e565b905082810360608401526113be818661110e565b905082810360808401526113d2818561110e565b9897505050505050505056fea2646970667358221220f24c72179ae52649db9edfc49327676600f6548bf80be2ac1838fbfaf00f29af64736f6c63430008170033" +access(all) let compiledFactoryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611452806100a56000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063aff51c3e11610097578063daa09e5411610066578063daa09e5414610216578063db6d56cd14610229578063dfe1ac361461023c578063f2fde38b1461024f57600080fd5b8063aff51c3e146101bd578063b3d5dbdc146101d0578063cc435bf3146101f0578063d974d2381461020357600080fd5b806366cd5014116100d357806366cd50141461017e578063715018a61461019157806383843c9e146101995780638da5cb5b146101ac57600080fd5b806304433bbc1461010557806314902ad314610135578063263e0c1b1461014a5780635ab1bd531461016d575b600080fd5b610118610113366004611067565b610262565b6040516001600160a01b0390911681526020015b60405180910390f35b6101486101433660046110b9565b6102da565b005b61015d6101583660046110b9565b610354565b604051901515815260200161012c565b6001546001600160a01b0316610118565b61011861018c366004611067565b610744565b610148610775565b6101486101a7366004611067565b610789565b6000546001600160a01b0316610118565b6101486101cb3660046110d6565b61088b565b6101e36101de3660046110b9565b6109a4565b60405161012c9190611178565b61015d6101fe3660046110b9565b610a17565b6101486102113660046110d6565b610a37565b61015d6102243660046110b9565b610b08565b61011861023736600461118b565b610b7e565b61015d61024a3660046110b9565b610c53565b61014861025d3660046110b9565b610cc2565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc90610293908590600401611178565b602060405180830381865afa1580156102b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d49190611280565b92915050565b6102e2610d00565b6102eb81610d2d565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161039a919061129d565b600060405180830381855afa9150503d80600081146103d5576040519150601f19603f3d011682016040523d82523d6000602084013e6103da565b606091505b50915091508115806103eb57508051155b156103fa575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610447919061129d565b600060405180830381855afa9150503d8060008114610482576040519150601f19603f3d011682016040523d82523d6000602084013e610487565b606091505b50909250905081158061049957508051155b156104a8575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104fc919061129d565b600060405180830381855afa9150503d8060008114610537576040519150601f19603f3d011682016040523d82523d6000602084013e61053c565b606091505b50909250905081158061054e57508051155b1561055d575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161059b9161129d565b600060405180830381855afa9150503d80600081146105d6576040519150601f19603f3d011682016040523d82523d6000602084013e6105db565b606091505b5090925090508115806105ed57508051155b156105fc575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161063a9161129d565b600060405180830381855afa9150503d8060008114610675576040519150601f19603f3d011682016040523d82523d6000602084013e61067a565b606091505b50909250905081158061068c57508051155b1561069b575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106d99161129d565b600060405180830381855afa9150503d8060008114610714576040519150601f19603f3d011682016040523d82523d6000602084013e610719565b606091505b50909250905081158061072b57508051155b1561073a575060009392505050565b5060019392505050565b6000600282604051610756919061129d565b908152604051908190036020019020546001600160a01b031692915050565b61077d610d00565b6107876000610d9f565b565b610791610d00565b60006002826040516107a3919061129d565b908152604051908190036020019020546001600160a01b03169050806108235760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610833919061129d565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b9061087f90849084906112b9565b60405180910390a15050565b610893610d00565b61089c81610def565b60006001600160a01b03166002836040516108b7919061129d565b908152604051908190036020019020546001600160a01b0316146109345760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b606482015260840161081a565b80600283604051610945919061129d565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f9061087f90849084906112b9565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109ef573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102d491908101906112e3565b6000610a2282610b08565b1515610a2d83610354565b1515141592915050565b610a3f610d00565b610a4881610def565b6000600283604051610a5a919061129d565b908152604051908190036020019020546001600160a01b0316905080610a8957610a84838361088b565b505050565b81600284604051610a9a919061129d565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610afb9085908490869061135a565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b72575060408051601f3d908101601f19168201909252610b6f9181019061138d565b60015b6102d457506000919050565b6000610b88610d00565b6000600288604051610b9a919061129d565b908152604051908190036020019020546001600160a01b03169050610bbe81610def565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bf7908c908c908c908c908c906004016113af565b6020604051808303816000875af1158015610c16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3a9190611280565b9050610c468682610e61565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c9e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d4919061138d565b610cca610d00565b6001600160a01b038116610cf457604051631e4fbdf760e01b81526000600482015260240161081a565b610cfd81610d9f565b50565b6000546001600160a01b031633146107875760405163118cdaa760e01b815233600482015260240161081a565b610d3681610ecc565b610d478163976998cb60e01b610f22565b610cfd5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b606482015260840161081a565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610df881610ecc565b610e098163476d399760e01b610f22565b610cfd5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b606482015260840161081a565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e9590869086906004016112b9565b600060405180830381600087803b158015610eaf57600080fd5b505af1158015610ec3573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cfd5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f206164647265737300604482015260640161081a565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f8f575060408051601f3d908101601f19168201909252610f8c9181019061138d565b60015b610f9b575060006102d4565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fe157610fe1610fa2565b604052919050565b600067ffffffffffffffff82111561100357611003610fa2565b50601f01601f191660200190565b600082601f83011261102257600080fd5b813561103561103082610fe9565b610fb8565b81815284602083860101111561104a57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561107957600080fd5b813567ffffffffffffffff81111561109057600080fd5b61109c84828501611011565b949350505050565b6001600160a01b0381168114610cfd57600080fd5b6000602082840312156110cb57600080fd5b8135610f9b816110a4565b600080604083850312156110e957600080fd5b823567ffffffffffffffff81111561110057600080fd5b61110c85828601611011565b925050602083013561111d816110a4565b809150509250929050565b60005b8381101561114357818101518382015260200161112b565b50506000910152565b60008151808452611164816020860160208601611128565b601f01601f19169290920160200192915050565b602081526000610f9b602083018461114c565b60008060008060008060c087890312156111a457600080fd5b863567ffffffffffffffff808211156111bc57600080fd5b6111c88a838b01611011565b975060208901359150808211156111de57600080fd5b6111ea8a838b01611011565b9650604089013591508082111561120057600080fd5b61120c8a838b01611011565b9550606089013591508082111561122257600080fd5b61122e8a838b01611011565b9450608089013591508082111561124457600080fd5b6112508a838b01611011565b935060a089013591508082111561126657600080fd5b5061127389828a01611011565b9150509295509295509295565b60006020828403121561129257600080fd5b8151610f9b816110a4565b600082516112af818460208701611128565b9190910192915050565b6040815260006112cc604083018561114c565b905060018060a01b03831660208301529392505050565b6000602082840312156112f557600080fd5b815167ffffffffffffffff81111561130c57600080fd5b8201601f8101841361131d57600080fd5b805161132b61103082610fe9565b81815285602083850101111561134057600080fd5b611351826020830160208601611128565b95945050505050565b60608152600061136d606083018661114c565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561139f57600080fd5b81518015158114610f9b57600080fd5b60a0815260006113c260a083018861114c565b82810360208401526113d4818861114c565b905082810360408401526113e8818761114c565b905082810360608401526113fc818661114c565b90508281036080840152611410818561114c565b9897505050505050505056fea264697066735822122026be7d4ef13534833344abdcc736e8876603e1f9d3463f0047ddca092a98cc2d64736f6c63430008170033" access(all) let erc20DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206fb41458119173f9f1d07720d0b22fbfacf4726505008b5c43816c9902cd0fc464736f6c63430008170033a2646970667358221220fbaaee74b0e14c12923bfbdc4701408031af759f454cf27df9e8defc7658e96264736f6c63430008170033" diff --git a/solidity/src/FlowBridgeFactory.sol b/solidity/src/FlowBridgeFactory.sol index d817e3c3..2e3a306c 100644 --- a/solidity/src/FlowBridgeFactory.sol +++ b/solidity/src/FlowBridgeFactory.sol @@ -19,7 +19,12 @@ import {FlowEVMDeploymentRegistry} from "./interfaces/FlowEVMDeploymentRegistry. * to be swapped out without affecting the underlying associations between Cadence and EVM contracts. */ contract FlowBridgeFactory is Ownable { - // Address of the deployment registry where deployed contract associations are registered + // Address of the deployment registry where deployed contract associations are registered. Note that this is a + // registry for EVM contracts deployed by the bridge factory and does not include those EVM-native contracts that + // have been onboarded to the bridge via Cadence contracts. The global source of truth is found in the Cadence + // side of the bridge, however this registry and publicly accessible methods can serve as a source of truth + // within EVM. Given some EVM contract, its bridge-supported Cadence type association can be found (and vice-versa) + // by querying this contract, thus preventing impersonation attacks. address private deploymentRegistry; // Mapping of deployer tags to their implementation addresses mapping(string => address) private deployers; @@ -161,6 +166,17 @@ contract FlowBridgeFactory is Ownable { } } + /** + * @dev Determines if a contract is a valid asset by checking if it is either an ERC20 or ERC721 implementation + * + * @param contractAddr The address of the contract to check + * + * @return True if the contract is a valid asset, false otherwise + */ + function isValidAsset(address contractAddr) public view returns (bool) { + return isERC20(contractAddr) != isERC721(contractAddr); + } + /** * @dev Retrieves the address of the deployment registry * From 19ee59c94e8ad8676b14e9da37d3638183db3198 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Wed, 8 May 2024 17:14:22 -0500 Subject: [PATCH 17/18] Apply suggestions from code review Co-authored-by: Jordan Schalm --- cadence/contracts/bridge/FlowEVMBridgeUtils.cdc | 2 +- solidity/src/FlowBridgeDeploymentRegistry.sol | 3 ++- solidity/src/FlowEVMBridgedERC20Deployer.sol | 2 +- solidity/src/FlowEVMBridgedERC721Deployer.sol | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index 4d27c2d6..39cf285a 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -277,7 +277,7 @@ contract FlowEVMBridgeUtils { access(all) view fun isValidFlowAsset(type: Type): Bool { let isFlowNFT = type.isSubtype(of: Type<@{NonFungibleToken.NFT}>()) - let isFlowToken = type.isSubtype(of: Type<@{FungibleToken.Vault}>()) + let isFlowFungibleToken = type.isSubtype(of: Type<@{FungibleToken.Vault}>()) return isFlowNFT != isFlowToken } diff --git a/solidity/src/FlowBridgeDeploymentRegistry.sol b/solidity/src/FlowBridgeDeploymentRegistry.sol index 4ca79495..ff34f937 100644 --- a/solidity/src/FlowBridgeDeploymentRegistry.sol +++ b/solidity/src/FlowBridgeDeploymentRegistry.sol @@ -7,7 +7,8 @@ import {FlowEVMDeploymentRegistry} from "./interfaces/FlowEVMDeploymentRegistry. /** * @title FlowBridgeDeploymentRegistry - * @dev A contract to manage the deployment of Flow EVM contracts and their association with Cadence contracts + * @dev A contract to manage the association between bridged Flow EVM contracts and a corresponding Cadence resource type. + * Deployment of new bridged Flow EVM contracts is handled in `FlowBridgeFactory`. */ contract FlowBridgeDeploymentRegistry is FlowEVMDeploymentRegistry, Ownable { constructor() Ownable(msg.sender) { diff --git a/solidity/src/FlowEVMBridgedERC20Deployer.sol b/solidity/src/FlowEVMBridgedERC20Deployer.sol index 5bfeb013..6d1aa8e2 100644 --- a/solidity/src/FlowEVMBridgedERC20Deployer.sol +++ b/solidity/src/FlowEVMBridgedERC20Deployer.sol @@ -9,7 +9,7 @@ import {FlowEVMBridgedERC20} from "./templates/FlowEVMBridgedERC20.sol"; /** * @title FlowEVMBridgedERC20Deployer - * @dev A contract to deploy FlowEVMBridgedERC20 contracts with named associations to Cadence contracts. Only the + * @dev A contract to deploy FlowEVMBridgedERC20 contracts with named associations to Cadence resources types. Only the * delegated deployer can deploy new contracts. This contract is used by the Flow EVM bridge to deploy and define * bridged ERC20 tokens which are defined natively in Cadence. */ diff --git a/solidity/src/FlowEVMBridgedERC721Deployer.sol b/solidity/src/FlowEVMBridgedERC721Deployer.sol index 86e0c1fb..7f55cde0 100644 --- a/solidity/src/FlowEVMBridgedERC721Deployer.sol +++ b/solidity/src/FlowEVMBridgedERC721Deployer.sol @@ -10,7 +10,7 @@ import {FlowEVMBridgedERC721} from "./templates/FlowEVMBridgedERC721.sol"; /** * @title FlowEVMBridgedERC721Deployer - * @dev A contract to deploy FlowEVMBridgedERC721 contracts with named associations to Cadence contracts. Only the + * @dev A contract to deploy FlowEVMBridgedERC721 contracts with named associations to Cadence resource types. Only the * delegated deployer can deploy new contracts. This contract is used by the Flow EVM bridge to deploy and define * bridged ERC721 tokens which are defined natively in Cadence. */ From 6c4c83510c5066496f62adaee13535667727b8b9 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Wed, 8 May 2024 17:19:59 -0500 Subject: [PATCH 18/18] recompile solidity from PR commit & replace bytecode values --- cadence/args/deploy-erc20-deployer-args.json | 2 +- cadence/args/deploy-erc721-deployer-args.json | 2 +- cadence/contracts/bridge/FlowEVMBridge.cdc | 4 ++-- cadence/contracts/bridge/FlowEVMBridgeUtils.cdc | 12 ++++++------ cadence/tests/test_helpers.cdc | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cadence/args/deploy-erc20-deployer-args.json b/cadence/args/deploy-erc20-deployer-args.json index 58400869..4274e6a4 100644 --- a/cadence/args/deploy-erc20-deployer-args.json +++ b/cadence/args/deploy-erc20-deployer-args.json @@ -1,7 +1,7 @@ [ { "type": "String", - "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206fb41458119173f9f1d07720d0b22fbfacf4726505008b5c43816c9902cd0fc464736f6c63430008170033a2646970667358221220fbaaee74b0e14c12923bfbdc4701408031af759f454cf27df9e8defc7658e96264736f6c63430008170033" + "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206fb41458119173f9f1d07720d0b22fbfacf4726505008b5c43816c9902cd0fc464736f6c63430008170033a26469706673582212201df4bdff78560cbe320524756593933725001e7f7f8e2f575636163e3d9cc87d64736f6c63430008170033" }, { "type": "UInt64", diff --git a/cadence/args/deploy-erc721-deployer-args.json b/cadence/args/deploy-erc721-deployer-args.json index 8230383c..7671744d 100644 --- a/cadence/args/deploy-erc721-deployer-args.json +++ b/cadence/args/deploy-erc721-deployer-args.json @@ -1,7 +1,7 @@ [ { "type": "String", - "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612657806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d3660046200043c565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c93660046200051a565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a7565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005fc565b620002bf565b6200010662000142366004620005fc565b6200036b565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b031633146200020b576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a204f6e60448201527f6c792064656c656761746564206465706c6f7965722063616e206465706c6f7960648201526084015b60405180910390fd5b600080546001600160a01b031687878787876040516200022b906200042e565b6200023c969594939291906200066f565b604051809103906000f08015801562000259573d6000803e3d6000fd5b5090507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f0818888888860405162000295959493929190620006f8565b60405180910390a19695505050505050565b620002b1620003af565b620002bd6000620003de565b565b620002c9620003af565b6001600160a01b03811662000349576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a20496e60448201527f76616c69642064656c656761746564206465706c6f7965722061646472657373606482015260840162000202565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000375620003af565b6001600160a01b038116620003a157604051631e4fbdf760e01b81526000600482015260240162000202565b620003ac81620003de565b50565b6000546001600160a01b03163314620002bd5760405163118cdaa760e01b815233600482015260240162000202565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611eb7806200076b83390190565b6000602082840312156200044f57600080fd5b81356001600160e01b0319811681146200046857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049757600080fd5b813567ffffffffffffffff80821115620004b557620004b56200046f565b604051601f8301601f19908116603f01168101908282118183101715620004e057620004e06200046f565b81604052838152866020858801011115620004fa57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200053357600080fd5b853567ffffffffffffffff808211156200054c57600080fd5b6200055a89838a0162000485565b965060208801359150808211156200057157600080fd5b6200057f89838a0162000485565b955060408801359150808211156200059657600080fd5b620005a489838a0162000485565b94506060880135915080821115620005bb57600080fd5b620005c989838a0162000485565b93506080880135915080821115620005e057600080fd5b50620005ef8882890162000485565b9150509295509295909350565b6000602082840312156200060f57600080fd5b81356001600160a01b03811681146200046857600080fd5b6000815180845260005b818110156200064f5760208185018101518683018201520162000631565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006959083018862000627565b8281036040840152620006a9818862000627565b90508281036060840152620006bf818762000627565b90508281036080840152620006d5818662000627565b905082810360a0840152620006eb818562000627565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071e9083018762000627565b828103604084015262000732818762000627565b9050828103606084015262000748818662000627565b905082810360808401526200075e818562000627565b9897505050505050505056fe60806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122074d34aec07c0da793ce5cac74069bf4177b7594babf4fede87db849ea2f57b3764736f6c63430008170033a264697066735822122064104e4f6458f9ff9e5aca71c897aa1948c1b57434e9d83b5f4ce4a9ab5d328564736f6c63430008170033" + "value": "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612657806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d3660046200043c565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c93660046200051a565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a7565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005fc565b620002bf565b6200010662000142366004620005fc565b6200036b565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b031633146200020b576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a204f6e60448201527f6c792064656c656761746564206465706c6f7965722063616e206465706c6f7960648201526084015b60405180910390fd5b600080546001600160a01b031687878787876040516200022b906200042e565b6200023c969594939291906200066f565b604051809103906000f08015801562000259573d6000803e3d6000fd5b5090507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f0818888888860405162000295959493929190620006f8565b60405180910390a19695505050505050565b620002b1620003af565b620002bd6000620003de565b565b620002c9620003af565b6001600160a01b03811662000349576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a20496e60448201527f76616c69642064656c656761746564206465706c6f7965722061646472657373606482015260840162000202565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000375620003af565b6001600160a01b038116620003a157604051631e4fbdf760e01b81526000600482015260240162000202565b620003ac81620003de565b50565b6000546001600160a01b03163314620002bd5760405163118cdaa760e01b815233600482015260240162000202565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611eb7806200076b83390190565b6000602082840312156200044f57600080fd5b81356001600160e01b0319811681146200046857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049757600080fd5b813567ffffffffffffffff80821115620004b557620004b56200046f565b604051601f8301601f19908116603f01168101908282118183101715620004e057620004e06200046f565b81604052838152866020858801011115620004fa57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200053357600080fd5b853567ffffffffffffffff808211156200054c57600080fd5b6200055a89838a0162000485565b965060208801359150808211156200057157600080fd5b6200057f89838a0162000485565b955060408801359150808211156200059657600080fd5b620005a489838a0162000485565b94506060880135915080821115620005bb57600080fd5b620005c989838a0162000485565b93506080880135915080821115620005e057600080fd5b50620005ef8882890162000485565b9150509295509295909350565b6000602082840312156200060f57600080fd5b81356001600160a01b03811681146200046857600080fd5b6000815180845260005b818110156200064f5760208185018101518683018201520162000631565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006959083018862000627565b8281036040840152620006a9818862000627565b90508281036060840152620006bf818762000627565b90508281036080840152620006d5818662000627565b905082810360a0840152620006eb818562000627565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071e9083018762000627565b828103604084015262000732818762000627565b9050828103606084015262000748818662000627565b905082810360808401526200075e818562000627565b9897505050505050505056fe60806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122074d34aec07c0da793ce5cac74069bf4177b7594babf4fede87db849ea2f57b3764736f6c63430008170033a2646970667358221220953493586f5fb5670e80849013b6c27540a3f06c628c3046b81886afa405e0c664736f6c63430008170033" }, { "type": "UInt64", diff --git a/cadence/contracts/bridge/FlowEVMBridge.cdc b/cadence/contracts/bridge/FlowEVMBridge.cdc index 7c8af54d..3199bb23 100644 --- a/cadence/contracts/bridge/FlowEVMBridge.cdc +++ b/cadence/contracts/bridge/FlowEVMBridge.cdc @@ -550,7 +550,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { /// access(all) view fun typeRequiresOnboarding(_ type: Type): Bool? { - if !FlowEVMBridgeUtils.isValidFlowAsset(type: type) { + if !FlowEVMBridgeUtils.isValidCadenceAsset(type: type) { return nil } return FlowEVMBridgeConfig.getEVMAddressAssociated(with: type) == nil && @@ -590,7 +590,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge { access(self) fun deployEVMContract(forAssetType: Type): FlowEVMBridgeUtils.EVMOnboardingValues { pre { - FlowEVMBridgeUtils.isValidFlowAsset(type: forAssetType): + FlowEVMBridgeUtils.isValidCadenceAsset(type: forAssetType): "Asset type is not supported by the bridge" } let isNFT = forAssetType.isSubtype(of: Type<@{NonFungibleToken.NFT}>()) diff --git a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc index 39cf285a..240139ef 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeUtils.cdc @@ -275,10 +275,10 @@ contract FlowEVMBridgeUtils { /// @return True if the type is either an NFT or FT, false otherwise /// access(all) - view fun isValidFlowAsset(type: Type): Bool { - let isFlowNFT = type.isSubtype(of: Type<@{NonFungibleToken.NFT}>()) - let isFlowFungibleToken = type.isSubtype(of: Type<@{FungibleToken.Vault}>()) - return isFlowNFT != isFlowToken + view fun isValidCadenceAsset(type: Type): Bool { + let isCadenceNFT = type.isSubtype(of: Type<@{NonFungibleToken.NFT}>()) + let isCadenceFungibleToken = type.isSubtype(of: Type<@{FungibleToken.Vault}>()) + return isCadenceNFT != isCadenceFungibleToken } /// Retrieves the bridge contract's COA EVMAddress @@ -304,7 +304,7 @@ contract FlowEVMBridgeUtils { access(all) fun getCadenceOnboardingValues(forAssetType: Type): CadenceOnboardingValues { pre { - self.isValidFlowAsset(type: forAssetType): "This type is not a supported Flow asset type." + self.isValidCadenceAsset(type: forAssetType): "This type is not a supported Flow asset type." } // If not an NFT, assumed to be fungible token. let isNFT = forAssetType.isSubtype(of: Type<@{NonFungibleToken.NFT}>()) @@ -726,7 +726,7 @@ contract FlowEVMBridgeUtils { /// access(all) view fun deriveEscrowStoragePath(fromType: Type): StoragePath? { - if !self.isValidFlowAsset(type: fromType) { + if !self.isValidCadenceAsset(type: fromType) { return nil } var prefix = "" diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc index 5d732366..af8e9c1a 100644 --- a/cadence/tests/test_helpers.cdc +++ b/cadence/tests/test_helpers.cdc @@ -13,9 +13,9 @@ import "EVM" access(all) let compiledFactoryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611452806100a56000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063aff51c3e11610097578063daa09e5411610066578063daa09e5414610216578063db6d56cd14610229578063dfe1ac361461023c578063f2fde38b1461024f57600080fd5b8063aff51c3e146101bd578063b3d5dbdc146101d0578063cc435bf3146101f0578063d974d2381461020357600080fd5b806366cd5014116100d357806366cd50141461017e578063715018a61461019157806383843c9e146101995780638da5cb5b146101ac57600080fd5b806304433bbc1461010557806314902ad314610135578063263e0c1b1461014a5780635ab1bd531461016d575b600080fd5b610118610113366004611067565b610262565b6040516001600160a01b0390911681526020015b60405180910390f35b6101486101433660046110b9565b6102da565b005b61015d6101583660046110b9565b610354565b604051901515815260200161012c565b6001546001600160a01b0316610118565b61011861018c366004611067565b610744565b610148610775565b6101486101a7366004611067565b610789565b6000546001600160a01b0316610118565b6101486101cb3660046110d6565b61088b565b6101e36101de3660046110b9565b6109a4565b60405161012c9190611178565b61015d6101fe3660046110b9565b610a17565b6101486102113660046110d6565b610a37565b61015d6102243660046110b9565b610b08565b61011861023736600461118b565b610b7e565b61015d61024a3660046110b9565b610c53565b61014861025d3660046110b9565b610cc2565b600154604051630110ceef60e21b81526000916001600160a01b0316906304433bbc90610293908590600401611178565b602060405180830381865afa1580156102b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d49190611280565b92915050565b6102e2610d00565b6102eb81610d2d565b600154604080516001600160a01b03928316815291831660208301527f61dad6e94cd5c0b65c9265246706a09bd0d11d5330f3e6b659d328151a664e8c910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b60408051600481526024810182526020810180516001600160e01b03166318160ddd60e01b1790529051600091829182916001600160a01b0386169161039a919061129d565b600060405180830381855afa9150503d80600081146103d5576040519150601f19603f3d011682016040523d82523d6000602084013e6103da565b606091505b50915091508115806103eb57508051155b156103fa575060009392505050565b604051600060248201526001600160a01b0385169060440160408051601f198184030181529181526020820180516001600160e01b03166370a0823160e01b17905251610447919061129d565b600060405180830381855afa9150503d8060008114610482576040519150601f19603f3d011682016040523d82523d6000602084013e610487565b606091505b50909250905081158061049957508051155b156104a8575060009392505050565b60405160006024820181905260448201526001600160a01b0385169060640160408051601f198184030181529181526020820180516001600160e01b0316636eb1769f60e11b179052516104fc919061129d565b600060405180830381855afa9150503d8060008114610537576040519150601f19603f3d011682016040523d82523d6000602084013e61053c565b606091505b50909250905081158061054e57508051155b1561055d575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516001600160a01b0386169161059b9161129d565b600060405180830381855afa9150503d80600081146105d6576040519150601f19603f3d011682016040523d82523d6000602084013e6105db565b606091505b5090925090508115806105ed57508051155b156105fc575060009392505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516001600160a01b0386169161063a9161129d565b600060405180830381855afa9150503d8060008114610675576040519150601f19603f3d011682016040523d82523d6000602084013e61067a565b606091505b50909250905081158061068c57508051155b1561069b575060009392505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290516001600160a01b038616916106d99161129d565b600060405180830381855afa9150503d8060008114610714576040519150601f19603f3d011682016040523d82523d6000602084013e610719565b606091505b50909250905081158061072b57508051155b1561073a575060009392505050565b5060019392505050565b6000600282604051610756919061129d565b908152604051908190036020019020546001600160a01b031692915050565b61077d610d00565b6107876000610d9f565b565b610791610d00565b60006002826040516107a3919061129d565b908152604051908190036020019020546001600160a01b03169050806108235760405162461bcd60e51b815260206004820152602a60248201527f466c6f77427269646765466163746f72793a204465706c6f796572206e6f74206044820152691c9959da5cdd195c995960b21b60648201526084015b60405180910390fd5b600282604051610833919061129d565b90815260405190819003602001812080546001600160a01b03191690557f03c7566b5f4959b890c1a6d38f39df053c6737c9965d9c0ddf612c86100a838b9061087f90849084906112b9565b60405180910390a15050565b610893610d00565b61089c81610def565b60006001600160a01b03166002836040516108b7919061129d565b908152604051908190036020019020546001600160a01b0316146109345760405162461bcd60e51b815260206004820152602e60248201527f466c6f77427269646765466163746f72793a204465706c6f79657220616c726560448201526d18591e481c9959da5cdd195c995960921b606482015260840161081a565b80600283604051610945919061129d565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557fc0c30f085f0b1397c8bf23f8b851b63b33e13d11832b8320a37fca1c07dcb40f9061087f90849084906112b9565b600154604051632cf576f760e21b81526001600160a01b038381166004830152606092169063b3d5dbdc90602401600060405180830381865afa1580156109ef573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102d491908101906112e3565b6000610a2282610b08565b1515610a2d83610354565b1515141592915050565b610a3f610d00565b610a4881610def565b6000600283604051610a5a919061129d565b908152604051908190036020019020546001600160a01b0316905080610a8957610a84838361088b565b505050565b81600284604051610a9a919061129d565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f848576f8a081c5af60d89f0215c8af528186670eefd6349c05014d5b2268864690610afb9085908490869061135a565b60405180910390a1505050565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610b72575060408051601f3d908101601f19168201909252610b6f9181019061138d565b60015b6102d457506000919050565b6000610b88610d00565b6000600288604051610b9a919061129d565b908152604051908190036020019020546001600160a01b03169050610bbe81610def565b60405163476d399760e01b815281906000906001600160a01b0383169063476d399790610bf7908c908c908c908c908c906004016113af565b6020604051808303816000875af1158015610c16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3a9190611280565b9050610c468682610e61565b9998505050505050505050565b60015460405163a6de610560e01b81526001600160a01b038381166004830152600092169063a6de610590602401602060405180830381865afa158015610c9e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d4919061138d565b610cca610d00565b6001600160a01b038116610cf457604051631e4fbdf760e01b81526000600482015260240161081a565b610cfd81610d9f565b50565b6000546001600160a01b031633146107875760405163118cdaa760e01b815233600482015260240161081a565b610d3681610ecc565b610d478163976998cb60e01b610f22565b610cfd5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c696420726567697360448201526274727960e81b606482015260840161081a565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610df881610ecc565b610e098163476d399760e01b610f22565b610cfd5760405162461bcd60e51b815260206004820152602360248201527f466c6f77427269646765466163746f72793a20496e76616c6964206465706c6f6044820152623cb2b960e91b606482015260840161081a565b60015460405163522791d160e01b81526001600160a01b0390911690819063522791d190610e9590869086906004016112b9565b600060405180830381600087803b158015610eaf57600080fd5b505af1158015610ec3573d6000803e3d6000fd5b50505050505050565b6001600160a01b038116610cfd5760405162461bcd60e51b815260206004820152601f60248201527f466c6f77427269646765466163746f72793a205a65726f206164647265737300604482015260640161081a565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a790602401602060405180830381865afa925050508015610f8f575060408051601f3d908101601f19168201909252610f8c9181019061138d565b60015b610f9b575060006102d4565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fe157610fe1610fa2565b604052919050565b600067ffffffffffffffff82111561100357611003610fa2565b50601f01601f191660200190565b600082601f83011261102257600080fd5b813561103561103082610fe9565b610fb8565b81815284602083860101111561104a57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561107957600080fd5b813567ffffffffffffffff81111561109057600080fd5b61109c84828501611011565b949350505050565b6001600160a01b0381168114610cfd57600080fd5b6000602082840312156110cb57600080fd5b8135610f9b816110a4565b600080604083850312156110e957600080fd5b823567ffffffffffffffff81111561110057600080fd5b61110c85828601611011565b925050602083013561111d816110a4565b809150509250929050565b60005b8381101561114357818101518382015260200161112b565b50506000910152565b60008151808452611164816020860160208601611128565b601f01601f19169290920160200192915050565b602081526000610f9b602083018461114c565b60008060008060008060c087890312156111a457600080fd5b863567ffffffffffffffff808211156111bc57600080fd5b6111c88a838b01611011565b975060208901359150808211156111de57600080fd5b6111ea8a838b01611011565b9650604089013591508082111561120057600080fd5b61120c8a838b01611011565b9550606089013591508082111561122257600080fd5b61122e8a838b01611011565b9450608089013591508082111561124457600080fd5b6112508a838b01611011565b935060a089013591508082111561126657600080fd5b5061127389828a01611011565b9150509295509295509295565b60006020828403121561129257600080fd5b8151610f9b816110a4565b600082516112af818460208701611128565b9190910192915050565b6040815260006112cc604083018561114c565b905060018060a01b03831660208301529392505050565b6000602082840312156112f557600080fd5b815167ffffffffffffffff81111561130c57600080fd5b8201601f8101841361131d57600080fd5b805161132b61103082610fe9565b81815285602083850101111561134057600080fd5b611351826020830160208601611128565b95945050505050565b60608152600061136d606083018661114c565b6001600160a01b0394851660208401529290931660409091015292915050565b60006020828403121561139f57600080fd5b81518015158114610f9b57600080fd5b60a0815260006113c260a083018861114c565b82810360208401526113d4818861114c565b905082810360408401526113e8818761114c565b905082810360608401526113fc818661114c565b90508281036080840152611410818561114c565b9897505050505050505056fea264697066735822122026be7d4ef13534833344abdcc736e8876603e1f9d3463f0047ddca092a98cc2d64736f6c63430008170033" -access(all) let erc20DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206fb41458119173f9f1d07720d0b22fbfacf4726505008b5c43816c9902cd0fc464736f6c63430008170033a2646970667358221220fbaaee74b0e14c12923bfbdc4701408031af759f454cf27df9e8defc7658e96264736f6c63430008170033" +access(all) let erc20DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612096806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d36600462000438565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c936600462000516565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a5565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005f8565b620002bd565b6200010662000142366004620005f8565b62000367565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b03163314620002095760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a204f6e6c60448201527f792064656c656761746564206465706c6f7965722063616e206465706c6f790060648201526084015b60405180910390fd5b600080546001600160a01b0316878787878760405162000229906200042a565b6200023a969594939291906200066b565b604051809103906000f08015801562000257573d6000803e3d6000fd5b5090507f99a64021330f1af36b3fd5f64a1d12b99b8ddf91fa553618c4df01ffba4c1cee818888888860405162000293959493929190620006f4565b60405180910390a19695505050505050565b620002af620003ab565b620002bb6000620003da565b565b620002c7620003ab565b6001600160a01b038116620003455760405162461bcd60e51b815260206004820152603f60248201527f466c6f7745564d4272696467656445524332304465706c6f7965723a20496e7660448201527f616c69642064656c656761746564206465706c6f796572206164647265737300606482015260840162000200565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000371620003ab565b6001600160a01b0381166200039d57604051631e4fbdf760e01b81526000600482015260240162000200565b620003a881620003da565b50565b6000546001600160a01b03163314620002bb5760405163118cdaa760e01b815233600482015260240162000200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118fa806200076783390190565b6000602082840312156200044b57600080fd5b81356001600160e01b0319811681146200046457600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049357600080fd5b813567ffffffffffffffff80821115620004b157620004b16200046b565b604051601f8301601f19908116603f01168101908282118183101715620004dc57620004dc6200046b565b81604052838152866020858801011115620004f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200052f57600080fd5b853567ffffffffffffffff808211156200054857600080fd5b6200055689838a0162000481565b965060208801359150808211156200056d57600080fd5b6200057b89838a0162000481565b955060408801359150808211156200059257600080fd5b620005a089838a0162000481565b94506060880135915080821115620005b757600080fd5b620005c589838a0162000481565b93506080880135915080821115620005dc57600080fd5b50620005eb8882890162000481565b9150509295509295909350565b6000602082840312156200060b57600080fd5b81356001600160a01b03811681146200046457600080fd5b6000815180845260005b818110156200064b576020818501810151868301820152016200062d565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006919083018862000623565b8281036040840152620006a5818862000623565b90508281036060840152620006bb818762000623565b90508281036080840152620006d1818662000623565b905082810360a0840152620006e7818562000623565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071a9083018762000623565b82810360408401526200072e818762000623565b9050828103606084015262000744818662000623565b905082810360808401526200075a818562000623565b9897505050505050505056fe6101606040523480156200001257600080fd5b50604051620018fa380380620018fa833981016040819052620000359162000357565b6040805180820190915260018152603160f81b6020820152859081908882886003620000628382620004db565b506004620000718282620004db565b5050506001600160a01b038116620000a457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000af816200019f565b50620000bd826006620001f1565b61012052620000ce816007620001f1565b61014052815160208084019190912060e052815190820120610100524660a0526200015c60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506009620001748482620004db565b50600a620001838382620004db565b50600b620001928282620004db565b5050505050505062000601565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602083511015620002115762000209836200022a565b905062000224565b816200021e8482620004db565b5060ff90505b92915050565b600080829050601f8151111562000258578260405163305a27a960e01b81526004016200009b9190620005a7565b80516200026582620005dc565b179392505050565b80516001600160a01b03811681146200028557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002bd578181015183820152602001620002a3565b50506000910152565b600082601f830112620002d857600080fd5b81516001600160401b0380821115620002f557620002f56200028a565b604051601f8301601f19908116603f011681019082821181831017156200032057620003206200028a565b816040528381528660208588010111156200033a57600080fd5b6200034d846020830160208901620002a0565b9695505050505050565b60008060008060008060c087890312156200037157600080fd5b6200037c876200026d565b60208801519096506001600160401b03808211156200039a57600080fd5b620003a88a838b01620002c6565b96506040890151915080821115620003bf57600080fd5b620003cd8a838b01620002c6565b95506060890151915080821115620003e457600080fd5b620003f28a838b01620002c6565b945060808901519150808211156200040957600080fd5b620004178a838b01620002c6565b935060a08901519150808211156200042e57600080fd5b506200043d89828a01620002c6565b9150509295509295509295565b600181811c908216806200045f57607f821691505b6020821081036200048057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d6576000816000526020600020601f850160051c81016020861015620004b15750805b601f850160051c820191505b81811015620004d257828155600101620004bd565b5050505b505050565b81516001600160401b03811115620004f757620004f76200028a565b6200050f816200050884546200044a565b8462000486565b602080601f8311600181146200054757600084156200052e5750858301515b600019600386901b1c1916600185901b178555620004d2565b600085815260208120601f198616915b82811015620005785788860151825594840194600190910190840162000557565b5085821015620005975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620005c8816040850160208701620002a0565b601f01601f19169190910160400192915050565b80516020808301519190811015620004805760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161129e6200065c6000396000610a8801526000610a5b01526000610918015260006108f00152600061084b015260006108750152600061089f015261129e6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de578063a76b4d5611610097578063dc9716eb11610071578063dc9716eb146102f8578063dd62ed3e14610300578063e8a3d48514610339578063f2fde38b1461034157600080fd5b8063a76b4d56146102ca578063a9059cbb146102d2578063d505accf146102e557600080fd5b8063715018a61461025e57806379cc6790146102665780637ecebe001461027957806384b0196e1461028c5780638da5cb5b146102a757806395d89b41146102c257600080fd5b8063313ce56711610130578063313ce567146101ee5780633644e515146101fd5780633fd4d4a81461020557806340c10f191461020d57806342966c681461022257806370a082311461023557600080fd5b806306fdde0314610178578063095ea7b3146101965780630cd9acb7146101b9578063120a88ad146101c157806318160ddd146101c957806323b872dd146101db575b600080fd5b610180610354565b60405161018d9190610fe8565b60405180910390f35b6101a96101a436600461101e565b6103e6565b604051901515815260200161018d565b610180610400565b61018061048e565b6002545b60405190815260200161018d565b6101a96101e9366004611048565b61049d565b6040516012815260200161018d565b6101cd6104c1565b6101806104d0565b61022061021b36600461101e565b6104df565b005b610220610230366004611084565b6104f5565b6101cd61024336600461109d565b6001600160a01b031660009081526020819052604090205490565b610220610502565b61022061027436600461101e565b610516565b6101cd61028736600461109d565b61052b565b610294610549565b60405161018d97969594939291906110b8565b6005546040516001600160a01b03909116815260200161018d565b61018061058f565b61018061059e565b6101a96102e036600461101e565b6105ab565b6102206102f3366004611151565b6105b9565b6101806106f8565b6101cd61030e3660046111c4565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610180610705565b61022061034f36600461109d565b610714565b606060038054610363906111f7565b80601f016020809104026020016040519081016040528092919081815260200182805461038f906111f7565b80156103dc5780601f106103b1576101008083540402835291602001916103dc565b820191906000526020600020905b8154815290600101906020018083116103bf57829003601f168201915b5050505050905090565b6000336103f481858561074f565b60019150505b92915050565b6009805461040d906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610439906111f7565b80156104865780601f1061045b57610100808354040283529160200191610486565b820191906000526020600020905b81548152906001019060200180831161046957829003601f168201915b505050505081565b606060098054610363906111f7565b6000336104ab858285610761565b6104b68585856107df565b506001949350505050565b60006104cb61083e565b905090565b6060600a8054610363906111f7565b6104e7610969565b6104f18282610996565b5050565b6104ff33826109cc565b50565b61050a610969565b6105146000610a02565b565b610521823383610761565b6104f182826109cc565b6001600160a01b0381166000908152600860205260408120546103fa565b60006060806000806000606061055d610a54565b610565610a81565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b606060048054610363906111f7565b600b805461040d906111f7565b6000336103f48185856107df565b834211156105e25760405163313c898160e11b8152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861062f8c6001600160a01b0316600090815260086020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061068a82610aae565b9050600061069a82878787610adb565b9050896001600160a01b0316816001600160a01b0316146106e1576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016105d9565b6106ec8a8a8a61074f565b50505050505050505050565b600a805461040d906111f7565b6060600b8054610363906111f7565b61071c610969565b6001600160a01b03811661074657604051631e4fbdf760e01b8152600060048201526024016105d9565b6104ff81610a02565b61075c8383836001610b09565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146107d957818110156107ca57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016105d9565b6107d984848484036000610b09565b50505050565b6001600160a01b03831661080957604051634b637e8f60e11b8152600060048201526024016105d9565b6001600160a01b0382166108335760405163ec442f0560e01b8152600060048201526024016105d9565b61075c838383610bde565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561089757507f000000000000000000000000000000000000000000000000000000000000000046145b156108c157507f000000000000000000000000000000000000000000000000000000000000000090565b6104cb604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6005546001600160a01b031633146105145760405163118cdaa760e01b81523360048201526024016105d9565b6001600160a01b0382166109c05760405163ec442f0560e01b8152600060048201526024016105d9565b6104f160008383610bde565b6001600160a01b0382166109f657604051634b637e8f60e11b8152600060048201526024016105d9565b6104f182600083610bde565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006006610d08565b60606104cb7f00000000000000000000000000000000000000000000000000000000000000006007610d08565b60006103fa610abb61083e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600080610aed88888888610db3565b925092509250610afd8282610e82565b50909695505050505050565b6001600160a01b038416610b335760405163e602df0560e01b8152600060048201526024016105d9565b6001600160a01b038316610b5d57604051634a1406b160e11b8152600060048201526024016105d9565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156107d957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610bd091815260200190565b60405180910390a350505050565b6001600160a01b038316610c09578060026000828254610bfe9190611231565b90915550610c7b9050565b6001600160a01b03831660009081526020819052604090205481811015610c5c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016105d9565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610c9757600280548290039055610cb6565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610cfb91815260200190565b60405180910390a3505050565b606060ff8314610d2257610d1b83610f3b565b90506103fa565b818054610d2e906111f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5a906111f7565b8015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b505050505090506103fa565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610dee5750600091506003905082610e78565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610e42573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e6e57506000925060019150829050610e78565b9250600091508190505b9450945094915050565b6000826003811115610e9657610e96611252565b03610e9f575050565b6001826003811115610eb357610eb3611252565b03610ed15760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610ee557610ee5611252565b03610f065760405163fce698f760e01b8152600481018290526024016105d9565b6003826003811115610f1a57610f1a611252565b036104f1576040516335e2f38360e21b8152600481018290526024016105d9565b60606000610f4883610f7a565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156103fa57604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b81811015610fc857602081850181015186830182015201610fac565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ffb6020830184610fa2565b9392505050565b80356001600160a01b038116811461101957600080fd5b919050565b6000806040838503121561103157600080fd5b61103a83611002565b946020939093013593505050565b60008060006060848603121561105d57600080fd5b61106684611002565b925061107460208501611002565b9150604084013590509250925092565b60006020828403121561109657600080fd5b5035919050565b6000602082840312156110af57600080fd5b610ffb82611002565b60ff60f81b881681526000602060e060208401526110d960e084018a610fa2565b83810360408501526110eb818a610fa2565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b8181101561113f57835183529284019291840191600101611123565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561116c57600080fd5b61117588611002565b965061118360208901611002565b95506040880135945060608801359350608088013560ff811681146111a757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111d757600080fd5b6111e083611002565b91506111ee60208401611002565b90509250929050565b600181811c9082168061120b57607f821691505b60208210810361122b57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103fa57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206fb41458119173f9f1d07720d0b22fbfacf4726505008b5c43816c9902cd0fc464736f6c63430008170033a26469706673582212201df4bdff78560cbe320524756593933725001e7f7f8e2f575636163e3d9cc87d64736f6c63430008170033" -access(all) let erc721DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612657806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d3660046200043c565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c93660046200051a565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a7565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005fc565b620002bf565b6200010662000142366004620005fc565b6200036b565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b031633146200020b576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a204f6e60448201527f6c792064656c656761746564206465706c6f7965722063616e206465706c6f7960648201526084015b60405180910390fd5b600080546001600160a01b031687878787876040516200022b906200042e565b6200023c969594939291906200066f565b604051809103906000f08015801562000259573d6000803e3d6000fd5b5090507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f0818888888860405162000295959493929190620006f8565b60405180910390a19695505050505050565b620002b1620003af565b620002bd6000620003de565b565b620002c9620003af565b6001600160a01b03811662000349576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a20496e60448201527f76616c69642064656c656761746564206465706c6f7965722061646472657373606482015260840162000202565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000375620003af565b6001600160a01b038116620003a157604051631e4fbdf760e01b81526000600482015260240162000202565b620003ac81620003de565b50565b6000546001600160a01b03163314620002bd5760405163118cdaa760e01b815233600482015260240162000202565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611eb7806200076b83390190565b6000602082840312156200044f57600080fd5b81356001600160e01b0319811681146200046857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049757600080fd5b813567ffffffffffffffff80821115620004b557620004b56200046f565b604051601f8301601f19908116603f01168101908282118183101715620004e057620004e06200046f565b81604052838152866020858801011115620004fa57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200053357600080fd5b853567ffffffffffffffff808211156200054c57600080fd5b6200055a89838a0162000485565b965060208801359150808211156200057157600080fd5b6200057f89838a0162000485565b955060408801359150808211156200059657600080fd5b620005a489838a0162000485565b94506060880135915080821115620005bb57600080fd5b620005c989838a0162000485565b93506080880135915080821115620005e057600080fd5b50620005ef8882890162000485565b9150509295509295909350565b6000602082840312156200060f57600080fd5b81356001600160a01b03811681146200046857600080fd5b6000815180845260005b818110156200064f5760208185018101518683018201520162000631565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006959083018862000627565b8281036040840152620006a9818862000627565b90508281036060840152620006bf818762000627565b90508281036080840152620006d5818662000627565b905082810360a0840152620006eb818562000627565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071e9083018762000627565b828103604084015262000732818762000627565b9050828103606084015262000748818662000627565b905082810360808401526200075e818562000627565b9897505050505050505056fe60806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122074d34aec07c0da793ce5cac74069bf4177b7594babf4fede87db849ea2f57b3764736f6c63430008170033a264697066735822122064104e4f6458f9ff9e5aca71c897aa1948c1b57434e9d83b5f4ce4a9ab5d328564736f6c63430008170033" +access(all) let erc721DeployerBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610046565b50610096565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612657806100a56000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063715018a61162000062578063715018a614620000fc5780638da5cb5b1462000108578063ee2d8496146200011a578063f2fde38b146200013157600080fd5b806301ffc9a7146200008c578063476d399714620000b85780636418e6de14620000e8575b600080fd5b620000a36200009d3660046200043c565b62000148565b60405190151581526020015b60405180910390f35b620000cf620000c93660046200051a565b62000180565b6040516001600160a01b039091168152602001620000af565b600154620000cf906001600160a01b031681565b62000106620002a7565b005b6000546001600160a01b0316620000cf565b620001066200012b366004620005fc565b620002bf565b6200010662000142366004620005fc565b6200036b565b60006001600160e01b0319821663476d399760e01b14806200017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546000906001600160a01b031633146200020b576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a204f6e60448201527f6c792064656c656761746564206465706c6f7965722063616e206465706c6f7960648201526084015b60405180910390fd5b600080546001600160a01b031687878787876040516200022b906200042e565b6200023c969594939291906200066f565b604051809103906000f08015801562000259573d6000803e3d6000fd5b5090507fbebce54951ebf20c0dcd195a45bb2388d9ac8e38b5974e00bb63c5822dbe65f0818888888860405162000295959493929190620006f8565b60405180910390a19695505050505050565b620002b1620003af565b620002bd6000620003de565b565b620002c9620003af565b6001600160a01b03811662000349576040805162461bcd60e51b81526020600482015260248101919091527f466c6f7745564d427269646765644552433732314465706c6f7965723a20496e60448201527f76616c69642064656c656761746564206465706c6f7965722061646472657373606482015260840162000202565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000375620003af565b6001600160a01b038116620003a157604051631e4fbdf760e01b81526000600482015260240162000202565b620003ac81620003de565b50565b6000546001600160a01b03163314620002bd5760405163118cdaa760e01b815233600482015260240162000202565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611eb7806200076b83390190565b6000602082840312156200044f57600080fd5b81356001600160e01b0319811681146200046857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049757600080fd5b813567ffffffffffffffff80821115620004b557620004b56200046f565b604051601f8301601f19908116603f01168101908282118183101715620004e057620004e06200046f565b81604052838152866020858801011115620004fa57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156200053357600080fd5b853567ffffffffffffffff808211156200054c57600080fd5b6200055a89838a0162000485565b965060208801359150808211156200057157600080fd5b6200057f89838a0162000485565b955060408801359150808211156200059657600080fd5b620005a489838a0162000485565b94506060880135915080821115620005bb57600080fd5b620005c989838a0162000485565b93506080880135915080821115620005e057600080fd5b50620005ef8882890162000485565b9150509295509295909350565b6000602082840312156200060f57600080fd5b81356001600160a01b03811681146200046857600080fd5b6000815180845260005b818110156200064f5760208185018101518683018201520162000631565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038716815260c060208201819052600090620006959083018862000627565b8281036040840152620006a9818862000627565b90508281036060840152620006bf818762000627565b90508281036080840152620006d5818662000627565b905082810360a0840152620006eb818562000627565b9998505050505050505050565b6001600160a01b038616815260a0602082018190526000906200071e9083018762000627565b828103604084015262000732818762000627565b9050828103606084015262000748818662000627565b905082810360808401526200075e818562000627565b9897505050505050505056fe60806040523480156200001157600080fd5b5060405162001eb738038062001eb7833981016040819052620000349162000202565b858585600062000045838262000386565b50600162000054828262000386565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000cb565b50600c620000a0848262000386565b50600d620000af838262000386565b50600e620000be828262000386565b5050505050505062000452565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200013557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200016257600080fd5b81516001600160401b03808211156200017f576200017f6200013a565b604051601f8301601f19908116603f01168101908282118183101715620001aa57620001aa6200013a565b8160405283815260209250866020858801011115620001c857600080fd5b600091505b83821015620001ec5785820183015181830184015290820190620001cd565b6000602085830101528094505050505092915050565b60008060008060008060c087890312156200021c57600080fd5b62000227876200011d565b60208801519096506001600160401b03808211156200024557600080fd5b620002538a838b0162000150565b965060408901519150808211156200026a57600080fd5b620002788a838b0162000150565b955060608901519150808211156200028f57600080fd5b6200029d8a838b0162000150565b94506080890151915080821115620002b457600080fd5b620002c28a838b0162000150565b935060a0890151915080821115620002d957600080fd5b50620002e889828a0162000150565b9150509295509295509295565b600181811c908216806200030a57607f821691505b6020821081036200032b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000381576000816000526020600020601f850160051c810160208610156200035c5750805b601f850160051c820191505b818110156200037d5782815560010162000368565b5050505b505050565b81516001600160401b03811115620003a257620003a26200013a565b620003ba81620003b38454620002f5565b8462000331565b602080601f831160018114620003f25760008415620003d95750858301515b600019600386901b1c1916600185901b1785556200037d565b600085815260208120601f198616915b82811015620004235788860151825594840194600190910190840162000402565b5085821015620004425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611a5580620004626000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a76b4d56116100a2578063cd279c7c11610071578063cd279c7c146103a8578063e8a3d485146103bb578063e985e9c5146103c3578063f2fde38b146103d657600080fd5b8063a76b4d5614610372578063b49bbd941461037a578063b88d4fde14610382578063c87b56dd1461039557600080fd5b806394e29329116100de57806394e293291461034757806395d89b411461034f578063a159047b14610357578063a22cb4651461035f57600080fd5b806370a082311461031b578063715018a61461032e5780638da5cb5b1461033657600080fd5b80632f745c59116101715780634f558e791161014b5780634f558e79146102c25780634f6ccce7146102ed5780635e0a9661146103005780636352211e1461030857600080fd5b80632f745c591461028957806342842e0e1461029c57806342966c68146102af57600080fd5b8063095ea7b3116101ad578063095ea7b31461023c57806318160ddd1461025157806318e97fd11461026357806323b872dd1461027657600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063081812fc14610211575b600080fd5b6101e76101e2366004611494565b6103e9565b60405190151581526020015b60405180910390f35b6102046103fa565b6040516101f39190611501565b61022461021f366004611514565b61048c565b6040516001600160a01b0390911681526020016101f3565b61024f61024a366004611549565b6104b5565b005b6009545b6040519081526020016101f3565b61024f61027136600461161f565b6104c4565b61024f610284366004611666565b6104d6565b610255610297366004611549565b610566565b61024f6102aa366004611666565b6105cb565b61024f6102bd366004611514565b6105eb565b6101e76102d0366004611514565b6000908152600260205260409020546001600160a01b0316151590565b6102556102fb366004611514565b6105f7565b610204610650565b610224610316366004611514565b61065f565b6102556103293660046116a2565b61066a565b61024f6106b2565b600b546001600160a01b0316610224565b6102046106c6565b6102046106d5565b6102046106e4565b61024f61036d3660046116bd565b610772565b61020461077d565b61020461078a565b61024f6103903660046116f9565b610797565b6102046103a3366004611514565b6107ae565b61024f6103b6366004611775565b6107b9565b6102046107d5565b6101e76103d13660046117cc565b6107e4565b61024f6103e43660046116a2565b610812565b60006103f482610850565b92915050565b606060008054610409906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610435906117ff565b80156104825780601f1061045757610100808354040283529160200191610482565b820191906000526020600020905b81548152906001019060200180831161046557829003601f168201915b5050505050905090565b600061049782610875565b506000828152600460205260409020546001600160a01b03166103f4565b6104c08282336108ae565b5050565b6104cc6108bb565b6104c082826108e8565b6001600160a01b03821661050557604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610512838333610938565b9050836001600160a01b0316816001600160a01b031614610560576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016104fc565b50505050565b60006105718361066a565b82106105a25760405163295f44f760e21b81526001600160a01b0384166004820152602481018390526044016104fc565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6105e683838360405180602001604052806000815250610797565b505050565b6104c060008233610938565b600061060260095490565b821061062b5760405163295f44f760e21b815260006004820152602481018390526044016104fc565b6009828154811061063e5761063e611839565b90600052602060002001549050919050565b6060600d8054610409906117ff565b60006103f482610875565b60006001600160a01b038216610696576040516322718ad960e21b8152600060048201526024016104fc565b506001600160a01b031660009081526003602052604090205490565b6106ba6108bb565b6106c4600061094d565b565b6060600c8054610409906117ff565b606060018054610409906117ff565b600d80546106f1906117ff565b80601f016020809104026020016040519081016040528092919081815260200182805461071d906117ff565b801561076a5780601f1061073f5761010080835404028352916020019161076a565b820191906000526020600020905b81548152906001019060200180831161074d57829003601f168201915b505050505081565b6104c033838361099f565b600e80546106f1906117ff565b600c80546106f1906117ff565b6107a28484846104d6565b61056084848484610a3e565b60606103f482610b67565b6107c16108bb565b6107cb8383610c70565b6105e682826108e8565b6060600e8054610409906117ff565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61081a6108bb565b6001600160a01b03811661084457604051631e4fbdf760e01b8152600060048201526024016104fc565b61084d8161094d565b50565b60006001600160e01b0319821663780e9d6360e01b14806103f457506103f482610c8a565b6000818152600260205260408120546001600160a01b0316806103f457604051637e27328960e01b8152600481018490526024016104fc565b6105e68383836001610caf565b600b546001600160a01b031633146106c45760405163118cdaa760e01b81523360048201526024016104fc565b6000828152600660205260409020610900828261189f565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b6000610945848484610db5565b949350505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166109d157604051630b61174360e31b81526001600160a01b03831660048201526024016104fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561056057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610a8090339088908790879060040161195f565b6020604051808303816000875af1925050508015610abb575060408051601f3d908101601f19168201909252610ab89181019061199c565b60015b610b24573d808015610ae9576040519150601f19603f3d011682016040523d82523d6000602084013e610aee565b606091505b508051600003610b1c57604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610b6057604051633250574960e11b81526001600160a01b03851660048201526024016104fc565b5050505050565b6060610b7282610875565b5060008281526006602052604081208054610b8c906117ff565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb8906117ff565b8015610c055780601f10610bda57610100808354040283529160200191610c05565b820191906000526020600020905b815481529060010190602001808311610be857829003601f168201915b505050505090506000610c2360408051602081019091526000815290565b90508051600003610c35575092915050565b815115610c67578082604051602001610c4f9291906119b9565b60405160208183030381529060405292505050919050565b61094584610e82565b6104c0828260405180602001604052806000815250610ef7565b60006001600160e01b03198216632483248360e11b14806103f457506103f482610f0e565b8080610cc357506001600160a01b03821615155b15610d85576000610cd384610875565b90506001600160a01b03831615801590610cff5750826001600160a01b0316816001600160a01b031614155b8015610d125750610d1081846107e4565b155b15610d3b5760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016104fc565b8115610d835783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600080610dc3858585610f5e565b90506001600160a01b038116610e2057610e1b84600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b610e43565b846001600160a01b0316816001600160a01b031614610e4357610e438185611057565b6001600160a01b038516610e5f57610e5a846110e8565b610945565b846001600160a01b0316816001600160a01b031614610945576109458585611197565b6060610e8d82610875565b506000610ea560408051602081019091526000815290565b90506000815111610ec55760405180602001604052806000815250610ef0565b80610ecf846111e7565b604051602001610ee09291906119b9565b6040516020818303038152906040525b9392505050565b610f01838361127a565b6105e66000848484610a3e565b60006001600160e01b031982166380ac58cd60e01b1480610f3f57506001600160e01b03198216635b5e139f60e01b145b806103f457506301ffc9a760e01b6001600160e01b03198316146103f4565b6000828152600260205260408120546001600160a01b0390811690831615610f8b57610f8b8184866112df565b6001600160a01b03811615610fc957610fa8600085600080610caf565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610ff8576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b60006110628361066a565b6000838152600860205260409020549091508082146110b5576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906110fa906001906119e8565b6000838152600a60205260408120546009805493945090928490811061112257611122611839565b90600052602060002001549050806009838154811061114357611143611839565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061117b5761117b611a09565b6001900381819060005260206000200160009055905550505050565b600060016111a48461066a565b6111ae91906119e8565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b606060006111f483611343565b600101905060008167ffffffffffffffff81111561121457611214611573565b6040519080825280601f01601f19166020018201604052801561123e576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461124857509392505050565b6001600160a01b0382166112a457604051633250574960e11b8152600060048201526024016104fc565b60006112b283836000610938565b90506001600160a01b038116156105e6576040516339e3563760e11b8152600060048201526024016104fc565b6112ea83838361141b565b6105e6576001600160a01b03831661131857604051637e27328960e01b8152600481018290526024016104fc565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016104fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106113825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106113ae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106113cc57662386f26fc10000830492506010015b6305f5e10083106113e4576305f5e100830492506008015b61271083106113f857612710830492506004015b6064831061140a576064830492506002015b600a83106103f45760010192915050565b60006001600160a01b038316158015906109455750826001600160a01b0316846001600160a01b03161480611455575061145584846107e4565b806109455750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461084d57600080fd5b6000602082840312156114a657600080fd5b8135610ef08161147e565b60005b838110156114cc5781810151838201526020016114b4565b50506000910152565b600081518084526114ed8160208601602086016114b1565b601f01601f19169290920160200192915050565b602081526000610ef060208301846114d5565b60006020828403121561152657600080fd5b5035919050565b80356001600160a01b038116811461154457600080fd5b919050565b6000806040838503121561155c57600080fd5b6115658361152d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156115a4576115a4611573565b604051601f8501601f19908116603f011681019082821181831017156115cc576115cc611573565b816040528093508581528686860111156115e557600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261161057600080fd5b610ef083833560208501611589565b6000806040838503121561163257600080fd5b82359150602083013567ffffffffffffffff81111561165057600080fd5b61165c858286016115ff565b9150509250929050565b60008060006060848603121561167b57600080fd5b6116848461152d565b92506116926020850161152d565b9150604084013590509250925092565b6000602082840312156116b457600080fd5b610ef08261152d565b600080604083850312156116d057600080fd5b6116d98361152d565b9150602083013580151581146116ee57600080fd5b809150509250929050565b6000806000806080858703121561170f57600080fd5b6117188561152d565b93506117266020860161152d565b925060408501359150606085013567ffffffffffffffff81111561174957600080fd5b8501601f8101871361175a57600080fd5b61176987823560208401611589565b91505092959194509250565b60008060006060848603121561178a57600080fd5b6117938461152d565b925060208401359150604084013567ffffffffffffffff8111156117b657600080fd5b6117c2868287016115ff565b9150509250925092565b600080604083850312156117df57600080fd5b6117e88361152d565b91506117f66020840161152d565b90509250929050565b600181811c9082168061181357607f821691505b60208210810361183357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b601f8211156105e6576000816000526020600020601f850160051c810160208610156118785750805b601f850160051c820191505b8181101561189757828155600101611884565b505050505050565b815167ffffffffffffffff8111156118b9576118b9611573565b6118cd816118c784546117ff565b8461184f565b602080601f83116001811461190257600084156118ea5750858301515b600019600386901b1c1916600185901b178555611897565b600085815260208120601f198616915b8281101561193157888601518255948401946001909101908401611912565b508582101561194f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611992908301846114d5565b9695505050505050565b6000602082840312156119ae57600080fd5b8151610ef08161147e565b600083516119cb8184602088016114b1565b8351908301906119df8183602088016114b1565b01949350505050565b818103818111156103f457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122074d34aec07c0da793ce5cac74069bf4177b7594babf4fede87db849ea2f57b3764736f6c63430008170033a2646970667358221220953493586f5fb5670e80849013b6c27540a3f06c628c3046b81886afa405e0c664736f6c63430008170033" access(all) let registryBytecode = "608060405234801561001057600080fd5b50338061003757604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61004081610058565b50600080546001600160a01b031916331790556100aa565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6108a5806100b96000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063862119ae11610071578063862119ae146101315780638da5cb5b14610144578063a6de610514610155578063b3d5dbdc14610168578063f2fde38b14610188578063faab9d391461019b57600080fd5b806301ffc9a7146100ae57806304433bbc146100d65780632b20e39714610101578063522791d114610114578063715018a614610129575b600080fd5b6100c16100bc36600461051c565b6101ae565b60405190151581526020015b60405180910390f35b6100e96100e43660046105f0565b6101e5565b6040516001600160a01b0390911681526020016100cd565b6000546100e9906001600160a01b031681565b610127610122366004610649565b610216565b005b6101276102b7565b6100c161013f3660046105f0565b6102cb565b6003546001600160a01b03166100e9565b6100c1610163366004610697565b610308565b61017b610176366004610697565b610334565b6040516100cd91906106d6565b610127610196366004610697565b6103e0565b6101276101a9366004610697565b61041e565b60006001600160e01b0319821663976998cb60e01b14806101df57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60006001826040516101f79190610709565b908152604051908190036020019020546001600160a01b031692915050565b6000546001600160a01b031633146102a95760405162461bcd60e51b815260206004820152604560248201527f466c6f774272696467654465706c6f796d656e7452656769737472793a204f6e60448201527f6c79207265676973747261722063616e207265676973746572206173736f636960648201526430ba34b7b760d91b608482015260a4015b60405180910390fd5b6102b38282610444565b5050565b6102bf61049d565b6102c960006104ca565b565b6000806001600160a01b03166001836040516102e79190610709565b908152604051908190036020019020546001600160a01b0316141592915050565b6001600160a01b0381166000908152600260205260408120805461032b90610725565b15159392505050565b6001600160a01b038116600090815260026020526040902080546060919061035b90610725565b80601f016020809104026020016040519081016040528092919081815260200182805461038790610725565b80156103d45780601f106103a9576101008083540402835291602001916103d4565b820191906000526020600020905b8154815290600101906020018083116103b757829003601f168201915b50505050509050919050565b6103e861049d565b6001600160a01b03811661041257604051631e4fbdf760e01b8152600060048201526024016102a0565b61041b816104ca565b50565b61042661049d565b600080546001600160a01b0319166001600160a01b03831617905550565b806001836040516104559190610709565b908152604080516020928190038301902080546001600160a01b0319166001600160a01b03948516179055918316600090815260029091522061049883826107af565b505050565b6003546001600160a01b031633146102c95760405163118cdaa760e01b81523360048201526024016102a0565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006020828403121561052e57600080fd5b81356001600160e01b03198116811461054657600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261057457600080fd5b813567ffffffffffffffff8082111561058f5761058f61054d565b604051601f8301601f19908116603f011681019082821181831017156105b7576105b761054d565b816040528381528660208588010111156105d057600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561060257600080fd5b813567ffffffffffffffff81111561061957600080fd5b61062584828501610563565b949350505050565b80356001600160a01b038116811461064457600080fd5b919050565b6000806040838503121561065c57600080fd5b823567ffffffffffffffff81111561067357600080fd5b61067f85828601610563565b92505061068e6020840161062d565b90509250929050565b6000602082840312156106a957600080fd5b6105468261062d565b60005b838110156106cd5781810151838201526020016106b5565b50506000910152565b60208152600082518060208401526106f58160408501602087016106b2565b601f01601f19169190910160400192915050565b6000825161071b8184602087016106b2565b9190910192915050565b600181811c9082168061073957607f821691505b60208210810361075957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610498576000816000526020600020601f850160051c810160208610156107885750805b601f850160051c820191505b818110156107a757828155600101610794565b505050505050565b815167ffffffffffffffff8111156107c9576107c961054d565b6107dd816107d78454610725565b8461075f565b602080601f83116001811461081257600084156107fa5750858301515b600019600386901b1c1916600185901b1785556107a7565b600085815260208120601f198616915b8281101561084157888601518255948401946001909101908401610822565b508582101561085f5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212204229c8738eb6a99e2fe8a2cd0be82f006719cf059ff7c5b2f748353eb7c5da4c64736f6c63430008170033"