diff --git a/DEPLOYMENTS.md b/DEPLOYMENTS.md index 29f505c6..2511b282 100644 --- a/DEPLOYMENTS.md +++ b/DEPLOYMENTS.md @@ -29,6 +29,7 @@ | `BalancesHelper` | `fuseSparknet` | 0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b | 0x17eca87186670f812655a315ee26a3f8a118accde1369e1a14e85e7f748ca63f | | `BalancesHelper` | `celo` | 0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b | 0xfc0dc010dd2df5473efc9e99d884818145c485de11993612ee8873680eed7b76 | | `BalancesHelper` | `celoTest` | 0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b | 0x6b910a25366bfda341b56258532d882579db1de46ace8e7457cc8da90cf9877b | +| `BalancesHelper` | `neonDevnet` | [0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b](https://neonscan.org/address/0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b) | [0x154f16bb095d820f6e20d631b2e7df8d0e3f1a82732e4ea463b5584cbb37ecd9](https://neonscan.org/tx/0x154f16bb095d820f6e20d631b2e7df8d0e3f1a82732e4ea463b5584cbb37ecd9) | | `BalancesHelper` | `arbitrumNova` | 0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b | 0xf4ffff6eccf68e8df568688c91c45cf82f2f7fba3401f92be057207fa3e3cff8 | | `BalancesHelper` | `arbitrumNitro` | 0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b | 0x34943a88565f9173b84843e04c737c6555210dae946eaa7d9e0ed72e9fc72171 | | `BalancesHelper` | `etherspot` | 0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b | 0xac7270105c381ce52e137b815727c88f9f03a0005afa776154de199de41c1d33 | @@ -52,6 +53,7 @@ | `BalancesHelperV2` | `fuse` | 0xe5A160F89f330cc933816E896a3F36376DE0a835 | 0xc2647efac011deb1cdd2ad539cbbb606cfa84106b7bea2e387f964ea2f5a288a | | `BalancesHelperV2` | `fuseSparknet` | 0xe5A160F89f330cc933816E896a3F36376DE0a835 | 0x794c538975130b41812df708b2174c971ab7af6fa1e19bb5d2b4301c7071c893 | | `BalancesHelperV2` | `celo` | 0xe5A160F89f330cc933816E896a3F36376DE0a835 | 0xfdc0e0d89733dfb237e8b3f4fa36810b84d079d6ecf0b50e435e9542d8b8cdbc | +| `BalancesHelperV2` | `neonDevnet` | [0xe5A160F89f330cc933816E896a3F36376DE0a835](https://neonscan.org/address/0xe5A160F89f330cc933816E896a3F36376DE0a835) | [0xf1b8cb6bbef86256c57e6ea7b672377a8ea4033e556da2b781203cc4e7bf97d5](https://neonscan.org/tx/0xf1b8cb6bbef86256c57e6ea7b672377a8ea4033e556da2b781203cc4e7bf97d5) | | `BalancesHelperV2` | `arbitrumNova` | 0xe5A160F89f330cc933816E896a3F36376DE0a835 | 0xf27547e4bd44530c8008614dcca0af25eaedeec002634d81dd0bea6a1442f96c | | `BalancesHelperV2` | `arbitrumNitro` | 0xe5A160F89f330cc933816E896a3F36376DE0a835 | 0x887cc509e64c1d4812491134cac0ebd165abcfa377807f2437404f2d9d303749 | | `CBridgeFacet` | `goerli` | [0x9d70f5253949Eb67850C3f1e7371f15b955ee073](https://goerli.etherscan.io/address/0x9d70f5253949Eb67850C3f1e7371f15b955ee073) | [0x047d8e991a3dc6bac32e2ef5d08078ecbf10abe3f32c20a7d87b32a2647a2390](https://goerli.etherscan.io/tx/0x047d8e991a3dc6bac32e2ef5d08078ecbf10abe3f32c20a7d87b32a2647a2390) | @@ -68,6 +70,7 @@ | `Diamond` | `arbitrumTest` | 0x3099eC5b37175c6A0011e7f0D48168CC69B21F11 | 0x2f608d6a09266a61a81ed21c545154727393062daa3386d99624c8a4e22baae3 | | `Diamond` | `fuse` | 0xF1447514368fCC942279862a8B5D6Ed7beDFf431 | 0x5931e70b172dc87726ad99af59018ccf9b8cfc9671a6c277f584dcd6871a9487 | | `Diamond` | `fuseSparknet` | 0xF1447514368fCC942279862a8B5D6Ed7beDFf431 | 0xb04462e8680ede04a12a3dfa9c2b9df35c6ae2f28ec7ea1a15a400e92a722995 | +| `Diamond` | `neonDevnet` | [0x3099eC5b37175c6A0011e7f0D48168CC69B21F11](https://neonscan.org/address/0x3099eC5b37175c6A0011e7f0D48168CC69B21F11) | [0x6ec59acf08e12b570cc26e55f8c5eaef448b987c8b95823cba061ceb533b845c](https://neonscan.org/tx/0x6ec59acf08e12b570cc26e55f8c5eaef448b987c8b95823cba061ceb533b845c) | | `Diamond` | `arbitrumNitro` | 0x87e0d943b347F7f692Ee99916C84Ec928D18f84e | 0x3a39b7086ac91d89d60d993a6b671be39b15b8c6ff77bd67036f642c91d3bc81 | | `DiamondCutFacet` | `goerli` | [0xB86fe0416161ded1370016c470622125a93a8218](https://goerli.etherscan.io/address/0xB86fe0416161ded1370016c470622125a93a8218) | [0xa9bd306861469625acd3508b7a704e7d80138e8d3cdaf9b8f8960e1ff810f7f7](https://goerli.etherscan.io/tx/0xa9bd306861469625acd3508b7a704e7d80138e8d3cdaf9b8f8960e1ff810f7f7) | | `DiamondCutFacet` | `kovan` | [0xB86fe0416161ded1370016c470622125a93a8218](https://kovan.etherscan.io/address/0xB86fe0416161ded1370016c470622125a93a8218) | [0xc927a0105e52571c53e1021ee5ff8a4aec02de7b78ac825d980940a54e7a8d7f](https://kovan.etherscan.io/tx/0xc927a0105e52571c53e1021ee5ff8a4aec02de7b78ac825d980940a54e7a8d7f) | @@ -76,6 +79,7 @@ | `DiamondCutFacet` | `arbitrumTest` | 0xB86fe0416161ded1370016c470622125a93a8218 | 0xe8912f2663cdbbf8b2254c9ef552477a991d2167d2813aa00df6ead43108cf2c | | `DiamondCutFacet` | `fuse` | 0xf859F683a47b3D0E2A964eFDdf7392972700a101 | 0x02bb6e8045d5d9b7c69dea3802d5e7a6d33a4844dd6f6263dc0c444604ecc450 | | `DiamondCutFacet` | `fuseSparknet` | 0xf859F683a47b3D0E2A964eFDdf7392972700a101 | 0x5e65bab5b380676f95b76498d68642e6e86894c08089c072b952f6aa1bf8451b | +| `DiamondCutFacet` | `neonDevnet` | [0xB86fe0416161ded1370016c470622125a93a8218](https://neonscan.org/address/0xB86fe0416161ded1370016c470622125a93a8218) | [0x650e66c9ac00bee56871d968b5c5c6dc0965f6d6043bc0e40cb3c9e83c9bf06d](https://neonscan.org/tx/0x650e66c9ac00bee56871d968b5c5c6dc0965f6d6043bc0e40cb3c9e83c9bf06d) | | `DiamondCutFacet` | `arbitrumNitro` | 0xB86fe0416161ded1370016c470622125a93a8218 | 0x8966a33c7598107dd9b140a361d3fcdb1c965737171aebaec2b0304896634da0 | | `DiamondLoupeFacet` | `goerli` | [0xF04D7fC2cB1976736f9263Ff010A048cF564b936](https://goerli.etherscan.io/address/0xF04D7fC2cB1976736f9263Ff010A048cF564b936) | [0x85654b08d44d500aa42ae13aab60b4c2779801c950e6219ddae929c7508a9939](https://goerli.etherscan.io/tx/0x85654b08d44d500aa42ae13aab60b4c2779801c950e6219ddae929c7508a9939) | | `DiamondLoupeFacet` | `kovan` | [0xF04D7fC2cB1976736f9263Ff010A048cF564b936](https://kovan.etherscan.io/address/0xF04D7fC2cB1976736f9263Ff010A048cF564b936) | [0xd6f0f21b3d3c33d3e005ac04161eece4699216bc8ae671eadb0741a74cc4001f](https://kovan.etherscan.io/tx/0xd6f0f21b3d3c33d3e005ac04161eece4699216bc8ae671eadb0741a74cc4001f) | @@ -84,6 +88,7 @@ | `DiamondLoupeFacet` | `arbitrumTest` | 0xF04D7fC2cB1976736f9263Ff010A048cF564b936 | 0xd078d9a6d7fb73313c6177d5be5219d7e3ce8b709d3cc3f83b493d3855aa7ba3 | | `DiamondLoupeFacet` | `fuse` | 0x8BFbB21683e21DC4B11af352117d6D4F2bc62f8e | 0x8710442a64820abbf2a0d69c611eda0beb5fc8b17db31da5e6c08d571f7a32b2 | | `DiamondLoupeFacet` | `fuseSparknet` | 0x8BFbB21683e21DC4B11af352117d6D4F2bc62f8e | 0xc4224d5b19ec685dcb17b0ab862ec9968dc1ab25dd63b6145b1a01b3ac3a1e70 | +| `DiamondLoupeFacet` | `neonDevnet` | [0xF04D7fC2cB1976736f9263Ff010A048cF564b936](https://neonscan.org/address/0xF04D7fC2cB1976736f9263Ff010A048cF564b936) | [0x713d668c7fafa561c5c6e3b8bdce5a60e8c7ec618ac69fc1273e45b4b8270e3d](https://neonscan.org/tx/0x713d668c7fafa561c5c6e3b8bdce5a60e8c7ec618ac69fc1273e45b4b8270e3d) | | `DiamondLoupeFacet` | `arbitrumNitro` | 0xF04D7fC2cB1976736f9263Ff010A048cF564b936 | 0x681e3a7e8dec2b6ec70145f5b8be0f4c218abc39b0d998b4fdf946d2516094c8 | | `ENSController` | `mainnet` | [0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08](https://etherscan.io/address/0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08) | [0xcb245478eb559307f977f2ffdfb3f487af38098f6f7499b2ff438f497107f024](https://etherscan.io/tx/0xcb245478eb559307f977f2ffdfb3f487af38098f6f7499b2ff438f497107f024) | | `ENSController` | `ropsten` | [0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08](https://ropsten.etherscan.io/address/0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08) | [0x8becdf6c4958d945ca128c50a66718e7a900379f344091cac282b89a8d86f5b0](https://ropsten.etherscan.io/tx/0x8becdf6c4958d945ca128c50a66718e7a900379f344091cac282b89a8d86f5b0) | @@ -112,6 +117,7 @@ | `ENSController` | `fuseSparknet` | 0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08 | 0xf73f44af58c7d1d4c28d2d86e8151d9df4afaa2577eb0699557abc16968dbd53 | | `ENSController` | `celo` | 0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08 | 0x506af71c933202ab4deb3de6599c0c5ec5f07af0750837ffa38216fddd1af7eb | | `ENSController` | `celoTest` | 0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08 | 0xc45d57662670d6ab754683f4a030859fa8d1b0fad29a6dd335b768f259665ecd | +| `ENSController` | `neonDevnet` | [0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08](https://neonscan.org/address/0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08) | [0x24da3b71a66b5ecbc9ae73762d856309525b4e69d7735977b2e29f9f443c7869](https://neonscan.org/tx/0x24da3b71a66b5ecbc9ae73762d856309525b4e69d7735977b2e29f9f443c7869) | | `ENSController` | `arbitrumNova` | 0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08 | 0x9eb6213b2320243c84290cac3acf4619a5ffffa586505c44a92f3bc4b6b7a4f9 | | `ENSController` | `arbitrumNitro` | 0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08 | 0x1ffee3063052940312d55fb7c90cc30212049c49f3e4ad3f1bef334484e98472 | | `ENSController` | `etherspot` | 0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08 | 0x2dd4c61274c93e97aa5ce56138d7d67d4cc74503a97b0e2af4f2dee9844c7253 | @@ -142,6 +148,7 @@ | `ENSHelper` | `fuseSparknet` | 0xF330b17e19474762E6F408D7dCf0327264d4A2C0 | 0x6db86ba1be399c574ea44d3ce3b36f9759d97db6875c1e2519667ab946b6e240 | | `ENSHelper` | `celo` | 0xF330b17e19474762E6F408D7dCf0327264d4A2C0 | 0x396ec3c9f1f3a8625402798581ae2cb925d2ae1d6743ad9e7b498e814c570057 | | `ENSHelper` | `celoTest` | 0xF330b17e19474762E6F408D7dCf0327264d4A2C0 | 0x42c9dce6afca7bd38dee552c2b8724061e01bf9a47ecff91f3094e730bd80caf | +| `ENSHelper` | `neonDevnet` | [0xF330b17e19474762E6F408D7dCf0327264d4A2C0](https://neonscan.org/address/0xF330b17e19474762E6F408D7dCf0327264d4A2C0) | [0x537758f8c59f5f98525af01cac5f20a29ccab5bdf76a04e327222c9c94c099bb](https://neonscan.org/tx/0x537758f8c59f5f98525af01cac5f20a29ccab5bdf76a04e327222c9c94c099bb) | | `ENSHelper` | `arbitrumNova` | 0xF330b17e19474762E6F408D7dCf0327264d4A2C0 | 0xe129a9c3c8a826a0b90b348bfb7f0dab93f7833faf4fafc6a1f650af78ff7b9e | | `ENSHelper` | `arbitrumNitro` | 0xF330b17e19474762E6F408D7dCf0327264d4A2C0 | 0x020b653764ca2fc7e9cd091d68878fed403ae42dcc22dcf66d9f594d8be78a01 | | `ENSHelper` | `etherspot` | 0xF330b17e19474762E6F408D7dCf0327264d4A2C0 | 0x7cf8135b5b04916485a8ec064d304c46cfe871e613ea14e128c51b6616f0d0f0 | @@ -171,6 +178,7 @@ | `ENSRegistry` | `fuseSparknet` | 0xf17BCfd10B65fD0792dEef7a17Aa08B4b0086688 | 0x9c446bb44fa6e652f05391ccf363679d32237782495f7384d1a04214c40c7536 | | `ENSRegistry` | `celo` | 0xf17BCfd10B65fD0792dEef7a17Aa08B4b0086688 | 0xfbd52c01cc283b000acfe5679ec13cd4956991d14ef2d9d899cc9cc4a30566aa | | `ENSRegistry` | `celoTest` | 0xf17BCfd10B65fD0792dEef7a17Aa08B4b0086688 | 0x6361fb53ae0e03f60f5886aa101620f050d2ca0a94765e45dd0be8fabe3e1f5a | +| `ENSRegistry` | `neonDevnet` | [0xf17BCfd10B65fD0792dEef7a17Aa08B4b0086688](https://neonscan.org/address/0xf17BCfd10B65fD0792dEef7a17Aa08B4b0086688) | [0x8e856f881e3a281aa213b7e0dfc652b333e7c7c54a7e6cec6a1d90fd1f7733c3](https://neonscan.org/tx/0x8e856f881e3a281aa213b7e0dfc652b333e7c7c54a7e6cec6a1d90fd1f7733c3) | | `ENSRegistry` | `arbitrumNova` | 0xf17BCfd10B65fD0792dEef7a17Aa08B4b0086688 | 0xe8c1efe9378204075510cebe52c49b883f718b5a2ebd2a7e7804a348e0c899ea | | `ENSRegistry` | `arbitrumNitro` | 0xf17BCfd10B65fD0792dEef7a17Aa08B4b0086688 | 0xa736c7bd9a26ba6a4d32962ac3dbef7110cf87e6aecce2226a993e4f2a0f088f | | `ENSRegistry` | `etherspot` | 0xf17BCfd10B65fD0792dEef7a17Aa08B4b0086688 | 0x1b419734e3beb7a4d97e835e3b0f594ddb74290ab7fc940ba3c5a3b37e035775 | @@ -200,6 +208,7 @@ | `ENSReverseRegistrar` | `fuseSparknet` | 0x523C92966e9d2067ba547f59D51E907c20FD8761 | 0x9d18868bf5babb156cc0551acc2874b85543f5168b89e0326473cd3e6630eca3 | | `ENSReverseRegistrar` | `celo` | 0x523C92966e9d2067ba547f59D51E907c20FD8761 | 0x3fda2be4237a4ca2103d46d8755edb14c5ea4bef154eabfc4aa91280d9f16836 | | `ENSReverseRegistrar` | `celoTest` | 0x523C92966e9d2067ba547f59D51E907c20FD8761 | 0x178149172d88aa3d6b00fde5ba0d0bc120924349c5fb5030f43136d86cbb7383 | +| `ENSReverseRegistrar` | `neonDevnet` | [0x523C92966e9d2067ba547f59D51E907c20FD8761](https://neonscan.org/address/0x523C92966e9d2067ba547f59D51E907c20FD8761) | [0x7c0f450722b503fc6a836fdb009f5f7d30c53ebc31599b58e83082b12ee9276b](https://neonscan.org/tx/0x7c0f450722b503fc6a836fdb009f5f7d30c53ebc31599b58e83082b12ee9276b) | | `ENSReverseRegistrar` | `arbitrumNova` | 0x523C92966e9d2067ba547f59D51E907c20FD8761 | 0xffa80fe1696aa362243347324934110b02fec48ddd62d7cf1c97a74291e2bb2b | | `ENSReverseRegistrar` | `arbitrumNitro` | 0x523C92966e9d2067ba547f59D51E907c20FD8761 | 0x70de389b15700bc9fde25e81f4d6c53549d74665209a237ca24e054bb0111d49 | | `ENSReverseRegistrar` | `etherspot` | 0x523C92966e9d2067ba547f59D51E907c20FD8761 | 0x3193533de6611dc509866e81e0d955674b8d351a82ca5db095e00b6e40414869 | @@ -230,6 +239,7 @@ | `ExternalAccountRegistry` | `fuseSparknet` | 0x502BbBcC044d2B146c310eB24E5cd8Eba37EdbEc | 0xaf97cd55f19b04f6aad22bfb1757d7c92346e5b9ebdb88d68bde2998ed2cafc2 | | `ExternalAccountRegistry` | `celo` | 0x502BbBcC044d2B146c310eB24E5cd8Eba37EdbEc | 0x01dbf81a93f634c4352e223da76269ade120e638386bfdb5e6850989ffd7e9d1 | | `ExternalAccountRegistry` | `celoTest` | 0x502BbBcC044d2B146c310eB24E5cd8Eba37EdbEc | 0xdec39d8ca0dc8bfdc627a7c1f97d9dd3697c53c6f39ed4824e2a199fb987c8fe | +| `ExternalAccountRegistry` | `neonDevnet` | [0x502BbBcC044d2B146c310eB24E5cd8Eba37EdbEc](https://neonscan.org/address/0x502BbBcC044d2B146c310eB24E5cd8Eba37EdbEc) | [0xd31152fbbb7e51f8ecdc84610a8c9c099cfd4995ea2f1f4a005a14318f12fcef](https://neonscan.org/tx/0xd31152fbbb7e51f8ecdc84610a8c9c099cfd4995ea2f1f4a005a14318f12fcef) | | `ExternalAccountRegistry` | `arbitrumNova` | 0x502BbBcC044d2B146c310eB24E5cd8Eba37EdbEc | 0x3f1964b962f1b259400e87b32214ae4f6031f17c3e2e5386151030e5e0b124f3 | | `ExternalAccountRegistry` | `arbitrumNitro` | 0x502BbBcC044d2B146c310eB24E5cd8Eba37EdbEc | 0x8865d755782e210b3a71afba0d372d8cc1504ad47d0dae7fb97020ff5c29424a | | `ExternalAccountRegistry` | `etherspot` | 0x502BbBcC044d2B146c310eB24E5cd8Eba37EdbEc | 0x0bec371bae9679a3eacab911686c48199f620c9f795d9cc5d5faec6f4ab0c669 | @@ -260,6 +270,7 @@ | `Gateway` | `fuseSparknet` | 0x432defD2b3733e6fEBb1bD4B17Ed85D15b882163 | 0x814795f50ab1bd03fa7eae4d28f70e85e24138ed8af01cab3ea0f98c98e81235 | | `Gateway` | `celo` | 0x432defD2b3733e6fEBb1bD4B17Ed85D15b882163 | 0x9f0a37c40e438898b92eb3404726cf7e3ab0566e3bd97453153d4502255f15d3 | | `Gateway` | `celoTest` | 0x432defD2b3733e6fEBb1bD4B17Ed85D15b882163 | 0x017b93cfff9bef60d74ed3f678617e31bce472a62c16e4170d27833d265295a6 | +| `Gateway` | `neonDevnet` | [0x432defD2b3733e6fEBb1bD4B17Ed85D15b882163](https://neonscan.org/address/0x432defD2b3733e6fEBb1bD4B17Ed85D15b882163) |[0x527b68d567e57e392dc2f25c13b067067ef03c7870f287b8eb0e3ade6aae7dbb](https://neonscan.org/tx/0x527b68d567e57e392dc2f25c13b067067ef03c7870f287b8eb0e3ade6aae7dbb) | | `Gateway` | `arbitrumNova` | 0x432defD2b3733e6fEBb1bD4B17Ed85D15b882163 | 0x79ff0dafd337c73d39c67bd8333fc6524df7690c879f8796789cb58f20c19f4a | | `Gateway` | `arbitrumNitro` | 0x432defD2b3733e6fEBb1bD4B17Ed85D15b882163 | 0x36f8325ad8033f74aaf44f3b83a5793928723d9af70eac918eaa8a288d1ab3e5 | | `Gateway` | `etherspot` | 0x432defD2b3733e6fEBb1bD4B17Ed85D15b882163 | 0xba898531d95380c97307201fb1fe773801fb83343d9096c6bc4380402ed4486b | @@ -281,6 +292,7 @@ | `OwnershipFacet` | `arbitrumTest` | 0x4e0BaFA6f2a4299f4b19b31250970fAdA52a9515 | 0x2208378485001a1c1b745a27b4e7743c2bd0f8a1cc991506c601f14f77514ce1 | | `OwnershipFacet` | `fuse` | 0xdd43fA3fCB57F9F075F48F0FA564162a0eE7fa70 | 0x6b077186eb6861290fb7f38c0d53e93b5e83f4e9e217b8d7dee5ab837c2cf4e8 | | `OwnershipFacet` | `fuseSparknet` | 0xdd43fA3fCB57F9F075F48F0FA564162a0eE7fa70 | 0xb65d9d8fa6bb8390d70c2dfd7341b91077ae8eec4fe4513d53ce61e636d12185 | +| `OwnershipFacet` | `neonDevnet` | [0x4e0BaFA6f2a4299f4b19b31250970fAdA52a9515](https://neonscan.org/address/0x4e0BaFA6f2a4299f4b19b31250970fAdA52a9515) | [0xf627177d138682ce38f84c295cf60692c81624170d5397b2e6d2881e57e028e4](https://neonscan.org/tx/0xf627177d138682ce38f84c295cf60692c81624170d5397b2e6d2881e57e028e4) | | `OwnershipFacet` | `arbitrumNitro` | 0x4e0BaFA6f2a4299f4b19b31250970fAdA52a9515 | 0x5f36f6d9ca5240c18b2752b39ad4114b52830b3055e98216d41429aec7cc5806 | | `PaymentRegistry` | `mainnet` | [0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312](https://etherscan.io/address/0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312) | [0x03172e98a8a14cbec4ce793277552de243df1451eefe8a163bacccd9187b2a4f](https://etherscan.io/tx/0x03172e98a8a14cbec4ce793277552de243df1451eefe8a163bacccd9187b2a4f) | | `PaymentRegistry` | `ropsten` | [0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312](https://ropsten.etherscan.io/address/0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312) | [0xef47e55c32941bb0d794c491d0a1fc25fb98826472fc62df31e6fcd0fad9b162](https://ropsten.etherscan.io/tx/0xef47e55c32941bb0d794c491d0a1fc25fb98826472fc62df31e6fcd0fad9b162) | @@ -309,6 +321,7 @@ | `PaymentRegistry` | `fuseSparknet` | 0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312 | 0x6c5375420adb40244862d193177f1bcb3bf6cf18bb53fd0693bca73d3693ca48 | | `PaymentRegistry` | `celo` | 0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312 | 0x70b6d0b59d9ca6cfc0a02f04742a91177f87166cfe4c287edd08170519390479 | | `PaymentRegistry` | `celoTest` | 0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312 | 0x82b9aa071e80bfb8521d76e0867035116153ee3f9e6d2ba49fd6ac2953d130bb | +| `PaymentRegistry` | `neonDevnet` | [0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312](https://neonscan.org/address/0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312) | [0x23514b60607e2f59c56170f5a4b9060b03c153224c94f0cd0332e08edf27e019](https://neonscan.org/tx/0x23514b60607e2f59c56170f5a4b9060b03c153224c94f0cd0332e08edf27e019) | | `PaymentRegistry` | `arbitrumNova` | 0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312 | 0xb7ec876ed6042538461dfaf4d7e492be17b5448fe07671160d82d9963f7c777e | | `PaymentRegistry` | `arbitrumNitro` | 0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312 | 0x805266d618015606750cbd0e794ef1420e7abed5584c7eb10dd2634c252eb0ec | | `PaymentRegistry` | `etherspot` | 0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312 | 0x96338b94bbc9fe24b6e5def6ad523983dfd56883620a85ebd4ca35d0be609d0c | @@ -339,6 +352,7 @@ | `PersonalAccountImplementationV1` | `fuseSparknet` | 0x0672aF0018fdEbACcc93c7D047D62b72CB12883A | 0x3fded149d1fa752a031943332ec16600ba871bb13aa6c7e4fd4c90b0c78a501f | | `PersonalAccountImplementationV1` | `celo` | 0x0672aF0018fdEbACcc93c7D047D62b72CB12883A | 0x0816d1e8803abb1a638e1aba5ec7395e5cd8228d2883cc3d7c1ea2af19fc0926 | | `PersonalAccountImplementationV1` | `celoTest` | 0x0672aF0018fdEbACcc93c7D047D62b72CB12883A | 0xbf4e974badd253ba96904e2281d01ac7e00ac798763568581b3674cf3e6df5df | +| `PersonalAccountImplementationV1` | `neonDevnet` | [0x0672aF0018fdEbACcc93c7D047D62b72CB12883A](https://neonscan.org/address/0x0672aF0018fdEbACcc93c7D047D62b72CB12883A) | [0x620748c84602085f064e8d9453530f6425c1a27cc17c13c881d797735cd4573f](https://neonscan.org/tx/0x620748c84602085f064e8d9453530f6425c1a27cc17c13c881d797735cd4573f) | | `PersonalAccountImplementationV1` | `arbitrumNova` | 0x0672aF0018fdEbACcc93c7D047D62b72CB12883A | 0x0bb5a57e646f35b1a2d9dffb012a3116206cd17ca18768f4b29af1d90ebfd37c | | `PersonalAccountImplementationV1` | `arbitrumNitro` | 0x0672aF0018fdEbACcc93c7D047D62b72CB12883A | 0x41e4b313037c8579d3a5da6d041d488df6fd41232892bbd2eb8510e41d82e73d | | `PersonalAccountImplementationV1` | `etherspot` | 0x0672aF0018fdEbACcc93c7D047D62b72CB12883A | 0x8ddcf689ffc89e45538b31941069088c0a63d34de0f24358cd29f536e8dce3e2 | @@ -369,6 +383,7 @@ | `PersonalAccountRegistry` | `fuseSparknet` | 0x7EB3A038F25B9F32f8e19A7F0De83D4916030eFa | 0xfbd74ec51c1c57acba61bc69f83923a3dc5f913524e8bbbfd00f97c9031d28dd | | `PersonalAccountRegistry` | `celo` | 0x7EB3A038F25B9F32f8e19A7F0De83D4916030eFa | 0x2a601f05cdc7d98281ce20575ba214505f325a9bc3a938c5255fa7a44fab39c5 | | `PersonalAccountRegistry` | `celoTest` | 0x7EB3A038F25B9F32f8e19A7F0De83D4916030eFa | 0x1462730017894782a39811340aa50ec65a2a9ad710f6a38de578ed7fc44e4b73 | +| `PersonalAccountRegistry` | `neonDevnet` | [0x7EB3A038F25B9F32f8e19A7F0De83D4916030eFa](https://neonscan.org/address/0x7EB3A038F25B9F32f8e19A7F0De83D4916030eFa) | [0x2a0d6342070736407eb6a3ddf0775e9b7e4c8e67ca488916a7f6b88e195fa89c](https://neonscan.org/tx/0x2a0d6342070736407eb6a3ddf0775e9b7e4c8e67ca488916a7f6b88e195fa89c) | | `PersonalAccountRegistry` | `arbitrumNova` | 0x7EB3A038F25B9F32f8e19A7F0De83D4916030eFa | 0xeb6718d5a1810061bc558f304417e667c8a03c03137903911bf48b60be7369ad | | `PersonalAccountRegistry` | `arbitrumNitro` | 0x7EB3A038F25B9F32f8e19A7F0De83D4916030eFa | 0x6779c8aff1b896b2228fd9248f244902ce6e7629b35eb962d862ffaca47a2851 | | `PersonalAccountRegistry` | `etherspot` | 0x7EB3A038F25B9F32f8e19A7F0De83D4916030eFa | 0xd9359a5aa653ba4acab01ad38a2cb644f2140f0d7d1648398414471422448346 | @@ -402,6 +417,7 @@ | `WrappedWeiToken` | `fuseSparknet` | 0x8e5ea4368fcd17A4efF851C5ffa6cd03bBDeb616 | 0x892803ea55222c0ba1f2143063ab79df1ee42ce2bf2e65385c80f8a8c842d067 | | `WrappedWeiToken` | `celo` | 0x8e5ea4368fcd17A4efF851C5ffa6cd03bBDeb616 | 0x81141ef3b78568d3c8889b4f4443868dd3766cd08b9eac34a5b8030c29636321 | | `WrappedWeiToken` | `celoTest` | 0x8e5ea4368fcd17A4efF851C5ffa6cd03bBDeb616 | 0xda0092889e56a998075e66d89d03e6f0f54382e43780adb837dc0ffac6f56b16 | +| `WrappedWeiToken` | `neonDevnet` | [0x8e5ea4368fcd17A4efF851C5ffa6cd03bBDeb616](https://neonscan.org/address/0x8e5ea4368fcd17A4efF851C5ffa6cd03bBDeb616) | [0x914aca830634bfd34953e0964b78873ddce6d6c0a62161b7a5501b4b5ca196f5](https://neonscan.org/tx/0x914aca830634bfd34953e0964b78873ddce6d6c0a62161b7a5501b4b5ca196f5) | | `WrappedWeiToken` | `arbitrumNova` | 0x8e5ea4368fcd17A4efF851C5ffa6cd03bBDeb616 | 0xaf496abf9b16e972369caf27ba70333c7eaee148f292af095374f067547aa8d3 | | `WrappedWeiToken` | `arbitrumNitro` | 0x8e5ea4368fcd17A4efF851C5ffa6cd03bBDeb616 | 0x990f502ea7ba7f8e5c3258281cb43e833aa7d040909cada623bc9417100f2460 | | `WrappedWeiToken` | `etherspot` | 0x8e5ea4368fcd17A4efF851C5ffa6cd03bBDeb616 | 0x97561b8070bdcb84cc0ef0fc47a1f59ebe56c36e3f7448e90e39cdcd65aefd9d | diff --git a/deployments/arbitrumNitro/CBridgeFacet.json b/deployments/arbitrumNitro/CBridgeFacet.json new file mode 100644 index 00000000..a31daecb --- /dev/null +++ b/deployments/arbitrumNitro/CBridgeFacet.json @@ -0,0 +1,255 @@ +{ + "address": "0x9d70f5253949Eb67850C3f1e7371f15b955ee073", + "abi": [ + { + "inputs": [], + "name": "CBSlippageTooLow", + "type": "error" + }, + { + "inputs": [], + "name": "CannotBridgeToSameNetwork", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyError", + "type": "error" + }, + { + "inputs": [], + "name": "TokenAddressIsZero", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressProvided", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "cBridge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "CBInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "bridgeUsed", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "qty", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "chainIdTo", + "type": "uint256" + } + ], + "name": "CBTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "CBUpdatedBridge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newSlippage", + "type": "uint256" + } + ], + "name": "CBUpdatedSlippageTolerance", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "dstChainId", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "qty", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct CBridgeFacet.CBridgeData", + "name": "_cbData", + "type": "tuple" + } + ], + "name": "cbBridgeTokens", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_cbBridge", + "type": "address" + } + ], + "name": "cbInitialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newAddress", + "type": "address" + } + ], + "name": "cbUpdateBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_newSlippage", + "type": "uint32" + } + ], + "name": "cbUpdateSlippageTolerance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x6b2f2dfd2f724949422b80464b10ad71fd064efe6bafbdefb2d26e464d6a388e", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x326b2D4f29E19C7089D038EA5E06f090Afa6FB7f", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "1247338", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8fd699faeb1893249cd2484a60f095176e5ff67c0e2e961240e70fd6fed78535", + "transactionHash": "0x6b2f2dfd2f724949422b80464b10ad71fd064efe6bafbdefb2d26e464d6a388e", + "logs": [], + "blockNumber": 156717, + "cumulativeGasUsed": "1247338", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "8d42885a5f19da22f710ffc8b637c191", + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CBSlippageTooLow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotBridgeToSameNetwork\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenAddressIsZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressProvided\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"cBridge\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"name\":\"CBInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"bridgeUsed\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"qty\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"chainIdTo\",\"type\":\"uint256\"}],\"name\":\"CBTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAddress\",\"type\":\"address\"}],\"name\":\"CBUpdatedBridge\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSlippage\",\"type\":\"uint256\"}],\"name\":\"CBUpdatedSlippageTolerance\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"dstChainId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"qty\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"struct CBridgeFacet.CBridgeData\",\"name\":\"_cbData\",\"type\":\"tuple\"}],\"name\":\"cbBridgeTokens\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_cbBridge\",\"type\":\"address\"}],\"name\":\"cbInitialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newAddress\",\"type\":\"address\"}],\"name\":\"cbUpdateBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_newSlippage\",\"type\":\"uint32\"}],\"name\":\"cbUpdateSlippageTolerance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cbBridgeTokens((uint64,uint64,uint256,address,address))\":{\"params\":{\"_cbData\":\": provides necessary data for cBridge transfer\"}},\"cbInitialize(address)\":{\"params\":{\"_cbBridge\":\"address of the CBridge router contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cbBridgeTokens((uint64,uint64,uint256,address,address))\":{\"notice\":\"initiates token bridging\"},\"cbInitialize(address)\":{\"notice\":\"initializes state variables for the cBridge facet\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/bridges/facets/CBridgeFacet.sol\":\"CBridgeFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"src/bridges/errors/CBridgeErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// solhint-disable-next-line\\npragma solidity 0.8.4;\\n\\nerror CBSlippageTooLow();\\n\",\"keccak256\":\"0x03cb94f117b0cca4864a126a41add3f939b7ec3ca8e398eb901c78788a7176c8\",\"license\":\"MIT\"},\"src/bridges/errors/GenericErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// solhint-disable-next-line\\npragma solidity 0.8.4;\\n\\nerror InvalidAmount();\\nerror TokenAddressIsZero();\\nerror CannotBridgeToSameNetwork();\\nerror ZeroPostSwapBalance();\\nerror InvalidBridgeConfigLength();\\nerror NoSwapDataProvided();\\nerror NativeValueWithERC();\\nerror ContractCallNotAllowed();\\nerror NullAddrIsNotAValidSpender();\\nerror NullAddrIsNotAnERC20Token();\\nerror NoTransferToNullAddress();\\nerror NativeAssetTransferFailed();\\nerror InvalidContract();\\nerror InvalidConfig();\\nerror ZeroAddressProvided();\\n\",\"keccak256\":\"0x8fbb39c8e0b8f0ed9b37b799fec0e47bbd9f209c290a8dd290e44241dedaceda\",\"license\":\"MIT\"},\"src/bridges/facets/CBridgeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// solhint-disable-next-line\\npragma solidity 0.8.4;\\n\\n/// @title CBridgeFacet\\n/// @author Luke Wickens \\n/// @notice cBridge intergration for bridging tokens\\n\\nimport {ICBridge} from \\\"../interfaces/ICBridge.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {ReentrancyGuard} from \\\"../../common/helpers/DiamondReentrancyGuard.sol\\\";\\nimport {CannotBridgeToSameNetwork, InvalidAmount, InvalidConfig, TokenAddressIsZero, ZeroAddressProvided} from \\\"../errors/GenericErrors.sol\\\";\\nimport {CBSlippageTooLow} from \\\"../errors/CBridgeErrors.sol\\\";\\nimport {LibDiamond} from \\\"../libs/LibDiamond.sol\\\";\\n\\ncontract CBridgeFacet is ReentrancyGuard {\\n using SafeERC20 for IERC20;\\n //////////////////////////////////////////////////////////////\\n /////////////////////////// Events ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n event CBInitialized(address cBridge, uint256 chainId);\\n event CBTransferStarted(\\n string bridgeUsed,\\n address token,\\n address from,\\n address to,\\n uint256 qty,\\n uint256 chainIdTo\\n );\\n event CBUpdatedBridge(address newAddress);\\n event CBUpdatedSlippageTolerance(uint256 newSlippage);\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Storage ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n bytes32 internal constant NAMESPACE =\\n keccak256(\\\"io.etherspot.facets.cbridge\\\");\\n struct Storage {\\n address cbBridge;\\n uint256 cbChainId;\\n uint32 cbSlippage;\\n }\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Structs ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n struct CBridgeData {\\n uint64 dstChainId;\\n uint64 nonce;\\n uint256 qty;\\n address to;\\n address token;\\n }\\n\\n /// @notice initializes state variables for the cBridge facet\\n /// @param _cbBridge address of the CBridge router contract\\n function cbInitialize(address _cbBridge) external {\\n LibDiamond.enforceIsContractOwner();\\n if (_cbBridge == address(0)) revert ZeroAddressProvided();\\n Storage storage s = getStorage();\\n s.cbBridge = _cbBridge;\\n s.cbChainId = block.chainid;\\n s.cbSlippage = 10000; // equates to 1% - has to be > 0.5% (slippage * 1M)\\n emit CBInitialized(_cbBridge, block.chainid);\\n }\\n\\n /// @notice initiates token bridging\\n /// @param _cbData: provides necessary data for cBridge transfer\\n\\n function cbBridgeTokens(CBridgeData calldata _cbData)\\n external\\n payable\\n nonReentrant\\n {\\n if (block.chainid == _cbData.dstChainId)\\n revert CannotBridgeToSameNetwork();\\n if (_cbData.to == address(0)) revert ZeroAddressProvided();\\n if (_cbData.qty <= 0) revert InvalidAmount();\\n if (_cbData.token == address(0)) revert TokenAddressIsZero();\\n\\n Storage storage s = getStorage();\\n address bridge = s.cbBridge;\\n\\n // this contract calls stargate swap()\\n IERC20(_cbData.token).safeTransferFrom(\\n msg.sender,\\n address(this),\\n _cbData.qty\\n );\\n IERC20(_cbData.token).safeApprove(address(bridge), _cbData.qty);\\n\\n ICBridge(bridge).send(\\n _cbData.to,\\n _cbData.token,\\n _cbData.qty,\\n _cbData.dstChainId,\\n _cbData.nonce,\\n s.cbSlippage\\n );\\n\\n emit CBTransferStarted(\\n \\\"cbridge\\\",\\n _cbData.token,\\n msg.sender,\\n _cbData.to,\\n _cbData.qty,\\n _cbData.dstChainId\\n );\\n }\\n\\n function cbUpdateSlippageTolerance(uint32 _newSlippage) external {\\n // should be > 0.5% (5000)\\n if (_newSlippage <= 5000) revert CBSlippageTooLow();\\n LibDiamond.enforceIsContractOwner();\\n Storage storage s = getStorage();\\n s.cbSlippage = _newSlippage;\\n emit CBUpdatedSlippageTolerance(_newSlippage);\\n }\\n\\n function cbUpdateBridge(address _newAddress) external {\\n LibDiamond.enforceIsContractOwner();\\n if (_newAddress == address(0)) revert ZeroAddressProvided();\\n Storage storage s = getStorage();\\n s.cbBridge = _newAddress;\\n emit CBUpdatedBridge(_newAddress);\\n }\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////// Private Functions /////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n /// @dev fetch local storage\\n function getStorage() private pure returns (Storage storage s) {\\n bytes32 namespace = NAMESPACE;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n s.slot := namespace\\n }\\n }\\n}\\n\",\"keccak256\":\"0x1555eba16c57843a441f5886a70a86f82ad73507f24dabdc44d6ec9e9c87ee9d\",\"license\":\"MIT\"},\"src/bridges/interfaces/ICBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// solhint-disable-next-line\\npragma solidity 0.8.4;\\n\\ninterface ICBridge {\\n function send(\\n address _receiver,\\n address _token,\\n uint256 _amount,\\n uint64 _dstChinId,\\n uint64 _nonce,\\n uint32 _maxSlippage\\n ) external;\\n\\n function sendNative(\\n address _receiver,\\n uint256 _amount,\\n uint64 _dstChinId,\\n uint64 _nonce,\\n uint32 _maxSlippage\\n ) external payable;\\n\\n function relay(\\n bytes calldata _relayRequest,\\n bytes[] calldata _sigs,\\n address[] calldata _signers,\\n uint256[] calldata _powers\\n ) external;\\n}\\n\",\"keccak256\":\"0x1d9e1f4ef38e6d8f810869d4e4126af4d3c5b70cf23ae0f61abb63151ef1c43c\",\"license\":\"MIT\"},\"src/bridges/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xc5184a3a9a2d9698572c007846bf12cf4a693dffc47425352b4b4f92beaae4db\",\"license\":\"MIT\"},\"src/bridges/libs/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress)\\n internal\\n {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x135cb5bb9fc0234dcc41a8ba75e6a95ad514cd965673f1d105103dbba18017cd\",\"license\":\"MIT\"},\"src/common/helpers/DiamondReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.4;\\n\\n/// @title Reentrancy Guard\\n/// @notice Abstract contract to provide protection against reentrancy\\nabstract contract ReentrancyGuard {\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Storage ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n bytes32 private constant NAMESPACE =\\n keccak256(\\\"io.etherspot.helpers.reentrancyguard\\\");\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Structs ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n struct ReentrancyStorage {\\n uint256 status;\\n }\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Errors ////////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n error ReentrancyError();\\n\\n //////////////////////////////////////////////////////////////\\n ///////////////////////// Constants //////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n uint256 private constant _NOT_ENTERED = 0;\\n uint256 private constant _ENTERED = 1;\\n\\n //////////////////////////////////////////////////////////////\\n ///////////////////////// Modifiers ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n modifier nonReentrant() {\\n ReentrancyStorage storage s = reentrancyStorage();\\n if (s.status == _ENTERED) revert ReentrancyError();\\n s.status = _ENTERED;\\n _;\\n s.status = _NOT_ENTERED;\\n }\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////// Private Functions /////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n /// @dev fetch local storage\\n function reentrancyStorage()\\n private\\n pure\\n returns (ReentrancyStorage storage data)\\n {\\n bytes32 position = NAMESPACE;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n data.slot := position\\n }\\n }\\n}\\n\",\"keccak256\":\"0x80669f5e1b6d50ad0b4020e8caeb447f515e3b904b14cad5d03cc32e345753d5\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506115ab806100206000396000f3fe60806040526004361061003f5760003560e01c806340d280a21461004457806352434c6e1461006d5780636f395e60146100895780639e32e2e6146100b2575b600080fd5b34801561005057600080fd5b5061006b60048036038101906100669190610dac565b6100db565b005b61008760048036038101906100829190610dfe565b610204565b005b34801561009557600080fd5b506100b060048036038101906100ab9190610dac565b6105f6565b005b3480156100be57600080fd5b506100d960048036038101906100d49190610e50565b6106ef565b005b6100e36107a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561014a576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061015461083d565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055504681600101819055506127108160020160006101000a81548163ffffffff021916908363ffffffff1602179055507fcbfd47a07530fc4fffba96f5686a7127e5661fe26dd01503239ca2f66fcad99082466040516101f892919061112b565b60405180910390a15050565b600061020e61086a565b905060018160000154141561024f576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816000018190555081600001602081019061026c9190610e79565b67ffffffffffffffff164614156102af576040517f4ac09ad300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168260600160208101906102da9190610dac565b73ffffffffffffffffffffffffffffffffffffffff161415610328576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826040013511610366576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168260800160208101906103919190610dac565b73ffffffffffffffffffffffffffffffffffffffff1614156103df576040517fdc2e5e8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103e961083d565b905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610457333086604001358760800160208101906104319190610dac565b73ffffffffffffffffffffffffffffffffffffffff16610897909392919063ffffffff16565b6104988185604001358660800160208101906104739190610dac565b73ffffffffffffffffffffffffffffffffffffffff166109209092919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff1663a5977fbb8560600160208101906104c79190610dac565b8660800160208101906104da9190610dac565b87604001358860000160208101906104f29190610e79565b8960200160208101906105059190610e79565b8860020160009054906101000a900463ffffffff166040518763ffffffff1660e01b815260040161053b969594939291906110ca565b600060405180830381600087803b15801561055557600080fd5b505af1158015610569573d6000803e3d6000fd5b505050507fd565a5cf794050de1a171170c91acd5d14cbf11877dc3fa020e9975495ab17578460800160208101906105a19190610dac565b338660600160208101906105b59190610dac565b87604001358860000160208101906105cd9190610e79565b6040516105de9594939291906111b6565b60405180910390a15050600081600001819055505050565b6105fe6107a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610665576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061066f61083d565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f4ae67faf3cf135d9eca1b5490d3613096d2d0610fca7496112fa46ef019fbd4e826040516106e3919061104f565b60405180910390a15050565b6113888163ffffffff1611610730576040517f9ff4125000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107386107a2565b600061074261083d565b9050818160020160006101000a81548163ffffffff021916908363ffffffff1602179055507f8d5e80c35df41e151b58f1a100ad605ae1ebcda3d0c329b22820b232767a773082604051610796919061127c565b60405180910390a15050565b6107aa610a7e565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461083b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083290611176565b60405180910390fd5b565b6000807f9d7253cc9498e9cc54011bbbe9471a68adbc99d0ac1eef42369f5a452e814c4a90508091505090565b6000807fc59b5acc5a6673a6c49ca2de898f87adbd9fdfdff36f689476b1c9e0c50964b490508091505090565b61091a846323b872dd60e01b8585856040516024016108b893929190611093565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610aab565b50505050565b60008114806109b9575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b815260040161096792919061106a565b60206040518083038186803b15801561097f57600080fd5b505afa158015610993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b79190610e27565b145b6109f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ef9061125c565b60405180910390fd5b610a798363095ea7b360e01b8484604051602401610a1792919061112b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610aab565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b6000610b0d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610b729092919063ffffffff16565b9050600081511115610b6d5780806020019051810190610b2d9190610dd5565b610b6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b639061123c565b60405180910390fd5b5b505050565b6060610b818484600085610b8a565b90509392505050565b606082471015610bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc690611196565b60405180910390fd5b610bd885610c9e565b610c17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0e9061121c565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610c409190611038565b60006040518083038185875af1925050503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b5091509150610c92828286610cc1565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315610cd157829050610d21565b600083511115610ce45782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d189190611154565b60405180910390fd5b9392505050565b600081359050610d378161152b565b92915050565b600081519050610d4c81611542565b92915050565b600060a08284031215610d6457600080fd5b81905092915050565b600081519050610d7c81611559565b92915050565b600081359050610d9181611570565b92915050565b600081359050610da681611587565b92915050565b600060208284031215610dbe57600080fd5b6000610dcc84828501610d28565b91505092915050565b600060208284031215610de757600080fd5b6000610df584828501610d3d565b91505092915050565b600060a08284031215610e1057600080fd5b6000610e1e84828501610d52565b91505092915050565b600060208284031215610e3957600080fd5b6000610e4784828501610d6d565b91505092915050565b600060208284031215610e6257600080fd5b6000610e7084828501610d82565b91505092915050565b600060208284031215610e8b57600080fd5b6000610e9984828501610d97565b91505092915050565b610eab816112c9565b82525050565b6000610ebc82611297565b610ec681856112ad565b9350610ed6818560208601611359565b80840191505092915050565b6000610eed826112a2565b610ef781856112b8565b9350610f07818560208601611359565b610f108161138c565b840191505092915050565b6000610f286022836112b8565b9150610f338261139d565b604082019050919050565b6000610f4b6026836112b8565b9150610f56826113ec565b604082019050919050565b6000610f6e6007836112b8565b9150610f798261143b565b602082019050919050565b6000610f91601d836112b8565b9150610f9c82611464565b602082019050919050565b6000610fb4602a836112b8565b9150610fbf8261148d565b604082019050919050565b6000610fd76036836112b8565b9150610fe2826114dc565b604082019050919050565b610ff681611307565b82525050565b61100581611335565b82525050565b61101481611311565b82525050565b61102381611347565b82525050565b61103281611321565b82525050565b60006110448284610eb1565b915081905092915050565b60006020820190506110646000830184610ea2565b92915050565b600060408201905061107f6000830185610ea2565b61108c6020830184610ea2565b9392505050565b60006060820190506110a86000830186610ea2565b6110b56020830185610ea2565b6110c26040830184610fed565b949350505050565b600060c0820190506110df6000830189610ea2565b6110ec6020830188610ea2565b6110f96040830187610fed565b6111066060830186611029565b6111136080830185611029565b61112060a083018461100b565b979650505050505050565b60006040820190506111406000830185610ea2565b61114d6020830184610fed565b9392505050565b6000602082019050818103600083015261116e8184610ee2565b905092915050565b6000602082019050818103600083015261118f81610f1b565b9050919050565b600060208201905081810360008301526111af81610f3e565b9050919050565b600060c08201905081810360008301526111cf81610f61565b90506111de6020830188610ea2565b6111eb6040830187610ea2565b6111f86060830186610ea2565b6112056080830185610fed565b61121260a083018461101a565b9695505050505050565b6000602082019050818103600083015261123581610f84565b9050919050565b6000602082019050818103600083015261125581610fa7565b9050919050565b6000602082019050818103600083015261127581610fca565b9050919050565b60006020820190506112916000830184610ffc565b92915050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60006112d4826112e7565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600067ffffffffffffffff82169050919050565b600061134082611311565b9050919050565b600061135282611321565b9050919050565b60005b8381101561137757808201518184015260208101905061135c565b83811115611386576000848401525b50505050565b6000601f19601f8301169050919050565b7f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f6362726964676500000000000000000000000000000000000000000000000000600082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000602082015250565b611534816112c9565b811461153f57600080fd5b50565b61154b816112db565b811461155657600080fd5b50565b61156281611307565b811461156d57600080fd5b50565b61157981611311565b811461158457600080fd5b50565b61159081611321565b811461159b57600080fd5b5056fea164736f6c6343000804000a", + "deployedBytecode": "0x60806040526004361061003f5760003560e01c806340d280a21461004457806352434c6e1461006d5780636f395e60146100895780639e32e2e6146100b2575b600080fd5b34801561005057600080fd5b5061006b60048036038101906100669190610dac565b6100db565b005b61008760048036038101906100829190610dfe565b610204565b005b34801561009557600080fd5b506100b060048036038101906100ab9190610dac565b6105f6565b005b3480156100be57600080fd5b506100d960048036038101906100d49190610e50565b6106ef565b005b6100e36107a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561014a576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061015461083d565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055504681600101819055506127108160020160006101000a81548163ffffffff021916908363ffffffff1602179055507fcbfd47a07530fc4fffba96f5686a7127e5661fe26dd01503239ca2f66fcad99082466040516101f892919061112b565b60405180910390a15050565b600061020e61086a565b905060018160000154141561024f576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816000018190555081600001602081019061026c9190610e79565b67ffffffffffffffff164614156102af576040517f4ac09ad300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168260600160208101906102da9190610dac565b73ffffffffffffffffffffffffffffffffffffffff161415610328576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826040013511610366576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168260800160208101906103919190610dac565b73ffffffffffffffffffffffffffffffffffffffff1614156103df576040517fdc2e5e8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103e961083d565b905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610457333086604001358760800160208101906104319190610dac565b73ffffffffffffffffffffffffffffffffffffffff16610897909392919063ffffffff16565b6104988185604001358660800160208101906104739190610dac565b73ffffffffffffffffffffffffffffffffffffffff166109209092919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff1663a5977fbb8560600160208101906104c79190610dac565b8660800160208101906104da9190610dac565b87604001358860000160208101906104f29190610e79565b8960200160208101906105059190610e79565b8860020160009054906101000a900463ffffffff166040518763ffffffff1660e01b815260040161053b969594939291906110ca565b600060405180830381600087803b15801561055557600080fd5b505af1158015610569573d6000803e3d6000fd5b505050507fd565a5cf794050de1a171170c91acd5d14cbf11877dc3fa020e9975495ab17578460800160208101906105a19190610dac565b338660600160208101906105b59190610dac565b87604001358860000160208101906105cd9190610e79565b6040516105de9594939291906111b6565b60405180910390a15050600081600001819055505050565b6105fe6107a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610665576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061066f61083d565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f4ae67faf3cf135d9eca1b5490d3613096d2d0610fca7496112fa46ef019fbd4e826040516106e3919061104f565b60405180910390a15050565b6113888163ffffffff1611610730576040517f9ff4125000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107386107a2565b600061074261083d565b9050818160020160006101000a81548163ffffffff021916908363ffffffff1602179055507f8d5e80c35df41e151b58f1a100ad605ae1ebcda3d0c329b22820b232767a773082604051610796919061127c565b60405180910390a15050565b6107aa610a7e565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461083b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083290611176565b60405180910390fd5b565b6000807f9d7253cc9498e9cc54011bbbe9471a68adbc99d0ac1eef42369f5a452e814c4a90508091505090565b6000807fc59b5acc5a6673a6c49ca2de898f87adbd9fdfdff36f689476b1c9e0c50964b490508091505090565b61091a846323b872dd60e01b8585856040516024016108b893929190611093565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610aab565b50505050565b60008114806109b9575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b815260040161096792919061106a565b60206040518083038186803b15801561097f57600080fd5b505afa158015610993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b79190610e27565b145b6109f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ef9061125c565b60405180910390fd5b610a798363095ea7b360e01b8484604051602401610a1792919061112b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610aab565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b6000610b0d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610b729092919063ffffffff16565b9050600081511115610b6d5780806020019051810190610b2d9190610dd5565b610b6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b639061123c565b60405180910390fd5b5b505050565b6060610b818484600085610b8a565b90509392505050565b606082471015610bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc690611196565b60405180910390fd5b610bd885610c9e565b610c17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0e9061121c565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610c409190611038565b60006040518083038185875af1925050503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b5091509150610c92828286610cc1565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315610cd157829050610d21565b600083511115610ce45782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d189190611154565b60405180910390fd5b9392505050565b600081359050610d378161152b565b92915050565b600081519050610d4c81611542565b92915050565b600060a08284031215610d6457600080fd5b81905092915050565b600081519050610d7c81611559565b92915050565b600081359050610d9181611570565b92915050565b600081359050610da681611587565b92915050565b600060208284031215610dbe57600080fd5b6000610dcc84828501610d28565b91505092915050565b600060208284031215610de757600080fd5b6000610df584828501610d3d565b91505092915050565b600060a08284031215610e1057600080fd5b6000610e1e84828501610d52565b91505092915050565b600060208284031215610e3957600080fd5b6000610e4784828501610d6d565b91505092915050565b600060208284031215610e6257600080fd5b6000610e7084828501610d82565b91505092915050565b600060208284031215610e8b57600080fd5b6000610e9984828501610d97565b91505092915050565b610eab816112c9565b82525050565b6000610ebc82611297565b610ec681856112ad565b9350610ed6818560208601611359565b80840191505092915050565b6000610eed826112a2565b610ef781856112b8565b9350610f07818560208601611359565b610f108161138c565b840191505092915050565b6000610f286022836112b8565b9150610f338261139d565b604082019050919050565b6000610f4b6026836112b8565b9150610f56826113ec565b604082019050919050565b6000610f6e6007836112b8565b9150610f798261143b565b602082019050919050565b6000610f91601d836112b8565b9150610f9c82611464565b602082019050919050565b6000610fb4602a836112b8565b9150610fbf8261148d565b604082019050919050565b6000610fd76036836112b8565b9150610fe2826114dc565b604082019050919050565b610ff681611307565b82525050565b61100581611335565b82525050565b61101481611311565b82525050565b61102381611347565b82525050565b61103281611321565b82525050565b60006110448284610eb1565b915081905092915050565b60006020820190506110646000830184610ea2565b92915050565b600060408201905061107f6000830185610ea2565b61108c6020830184610ea2565b9392505050565b60006060820190506110a86000830186610ea2565b6110b56020830185610ea2565b6110c26040830184610fed565b949350505050565b600060c0820190506110df6000830189610ea2565b6110ec6020830188610ea2565b6110f96040830187610fed565b6111066060830186611029565b6111136080830185611029565b61112060a083018461100b565b979650505050505050565b60006040820190506111406000830185610ea2565b61114d6020830184610fed565b9392505050565b6000602082019050818103600083015261116e8184610ee2565b905092915050565b6000602082019050818103600083015261118f81610f1b565b9050919050565b600060208201905081810360008301526111af81610f3e565b9050919050565b600060c08201905081810360008301526111cf81610f61565b90506111de6020830188610ea2565b6111eb6040830187610ea2565b6111f86060830186610ea2565b6112056080830185610fed565b61121260a083018461101a565b9695505050505050565b6000602082019050818103600083015261123581610f84565b9050919050565b6000602082019050818103600083015261125581610fa7565b9050919050565b6000602082019050818103600083015261127581610fca565b9050919050565b60006020820190506112916000830184610ffc565b92915050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60006112d4826112e7565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600067ffffffffffffffff82169050919050565b600061134082611311565b9050919050565b600061135282611321565b9050919050565b60005b8381101561137757808201518184015260208101905061135c565b83811115611386576000848401525b50505050565b6000601f19601f8301169050919050565b7f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f6362726964676500000000000000000000000000000000000000000000000000600082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000602082015250565b611534816112c9565b811461153f57600080fd5b50565b61154b816112db565b811461155657600080fd5b50565b61156281611307565b811461156d57600080fd5b50565b61157981611311565b811461158457600080fd5b50565b61159081611321565b811461159b57600080fd5b5056fea164736f6c6343000804000a", + "devdoc": { + "kind": "dev", + "methods": { + "cbBridgeTokens((uint64,uint64,uint256,address,address))": { + "params": { + "_cbData": ": provides necessary data for cBridge transfer" + } + }, + "cbInitialize(address)": { + "params": { + "_cbBridge": "address of the CBridge router contract" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "cbBridgeTokens((uint64,uint64,uint256,address,address))": { + "notice": "initiates token bridging" + }, + "cbInitialize(address)": { + "notice": "initializes state variables for the cBridge facet" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrumNitro/solcInputs/8d42885a5f19da22f710ffc8b637c191.json b/deployments/arbitrumNitro/solcInputs/8d42885a5f19da22f710ffc8b637c191.json new file mode 100644 index 00000000..edfd6042 --- /dev/null +++ b/deployments/arbitrumNitro/solcInputs/8d42885a5f19da22f710ffc8b637c191.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "src/bridges/facets/StargateFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.4;\n\nimport {IStargateRouter} from \"../interfaces/IStargateRouter.sol\";\nimport {IStargateReceiver} from \"../interfaces/IStargateReceiver.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {ReentrancyGuard} from \"../../common/helpers/DiamondReentrancyGuard.sol\";\nimport {CannotBridgeToSameNetwork, InvalidAmount, InvalidConfig} from \"../errors/GenericErrors.sol\";\nimport {SenderNotStargateRouter, NoMsgValueForCrossChainMessage, StargateRouterAddressZero, InvalidSourcePoolId, InvalidDestinationPoolId} from \"../errors/StargateErrors.sol\";\nimport {LibDiamond} from \"../libs/LibDiamond.sol\";\n\n/// @title StargateFacet\n/// @author Luke Wickens \n/// @notice Stargate/LayerZero intergration for bridging tokens\n\ncontract StargateFacet is IStargateReceiver, ReentrancyGuard {\n using SafeERC20 for IERC20;\n\n //////////////////////////////////////////////////////////////\n /////////////////////////// Events ///////////////////////////\n //////////////////////////////////////////////////////////////\n event SGInitialized(address stargate, uint16 chainId);\n event SGTransferStarted(\n string bridgeUsed,\n address fromToken,\n address toToken,\n address from,\n address to,\n uint256 amount,\n uint16 chainIdTo\n );\n event SGReceivedOnDestination(address token, uint256 amount);\n event SGUpdatedRouter(address newAddress);\n event SGUpdatedSlippageTolerance(uint256 newSlippage);\n event SGAddedPool(uint16 chainId, address token, uint16 poolId);\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Storage ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"io.etherspot.facets.stargate\");\n struct Storage {\n address stargateRouter;\n uint16 chainId;\n uint256 dstGas;\n uint256 slippage;\n mapping(uint16 => mapping(address => uint16)) poolIds;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Structs ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n struct StargateData {\n uint256 qty;\n address fromToken;\n address toToken;\n uint16 dstChainId;\n address to;\n address destStargateComposed;\n }\n\n /// @notice initializes state variables for the Stargate facet\n /// @param _stargateRouter - address of the Stargate router contract\n /// @param _chainId - current chain id\n function sgInitialize(address _stargateRouter, uint16 _chainId) external {\n if (_stargateRouter == address(0)) revert InvalidConfig();\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.stargateRouter = address(_stargateRouter);\n s.chainId = _chainId;\n s.slippage = 50; // equates to 0.5%\n // Adding pre-existing pools => USDC: 1, USDT: 2, BUSD: 5\n sgAddPool(1, 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, 1);\n sgAddPool(1, 0xdAC17F958D2ee523a2206206994597C13D831ec7, 2);\n sgAddPool(2, 0x55d398326f99059fF775485246999027B3197955, 2);\n sgAddPool(2, 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56, 5);\n sgAddPool(6, 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E, 1);\n sgAddPool(6, 0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7, 2);\n sgAddPool(9, 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174, 1);\n sgAddPool(9, 0xc2132D05D31c914a87C6611C10748AEb04B58e8F, 2);\n sgAddPool(10, 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8, 1);\n sgAddPool(10, 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9, 2);\n sgAddPool(11, 0x7F5c764cBc14f9669B88837ca1490cCa17c31607, 1);\n sgAddPool(12, 0x04068DA6C83AFCFA0e13ba15A6696662335D5B75, 1);\n emit SGInitialized(_stargateRouter, _chainId);\n }\n\n /// @notice initializes state variables for the stargate facet\n /// @param _sgData - struct containing information required to execute bridge\n function sgBridgeTokens(StargateData memory _sgData)\n external\n payable\n nonReentrant\n {\n // if (msg.value <= 0) revert NoMsgValueForCrossChainMessage();\n if (_sgData.qty <= 0) revert InvalidAmount();\n if (\n _sgData.fromToken == address(0) ||\n _sgData.toToken == address(0) ||\n _sgData.to == address(0) ||\n _sgData.destStargateComposed == address(0)\n ) revert InvalidConfig();\n\n // access storage\n Storage storage s = getStorage();\n\n // check pool ids are valid\n uint16 srcPoolId = sgRetrievePoolId(s.chainId, _sgData.fromToken);\n if (srcPoolId == 0) revert InvalidSourcePoolId();\n uint16 dstPoolId = sgRetrievePoolId(\n _sgData.dstChainId,\n _sgData.toToken\n );\n\n // calculate cross chain fees\n uint256 fees = sgCalculateFees(\n _sgData.dstChainId,\n _sgData.to,\n s.stargateRouter\n );\n\n // calculate slippage\n uint256 minAmountOut = sgMinAmountOut(_sgData.qty);\n\n // encode sgReceive implemented\n bytes memory destination = abi.encodePacked(\n _sgData.destStargateComposed\n );\n\n // encode payload data to send to destination contract, which it will handle with sgReceive()\n bytes memory payload = abi.encode(_sgData.to);\n\n // this contract calls stargate swap()\n IERC20(_sgData.fromToken).safeTransferFrom(\n msg.sender,\n address(this),\n _sgData.qty\n );\n\n IERC20(_sgData.fromToken).safeApprove(\n address(s.stargateRouter),\n _sgData.qty\n );\n\n // Stargate's Router.swap() function sends the tokens to the destination chain.\n IStargateRouter(s.stargateRouter).swap{value: fees}(\n _sgData.dstChainId, // the destination chain id\n srcPoolId, // the source Stargate poolId\n dstPoolId, // the destination Stargate poolId\n payable(msg.sender), // refund adddress. if msg.sender pays too much gas, return extra eth\n _sgData.qty, // total tokens to send to destination chain\n minAmountOut, // min amount allowed out\n IStargateRouter.lzTxObj(200000, 0, \"0x\"), // default lzTxObj\n destination, // destination address, the sgReceive() implementer\n payload // bytes payload\n );\n\n emit SGTransferStarted(\n \"stargate\",\n _sgData.fromToken,\n _sgData.toToken,\n msg.sender,\n _sgData.to,\n _sgData.qty,\n _sgData.dstChainId\n );\n }\n\n /// @notice required to receive tokens on destination chain\n /// @param _chainId The remote chainId sending the tokens\n /// @param _srcAddress The remote Bridge address\n /// @param _nonce The message ordering nonce\n /// @param _token The token contract on the local chain\n /// @param amountLD The qty of local _token contract tokens\n /// @param _payload The bytes containing the toAddress\n function sgReceive(\n uint16 _chainId,\n bytes memory _srcAddress,\n uint256 _nonce,\n address _token,\n uint256 amountLD,\n bytes memory _payload\n ) external override {\n Storage storage s = getStorage();\n if (msg.sender != address(s.stargateRouter))\n revert SenderNotStargateRouter();\n\n address _toAddr = abi.decode(_payload, (address));\n IERC20(_token).transfer(_toAddr, amountLD);\n emit SGReceivedOnDestination(_token, amountLD);\n }\n\n /// @notice Calculates cross chain fee\n /// @param _destChain Destination chain id\n /// @param _receiver Receiver on destination chain\n /// @param _router Address of stargate router\n function sgCalculateFees(\n uint16 _destChain,\n address _receiver,\n address _router\n ) public view returns (uint256) {\n (uint256 nativeFee, ) = IStargateRouter(_router).quoteLayerZeroFee(\n _destChain, // destination chain id\n 1, // 1 = swap\n abi.encodePacked(_receiver), // receiver on destination chain\n \"0x\", // payload, using abi.encode()\n IStargateRouter.lzTxObj(200000, 0, \"0x\")\n );\n return nativeFee;\n }\n\n /// @notice Calculates the minimum amount out using slippage tolerance\n /// @param _amount Transfer amount\n function sgMinAmountOut(uint256 _amount) public view returns (uint256) {\n Storage storage s = getStorage();\n // equates to 0.5% slippage\n return (_amount * (10000 - s.slippage)) / (10000);\n }\n\n /// @notice Updates stargate router address for deployed chain\n /// @param _newAddress Address of the new router\n function sgUpdateRouter(address _newAddress) external {\n LibDiamond.enforceIsContractOwner();\n if (_newAddress == address(0)) revert StargateRouterAddressZero();\n Storage storage s = getStorage();\n s.stargateRouter = address(_newAddress);\n emit SGUpdatedRouter(_newAddress);\n }\n\n /// @notice Updates slippage tolerance amount\n /// @param _newSlippage New slippage amount\n function sgUpdateSlippageTolerance(uint256 _newSlippage) external {\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.slippage = _newSlippage;\n emit SGUpdatedSlippageTolerance(_newSlippage);\n }\n\n /// @notice Adds a new pool for a specific token and chain\n /// @param _chainId Chain id of new pool (NOT actual chain id - check stargate pool ids docs)\n /// @param _token Address of token\n /// @param _poolId Pool id (check stargate pool ids docs)\n function sgAddPool(\n uint16 _chainId,\n address _token,\n uint16 _poolId\n ) public {\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.poolIds[_chainId][_token] = _poolId;\n emit SGAddedPool(_chainId, _token, _poolId);\n }\n\n /// @notice Checks for a valid token pool on specific chain\n /// @param _chainId Chain id of new pool (NOT actual chain id - check stargate pool ids docs)\n /// @param _token Address of token\n /// @param _poolId Pool id (check stargate pool ids docs)\n function sgCheckPoolId(\n uint16 _chainId,\n address _token,\n uint16 _poolId\n ) external view returns (bool) {\n Storage storage s = getStorage();\n return s.poolIds[_chainId][_token] == _poolId ? true : false;\n }\n\n /// @notice Retrieves pool id for a token on a specified chain\n /// @param _chainId Chain id of new pool (NOT actual chain id - check stargate pool ids docs)\n /// @param _token Address of token\n function sgRetrievePoolId(uint16 _chainId, address _token)\n public\n view\n returns (uint16)\n {\n Storage storage s = getStorage();\n return s.poolIds[_chainId][_token];\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////// Private Functions /////////////////////\n //////////////////////////////////////////////////////////////\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/bridges/interfaces/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier:MIT\n\npragma solidity 0.8.4;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function addLiquidity(\n uint256 _poolId,\n uint256 _amountLD,\n address _to\n ) external;\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n\n function redeemRemote(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLP,\n uint256 _minAmountLD,\n bytes calldata _to,\n lzTxObj memory _lzTxParams\n ) external payable;\n\n function instantRedeemLocal(\n uint16 _srcPoolId,\n uint256 _amountLP,\n address _to\n ) external returns (uint256);\n\n function redeemLocal(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLP,\n bytes calldata _to,\n lzTxObj memory _lzTxParams\n ) external payable;\n\n function sendCredits(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress\n ) external payable;\n\n function quoteLayerZeroFee(\n uint16 _dstChainId,\n uint8 _functionType,\n bytes calldata _toAddress,\n bytes calldata _transferAndCallPayload,\n lzTxObj memory _lzTxParams\n ) external view returns (uint256, uint256);\n}\n" + }, + "src/bridges/interfaces/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.4;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "src/common/helpers/DiamondReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.4;\n\n/// @title Reentrancy Guard\n/// @notice Abstract contract to provide protection against reentrancy\nabstract contract ReentrancyGuard {\n //////////////////////////////////////////////////////////////\n ////////////////////////// Storage ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n bytes32 private constant NAMESPACE =\n keccak256(\"io.etherspot.helpers.reentrancyguard\");\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Structs ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n struct ReentrancyStorage {\n uint256 status;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Errors ////////////////////////////\n //////////////////////////////////////////////////////////////\n\n error ReentrancyError();\n\n //////////////////////////////////////////////////////////////\n ///////////////////////// Constants //////////////////////////\n //////////////////////////////////////////////////////////////\n\n uint256 private constant _NOT_ENTERED = 0;\n uint256 private constant _ENTERED = 1;\n\n //////////////////////////////////////////////////////////////\n ///////////////////////// Modifiers ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n modifier nonReentrant() {\n ReentrancyStorage storage s = reentrancyStorage();\n if (s.status == _ENTERED) revert ReentrancyError();\n s.status = _ENTERED;\n _;\n s.status = _NOT_ENTERED;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////// Private Functions /////////////////////\n //////////////////////////////////////////////////////////////\n\n /// @dev fetch local storage\n function reentrancyStorage()\n private\n pure\n returns (ReentrancyStorage storage data)\n {\n bytes32 position = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n data.slot := position\n }\n }\n}\n" + }, + "src/bridges/errors/GenericErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\nerror InvalidAmount();\nerror TokenAddressIsZero();\nerror CannotBridgeToSameNetwork();\nerror ZeroPostSwapBalance();\nerror InvalidBridgeConfigLength();\nerror NoSwapDataProvided();\nerror NativeValueWithERC();\nerror ContractCallNotAllowed();\nerror NullAddrIsNotAValidSpender();\nerror NullAddrIsNotAnERC20Token();\nerror NoTransferToNullAddress();\nerror NativeAssetTransferFailed();\nerror InvalidContract();\nerror InvalidConfig();\nerror ZeroAddressProvided();\n" + }, + "src/bridges/errors/StargateErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\nerror SenderNotStargateRouter();\nerror NoMsgValueForCrossChainMessage();\nerror StargateRouterAddressZero();\nerror InvalidSourcePoolId();\nerror InvalidDestinationPoolId();\n" + }, + "src/bridges/libs/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\nlibrary LibDiamond {\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\n keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(\n msg.sender == diamondStorage().contractOwner,\n \"LibDiamond: Must be contract owner\"\n );\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n require(\n _functionSelectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n require(\n _functionSelectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n require(\n _functionSelectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress)\n internal\n {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata)\n internal\n {\n if (_init == address(0)) {\n require(\n _calldata.length == 0,\n \"LibDiamondCut: _init is address(0) but_calldata is not empty\"\n );\n } else {\n require(\n _calldata.length > 0,\n \"LibDiamondCut: _calldata is empty but _init is not address(0)\"\n );\n if (_init != address(this)) {\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n }\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "src/bridges/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "src/bridges/libs/LibAsset.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\n// solhint-disable-next-line\npragma solidity 0.8.4;\nimport {NullAddrIsNotAnERC20Token, NullAddrIsNotAValidSpender, NoTransferToNullAddress, InvalidAmount, NativeValueWithERC, NativeAssetTransferFailed} from \"../errors/GenericErrors.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title LibAsset\n/// @author Connext \n/// @notice This library contains helpers for dealing with onchain transfers\n/// of assets, including accounting for the native asset `assetId`\n/// conventions and any noncompliant ERC20 transfers\nlibrary LibAsset {\n uint256 private constant MAX_INT = type(uint256).max;\n\n address internal constant NULL_ADDRESS =\n 0x0000000000000000000000000000000000000000; //address(0)\n\n /// @dev All native assets use the empty address for their asset id\n /// by convention\n\n address internal constant NATIVE_ASSETID = NULL_ADDRESS; //address(0)\n\n /// @notice Gets the balance of the inheriting contract for the given asset\n /// @param assetId The asset identifier to get the balance of\n /// @return Balance held by contracts using this library\n function getOwnBalance(address assetId) internal view returns (uint256) {\n return\n assetId == NATIVE_ASSETID\n ? address(this).balance\n : IERC20(assetId).balanceOf(address(this));\n }\n\n /// @notice Transfers ether from the inheriting contract to a given\n /// recipient\n /// @param recipient Address to send ether to\n /// @param amount Amount to send to given recipient\n function transferNativeAsset(address payable recipient, uint256 amount)\n private\n {\n if (recipient == NULL_ADDRESS) revert NoTransferToNullAddress();\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = recipient.call{value: amount}(\"\");\n if (!success) revert NativeAssetTransferFailed();\n }\n\n /// @notice Gives MAX approval for another address to spend tokens\n /// @param assetId Token address to transfer\n /// @param spender Address to give spend approval to\n /// @param amount Amount to approve for spending\n function maxApproveERC20(\n IERC20 assetId,\n address spender,\n uint256 amount\n ) internal {\n if (address(assetId) == NATIVE_ASSETID) return;\n if (spender == NULL_ADDRESS) revert NullAddrIsNotAValidSpender();\n uint256 allowance = assetId.allowance(address(this), spender);\n if (allowance < amount)\n SafeERC20.safeApprove(IERC20(assetId), spender, MAX_INT);\n }\n\n /// @notice Transfers tokens from the inheriting contract to a given\n /// recipient\n /// @param assetId Token address to transfer\n /// @param recipient Address to send token to\n /// @param amount Amount to send to given recipient\n function transferERC20(\n address assetId,\n address recipient,\n uint256 amount\n ) private {\n if (isNativeAsset(assetId)) revert NullAddrIsNotAnERC20Token();\n SafeERC20.safeTransfer(IERC20(assetId), recipient, amount);\n }\n\n /// @notice Transfers tokens from a sender to a given recipient\n /// @param assetId Token address to transfer\n /// @param from Address of sender/owner\n /// @param to Address of recipient/spender\n /// @param amount Amount to transfer from owner to spender\n function transferFromERC20(\n address assetId,\n address from,\n address to,\n uint256 amount\n ) internal {\n if (assetId == NATIVE_ASSETID) revert NullAddrIsNotAnERC20Token();\n if (to == NULL_ADDRESS) revert NoTransferToNullAddress();\n SafeERC20.safeTransferFrom(IERC20(assetId), from, to, amount);\n }\n\n /// @notice Deposits an asset into the contract and performs checks to avoid NativeValueWithERC\n /// @param tokenId Token to deposit\n /// @param amount Amount to deposit\n /// @param isNative Wether the token is native or ERC20\n function depositAsset(\n address tokenId,\n uint256 amount,\n bool isNative\n ) internal {\n if (amount == 0) revert InvalidAmount();\n if (isNative) {\n if (msg.value != amount) revert InvalidAmount();\n } else {\n if (msg.value != 0) revert NativeValueWithERC();\n uint256 _fromTokenBalance = LibAsset.getOwnBalance(tokenId);\n LibAsset.transferFromERC20(\n tokenId,\n msg.sender,\n address(this),\n amount\n );\n if (LibAsset.getOwnBalance(tokenId) - _fromTokenBalance != amount)\n revert InvalidAmount();\n }\n }\n\n /// @notice Overload for depositAsset(address tokenId, uint256 amount, bool isNative)\n /// @param tokenId Token to deposit\n /// @param amount Amount to deposit\n function depositAsset(address tokenId, uint256 amount) internal {\n return depositAsset(tokenId, amount, tokenId == NATIVE_ASSETID);\n }\n\n /// @notice Determines whether the given assetId is the native asset\n /// @param assetId The asset identifier to evaluate\n /// @return Boolean indicating if the asset is the native asset\n function isNativeAsset(address assetId) internal pure returns (bool) {\n return assetId == NATIVE_ASSETID;\n }\n\n /// @notice Wrapper function to transfer a given asset (native or erc20) to\n /// some recipient. Should handle all non-compliant return value\n /// tokens as well by using the SafeERC20 contract by open zeppelin.\n /// @param assetId Asset id for transfer (address(0) for native asset,\n /// token address for erc20s)\n /// @param recipient Address to send asset to\n /// @param amount Amount to send to given recipient\n function transferAsset(\n address assetId,\n address payable recipient,\n uint256 amount\n ) internal {\n (assetId == NATIVE_ASSETID)\n ? transferNativeAsset(recipient, amount)\n : transferERC20(assetId, recipient, amount);\n }\n\n /// @dev Checks whether the given address is a contract and contains code\n function isContract(address _contractAddr) internal view returns (bool) {\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n size := extcodesize(_contractAddr)\n }\n return size > 0;\n }\n}\n" + }, + "src/bridges/facets/CBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\n/// @title CBridgeFacet\n/// @author Luke Wickens \n/// @notice cBridge intergration for bridging tokens\n\nimport {ICBridge} from \"../interfaces/ICBridge.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {ReentrancyGuard} from \"../../common/helpers/DiamondReentrancyGuard.sol\";\nimport {CannotBridgeToSameNetwork, InvalidAmount, InvalidConfig, TokenAddressIsZero, ZeroAddressProvided} from \"../errors/GenericErrors.sol\";\nimport {CBSlippageTooLow} from \"../errors/CBridgeErrors.sol\";\nimport {LibDiamond} from \"../libs/LibDiamond.sol\";\n\ncontract CBridgeFacet is ReentrancyGuard {\n using SafeERC20 for IERC20;\n //////////////////////////////////////////////////////////////\n /////////////////////////// Events ///////////////////////////\n //////////////////////////////////////////////////////////////\n event CBInitialized(address cBridge, uint256 chainId);\n event CBTransferStarted(\n string bridgeUsed,\n address token,\n address from,\n address to,\n uint256 qty,\n uint256 chainIdTo\n );\n event CBUpdatedBridge(address newAddress);\n event CBUpdatedSlippageTolerance(uint256 newSlippage);\n //////////////////////////////////////////////////////////////\n ////////////////////////// Storage ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"io.etherspot.facets.cbridge\");\n struct Storage {\n address cbBridge;\n uint256 cbChainId;\n uint32 cbSlippage;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Structs ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n struct CBridgeData {\n uint64 dstChainId;\n uint64 nonce;\n uint256 qty;\n address to;\n address token;\n }\n\n /// @notice initializes state variables for the cBridge facet\n /// @param _cbBridge address of the CBridge router contract\n function cbInitialize(address _cbBridge) external {\n LibDiamond.enforceIsContractOwner();\n if (_cbBridge == address(0)) revert ZeroAddressProvided();\n Storage storage s = getStorage();\n s.cbBridge = _cbBridge;\n s.cbChainId = block.chainid;\n s.cbSlippage = 10000; // equates to 1% - has to be > 0.5% (slippage * 1M)\n emit CBInitialized(_cbBridge, block.chainid);\n }\n\n /// @notice initiates token bridging\n /// @param _cbData: provides necessary data for cBridge transfer\n\n function cbBridgeTokens(CBridgeData calldata _cbData)\n external\n payable\n nonReentrant\n {\n if (block.chainid == _cbData.dstChainId)\n revert CannotBridgeToSameNetwork();\n if (_cbData.to == address(0)) revert ZeroAddressProvided();\n if (_cbData.qty <= 0) revert InvalidAmount();\n if (_cbData.token == address(0)) revert TokenAddressIsZero();\n\n Storage storage s = getStorage();\n address bridge = s.cbBridge;\n\n // this contract calls stargate swap()\n IERC20(_cbData.token).safeTransferFrom(\n msg.sender,\n address(this),\n _cbData.qty\n );\n IERC20(_cbData.token).safeApprove(address(bridge), _cbData.qty);\n\n ICBridge(bridge).send(\n _cbData.to,\n _cbData.token,\n _cbData.qty,\n _cbData.dstChainId,\n _cbData.nonce,\n s.cbSlippage\n );\n\n emit CBTransferStarted(\n \"cbridge\",\n _cbData.token,\n msg.sender,\n _cbData.to,\n _cbData.qty,\n _cbData.dstChainId\n );\n }\n\n function cbUpdateSlippageTolerance(uint32 _newSlippage) external {\n // should be > 0.5% (5000)\n if (_newSlippage <= 5000) revert CBSlippageTooLow();\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.cbSlippage = _newSlippage;\n emit CBUpdatedSlippageTolerance(_newSlippage);\n }\n\n function cbUpdateBridge(address _newAddress) external {\n LibDiamond.enforceIsContractOwner();\n if (_newAddress == address(0)) revert ZeroAddressProvided();\n Storage storage s = getStorage();\n s.cbBridge = _newAddress;\n emit CBUpdatedBridge(_newAddress);\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////// Private Functions /////////////////////\n //////////////////////////////////////////////////////////////\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/bridges/interfaces/ICBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\ninterface ICBridge {\n function send(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChinId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external;\n\n function sendNative(\n address _receiver,\n uint256 _amount,\n uint64 _dstChinId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external payable;\n\n function relay(\n bytes calldata _relayRequest,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external;\n}\n" + }, + "src/bridges/errors/CBridgeErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\nerror CBSlippageTooLow();\n" + }, + "src/bridges/facets/HopFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.4;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { IHopBridge } from \"../interfaces/IHopBridge.sol\";\nimport { LibAsset } from \"../libs/LibAsset.sol\";\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\nimport { ReentrancyGuard } from \"../../common/helpers/DiamondReentrancyGuard.sol\";\nimport {\n InvalidAmount,\n InvalidBridgeConfigLength,\n CannotBridgeToSameNetwork,\n NativeValueWithERC,\n InvalidConfig\n} from \"../errors/GenericErrors.sol\";\n\n/**\n * @title Hop Protocol Integration\n *\n * @notice Contract which provides bridging functionality through Hop Protocol\n *\n */\ncontract HopFacet is ReentrancyGuard {\n // storage\n\n bytes32 internal constant NAMESPACE = keccak256(\"io.etherspot.facets.hop\");\n struct Storage {\n uint256 chainLayerId;\n }\n\n // types\n\n struct HopData {\n address bridge;\n address ammWrapper;\n address asset;\n address recipient;\n uint256 chainId;\n uint256 amount;\n uint256 bonderFee;\n uint256 amountOutMin;\n uint256 deadline;\n uint256 destinationAmountOutMin;\n uint256 destinationDeadline;\n }\n\n // events\n\n /**\n * @dev Emitted when facet initializes\n * @param chainId current chain id\n * @param chainLayerId current chain layer id\n */\n event HopInitialized(\n uint256 chainId,\n uint256 chainLayerId\n );\n\n /**\n * @dev Emitted on token swap\n * @param _destination destination chain id\n * @param _bridge address of the bridge on chain _destination,\n * @param _ammWrapper address of the amm wrapper,\n * @param _recipient recipient\n * @param _asset address of the asset\n * @param _amount amount of assets\n * @param _bonderFee fee\n * @param _amountOutMin The minimum amount received after attempting to\n * swap in the destination\n * @param _deadline The deadline for swapping in the destination AMM market.\n * 0 if no * swap is intended.\n * @param _destinationAmountOutMin The minimum amount of tokens to receive after bridging\n * @param _destinationDeadline The time the transaction must be completed\n */\n event HopTokenSwap(\n uint256 indexed _destination,\n address _bridge,\n address _ammWrapper,\n address indexed _recipient,\n address indexed _asset,\n uint256 _amount,\n uint256 _bonderFee,\n uint256 _amountOutMin,\n uint256 _deadline,\n uint256 _destinationAmountOutMin,\n uint256 _destinationDeadline\n );\n\n\n\n // external functions\n\n /**\n * @notice Initializes local variables for the Connext facet\n */\n function initHop(uint256 _chainLayerId) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n s.chainLayerId = _chainLayerId;\n\n emit HopInitialized(\n getChainID(),\n _chainLayerId\n );\n }\n\n /**\n * @notice Bridges tokens via Hop Protocol\n * @param _hopData data specific to Hop Protocol\n */\n function hopTokenTransfer(\n HopData calldata _hopData\n ) external payable nonReentrant {\n LibAsset.depositAsset(_hopData.asset, _hopData.amount);\n\n address bridge;\n if (getLayerId() == 1) {\n bridge = _hopData.bridge;\n } else {\n bridge = _hopData.ammWrapper;\n }\n\n if (getChainID() == _hopData.chainId)\n revert CannotBridgeToSameNetwork();\n\n // Give Hop approval to bridge tokens\n LibAsset.maxApproveERC20(\n IERC20(_hopData.asset),\n bridge,\n _hopData.amount\n );\n\n uint256 value = LibAsset.isNativeAsset(_hopData.asset)\n ? _hopData.amount\n : 0;\n\n if (getLayerId() == 1) {\n // Ethereum L1\n IHopBridge(bridge).sendToL2{value: value}(\n _hopData.chainId,\n _hopData.recipient,\n _hopData.amount,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline,\n address(0),\n 0\n );\n } else {\n // L2\n IHopBridge(bridge).swapAndSend{value: value}(\n _hopData.chainId,\n _hopData.recipient,\n _hopData.amount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n }\n emit HopTokenSwap(\n _hopData.chainId,\n _hopData.bridge,\n _hopData.ammWrapper,\n _hopData.recipient,\n _hopData.asset,\n _hopData.amount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n }\n\n /// private Methods ///\n\n /**\n * @dev returns local storage\n */\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n\n /**\n * @dev returns current chain layer number\n * @return uint256 layer number\n */\n function getLayerId() private view returns (uint256) {\n return getStorage().chainLayerId;\n }\n\n /**\n * @dev fetch chain id\n */\n function getChainID() private view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n}\n" + }, + "src/bridges/interfaces/IHopBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.4;\n\ninterface IHopBridge {\n function sendToL2(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 amountOutMin,\n uint256 deadline,\n address relayer,\n uint256 relayerFee\n ) external payable;\n\n function swapAndSend(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 deadline,\n uint256 destinationAmountOutMin,\n uint256 destinationDeadline\n ) external payable;\n}\n" + } + }, + "settings": { + "evmVersion": "istanbul", + "metadata": { + "bytecodeHash": "none", + "useLiteralContent": true + }, + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/.chainId b/deployments/neonDevnet/.chainId new file mode 100644 index 00000000..e752c50f --- /dev/null +++ b/deployments/neonDevnet/.chainId @@ -0,0 +1 @@ +245022926 \ No newline at end of file diff --git a/deployments/neonDevnet/BalancesHelper.json b/deployments/neonDevnet/BalancesHelper.json new file mode 100644 index 00000000..85107924 --- /dev/null +++ b/deployments/neonDevnet/BalancesHelper.json @@ -0,0 +1,81 @@ +{ + "address": "0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b", + "abi": [ + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getBalances", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x154f16bb095d820f6e20d631b2e7df8d0e3f1a82732e4ea463b5584cbb37ecd9", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "28969680", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x483c0623530c29e53fc4515f604af3512f1ce74497a8bab65e23827992fff04a", + "transactionHash": "0x154f16bb095d820f6e20d631b2e7df8d0e3f1a82732e4ea463b5584cbb37ecd9", + "logs": [], + "blockNumber": 173996669, + "cumulativeGasUsed": "28969680", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getBalances\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Jegor Sidorenko Stanis\\u0142aw G\\u0142ogowski \",\"kind\":\"dev\",\"methods\":{\"getBalances(address[],address[])\":{\"details\":\"Pass 0x0 as a \\\"token\\\" address to get ETH balance. Possible error throws: - extremely large arrays for account and or tokens (gas cost too high)\",\"params\":{\"accounts\":\"array of accounts addresses\",\"tokens\":\"array of tokens addresses\"},\"returns\":{\"_0\":\"a one-dimensional that's user.length * tokens.length long. The array is ordered by all of the 0th accounts token balances, then the 1th user, and so on.\"}}},\"title\":\"Balances helper\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getBalances(address[],address[])\":{\"notice\":\"Checks the token balances of accounts for multiple tokens.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/common/helpers/BalancesHelper.sol\":\"BalancesHelper\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/helpers/BalancesHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../token/ERC20Token.sol\\\";\\nimport \\\"../libs/SafeMathLib.sol\\\";\\n\\n\\n/**\\n * @title Balances helper\\n *\\n * @author Jegor Sidorenko \\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract BalancesHelper {\\n using SafeMathLib for uint256;\\n\\n // external functions\\n\\n /**\\n * @notice Checks the token balances of accounts for multiple tokens.\\n * @dev Pass 0x0 as a \\\"token\\\" address to get ETH balance.\\n *\\n * Possible error throws:\\n * - extremely large arrays for account and or tokens (gas cost too high)\\n *\\n * @param accounts array of accounts addresses\\n * @param tokens array of tokens addresses\\n * @return a one-dimensional that's user.length * tokens.length long. The\\n * array is ordered by all of the 0th accounts token balances, then the 1th\\n * user, and so on.\\n */\\n function getBalances(\\n address[] calldata accounts,\\n address[] calldata tokens\\n )\\n external\\n view\\n returns (uint[] memory)\\n {\\n uint[] memory result = new uint[](accounts.length.mul(tokens.length));\\n\\n for (uint i = 0; i < accounts.length; i++) {\\n for (uint j = 0; j < tokens.length; j++) {\\n uint index = j.add(tokens.length.mul(i));\\n\\n if (tokens[j] != address(0x0)) {\\n result[index] = _getBalance(accounts[i], tokens[j]);\\n } else {\\n result[index] = accounts[i].balance;\\n }\\n }\\n }\\n\\n return result;\\n }\\n\\n // private functions\\n\\n function _getBalance(\\n address account,\\n address token\\n )\\n private\\n view\\n returns (uint256)\\n {\\n uint256 result = 0;\\n uint256 tokenCode;\\n\\n /// @dev check if token is actually a contract\\n // solhint-disable-next-line no-inline-assembly\\n assembly { tokenCode := extcodesize(token) } // contract code size\\n\\n if (tokenCode > 0) {\\n /// @dev is it a contract and does it implement balanceOf\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool methodExists,) = token.staticcall(abi.encodeWithSelector(\\n ERC20Token(token).balanceOf.selector,\\n account\\n ));\\n\\n if (methodExists) {\\n result = ERC20Token(token).balanceOf(account);\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x76a5729807b8581731967ea74fc5e16a2c5c9067457c9059da97f089ffff68b9\",\"license\":\"MIT\"},\"src/common/libs/SafeMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Safe math library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol\\n */\\nlibrary SafeMathLib {\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n\\n require(c >= a, \\\"SafeMathLib: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMathLib: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n\\n return a - b;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n\\n require(c / a == b, \\\"SafeMathLib: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMathLib: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n\\n return a / b;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMathLib: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x6089f354ca754d9c5dd9e800ee5ed86717dbf8f9af470604e0be691ac57c0107\",\"license\":\"MIT\"},\"src/common/token/ERC20Token.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/SafeMathLib.sol\\\";\\n\\n\\n/**\\n * @title ERC20 token\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol\\n */\\ncontract ERC20Token {\\n using SafeMathLib for uint256;\\n\\n string public name;\\n string public symbol;\\n uint8 public decimals;\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) internal balances;\\n mapping(address => mapping(address => uint256)) internal allowances;\\n\\n // events\\n\\n event Transfer(\\n address indexed from,\\n address indexed to,\\n uint256 value\\n );\\n\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // external functions\\n\\n function transfer(\\n address to,\\n uint256 value\\n )\\n external\\n returns (bool)\\n {\\n _transfer(_getSender(), to, value);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n address sender = _getSender();\\n\\n _transfer(from, to, value);\\n _approve(from, sender, allowances[from][sender].sub(value));\\n\\n return true;\\n }\\n\\n function approve(\\n address spender,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n _approve(_getSender(), spender, value);\\n\\n return true;\\n }\\n\\n // external functions (views)\\n\\n function balanceOf(\\n address owner\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return balances[owner];\\n }\\n\\n function allowance(\\n address owner,\\n address spender\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return allowances[owner][spender];\\n }\\n\\n // internal functions\\n\\n function _transfer(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n from != address(0),\\n \\\"ERC20Token: cannot transfer from 0x0 address\\\"\\n );\\n require(\\n to != address(0),\\n \\\"ERC20Token: cannot transfer to 0x0 address\\\"\\n );\\n\\n balances[from] = balances[from].sub(value);\\n balances[to] = balances[to].add(value);\\n\\n emit Transfer(from, to, value);\\n }\\n\\n function _approve(\\n address owner,\\n address spender,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot approve from 0x0 address\\\"\\n );\\n require(\\n spender != address(0),\\n \\\"ERC20Token: cannot approve to 0x0 address\\\"\\n );\\n\\n allowances[owner][spender] = value;\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function _mint(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot mint to 0x0 address\\\"\\n );\\n require(\\n value > 0,\\n \\\"ERC20Token: cannot mint 0 value\\\"\\n );\\n\\n balances[owner] = balances[owner].add(value);\\n totalSupply = totalSupply.add(value);\\n\\n emit Transfer(address(0), owner, value);\\n }\\n\\n function _burn(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot burn from 0x0 address\\\"\\n );\\n\\n balances[owner] = balances[owner].sub(\\n value,\\n \\\"ERC20Token: burn value exceeds balance\\\"\\n );\\n\\n totalSupply = totalSupply.sub(value);\\n\\n emit Transfer(owner, address(0), value);\\n }\\n\\n // internal functions (views)\\n\\n function _getSender()\\n virtual\\n internal\\n view\\n returns (address)\\n {\\n return msg.sender;\\n }\\n}\\n\",\"keccak256\":\"0x6f2b0bd08da549c6c1f5ceee85766832d587dde62c56bebc3a14bd9ea407e03d\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506106a2806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ef5bfc3714610030575b600080fd5b6100fc6004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184602083028401116401000000008311171561009757600080fd5b9091929391929390803590602001906401000000008111156100b857600080fd5b8201836020820111156100ca57600080fd5b803590602001918460208302840111640100000000831117156100ec57600080fd5b9091929391929390505050610153565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561013f578082015181840152602081019050610124565b505050509050019250505060405180910390f35b60608061016f848490508787905061035490919063ffffffff16565b67ffffffffffffffff8111801561018557600080fd5b506040519080825280602002602001820160405280156101b45781602001602082028036833780820191505090505b50905060005b868690508110156103475760005b858590508110156103395760006101fd6101ee848989905061035490919063ffffffff16565b836103da90919063ffffffff16565b9050600073ffffffffffffffffffffffffffffffffffffffff1687878481811061022357fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146102d2576102b589898581811061026a57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1688888581811061029357fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16610462565b8482815181106102c157fe5b60200260200101818152505061032b565b8888848181106102de57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163184828151811061031e57fe5b6020026020010181815250505b5080806001019150506101c8565b5080806001019150506101ba565b5080915050949350505050565b60008083141561036757600090506103d4565b600082840290508284828161037857fe5b04146103cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806106726024913960400191505060405180910390fd5b809150505b92915050565b600080828401905083811015610458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174684c69623a206164646974696f6e206f766572666c6f77000081525060200191505060405180910390fd5b8091505092915050565b600080600090506000833b905060008111156106665760008473ffffffffffffffffffffffffffffffffffffffff166370a0823160e01b87604051602401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310610550578051825260208201915060208101905060208303925061052d565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146105b0576040519150601f19603f3d011682016040523d82523d6000602084013e6105b5565b606091505b505090508015610664578473ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561062657600080fd5b505afa15801561063a573d6000803e3d6000fd5b505050506040513d602081101561065057600080fd5b810190808051906020019092919050505092505b505b81925050509291505056fe536166654d6174684c69623a206d756c7469706c69636174696f6e206f766572666c6f77a164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ef5bfc3714610030575b600080fd5b6100fc6004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184602083028401116401000000008311171561009757600080fd5b9091929391929390803590602001906401000000008111156100b857600080fd5b8201836020820111156100ca57600080fd5b803590602001918460208302840111640100000000831117156100ec57600080fd5b9091929391929390505050610153565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561013f578082015181840152602081019050610124565b505050509050019250505060405180910390f35b60608061016f848490508787905061035490919063ffffffff16565b67ffffffffffffffff8111801561018557600080fd5b506040519080825280602002602001820160405280156101b45781602001602082028036833780820191505090505b50905060005b868690508110156103475760005b858590508110156103395760006101fd6101ee848989905061035490919063ffffffff16565b836103da90919063ffffffff16565b9050600073ffffffffffffffffffffffffffffffffffffffff1687878481811061022357fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146102d2576102b589898581811061026a57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1688888581811061029357fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16610462565b8482815181106102c157fe5b60200260200101818152505061032b565b8888848181106102de57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163184828151811061031e57fe5b6020026020010181815250505b5080806001019150506101c8565b5080806001019150506101ba565b5080915050949350505050565b60008083141561036757600090506103d4565b600082840290508284828161037857fe5b04146103cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806106726024913960400191505060405180910390fd5b809150505b92915050565b600080828401905083811015610458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174684c69623a206164646974696f6e206f766572666c6f77000081525060200191505060405180910390fd5b8091505092915050565b600080600090506000833b905060008111156106665760008473ffffffffffffffffffffffffffffffffffffffff166370a0823160e01b87604051602401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310610550578051825260208201915060208101905060208303925061052d565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146105b0576040519150601f19603f3d011682016040523d82523d6000602084013e6105b5565b606091505b505090508015610664578473ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561062657600080fd5b505afa15801561063a573d6000803e3d6000fd5b505050506040513d602081101561065057600080fd5b810190808051906020019092919050505092505b505b81925050509291505056fe536166654d6174684c69623a206d756c7469706c69636174696f6e206f766572666c6f77a164736f6c634300060c000a", + "devdoc": { + "author": "Jegor Sidorenko Stanisław Głogowski ", + "kind": "dev", + "methods": { + "getBalances(address[],address[])": { + "details": "Pass 0x0 as a \"token\" address to get ETH balance. Possible error throws: - extremely large arrays for account and or tokens (gas cost too high)", + "params": { + "accounts": "array of accounts addresses", + "tokens": "array of tokens addresses" + }, + "returns": { + "_0": "a one-dimensional that's user.length * tokens.length long. The array is ordered by all of the 0th accounts token balances, then the 1th user, and so on." + } + } + }, + "title": "Balances helper", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "getBalances(address[],address[])": { + "notice": "Checks the token balances of accounts for multiple tokens." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/BalancesHelperV2.json b/deployments/neonDevnet/BalancesHelperV2.json new file mode 100644 index 00000000..4fc953a2 --- /dev/null +++ b/deployments/neonDevnet/BalancesHelperV2.json @@ -0,0 +1,160 @@ +{ + "address": "0xe5A160F89f330cc933816E896a3F36376DE0a835", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "AccountZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "TokenZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getBalances", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getSuperfluidWrappedTokenBalances", + "outputs": [ + { + "internalType": "int256[]", + "name": "", + "type": "int256[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xf1b8cb6bbef86256c57e6ea7b672377a8ea4033e556da2b781203cc4e7bf97d5", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "48826560", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x22a1e46582c7b9544b3001f90c5e0b3066b2f51e28feadc055d316907cdd1d5f", + "transactionHash": "0xf1b8cb6bbef86256c57e6ea7b672377a8ea4033e556da2b781203cc4e7bf97d5", + "logs": [], + "blockNumber": 173996704, + "cumulativeGasUsed": "48826560", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "82f81c73c615e1d8d0ff013db621d6da", + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"AccountZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getBalances\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getSuperfluidWrappedTokenBalances\",\"outputs\":[{\"internalType\":\"int256[]\",\"name\":\"\",\"type\":\"int256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getBalances(address[],address[])\":{\"details\":\"Error thrown if: account or token address is address(0), large arrays of accounts/tokens are passed in could cause gas block limit issue\",\"params\":{\"accounts\":\"= Array of accounts addresses\",\"tokens\":\"= Array of tokens addresses\"},\"returns\":{\"_0\":\"One-dimensional that's accounts.length * tokens.length long. The array is ordered by all of accounts[0] token balances, then accounts[1] etc.\"}},\"getSuperfluidWrappedTokenBalances(address[],address[])\":{\"details\":\"Error thrown if: account or token address is address(0), large arrays of accounts/tokens are passed in could cause gas block limit issue\",\"params\":{\"accounts\":\"= Array of accounts addresses\",\"tokens\":\"= Array of tokens addresses\"},\"returns\":{\"_0\":\"One-dimensional that's accounts.length * tokens.length long. The array is ordered by all of accounts[0] token balances, then accounts[1] etc.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"AccountZeroAddress(address,address)\":[{\"notice\":\"Custom errors to handle address(0)\"}]},\"kind\":\"user\",\"methods\":{\"getBalances(address[],address[])\":{\"notice\":\"Returns balances of accounts for multiple ERC20 tokens.\"},\"getSuperfluidWrappedTokenBalances(address[],address[])\":{\"notice\":\"Returns balances of accounts for multiple Wrapped Super Tokens.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/common/helpers/BalancesHelperV2.sol\":\"BalancesHelperV2\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../token/ERC20/IERC20.sol\\\";\\n\",\"keccak256\":\"0x6ebf1944ab804b8660eb6fc52f9fe84588cee01c2566a69023e59497e7d27f45\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperAgreement.sol\":{\"content\":\"// SPDX-License-Identifier: AGPLv3\\npragma solidity >= 0.8.0;\\n\\nimport { ISuperfluidToken } from \\\"./ISuperfluidToken.sol\\\";\\n\\n/**\\n * @title Super agreement interface\\n * @author Superfluid\\n */\\ninterface ISuperAgreement {\\n\\n /**\\n * @dev Get the type of the agreement class\\n */\\n function agreementType() external view returns (bytes32);\\n\\n /**\\n * @dev Calculate the real-time balance for the account of this agreement class\\n * @param account Account the state belongs to\\n * @param time Time used for the calculation\\n * @return dynamicBalance Dynamic balance portion of real-time balance of this agreement\\n * @return deposit Account deposit amount of this agreement\\n * @return owedDeposit Account owed deposit amount of this agreement\\n */\\n function realtimeBalanceOf(\\n ISuperfluidToken token,\\n address account,\\n uint256 time\\n )\\n external\\n view\\n returns (\\n int256 dynamicBalance,\\n uint256 deposit,\\n uint256 owedDeposit\\n );\\n\\n}\\n\",\"keccak256\":\"0xc3a6a907245116bcecc70fe4b207454012e8ce4fa190228fb8bbe39e0b1bc5cf\",\"license\":\"AGPLv3\"},\"@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluidToken.sol\":{\"content\":\"// SPDX-License-Identifier: AGPLv3\\npragma solidity >= 0.8.0;\\n\\nimport { ISuperAgreement } from \\\"./ISuperAgreement.sol\\\";\\n\\n\\n/**\\n * @title Superfluid token interface\\n * @author Superfluid\\n */\\ninterface ISuperfluidToken {\\n\\n /**************************************************************************\\n * Basic information\\n *************************************************************************/\\n\\n /**\\n * @dev Get superfluid host contract address\\n */\\n function getHost() external view returns(address host);\\n\\n /**\\n * @dev Encoded liquidation type data mainly used for handling stack to deep errors\\n *\\n * Note:\\n * - version: 1\\n * - liquidationType key:\\n * - 0 = reward account receives reward (PIC period)\\n * - 1 = liquidator account receives reward (Pleb period)\\n * - 2 = liquidator account receives reward (Pirate period/bailout)\\n */\\n struct LiquidationTypeData {\\n uint256 version;\\n uint8 liquidationType;\\n }\\n\\n /**************************************************************************\\n * Real-time balance functions\\n *************************************************************************/\\n\\n /**\\n * @dev Calculate the real balance of a user, taking in consideration all agreements of the account\\n * @param account for the query\\n * @param timestamp Time of balance\\n * @return availableBalance Real-time balance\\n * @return deposit Account deposit\\n * @return owedDeposit Account owed Deposit\\n */\\n function realtimeBalanceOf(\\n address account,\\n uint256 timestamp\\n )\\n external view\\n returns (\\n int256 availableBalance,\\n uint256 deposit,\\n uint256 owedDeposit);\\n\\n /**\\n * @notice Calculate the realtime balance given the current host.getNow() value\\n * @dev realtimeBalanceOf with timestamp equals to block timestamp\\n * @param account for the query\\n * @return availableBalance Real-time balance\\n * @return deposit Account deposit\\n * @return owedDeposit Account owed Deposit\\n */\\n function realtimeBalanceOfNow(\\n address account\\n )\\n external view\\n returns (\\n int256 availableBalance,\\n uint256 deposit,\\n uint256 owedDeposit,\\n uint256 timestamp);\\n\\n /**\\n * @notice Check if account is critical\\n * @dev A critical account is when availableBalance < 0\\n * @param account The account to check\\n * @param timestamp The time we'd like to check if the account is critical (should use future)\\n * @return isCritical Whether the account is critical\\n */\\n function isAccountCritical(\\n address account,\\n uint256 timestamp\\n )\\n external view\\n returns(bool isCritical);\\n\\n /**\\n * @notice Check if account is critical now (current host.getNow())\\n * @dev A critical account is when availableBalance < 0\\n * @param account The account to check\\n * @return isCritical Whether the account is critical\\n */\\n function isAccountCriticalNow(\\n address account\\n )\\n external view\\n returns(bool isCritical);\\n\\n /**\\n * @notice Check if account is solvent\\n * @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance\\n * @param account The account to check\\n * @param timestamp The time we'd like to check if the account is solvent (should use future)\\n * @return isSolvent\\n */\\n function isAccountSolvent(\\n address account,\\n uint256 timestamp\\n )\\n external view\\n returns(bool isSolvent);\\n\\n /**\\n * @notice Check if account is solvent now\\n * @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance\\n * @param account The account to check\\n * @return isSolvent\\n */\\n function isAccountSolventNow(\\n address account\\n )\\n external view\\n returns(bool isSolvent);\\n\\n /**\\n * @notice Get a list of agreements that is active for the account\\n * @dev An active agreement is one that has state for the account\\n * @param account Account to query\\n * @return activeAgreements List of accounts that have non-zero states for the account\\n */\\n function getAccountActiveAgreements(address account)\\n external view\\n returns(ISuperAgreement[] memory activeAgreements);\\n\\n\\n /**************************************************************************\\n * Super Agreement hosting functions\\n *************************************************************************/\\n\\n /**\\n * @dev Create a new agreement\\n * @param id Agreement ID\\n * @param data Agreement data\\n */\\n function createAgreement(\\n bytes32 id,\\n bytes32[] calldata data\\n )\\n external;\\n /**\\n * @dev Agreement created event\\n * @param agreementClass Contract address of the agreement\\n * @param id Agreement ID\\n * @param data Agreement data\\n */\\n event AgreementCreated(\\n address indexed agreementClass,\\n bytes32 id,\\n bytes32[] data\\n );\\n\\n /**\\n * @dev Get data of the agreement\\n * @param agreementClass Contract address of the agreement\\n * @param id Agreement ID\\n * @return data Data of the agreement\\n */\\n function getAgreementData(\\n address agreementClass,\\n bytes32 id,\\n uint dataLength\\n )\\n external view\\n returns(bytes32[] memory data);\\n\\n /**\\n * @dev Create a new agreement\\n * @param id Agreement ID\\n * @param data Agreement data\\n */\\n function updateAgreementData(\\n bytes32 id,\\n bytes32[] calldata data\\n )\\n external;\\n /**\\n * @dev Agreement updated event\\n * @param agreementClass Contract address of the agreement\\n * @param id Agreement ID\\n * @param data Agreement data\\n */\\n event AgreementUpdated(\\n address indexed agreementClass,\\n bytes32 id,\\n bytes32[] data\\n );\\n\\n /**\\n * @dev Close the agreement\\n * @param id Agreement ID\\n */\\n function terminateAgreement(\\n bytes32 id,\\n uint dataLength\\n )\\n external;\\n /**\\n * @dev Agreement terminated event\\n * @param agreementClass Contract address of the agreement\\n * @param id Agreement ID\\n */\\n event AgreementTerminated(\\n address indexed agreementClass,\\n bytes32 id\\n );\\n\\n /**\\n * @dev Update agreement state slot\\n * @param account Account to be updated\\n *\\n * NOTE\\n * - To clear the storage out, provide zero-ed array of intended length\\n */\\n function updateAgreementStateSlot(\\n address account,\\n uint256 slotId,\\n bytes32[] calldata slotData\\n )\\n external;\\n /**\\n * @dev Agreement account state updated event\\n * @param agreementClass Contract address of the agreement\\n * @param account Account updated\\n * @param slotId slot id of the agreement state\\n */\\n event AgreementStateUpdated(\\n address indexed agreementClass,\\n address indexed account,\\n uint256 slotId\\n );\\n\\n /**\\n * @dev Get data of the slot of the state of an agreement\\n * @param agreementClass Contract address of the agreement\\n * @param account Account to query\\n * @param slotId slot id of the state\\n * @param dataLength length of the state data\\n */\\n function getAgreementStateSlot(\\n address agreementClass,\\n address account,\\n uint256 slotId,\\n uint dataLength\\n )\\n external view\\n returns (bytes32[] memory slotData);\\n\\n /**\\n * @notice Settle balance from an account by the agreement\\n * @dev The agreement needs to make sure that the balance delta is balanced afterwards\\n * @param account Account to query.\\n * @param delta Amount of balance delta to be settled\\n *\\n * Modifiers:\\n * - onlyAgreement\\n */\\n function settleBalance(\\n address account,\\n int256 delta\\n )\\n external;\\n\\n /**\\n * @dev Make liquidation payouts (v2)\\n * @param id Agreement ID\\n * @param liquidationTypeData Data regarding the version of the liquidation schema and the type\\n * @param liquidatorAccount Address of the executor of the liquidation\\n * @param useDefaultRewardAccount Whether or not the default reward account receives the rewardAmount\\n * @param targetAccount Account of the stream sender\\n * @param rewardAmount The amount the reward recepient account will receive\\n * @param targetAccountBalanceDelta The amount the sender account balance should change by\\n *\\n * - If a bailout is required (bailoutAmount > 0)\\n * - the actual reward (single deposit) goes to the executor,\\n * - while the reward account becomes the bailout account\\n * - total bailout include: bailout amount + reward amount\\n * - the targetAccount will be bailed out\\n * - If a bailout is not required\\n * - the targetAccount will pay the rewardAmount\\n * - the liquidator (reward account in PIC period) will receive the rewardAmount\\n *\\n * Modifiers:\\n * - onlyAgreement\\n */\\n function makeLiquidationPayoutsV2\\n (\\n bytes32 id,\\n bytes memory liquidationTypeData,\\n address liquidatorAccount,\\n bool useDefaultRewardAccount,\\n address targetAccount,\\n uint256 rewardAmount,\\n int256 targetAccountBalanceDelta\\n ) external;\\n /**\\n * @dev Agreement liquidation event v2 (including agent account)\\n * @param agreementClass Contract address of the agreement\\n * @param id Agreement ID\\n * @param liquidatorAccount Address of the executor of the liquidation\\n * @param targetAccount Account of the stream sender\\n * @param rewardAccount Account that collects the reward or bails out insolvent accounts\\n * @param rewardAmount The amount the reward recipient account balance should change by\\n * @param targetAccountBalanceDelta The amount the sender account balance should change by\\n * @param liquidationTypeData The encoded liquidation type data including the version (how to decode)\\n *\\n * NOTE:\\n * Reward account rule:\\n * - if the agreement is liquidated during the PIC period\\n * - the rewardAccount will get the rewardAmount (remaining deposit), regardless of the liquidatorAccount\\n * - the targetAccount will pay for the rewardAmount\\n * - if the agreement is liquidated after the PIC period AND the targetAccount is solvent\\n * - the liquidatorAccount will get the rewardAmount (remaining deposit)\\n * - the targetAccount will pay for the rewardAmount\\n * - if the targetAccount is insolvent\\n * - the liquidatorAccount will get the rewardAmount (single deposit)\\n * - the rewardAccount will pay for both the rewardAmount and bailoutAmount\\n * - the targetAccount will receive the bailoutAmount\\n */\\n event AgreementLiquidatedV2(\\n address indexed agreementClass,\\n bytes32 id,\\n address indexed liquidatorAccount,\\n address indexed targetAccount,\\n address rewardAccount,\\n uint256 rewardAmount,\\n int256 targetAccountBalanceDelta,\\n bytes liquidationTypeData\\n );\\n\\n /**************************************************************************\\n * Function modifiers for access control and parameter validations\\n *\\n * While they cannot be explicitly stated in function definitions, they are\\n * listed in function definition comments instead for clarity.\\n *\\n * NOTE: solidity-coverage not supporting it\\n *************************************************************************/\\n\\n /// @dev The msg.sender must be host contract\\n //modifier onlyHost() virtual;\\n\\n /// @dev The msg.sender must be a listed agreement.\\n //modifier onlyAgreement() virtual;\\n\\n /**************************************************************************\\n * DEPRECATED\\n *************************************************************************/\\n\\n /**\\n * @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedBy)\\n * @param agreementClass Contract address of the agreement\\n * @param id Agreement ID\\n * @param penaltyAccount Account of the agreement to be penalized\\n * @param rewardAccount Account that collect the reward\\n * @param rewardAmount Amount of liquidation reward\\n *\\n * NOTE:\\n *\\n * [DEPRECATED] Use AgreementLiquidatedV2 instead\\n */\\n event AgreementLiquidated(\\n address indexed agreementClass,\\n bytes32 id,\\n address indexed penaltyAccount,\\n address indexed rewardAccount,\\n uint256 rewardAmount\\n );\\n\\n /**\\n * @dev System bailout occurred (DEPRECATED BY AgreementLiquidatedBy)\\n * @param bailoutAccount Account that bailout the penalty account\\n * @param bailoutAmount Amount of account bailout\\n *\\n * NOTE:\\n *\\n * [DEPRECATED] Use AgreementLiquidatedV2 instead\\n */\\n event Bailout(\\n address indexed bailoutAccount,\\n uint256 bailoutAmount\\n );\\n\\n /**\\n * @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedV2)\\n * @param liquidatorAccount Account of the agent that performed the liquidation.\\n * @param agreementClass Contract address of the agreement\\n * @param id Agreement ID\\n * @param penaltyAccount Account of the agreement to be penalized\\n * @param bondAccount Account that collect the reward or bailout accounts\\n * @param rewardAmount Amount of liquidation reward\\n * @param bailoutAmount Amount of liquidation bailouot\\n *\\n * NOTE:\\n * Reward account rule:\\n * - if bailout is equal to 0, then\\n * - the bondAccount will get the rewardAmount,\\n * - the penaltyAccount will pay for the rewardAmount.\\n * - if bailout is larger than 0, then\\n * - the liquidatorAccount will get the rewardAmouont,\\n * - the bondAccount will pay for both the rewardAmount and bailoutAmount,\\n * - the penaltyAccount will pay for the rewardAmount while get the bailoutAmount.\\n */\\n event AgreementLiquidatedBy(\\n address liquidatorAccount,\\n address indexed agreementClass,\\n bytes32 id,\\n address indexed penaltyAccount,\\n address indexed bondAccount,\\n uint256 rewardAmount,\\n uint256 bailoutAmount\\n );\\n}\\n\",\"keccak256\":\"0x9189eaba9e856cc4932ea29eeaf4e89a09448dde13860591691ec122856fdc75\",\"license\":\"AGPLv3\"},\"src/common/helpers/BalancesHelperV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// solhint-disable-next-line\\npragma solidity 0.8.4;\\n\\n/// @title BalancesHelperV2\\n/// @author Luke Wickens \\n/// @notice Used to get account balances of ERC20 tokens and Wrapped Super Tokens\\n\\nimport {ISuperfluidToken} from \\\"@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluidToken.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\ncontract BalancesHelperV2 {\\n using Address for address;\\n\\n /// @notice Custom errors to handle address(0)\\n error AccountZeroAddress(address account, address token);\\n error TokenZeroAddress(address account, address token);\\n\\n constructor() {}\\n\\n /// @notice Returns balances of accounts for multiple ERC20 tokens.\\n /// @dev Error thrown if: account or token address is address(0),\\n /// large arrays of accounts/tokens are passed in could cause gas block limit issue\\n /// @param accounts = Array of accounts addresses\\n /// @param tokens = Array of tokens addresses\\n /// @return One-dimensional that's accounts.length * tokens.length long. The\\n /// array is ordered by all of accounts[0] token balances, then accounts[1] etc.\\n\\n function getBalances(address[] calldata accounts, address[] calldata tokens)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n uint256[] memory result = new uint256[](\\n accounts.length * tokens.length\\n );\\n\\n for (uint256 i; i < accounts.length; i++) {\\n for (uint256 j; j < tokens.length; j++) {\\n uint256 index = j + (tokens.length * i);\\n result[index] = _getBalance(accounts[i], tokens[j]);\\n }\\n }\\n return result;\\n }\\n\\n /// @notice Returns balances of accounts for multiple Wrapped Super Tokens.\\n /// @dev Error thrown if: account or token address is address(0),\\n /// large arrays of accounts/tokens are passed in could cause gas block limit issue\\n /// @param accounts = Array of accounts addresses\\n /// @param tokens = Array of tokens addresses\\n /// @return One-dimensional that's accounts.length * tokens.length long. The\\n /// array is ordered by all of accounts[0] token balances, then accounts[1] etc.\\n\\n function getSuperfluidWrappedTokenBalances(\\n address[] calldata accounts,\\n address[] calldata tokens\\n ) external view returns (int256[] memory) {\\n int256[] memory result = new int256[](accounts.length * tokens.length);\\n\\n for (uint256 i; i < accounts.length; i++) {\\n for (uint256 j; j < tokens.length; j++) {\\n uint256 index = j + (tokens.length * i);\\n result[index] = _getSuperfluidWrappedTokenBalance(\\n accounts[i],\\n tokens[j]\\n );\\n }\\n }\\n return result;\\n }\\n\\n /// Private fuctions\\n\\n /// @notice Returns balance of account for an ERC20 token.\\n /// @dev Error thrown if: account or token address is address(0)\\n /// @param account = account address\\n /// @param token = tokens address\\n /// @return balance of account as uint256.\\n\\n function _getBalance(address account, address token)\\n private\\n view\\n returns (uint256)\\n {\\n if (account == address(0)) revert AccountZeroAddress(account, token);\\n if (token == address(0)) revert TokenZeroAddress(account, token);\\n\\n bytes memory returnedData = token.functionStaticCall(\\n abi.encodeWithSelector(IERC20(token).balanceOf.selector, account)\\n );\\n\\n return abi.decode(returnedData, (uint256));\\n }\\n\\n /// @notice Returns real balance of a user, taking into consideration all agreements of account\\n /// @dev Error thrown if: account or token address is address(0)\\n /// @param account = account address\\n /// @param token = tokens address\\n /// @return available balance of account as int256.\\n\\n function _getSuperfluidWrappedTokenBalance(address account, address token)\\n private\\n view\\n returns (int256)\\n {\\n if (account == address(0)) revert AccountZeroAddress(account, token);\\n if (token == address(0)) revert TokenZeroAddress(account, token);\\n\\n bytes memory returnedData = token.functionStaticCall(\\n abi.encodeWithSelector(\\n ISuperfluidToken(token).realtimeBalanceOfNow.selector,\\n account\\n )\\n );\\n\\n (int256 availableBalance, , , ) = abi.decode(\\n returnedData,\\n (int256, uint256, uint256, uint256)\\n );\\n return availableBalance;\\n }\\n}\\n\",\"keccak256\":\"0x02dfe13a8521bebc6f623a9df9877d7c66f8cfb67c10ee1a041dcba42ef7b973\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061108a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806350c5a7101461003b578063ef5bfc371461006b575b600080fd5b610055600480360381019061005091906109e6565b61009b565b6040516100629190610ce8565b60405180910390f35b610085600480360381019061008091906109e6565b610279565b6040516100929190610d0a565b60405180910390f35b6060600083839050868690506100b19190610e68565b67ffffffffffffffff8111156100f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405190808252806020026020018201604052801561011e5781602001602082028036833780820191505090505b50905060005b8686905081101561026c5760005b85859050811015610258576000828787905061014e9190610e68565b826101599190610e12565b90506101ff898985818110610197577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906101ac91906109bd565b8888858181106101e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906101fa91906109bd565b610457565b848281518110610238577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505050808061025090610f3b565b915050610132565b50808061026490610f3b565b915050610124565b5080915050949350505050565b60606000838390508686905061028f9190610e68565b67ffffffffffffffff8111156102ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156102fc5781602001602082028036833780820191505090505b50905060005b8686905081101561044a5760005b85859050811015610436576000828787905061032c9190610e68565b826103379190610e12565b90506103dd898985818110610375577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b905060200201602081019061038a91906109bd565b8888858181106103c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906103d891906109bd565b610608565b848281518110610416577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505050808061042e90610f3b565b915050610310565b50808061044290610f3b565b915050610302565b5080915050949350505050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156104cc5782826040517f484305ff0000000000000000000000000000000000000000000000000000000081526004016104c3929190610cbf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156105405782826040517f41f93bdf000000000000000000000000000000000000000000000000000000008152600401610537929190610cbf565b60405180910390fd5b60006105e0632ec8eec760e01b8560405160240161055e9190610ca4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508473ffffffffffffffffffffffffffffffffffffffff166107b090919063ffffffff16565b90506000818060200190518101906105f89190610a5b565b5050509050809250505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561067d5782826040517f484305ff000000000000000000000000000000000000000000000000000000008152600401610674929190610cbf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156106f15782826040517f41f93bdf0000000000000000000000000000000000000000000000000000000081526004016106e8929190610cbf565b60405180910390fd5b60006107916370a0823160e01b8560405160240161070f9190610ca4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508473ffffffffffffffffffffffffffffffffffffffff166107b090919063ffffffff16565b9050808060200190518101906107a79190610abe565b91505092915050565b60606107d58383604051806060016040528060258152602001611059602591396107dd565b905092915050565b60606107e8846108aa565b610827576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081e90610d4e565b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168560405161084f9190610c8d565b600060405180830381855afa9150503d806000811461088a576040519150601f19603f3d011682016040523d82523d6000602084013e61088f565b606091505b509150915061089f8282866108cd565b925050509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156108dd5782905061092d565b6000835111156108f05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109249190610d2c565b60405180910390fd5b9392505050565b60008135905061094381611013565b92915050565b60008083601f84011261095b57600080fd5b8235905067ffffffffffffffff81111561097457600080fd5b60208301915083602082028301111561098c57600080fd5b9250929050565b6000815190506109a28161102a565b92915050565b6000815190506109b781611041565b92915050565b6000602082840312156109cf57600080fd5b60006109dd84828501610934565b91505092915050565b600080600080604085870312156109fc57600080fd5b600085013567ffffffffffffffff811115610a1657600080fd5b610a2287828801610949565b9450945050602085013567ffffffffffffffff811115610a4157600080fd5b610a4d87828801610949565b925092505092959194509250565b60008060008060808587031215610a7157600080fd5b6000610a7f87828801610993565b9450506020610a90878288016109a8565b9350506040610aa1878288016109a8565b9250506060610ab2878288016109a8565b91505092959194509250565b600060208284031215610ad057600080fd5b6000610ade848285016109a8565b91505092915050565b6000610af38383610c13565b60208301905092915050565b6000610b0b8383610c7e565b60208301905092915050565b610b2081610ec2565b82525050565b6000610b3182610d8e565b610b3b8185610dd4565b9350610b4683610d6e565b8060005b83811015610b77578151610b5e8882610ae7565b9750610b6983610dba565b925050600181019050610b4a565b5085935050505092915050565b6000610b8f82610d99565b610b998185610de5565b9350610ba483610d7e565b8060005b83811015610bd5578151610bbc8882610aff565b9750610bc783610dc7565b925050600181019050610ba8565b5085935050505092915050565b6000610bed82610da4565b610bf78185610df6565b9350610c07818560208601610f08565b80840191505092915050565b610c1c81610ed4565b82525050565b6000610c2d82610daf565b610c378185610e01565b9350610c47818560208601610f08565b610c5081610fb3565b840191505092915050565b6000610c68602483610e01565b9150610c7382610fc4565b604082019050919050565b610c8781610efe565b82525050565b6000610c998284610be2565b915081905092915050565b6000602082019050610cb96000830184610b17565b92915050565b6000604082019050610cd46000830185610b17565b610ce16020830184610b17565b9392505050565b60006020820190508181036000830152610d028184610b26565b905092915050565b60006020820190508181036000830152610d248184610b84565b905092915050565b60006020820190508181036000830152610d468184610c22565b905092915050565b60006020820190508181036000830152610d6781610c5b565b9050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000610e1d82610efe565b9150610e2883610efe565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610e5d57610e5c610f84565b5b828201905092915050565b6000610e7382610efe565b9150610e7e83610efe565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610eb757610eb6610f84565b5b828202905092915050565b6000610ecd82610ede565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b83811015610f26578082015181840152602081019050610f0b565b83811115610f35576000848401525b50505050565b6000610f4682610efe565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f7957610f78610f84565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000601f19601f8301169050919050565b7f416464726573733a207374617469632063616c6c20746f206e6f6e2d636f6e7460008201527f7261637400000000000000000000000000000000000000000000000000000000602082015250565b61101c81610ec2565b811461102757600080fd5b50565b61103381610ed4565b811461103e57600080fd5b50565b61104a81610efe565b811461105557600080fd5b5056fe416464726573733a206c6f772d6c6576656c207374617469632063616c6c206661696c6564a164736f6c6343000804000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806350c5a7101461003b578063ef5bfc371461006b575b600080fd5b610055600480360381019061005091906109e6565b61009b565b6040516100629190610ce8565b60405180910390f35b610085600480360381019061008091906109e6565b610279565b6040516100929190610d0a565b60405180910390f35b6060600083839050868690506100b19190610e68565b67ffffffffffffffff8111156100f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405190808252806020026020018201604052801561011e5781602001602082028036833780820191505090505b50905060005b8686905081101561026c5760005b85859050811015610258576000828787905061014e9190610e68565b826101599190610e12565b90506101ff898985818110610197577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906101ac91906109bd565b8888858181106101e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906101fa91906109bd565b610457565b848281518110610238577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505050808061025090610f3b565b915050610132565b50808061026490610f3b565b915050610124565b5080915050949350505050565b60606000838390508686905061028f9190610e68565b67ffffffffffffffff8111156102ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156102fc5781602001602082028036833780820191505090505b50905060005b8686905081101561044a5760005b85859050811015610436576000828787905061032c9190610e68565b826103379190610e12565b90506103dd898985818110610375577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b905060200201602081019061038a91906109bd565b8888858181106103c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906103d891906109bd565b610608565b848281518110610416577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505050808061042e90610f3b565b915050610310565b50808061044290610f3b565b915050610302565b5080915050949350505050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156104cc5782826040517f484305ff0000000000000000000000000000000000000000000000000000000081526004016104c3929190610cbf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156105405782826040517f41f93bdf000000000000000000000000000000000000000000000000000000008152600401610537929190610cbf565b60405180910390fd5b60006105e0632ec8eec760e01b8560405160240161055e9190610ca4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508473ffffffffffffffffffffffffffffffffffffffff166107b090919063ffffffff16565b90506000818060200190518101906105f89190610a5b565b5050509050809250505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561067d5782826040517f484305ff000000000000000000000000000000000000000000000000000000008152600401610674929190610cbf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156106f15782826040517f41f93bdf0000000000000000000000000000000000000000000000000000000081526004016106e8929190610cbf565b60405180910390fd5b60006107916370a0823160e01b8560405160240161070f9190610ca4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508473ffffffffffffffffffffffffffffffffffffffff166107b090919063ffffffff16565b9050808060200190518101906107a79190610abe565b91505092915050565b60606107d58383604051806060016040528060258152602001611059602591396107dd565b905092915050565b60606107e8846108aa565b610827576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081e90610d4e565b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168560405161084f9190610c8d565b600060405180830381855afa9150503d806000811461088a576040519150601f19603f3d011682016040523d82523d6000602084013e61088f565b606091505b509150915061089f8282866108cd565b925050509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156108dd5782905061092d565b6000835111156108f05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109249190610d2c565b60405180910390fd5b9392505050565b60008135905061094381611013565b92915050565b60008083601f84011261095b57600080fd5b8235905067ffffffffffffffff81111561097457600080fd5b60208301915083602082028301111561098c57600080fd5b9250929050565b6000815190506109a28161102a565b92915050565b6000815190506109b781611041565b92915050565b6000602082840312156109cf57600080fd5b60006109dd84828501610934565b91505092915050565b600080600080604085870312156109fc57600080fd5b600085013567ffffffffffffffff811115610a1657600080fd5b610a2287828801610949565b9450945050602085013567ffffffffffffffff811115610a4157600080fd5b610a4d87828801610949565b925092505092959194509250565b60008060008060808587031215610a7157600080fd5b6000610a7f87828801610993565b9450506020610a90878288016109a8565b9350506040610aa1878288016109a8565b9250506060610ab2878288016109a8565b91505092959194509250565b600060208284031215610ad057600080fd5b6000610ade848285016109a8565b91505092915050565b6000610af38383610c13565b60208301905092915050565b6000610b0b8383610c7e565b60208301905092915050565b610b2081610ec2565b82525050565b6000610b3182610d8e565b610b3b8185610dd4565b9350610b4683610d6e565b8060005b83811015610b77578151610b5e8882610ae7565b9750610b6983610dba565b925050600181019050610b4a565b5085935050505092915050565b6000610b8f82610d99565b610b998185610de5565b9350610ba483610d7e565b8060005b83811015610bd5578151610bbc8882610aff565b9750610bc783610dc7565b925050600181019050610ba8565b5085935050505092915050565b6000610bed82610da4565b610bf78185610df6565b9350610c07818560208601610f08565b80840191505092915050565b610c1c81610ed4565b82525050565b6000610c2d82610daf565b610c378185610e01565b9350610c47818560208601610f08565b610c5081610fb3565b840191505092915050565b6000610c68602483610e01565b9150610c7382610fc4565b604082019050919050565b610c8781610efe565b82525050565b6000610c998284610be2565b915081905092915050565b6000602082019050610cb96000830184610b17565b92915050565b6000604082019050610cd46000830185610b17565b610ce16020830184610b17565b9392505050565b60006020820190508181036000830152610d028184610b26565b905092915050565b60006020820190508181036000830152610d248184610b84565b905092915050565b60006020820190508181036000830152610d468184610c22565b905092915050565b60006020820190508181036000830152610d6781610c5b565b9050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000610e1d82610efe565b9150610e2883610efe565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610e5d57610e5c610f84565b5b828201905092915050565b6000610e7382610efe565b9150610e7e83610efe565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610eb757610eb6610f84565b5b828202905092915050565b6000610ecd82610ede565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b83811015610f26578082015181840152602081019050610f0b565b83811115610f35576000848401525b50505050565b6000610f4682610efe565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f7957610f78610f84565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000601f19601f8301169050919050565b7f416464726573733a207374617469632063616c6c20746f206e6f6e2d636f6e7460008201527f7261637400000000000000000000000000000000000000000000000000000000602082015250565b61101c81610ec2565b811461102757600080fd5b50565b61103381610ed4565b811461103e57600080fd5b50565b61104a81610efe565b811461105557600080fd5b5056fe416464726573733a206c6f772d6c6576656c207374617469632063616c6c206661696c6564a164736f6c6343000804000a", + "devdoc": { + "kind": "dev", + "methods": { + "getBalances(address[],address[])": { + "details": "Error thrown if: account or token address is address(0), large arrays of accounts/tokens are passed in could cause gas block limit issue", + "params": { + "accounts": "= Array of accounts addresses", + "tokens": "= Array of tokens addresses" + }, + "returns": { + "_0": "One-dimensional that's accounts.length * tokens.length long. The array is ordered by all of accounts[0] token balances, then accounts[1] etc." + } + }, + "getSuperfluidWrappedTokenBalances(address[],address[])": { + "details": "Error thrown if: account or token address is address(0), large arrays of accounts/tokens are passed in could cause gas block limit issue", + "params": { + "accounts": "= Array of accounts addresses", + "tokens": "= Array of tokens addresses" + }, + "returns": { + "_0": "One-dimensional that's accounts.length * tokens.length long. The array is ordered by all of accounts[0] token balances, then accounts[1] etc." + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "AccountZeroAddress(address,address)": [ + { + "notice": "Custom errors to handle address(0)" + } + ] + }, + "kind": "user", + "methods": { + "getBalances(address[],address[])": { + "notice": "Returns balances of accounts for multiple ERC20 tokens." + }, + "getSuperfluidWrappedTokenBalances(address[],address[])": { + "notice": "Returns balances of accounts for multiple Wrapped Super Tokens." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/CBridgeFacet.json b/deployments/neonDevnet/CBridgeFacet.json new file mode 100644 index 00000000..f0e50078 --- /dev/null +++ b/deployments/neonDevnet/CBridgeFacet.json @@ -0,0 +1,255 @@ +{ + "address": "0x9d70f5253949Eb67850C3f1e7371f15b955ee073", + "abi": [ + { + "inputs": [], + "name": "CBSlippageTooLow", + "type": "error" + }, + { + "inputs": [], + "name": "CannotBridgeToSameNetwork", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyError", + "type": "error" + }, + { + "inputs": [], + "name": "TokenAddressIsZero", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressProvided", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "cBridge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "CBInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "bridgeUsed", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "qty", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "chainIdTo", + "type": "uint256" + } + ], + "name": "CBTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "CBUpdatedBridge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newSlippage", + "type": "uint256" + } + ], + "name": "CBUpdatedSlippageTolerance", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "dstChainId", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "qty", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct CBridgeFacet.CBridgeData", + "name": "_cbData", + "type": "tuple" + } + ], + "name": "cbBridgeTokens", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_cbBridge", + "type": "address" + } + ], + "name": "cbInitialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newAddress", + "type": "address" + } + ], + "name": "cbUpdateBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_newSlippage", + "type": "uint32" + } + ], + "name": "cbUpdateSlippageTolerance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x209ed17e8efe6be0ff138e20d79021e726f96d82d5283cc86439c0835ffe571d", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "59106480", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x07ad07298175cc5de0ebe6088da8e9def9436f60e9efb54cd09ed1df89890c15", + "transactionHash": "0x209ed17e8efe6be0ff138e20d79021e726f96d82d5283cc86439c0835ffe571d", + "logs": [], + "blockNumber": 173997796, + "cumulativeGasUsed": "59106480", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "8d42885a5f19da22f710ffc8b637c191", + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CBSlippageTooLow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotBridgeToSameNetwork\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenAddressIsZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressProvided\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"cBridge\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"name\":\"CBInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"bridgeUsed\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"qty\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"chainIdTo\",\"type\":\"uint256\"}],\"name\":\"CBTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAddress\",\"type\":\"address\"}],\"name\":\"CBUpdatedBridge\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSlippage\",\"type\":\"uint256\"}],\"name\":\"CBUpdatedSlippageTolerance\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"dstChainId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"qty\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"struct CBridgeFacet.CBridgeData\",\"name\":\"_cbData\",\"type\":\"tuple\"}],\"name\":\"cbBridgeTokens\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_cbBridge\",\"type\":\"address\"}],\"name\":\"cbInitialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newAddress\",\"type\":\"address\"}],\"name\":\"cbUpdateBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_newSlippage\",\"type\":\"uint32\"}],\"name\":\"cbUpdateSlippageTolerance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cbBridgeTokens((uint64,uint64,uint256,address,address))\":{\"params\":{\"_cbData\":\": provides necessary data for cBridge transfer\"}},\"cbInitialize(address)\":{\"params\":{\"_cbBridge\":\"address of the CBridge router contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cbBridgeTokens((uint64,uint64,uint256,address,address))\":{\"notice\":\"initiates token bridging\"},\"cbInitialize(address)\":{\"notice\":\"initializes state variables for the cBridge facet\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/bridges/facets/CBridgeFacet.sol\":\"CBridgeFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"src/bridges/errors/CBridgeErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// solhint-disable-next-line\\npragma solidity 0.8.4;\\n\\nerror CBSlippageTooLow();\\n\",\"keccak256\":\"0x03cb94f117b0cca4864a126a41add3f939b7ec3ca8e398eb901c78788a7176c8\",\"license\":\"MIT\"},\"src/bridges/errors/GenericErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// solhint-disable-next-line\\npragma solidity 0.8.4;\\n\\nerror InvalidAmount();\\nerror TokenAddressIsZero();\\nerror CannotBridgeToSameNetwork();\\nerror ZeroPostSwapBalance();\\nerror InvalidBridgeConfigLength();\\nerror NoSwapDataProvided();\\nerror NativeValueWithERC();\\nerror ContractCallNotAllowed();\\nerror NullAddrIsNotAValidSpender();\\nerror NullAddrIsNotAnERC20Token();\\nerror NoTransferToNullAddress();\\nerror NativeAssetTransferFailed();\\nerror InvalidContract();\\nerror InvalidConfig();\\nerror ZeroAddressProvided();\\n\",\"keccak256\":\"0x8fbb39c8e0b8f0ed9b37b799fec0e47bbd9f209c290a8dd290e44241dedaceda\",\"license\":\"MIT\"},\"src/bridges/facets/CBridgeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// solhint-disable-next-line\\npragma solidity 0.8.4;\\n\\n/// @title CBridgeFacet\\n/// @author Luke Wickens \\n/// @notice cBridge intergration for bridging tokens\\n\\nimport {ICBridge} from \\\"../interfaces/ICBridge.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {ReentrancyGuard} from \\\"../../common/helpers/DiamondReentrancyGuard.sol\\\";\\nimport {CannotBridgeToSameNetwork, InvalidAmount, InvalidConfig, TokenAddressIsZero, ZeroAddressProvided} from \\\"../errors/GenericErrors.sol\\\";\\nimport {CBSlippageTooLow} from \\\"../errors/CBridgeErrors.sol\\\";\\nimport {LibDiamond} from \\\"../libs/LibDiamond.sol\\\";\\n\\ncontract CBridgeFacet is ReentrancyGuard {\\n using SafeERC20 for IERC20;\\n //////////////////////////////////////////////////////////////\\n /////////////////////////// Events ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n event CBInitialized(address cBridge, uint256 chainId);\\n event CBTransferStarted(\\n string bridgeUsed,\\n address token,\\n address from,\\n address to,\\n uint256 qty,\\n uint256 chainIdTo\\n );\\n event CBUpdatedBridge(address newAddress);\\n event CBUpdatedSlippageTolerance(uint256 newSlippage);\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Storage ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n bytes32 internal constant NAMESPACE =\\n keccak256(\\\"io.etherspot.facets.cbridge\\\");\\n struct Storage {\\n address cbBridge;\\n uint256 cbChainId;\\n uint32 cbSlippage;\\n }\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Structs ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n struct CBridgeData {\\n uint64 dstChainId;\\n uint64 nonce;\\n uint256 qty;\\n address to;\\n address token;\\n }\\n\\n /// @notice initializes state variables for the cBridge facet\\n /// @param _cbBridge address of the CBridge router contract\\n function cbInitialize(address _cbBridge) external {\\n LibDiamond.enforceIsContractOwner();\\n if (_cbBridge == address(0)) revert ZeroAddressProvided();\\n Storage storage s = getStorage();\\n s.cbBridge = _cbBridge;\\n s.cbChainId = block.chainid;\\n s.cbSlippage = 10000; // equates to 1% - has to be > 0.5% (slippage * 1M)\\n emit CBInitialized(_cbBridge, block.chainid);\\n }\\n\\n /// @notice initiates token bridging\\n /// @param _cbData: provides necessary data for cBridge transfer\\n\\n function cbBridgeTokens(CBridgeData calldata _cbData)\\n external\\n payable\\n nonReentrant\\n {\\n if (block.chainid == _cbData.dstChainId)\\n revert CannotBridgeToSameNetwork();\\n if (_cbData.to == address(0)) revert ZeroAddressProvided();\\n if (_cbData.qty <= 0) revert InvalidAmount();\\n if (_cbData.token == address(0)) revert TokenAddressIsZero();\\n\\n Storage storage s = getStorage();\\n address bridge = s.cbBridge;\\n\\n // this contract calls stargate swap()\\n IERC20(_cbData.token).safeTransferFrom(\\n msg.sender,\\n address(this),\\n _cbData.qty\\n );\\n IERC20(_cbData.token).safeApprove(address(bridge), _cbData.qty);\\n\\n ICBridge(bridge).send(\\n _cbData.to,\\n _cbData.token,\\n _cbData.qty,\\n _cbData.dstChainId,\\n _cbData.nonce,\\n s.cbSlippage\\n );\\n\\n emit CBTransferStarted(\\n \\\"cbridge\\\",\\n _cbData.token,\\n msg.sender,\\n _cbData.to,\\n _cbData.qty,\\n _cbData.dstChainId\\n );\\n }\\n\\n function cbUpdateSlippageTolerance(uint32 _newSlippage) external {\\n // should be > 0.5% (5000)\\n if (_newSlippage <= 5000) revert CBSlippageTooLow();\\n LibDiamond.enforceIsContractOwner();\\n Storage storage s = getStorage();\\n s.cbSlippage = _newSlippage;\\n emit CBUpdatedSlippageTolerance(_newSlippage);\\n }\\n\\n function cbUpdateBridge(address _newAddress) external {\\n LibDiamond.enforceIsContractOwner();\\n if (_newAddress == address(0)) revert ZeroAddressProvided();\\n Storage storage s = getStorage();\\n s.cbBridge = _newAddress;\\n emit CBUpdatedBridge(_newAddress);\\n }\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////// Private Functions /////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n /// @dev fetch local storage\\n function getStorage() private pure returns (Storage storage s) {\\n bytes32 namespace = NAMESPACE;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n s.slot := namespace\\n }\\n }\\n}\\n\",\"keccak256\":\"0x1555eba16c57843a441f5886a70a86f82ad73507f24dabdc44d6ec9e9c87ee9d\",\"license\":\"MIT\"},\"src/bridges/interfaces/ICBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// solhint-disable-next-line\\npragma solidity 0.8.4;\\n\\ninterface ICBridge {\\n function send(\\n address _receiver,\\n address _token,\\n uint256 _amount,\\n uint64 _dstChinId,\\n uint64 _nonce,\\n uint32 _maxSlippage\\n ) external;\\n\\n function sendNative(\\n address _receiver,\\n uint256 _amount,\\n uint64 _dstChinId,\\n uint64 _nonce,\\n uint32 _maxSlippage\\n ) external payable;\\n\\n function relay(\\n bytes calldata _relayRequest,\\n bytes[] calldata _sigs,\\n address[] calldata _signers,\\n uint256[] calldata _powers\\n ) external;\\n}\\n\",\"keccak256\":\"0x1d9e1f4ef38e6d8f810869d4e4126af4d3c5b70cf23ae0f61abb63151ef1c43c\",\"license\":\"MIT\"},\"src/bridges/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xc5184a3a9a2d9698572c007846bf12cf4a693dffc47425352b4b4f92beaae4db\",\"license\":\"MIT\"},\"src/bridges/libs/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress)\\n internal\\n {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x135cb5bb9fc0234dcc41a8ba75e6a95ad514cd965673f1d105103dbba18017cd\",\"license\":\"MIT\"},\"src/common/helpers/DiamondReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.4;\\n\\n/// @title Reentrancy Guard\\n/// @notice Abstract contract to provide protection against reentrancy\\nabstract contract ReentrancyGuard {\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Storage ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n bytes32 private constant NAMESPACE =\\n keccak256(\\\"io.etherspot.helpers.reentrancyguard\\\");\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Structs ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n struct ReentrancyStorage {\\n uint256 status;\\n }\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////////// Errors ////////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n error ReentrancyError();\\n\\n //////////////////////////////////////////////////////////////\\n ///////////////////////// Constants //////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n uint256 private constant _NOT_ENTERED = 0;\\n uint256 private constant _ENTERED = 1;\\n\\n //////////////////////////////////////////////////////////////\\n ///////////////////////// Modifiers ///////////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n modifier nonReentrant() {\\n ReentrancyStorage storage s = reentrancyStorage();\\n if (s.status == _ENTERED) revert ReentrancyError();\\n s.status = _ENTERED;\\n _;\\n s.status = _NOT_ENTERED;\\n }\\n\\n //////////////////////////////////////////////////////////////\\n ////////////////////// Private Functions /////////////////////\\n //////////////////////////////////////////////////////////////\\n\\n /// @dev fetch local storage\\n function reentrancyStorage()\\n private\\n pure\\n returns (ReentrancyStorage storage data)\\n {\\n bytes32 position = NAMESPACE;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n data.slot := position\\n }\\n }\\n}\\n\",\"keccak256\":\"0x80669f5e1b6d50ad0b4020e8caeb447f515e3b904b14cad5d03cc32e345753d5\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506115ab806100206000396000f3fe60806040526004361061003f5760003560e01c806340d280a21461004457806352434c6e1461006d5780636f395e60146100895780639e32e2e6146100b2575b600080fd5b34801561005057600080fd5b5061006b60048036038101906100669190610dac565b6100db565b005b61008760048036038101906100829190610dfe565b610204565b005b34801561009557600080fd5b506100b060048036038101906100ab9190610dac565b6105f6565b005b3480156100be57600080fd5b506100d960048036038101906100d49190610e50565b6106ef565b005b6100e36107a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561014a576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061015461083d565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055504681600101819055506127108160020160006101000a81548163ffffffff021916908363ffffffff1602179055507fcbfd47a07530fc4fffba96f5686a7127e5661fe26dd01503239ca2f66fcad99082466040516101f892919061112b565b60405180910390a15050565b600061020e61086a565b905060018160000154141561024f576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816000018190555081600001602081019061026c9190610e79565b67ffffffffffffffff164614156102af576040517f4ac09ad300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168260600160208101906102da9190610dac565b73ffffffffffffffffffffffffffffffffffffffff161415610328576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826040013511610366576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168260800160208101906103919190610dac565b73ffffffffffffffffffffffffffffffffffffffff1614156103df576040517fdc2e5e8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103e961083d565b905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610457333086604001358760800160208101906104319190610dac565b73ffffffffffffffffffffffffffffffffffffffff16610897909392919063ffffffff16565b6104988185604001358660800160208101906104739190610dac565b73ffffffffffffffffffffffffffffffffffffffff166109209092919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff1663a5977fbb8560600160208101906104c79190610dac565b8660800160208101906104da9190610dac565b87604001358860000160208101906104f29190610e79565b8960200160208101906105059190610e79565b8860020160009054906101000a900463ffffffff166040518763ffffffff1660e01b815260040161053b969594939291906110ca565b600060405180830381600087803b15801561055557600080fd5b505af1158015610569573d6000803e3d6000fd5b505050507fd565a5cf794050de1a171170c91acd5d14cbf11877dc3fa020e9975495ab17578460800160208101906105a19190610dac565b338660600160208101906105b59190610dac565b87604001358860000160208101906105cd9190610e79565b6040516105de9594939291906111b6565b60405180910390a15050600081600001819055505050565b6105fe6107a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610665576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061066f61083d565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f4ae67faf3cf135d9eca1b5490d3613096d2d0610fca7496112fa46ef019fbd4e826040516106e3919061104f565b60405180910390a15050565b6113888163ffffffff1611610730576040517f9ff4125000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107386107a2565b600061074261083d565b9050818160020160006101000a81548163ffffffff021916908363ffffffff1602179055507f8d5e80c35df41e151b58f1a100ad605ae1ebcda3d0c329b22820b232767a773082604051610796919061127c565b60405180910390a15050565b6107aa610a7e565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461083b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083290611176565b60405180910390fd5b565b6000807f9d7253cc9498e9cc54011bbbe9471a68adbc99d0ac1eef42369f5a452e814c4a90508091505090565b6000807fc59b5acc5a6673a6c49ca2de898f87adbd9fdfdff36f689476b1c9e0c50964b490508091505090565b61091a846323b872dd60e01b8585856040516024016108b893929190611093565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610aab565b50505050565b60008114806109b9575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b815260040161096792919061106a565b60206040518083038186803b15801561097f57600080fd5b505afa158015610993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b79190610e27565b145b6109f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ef9061125c565b60405180910390fd5b610a798363095ea7b360e01b8484604051602401610a1792919061112b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610aab565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b6000610b0d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610b729092919063ffffffff16565b9050600081511115610b6d5780806020019051810190610b2d9190610dd5565b610b6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b639061123c565b60405180910390fd5b5b505050565b6060610b818484600085610b8a565b90509392505050565b606082471015610bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc690611196565b60405180910390fd5b610bd885610c9e565b610c17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0e9061121c565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610c409190611038565b60006040518083038185875af1925050503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b5091509150610c92828286610cc1565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315610cd157829050610d21565b600083511115610ce45782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d189190611154565b60405180910390fd5b9392505050565b600081359050610d378161152b565b92915050565b600081519050610d4c81611542565b92915050565b600060a08284031215610d6457600080fd5b81905092915050565b600081519050610d7c81611559565b92915050565b600081359050610d9181611570565b92915050565b600081359050610da681611587565b92915050565b600060208284031215610dbe57600080fd5b6000610dcc84828501610d28565b91505092915050565b600060208284031215610de757600080fd5b6000610df584828501610d3d565b91505092915050565b600060a08284031215610e1057600080fd5b6000610e1e84828501610d52565b91505092915050565b600060208284031215610e3957600080fd5b6000610e4784828501610d6d565b91505092915050565b600060208284031215610e6257600080fd5b6000610e7084828501610d82565b91505092915050565b600060208284031215610e8b57600080fd5b6000610e9984828501610d97565b91505092915050565b610eab816112c9565b82525050565b6000610ebc82611297565b610ec681856112ad565b9350610ed6818560208601611359565b80840191505092915050565b6000610eed826112a2565b610ef781856112b8565b9350610f07818560208601611359565b610f108161138c565b840191505092915050565b6000610f286022836112b8565b9150610f338261139d565b604082019050919050565b6000610f4b6026836112b8565b9150610f56826113ec565b604082019050919050565b6000610f6e6007836112b8565b9150610f798261143b565b602082019050919050565b6000610f91601d836112b8565b9150610f9c82611464565b602082019050919050565b6000610fb4602a836112b8565b9150610fbf8261148d565b604082019050919050565b6000610fd76036836112b8565b9150610fe2826114dc565b604082019050919050565b610ff681611307565b82525050565b61100581611335565b82525050565b61101481611311565b82525050565b61102381611347565b82525050565b61103281611321565b82525050565b60006110448284610eb1565b915081905092915050565b60006020820190506110646000830184610ea2565b92915050565b600060408201905061107f6000830185610ea2565b61108c6020830184610ea2565b9392505050565b60006060820190506110a86000830186610ea2565b6110b56020830185610ea2565b6110c26040830184610fed565b949350505050565b600060c0820190506110df6000830189610ea2565b6110ec6020830188610ea2565b6110f96040830187610fed565b6111066060830186611029565b6111136080830185611029565b61112060a083018461100b565b979650505050505050565b60006040820190506111406000830185610ea2565b61114d6020830184610fed565b9392505050565b6000602082019050818103600083015261116e8184610ee2565b905092915050565b6000602082019050818103600083015261118f81610f1b565b9050919050565b600060208201905081810360008301526111af81610f3e565b9050919050565b600060c08201905081810360008301526111cf81610f61565b90506111de6020830188610ea2565b6111eb6040830187610ea2565b6111f86060830186610ea2565b6112056080830185610fed565b61121260a083018461101a565b9695505050505050565b6000602082019050818103600083015261123581610f84565b9050919050565b6000602082019050818103600083015261125581610fa7565b9050919050565b6000602082019050818103600083015261127581610fca565b9050919050565b60006020820190506112916000830184610ffc565b92915050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60006112d4826112e7565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600067ffffffffffffffff82169050919050565b600061134082611311565b9050919050565b600061135282611321565b9050919050565b60005b8381101561137757808201518184015260208101905061135c565b83811115611386576000848401525b50505050565b6000601f19601f8301169050919050565b7f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f6362726964676500000000000000000000000000000000000000000000000000600082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000602082015250565b611534816112c9565b811461153f57600080fd5b50565b61154b816112db565b811461155657600080fd5b50565b61156281611307565b811461156d57600080fd5b50565b61157981611311565b811461158457600080fd5b50565b61159081611321565b811461159b57600080fd5b5056fea164736f6c6343000804000a", + "deployedBytecode": "0x60806040526004361061003f5760003560e01c806340d280a21461004457806352434c6e1461006d5780636f395e60146100895780639e32e2e6146100b2575b600080fd5b34801561005057600080fd5b5061006b60048036038101906100669190610dac565b6100db565b005b61008760048036038101906100829190610dfe565b610204565b005b34801561009557600080fd5b506100b060048036038101906100ab9190610dac565b6105f6565b005b3480156100be57600080fd5b506100d960048036038101906100d49190610e50565b6106ef565b005b6100e36107a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561014a576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061015461083d565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055504681600101819055506127108160020160006101000a81548163ffffffff021916908363ffffffff1602179055507fcbfd47a07530fc4fffba96f5686a7127e5661fe26dd01503239ca2f66fcad99082466040516101f892919061112b565b60405180910390a15050565b600061020e61086a565b905060018160000154141561024f576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816000018190555081600001602081019061026c9190610e79565b67ffffffffffffffff164614156102af576040517f4ac09ad300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168260600160208101906102da9190610dac565b73ffffffffffffffffffffffffffffffffffffffff161415610328576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826040013511610366576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168260800160208101906103919190610dac565b73ffffffffffffffffffffffffffffffffffffffff1614156103df576040517fdc2e5e8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103e961083d565b905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610457333086604001358760800160208101906104319190610dac565b73ffffffffffffffffffffffffffffffffffffffff16610897909392919063ffffffff16565b6104988185604001358660800160208101906104739190610dac565b73ffffffffffffffffffffffffffffffffffffffff166109209092919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff1663a5977fbb8560600160208101906104c79190610dac565b8660800160208101906104da9190610dac565b87604001358860000160208101906104f29190610e79565b8960200160208101906105059190610e79565b8860020160009054906101000a900463ffffffff166040518763ffffffff1660e01b815260040161053b969594939291906110ca565b600060405180830381600087803b15801561055557600080fd5b505af1158015610569573d6000803e3d6000fd5b505050507fd565a5cf794050de1a171170c91acd5d14cbf11877dc3fa020e9975495ab17578460800160208101906105a19190610dac565b338660600160208101906105b59190610dac565b87604001358860000160208101906105cd9190610e79565b6040516105de9594939291906111b6565b60405180910390a15050600081600001819055505050565b6105fe6107a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610665576040517f8474420100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061066f61083d565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f4ae67faf3cf135d9eca1b5490d3613096d2d0610fca7496112fa46ef019fbd4e826040516106e3919061104f565b60405180910390a15050565b6113888163ffffffff1611610730576040517f9ff4125000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107386107a2565b600061074261083d565b9050818160020160006101000a81548163ffffffff021916908363ffffffff1602179055507f8d5e80c35df41e151b58f1a100ad605ae1ebcda3d0c329b22820b232767a773082604051610796919061127c565b60405180910390a15050565b6107aa610a7e565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461083b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083290611176565b60405180910390fd5b565b6000807f9d7253cc9498e9cc54011bbbe9471a68adbc99d0ac1eef42369f5a452e814c4a90508091505090565b6000807fc59b5acc5a6673a6c49ca2de898f87adbd9fdfdff36f689476b1c9e0c50964b490508091505090565b61091a846323b872dd60e01b8585856040516024016108b893929190611093565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610aab565b50505050565b60008114806109b9575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b815260040161096792919061106a565b60206040518083038186803b15801561097f57600080fd5b505afa158015610993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b79190610e27565b145b6109f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ef9061125c565b60405180910390fd5b610a798363095ea7b360e01b8484604051602401610a1792919061112b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610aab565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b6000610b0d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610b729092919063ffffffff16565b9050600081511115610b6d5780806020019051810190610b2d9190610dd5565b610b6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b639061123c565b60405180910390fd5b5b505050565b6060610b818484600085610b8a565b90509392505050565b606082471015610bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc690611196565b60405180910390fd5b610bd885610c9e565b610c17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0e9061121c565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610c409190611038565b60006040518083038185875af1925050503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b5091509150610c92828286610cc1565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315610cd157829050610d21565b600083511115610ce45782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d189190611154565b60405180910390fd5b9392505050565b600081359050610d378161152b565b92915050565b600081519050610d4c81611542565b92915050565b600060a08284031215610d6457600080fd5b81905092915050565b600081519050610d7c81611559565b92915050565b600081359050610d9181611570565b92915050565b600081359050610da681611587565b92915050565b600060208284031215610dbe57600080fd5b6000610dcc84828501610d28565b91505092915050565b600060208284031215610de757600080fd5b6000610df584828501610d3d565b91505092915050565b600060a08284031215610e1057600080fd5b6000610e1e84828501610d52565b91505092915050565b600060208284031215610e3957600080fd5b6000610e4784828501610d6d565b91505092915050565b600060208284031215610e6257600080fd5b6000610e7084828501610d82565b91505092915050565b600060208284031215610e8b57600080fd5b6000610e9984828501610d97565b91505092915050565b610eab816112c9565b82525050565b6000610ebc82611297565b610ec681856112ad565b9350610ed6818560208601611359565b80840191505092915050565b6000610eed826112a2565b610ef781856112b8565b9350610f07818560208601611359565b610f108161138c565b840191505092915050565b6000610f286022836112b8565b9150610f338261139d565b604082019050919050565b6000610f4b6026836112b8565b9150610f56826113ec565b604082019050919050565b6000610f6e6007836112b8565b9150610f798261143b565b602082019050919050565b6000610f91601d836112b8565b9150610f9c82611464565b602082019050919050565b6000610fb4602a836112b8565b9150610fbf8261148d565b604082019050919050565b6000610fd76036836112b8565b9150610fe2826114dc565b604082019050919050565b610ff681611307565b82525050565b61100581611335565b82525050565b61101481611311565b82525050565b61102381611347565b82525050565b61103281611321565b82525050565b60006110448284610eb1565b915081905092915050565b60006020820190506110646000830184610ea2565b92915050565b600060408201905061107f6000830185610ea2565b61108c6020830184610ea2565b9392505050565b60006060820190506110a86000830186610ea2565b6110b56020830185610ea2565b6110c26040830184610fed565b949350505050565b600060c0820190506110df6000830189610ea2565b6110ec6020830188610ea2565b6110f96040830187610fed565b6111066060830186611029565b6111136080830185611029565b61112060a083018461100b565b979650505050505050565b60006040820190506111406000830185610ea2565b61114d6020830184610fed565b9392505050565b6000602082019050818103600083015261116e8184610ee2565b905092915050565b6000602082019050818103600083015261118f81610f1b565b9050919050565b600060208201905081810360008301526111af81610f3e565b9050919050565b600060c08201905081810360008301526111cf81610f61565b90506111de6020830188610ea2565b6111eb6040830187610ea2565b6111f86060830186610ea2565b6112056080830185610fed565b61121260a083018461101a565b9695505050505050565b6000602082019050818103600083015261123581610f84565b9050919050565b6000602082019050818103600083015261125581610fa7565b9050919050565b6000602082019050818103600083015261127581610fca565b9050919050565b60006020820190506112916000830184610ffc565b92915050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60006112d4826112e7565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600067ffffffffffffffff82169050919050565b600061134082611311565b9050919050565b600061135282611321565b9050919050565b60005b8381101561137757808201518184015260208101905061135c565b83811115611386576000848401525b50505050565b6000601f19601f8301169050919050565b7f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f6362726964676500000000000000000000000000000000000000000000000000600082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000602082015250565b611534816112c9565b811461153f57600080fd5b50565b61154b816112db565b811461155657600080fd5b50565b61156281611307565b811461156d57600080fd5b50565b61157981611311565b811461158457600080fd5b50565b61159081611321565b811461159b57600080fd5b5056fea164736f6c6343000804000a", + "devdoc": { + "kind": "dev", + "methods": { + "cbBridgeTokens((uint64,uint64,uint256,address,address))": { + "params": { + "_cbData": ": provides necessary data for cBridge transfer" + } + }, + "cbInitialize(address)": { + "params": { + "_cbBridge": "address of the CBridge router contract" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "cbBridgeTokens((uint64,uint64,uint256,address,address))": { + "notice": "initiates token bridging" + }, + "cbInitialize(address)": { + "notice": "initializes state variables for the cBridge facet" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/Diamond.json b/deployments/neonDevnet/Diamond.json new file mode 100644 index 00000000..ff6e8d29 --- /dev/null +++ b/deployments/neonDevnet/Diamond.json @@ -0,0 +1,94 @@ +{ + "address": "0x3099eC5b37175c6A0011e7f0D48168CC69B21F11", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x6ec59acf08e12b570cc26e55f8c5eaef448b987c8b95823cba061ceb533b845c", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "92219320", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1b99af7148aaa8fe2227b437b8f59d19ec456d5e15be073c75223175ee80770f", + "transactionHash": "0x6ec59acf08e12b570cc26e55f8c5eaef448b987c8b95823cba061ceb533b845c", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 173997671, + "transactionHash": "0x6ec59acf08e12b570cc26e55f8c5eaef448b987c8b95823cba061ceb533b845c", + "address": "0x3099eC5b37175c6A0011e7f0D48168CC69B21F11", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000053fe9288897e254698175740aa359e19e26c10af" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x1b99af7148aaa8fe2227b437b8f59d19ec456d5e15be073c75223175ee80770f" + }, + { + "transactionIndex": 0, + "blockNumber": 173997671, + "transactionHash": "0x6ec59acf08e12b570cc26e55f8c5eaef448b987c8b95823cba061ceb533b845c", + "address": "0x3099eC5b37175c6A0011e7f0D48168CC69B21F11", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b86fe0416161ded1370016c470622125a93a82180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 1, + "blockHash": "0x1b99af7148aaa8fe2227b437b8f59d19ec456d5e15be073c75223175ee80770f" + } + ], + "blockNumber": 173997671, + "cumulativeGasUsed": "92219320", + "status": 1, + "byzantium": true + }, + "args": [ + "0x53fE9288897e254698175740aa359E19E26c10af", + "0xB86fe0416161ded1370016c470622125a93a8218" + ], + "solcInputHash": "ae94371f40f594d6ee02698e497ed59a", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_contractOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/bridges/Diamond.sol\":\"Diamond\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/bridges/Diamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport {LibDiamond} from \\\"./libs/LibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\ncontract Diamond {\\n constructor(address _contractOwner, address _diamondCutFacet) payable {\\n LibDiamond.setContractOwner(_contractOwner);\\n\\n // Add the diamondCut external function from the diamondCutFacet\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n // Find facet for function that is called and execute the\\n // function if a facet is found and return any value.\\n // solhint-disable-next-line no-complex-fallback\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n\\n // get diamond storage\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n ds.slot := position\\n }\\n\\n // get facet from function selector\\n address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;\\n require(facet != address(0), \\\"Diamond: Function does not exist\\\");\\n\\n // Execute external function from facet using delegatecall and return any value.\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // Able to receive ether\\n // solhint-disable-next-line no-empty-blocks\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xa344040a356927a1bb8eb966012cd7b49449b1d94f08ab138d4b6d34b81134fc\",\"license\":\"MIT\"},\"src/bridges/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xc5184a3a9a2d9698572c007846bf12cf4a693dffc47425352b4b4f92beaae4db\",\"license\":\"MIT\"},\"src/bridges/libs/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress)\\n internal\\n {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x135cb5bb9fc0234dcc41a8ba75e6a95ad514cd965673f1d105103dbba18017cd\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260405162004967380380620049678339818101604052810190620000299190620018d0565b6200003f82620001f760201b620001671760201c565b6000600167ffffffffffffffff8111156200005f576200005e62001917565b5b6040519080825280602002602001820160405280156200009c57816020015b620000886200181a565b8152602001906001900390816200007e5790505b5090506000600167ffffffffffffffff811115620000bf57620000be62001917565b5b604051908082528060200260200182016040528015620000ee5781602001602082028036833780820191505090505b509050631f931c1c60e01b8160008151811062000110576200010f62001946565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060405180606001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001600060028111156200019a576200019962001975565b5b81526020018281525082600081518110620001ba57620001b962001946565b5b6020026020010181905250620001ed82600060405180602001604052806000815250620002d660201b6200023e1760201c565b50505050620025cb565b6000620002096200055a60201b60201c565b905060008160040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050828260040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b60005b835181101562000505576000848281518110620002fb57620002fa62001946565b5b60200260200101516020015190506000600281111562000320576200031f62001975565b5b81600281111562000336576200033562001975565b5b0362000396576200039085838151811062000356576200035562001946565b5b60200260200101516000015186848151811062000378576200037762001946565b5b6020026020010151604001516200058760201b60201c565b620004ee565b60016002811115620003ad57620003ac62001975565b5b816002811115620003c357620003c262001975565b5b0362000423576200041d858381518110620003e357620003e262001946565b5b60200260200101516000015186848151811062000405576200040462001946565b5b6020026020010151604001516200082960201b60201c565b620004ed565b60028081111562000439576200043862001975565b5b8160028111156200044f576200044e62001975565b5b03620004af57620004a98583815181106200046f576200046e62001946565b5b60200260200101516000015186848151811062000491576200049062001946565b5b60200260200101516040015162000add60201b60201c565b620004ec565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004e39062001a2b565b60405180910390fd5b5b5b508080620004fc9062001a86565b915050620002d9565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738383836040516200053b9392919062001e0a565b60405180910390a162000555828262000c8560201b60201c565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b6000815111620005ce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005c59062001ecb565b60405180910390fd5b6000620005e06200055a60201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000654576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200064b9062001f63565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff1603620006ca57620006c9828562000eb360201b60201c565b5b60005b835181101562000822576000848281518110620006ef57620006ee62001946565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614620007e6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007dd9062001ffb565b60405180910390fd5b620007fa8583868a62000f9760201b60201c565b8380620008079062002035565b94505050508080620008199062001a86565b915050620006cd565b5050505050565b600081511162000870576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620008679062001ecb565b60405180910390fd5b6000620008826200055a60201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603620008f6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620008ed9062001f63565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16036200096c576200096b828562000eb360201b60201c565b5b60005b835181101562000ad657600084828151811062000991576200099062001946565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362000a87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000a7e90620020e4565b60405180910390fd5b62000a9a8582846200114460201b60201c565b62000aae8583868a62000f9760201b60201c565b838062000abb9062002035565b9450505050808062000acd9062001a86565b9150506200096f565b5050505050565b600081511162000b24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b1b9062001ecb565b60405180910390fd5b600062000b366200055a60201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161462000baa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000ba1906200217c565b60405180910390fd5b60005b825181101562000c7f57600083828151811062000bcf5762000bce62001946565b5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905062000c678482846200114460201b60201c565b5050808062000c769062001a86565b91505062000bad565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000d0757600081511462000d01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000cf89062002214565b60405180910390fd5b62000eaf565b600081511162000d4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000d4590620022ac565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000dae5762000dad826040518060600160405280602881526020016200491b60289139620017c560201b60201c565b5b6000808373ffffffffffffffffffffffffffffffffffffffff168360405162000dd8919062002310565b600060405180830381855af49150503d806000811462000e15576040519150601f19603f3d011682016040523d82523d6000602084013e62000e1a565b606091505b50915091508162000eac5760008151111562000e6f57806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000e66919062002375565b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000ea3906200240f565b60405180910390fd5b50505b5050565b62000ede816040518060600160405280602481526020016200494360249139620017c560201b60201c565b81600201805490508260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620011b6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620011ad90620024a7565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362001227576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200121e906200253f565b60405180910390fd5b6000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905062001300919062002561565b90508082146200149b5760008560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001828154811062001365576200136462001946565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018481548110620013e457620013e362001946565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505b8460010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805480620014f257620014f16200259c565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff0219169055505060008103620017be57600060018660020180549050620015df919062002561565b905060008660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549050818114620017275760008760020183815481106200164d576200164c62001946565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508088600201838154811062001694576200169362001946565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818860010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505b866002018054806200173e576200173d6200259c565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590558660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000905550505b5050505050565b6000823b905060008111829062001814576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200180b919062002375565b60405180910390fd5b50505050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000600281111562001859576200185862001975565b5b8152602001606081525090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062001898826200186b565b9050919050565b620018aa816200188b565b8114620018b657600080fd5b50565b600081519050620018ca816200189f565b92915050565b60008060408385031215620018ea57620018e962001866565b5b6000620018fa85828601620018b9565b92505060206200190d85828601620018b9565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600082825260208201905092915050565b7f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560008201527f74416374696f6e00000000000000000000000000000000000000000000000000602082015250565b600062001a13602783620019a4565b915062001a2082620019b5565b604082019050919050565b6000602082019050818103600083015262001a468162001a04565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b600062001a938262001a7c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362001ac85762001ac762001a4d565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b62001b0a816200188b565b82525050565b6003811062001b245762001b2362001975565b5b50565b600081905062001b378262001b10565b919050565b600062001b498262001b27565b9050919050565b62001b5b8162001b3c565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62001bc48162001b8d565b82525050565b600062001bd8838362001bb9565b60208301905092915050565b6000602082019050919050565b600062001bfe8262001b61565b62001c0a818562001b6c565b935062001c178362001b7d565b8060005b8381101562001c4e57815162001c32888262001bca565b975062001c3f8362001be4565b92505060018101905062001c1b565b5085935050505092915050565b600060608301600083015162001c75600086018262001aff565b50602083015162001c8a602086018262001b50565b506040830151848203604086015262001ca4828262001bf1565b9150508091505092915050565b600062001cbf838362001c5b565b905092915050565b6000602082019050919050565b600062001ce18262001ad3565b62001ced818562001ade565b93508360208202850162001d018562001aef565b8060005b8581101562001d43578484038952815162001d21858262001cb1565b945062001d2e8362001cc7565b925060208a0199505060018101905062001d05565b50829750879550505050505092915050565b62001d60816200188b565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101562001da257808201518184015260208101905062001d85565b8381111562001db2576000848401525b50505050565b6000601f19601f8301169050919050565b600062001dd68262001d66565b62001de2818562001d71565b935062001df481856020860162001d82565b62001dff8162001db8565b840191505092915050565b6000606082019050818103600083015262001e26818662001cd4565b905062001e37602083018562001d55565b818103604083015262001e4b818462001dc9565b9050949350505050565b7f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660008201527f6163657420746f20637574000000000000000000000000000000000000000000602082015250565b600062001eb3602b83620019a4565b915062001ec08262001e55565b604082019050919050565b6000602082019050818103600083015262001ee68162001ea4565b9050919050565b7f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260008201527f6520616464726573732830290000000000000000000000000000000000000000602082015250565b600062001f4b602c83620019a4565b915062001f588262001eed565b604082019050919050565b6000602082019050818103600083015262001f7e8162001f3c565b9050919050565b7f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60008201527f6e207468617420616c7265616479206578697374730000000000000000000000602082015250565b600062001fe3603583620019a4565b915062001ff08262001f85565b604082019050919050565b60006020820190508181036000830152620020168162001fd4565b9050919050565b60006bffffffffffffffffffffffff82169050919050565b600062002042826200201d565b91506bffffffffffffffffffffffff820362002063576200206262001a4d565b5b600182019050919050565b7f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60008201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000602082015250565b6000620020cc603883620019a4565b9150620020d9826200206e565b604082019050919050565b60006020820190508181036000830152620020ff81620020bd565b9050919050565b7f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260008201527f657373206d757374206265206164647265737328302900000000000000000000602082015250565b600062002164603683620019a4565b9150620021718262002106565b604082019050919050565b60006020820190508181036000830152620021978162002155565b9050919050565b7f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860008201527f3029206275745f63616c6c64617461206973206e6f7420656d70747900000000602082015250565b6000620021fc603c83620019a4565b915062002209826200219e565b604082019050919050565b600060208201905081810360008301526200222f81620021ed565b9050919050565b7f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460008201527f7920627574205f696e6974206973206e6f742061646472657373283029000000602082015250565b600062002294603d83620019a4565b9150620022a18262002236565b604082019050919050565b60006020820190508181036000830152620022c78162002285565b9050919050565b600081905092915050565b6000620022e68262001d66565b620022f28185620022ce565b93506200230481856020860162001d82565b80840191505092915050565b60006200231e8284620022d9565b915081905092915050565b600081519050919050565b6000620023418262002329565b6200234d8185620019a4565b93506200235f81856020860162001d82565b6200236a8162001db8565b840191505092915050565b6000602082019050818103600083015262002391818462002334565b905092915050565b7f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e20726560008201527f7665727465640000000000000000000000000000000000000000000000000000602082015250565b6000620023f7602683620019a4565b9150620024048262002399565b604082019050919050565b600060208201905081810360008301526200242a81620023e8565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360008201527f74696f6e207468617420646f65736e2774206578697374000000000000000000602082015250565b60006200248f603783620019a4565b91506200249c8262002431565b604082019050919050565b60006020820190508181036000830152620024c28162002480565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560008201527f7461626c652066756e6374696f6e000000000000000000000000000000000000602082015250565b600062002527602e83620019a4565b91506200253482620024c9565b604082019050919050565b600060208201905081810360008301526200255a8162002518565b9050919050565b60006200256e8262001a7c565b91506200257b8362001a7c565b92508282101562002591576200259062001a4d565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b61234080620025db6000396000f3fe60806040523661000b57005b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c9050809150600082600001600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610141576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610138906116c8565b60405180910390fd5b3660008037600080366000845af43d6000803e8060008114610162573d6000f35b3d6000fd5b600061017161046d565b905060008160040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050828260040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b60005b835181101561042257600084828151811061025f5761025e6116e8565b5b60200260200101516020015190506000600281111561028157610280611717565b5b81600281111561029457610293611717565b5b036102e4576102df8583815181106102af576102ae6116e8565b5b6020026020010151600001518684815181106102ce576102cd6116e8565b5b60200260200101516040015161049a565b61040e565b600160028111156102f8576102f7611717565b5b81600281111561030b5761030a611717565b5b0361035b57610356858381518110610326576103256116e8565b5b602002602001015160000151868481518110610345576103446116e8565b5b602002602001015160400151610711565b61040d565b60028081111561036e5761036d611717565b5b81600281111561038157610380611717565b5b036103d1576103cc85838151811061039c5761039b6116e8565b5b6020026020010151600001518684815181106103bb576103ba6116e8565b5b602002602001015160400151610992565b61040c565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610403906117b8565b60405180910390fd5b5b5b50808061041a90611811565b915050610241565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161045693929190611b86565b60405180910390a16104688282610b1d565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b60008151116104de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d590611c3d565b60405180910390fd5b60006104e861046d565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610559576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161055090611ccf565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16036105c6576105c58285610d2f565b5b60005b835181101561070a5760008482815181106105e7576105e66116e8565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106d290611d61565b60405180910390fd5b6106e78583868a610e0a565b83806106f290611d99565b9450505050808061070290611811565b9150506105c9565b5050505050565b6000815111610755576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074c90611c3d565b60405180910390fd5b600061075f61046d565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036107d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107c790611ccf565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff160361083d5761083c8285610d2f565b5b60005b835181101561098b57600084828151811061085e5761085d6116e8565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610951576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094890611e3f565b60405180910390fd5b61095c858284610fb7565b6109688583868a610e0a565b838061097390611d99565b9450505050808061098390611811565b915050610840565b5050505050565b60008151116109d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109cd90611c3d565b60405180910390fd5b60006109e061046d565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890611ed1565b60405180910390fd5b60005b8251811015610b17576000838281518110610a7257610a716116e8565b5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610b02848284610fb7565b50508080610b0f90611811565b915050610a54565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b9a576000815114610b95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8c90611f63565b60405180910390fd5b610d2b565b6000815111610bde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd590611ff5565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610c3457610c33826040518060600160405280602881526020016122e860289139611619565b5b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610c5c9190612051565b600060405180830381855af49150503d8060008114610c97576040519150601f19603f3d011682016040523d82523d6000602084013e610c9c565b606091505b509150915081610d2857600081511115610ced57806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce491906120ac565b60405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1f90612140565b60405180910390fd5b50505b5050565b610d518160405180606001604052806024815260200161231060249139611619565b81600201805490508260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611026576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101d906121d2565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611094576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108b90612264565b60405180910390fd5b6000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905061116b9190612284565b90508082146112ff5760008560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000182815481106111cc576111cb6116e8565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018481548110611248576112476116e8565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505b8460010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805480611353576113526122b8565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff02191690555050600081036116125760006001866002018054905061143d9190612284565b905060008660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905081811461157e5760008760020183815481106114a7576114a66116e8565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808860020183815481106114eb576114ea6116e8565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818860010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505b86600201805480611592576115916122b8565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590558660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000905550505b5050505050565b6000823b9050600081118290611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165c91906120ac565b60405180910390fd5b50505050565b600082825260208201905092915050565b7f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f74206578697374600082015250565b60006116b260208361166b565b91506116bd8261167c565b602082019050919050565b600060208201905081810360008301526116e1816116a5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560008201527f74416374696f6e00000000000000000000000000000000000000000000000000602082015250565b60006117a260278361166b565b91506117ad82611746565b604082019050919050565b600060208201905081810360008301526117d181611795565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b600061181c82611807565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361184e5761184d6117d8565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006118b082611885565b9050919050565b6118c0816118a5565b82525050565b600381106118d7576118d6611717565b5b50565b60008190506118e8826118c6565b919050565b60006118f8826118da565b9050919050565b611908816118ed565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61196f8161193a565b82525050565b60006119818383611966565b60208301905092915050565b6000602082019050919050565b60006119a58261190e565b6119af8185611919565b93506119ba8361192a565b8060005b838110156119eb5781516119d28882611975565b97506119dd8361198d565b9250506001810190506119be565b5085935050505092915050565b6000606083016000830151611a1060008601826118b7565b506020830151611a2360208601826118ff565b5060408301518482036040860152611a3b828261199a565b9150508091505092915050565b6000611a5483836119f8565b905092915050565b6000602082019050919050565b6000611a7482611859565b611a7e8185611864565b935083602082028501611a9085611875565b8060005b85811015611acc5784840389528151611aad8582611a48565b9450611ab883611a5c565b925060208a01995050600181019050611a94565b50829750879550505050505092915050565b611ae7816118a5565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611b27578082015181840152602081019050611b0c565b83811115611b36576000848401525b50505050565b6000601f19601f8301169050919050565b6000611b5882611aed565b611b628185611af8565b9350611b72818560208601611b09565b611b7b81611b3c565b840191505092915050565b60006060820190508181036000830152611ba08186611a69565b9050611baf6020830185611ade565b8181036040830152611bc18184611b4d565b9050949350505050565b7f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660008201527f6163657420746f20637574000000000000000000000000000000000000000000602082015250565b6000611c27602b8361166b565b9150611c3282611bcb565b604082019050919050565b60006020820190508181036000830152611c5681611c1a565b9050919050565b7f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260008201527f6520616464726573732830290000000000000000000000000000000000000000602082015250565b6000611cb9602c8361166b565b9150611cc482611c5d565b604082019050919050565b60006020820190508181036000830152611ce881611cac565b9050919050565b7f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60008201527f6e207468617420616c7265616479206578697374730000000000000000000000602082015250565b6000611d4b60358361166b565b9150611d5682611cef565b604082019050919050565b60006020820190508181036000830152611d7a81611d3e565b9050919050565b60006bffffffffffffffffffffffff82169050919050565b6000611da482611d81565b91506bffffffffffffffffffffffff8203611dc257611dc16117d8565b5b600182019050919050565b7f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60008201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000602082015250565b6000611e2960388361166b565b9150611e3482611dcd565b604082019050919050565b60006020820190508181036000830152611e5881611e1c565b9050919050565b7f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260008201527f657373206d757374206265206164647265737328302900000000000000000000602082015250565b6000611ebb60368361166b565b9150611ec682611e5f565b604082019050919050565b60006020820190508181036000830152611eea81611eae565b9050919050565b7f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860008201527f3029206275745f63616c6c64617461206973206e6f7420656d70747900000000602082015250565b6000611f4d603c8361166b565b9150611f5882611ef1565b604082019050919050565b60006020820190508181036000830152611f7c81611f40565b9050919050565b7f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460008201527f7920627574205f696e6974206973206e6f742061646472657373283029000000602082015250565b6000611fdf603d8361166b565b9150611fea82611f83565b604082019050919050565b6000602082019050818103600083015261200e81611fd2565b9050919050565b600081905092915050565b600061202b82611aed565b6120358185612015565b9350612045818560208601611b09565b80840191505092915050565b600061205d8284612020565b915081905092915050565b600081519050919050565b600061207e82612068565b612088818561166b565b9350612098818560208601611b09565b6120a181611b3c565b840191505092915050565b600060208201905081810360008301526120c68184612073565b905092915050565b7f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e20726560008201527f7665727465640000000000000000000000000000000000000000000000000000602082015250565b600061212a60268361166b565b9150612135826120ce565b604082019050919050565b600060208201905081810360008301526121598161211d565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360008201527f74696f6e207468617420646f65736e2774206578697374000000000000000000602082015250565b60006121bc60378361166b565b91506121c782612160565b604082019050919050565b600060208201905081810360008301526121eb816121af565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560008201527f7461626c652066756e6374696f6e000000000000000000000000000000000000602082015250565b600061224e602e8361166b565b9150612259826121f2565b604082019050919050565b6000602082019050818103600083015261227d81612241565b9050919050565b600061228f82611807565b915061229a83611807565b9250828210156122ad576122ac6117d8565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a164736f6c634300080f000a4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465", + "deployedBytecode": "0x60806040523661000b57005b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c9050809150600082600001600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610141576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610138906116c8565b60405180910390fd5b3660008037600080366000845af43d6000803e8060008114610162573d6000f35b3d6000fd5b600061017161046d565b905060008160040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050828260040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b60005b835181101561042257600084828151811061025f5761025e6116e8565b5b60200260200101516020015190506000600281111561028157610280611717565b5b81600281111561029457610293611717565b5b036102e4576102df8583815181106102af576102ae6116e8565b5b6020026020010151600001518684815181106102ce576102cd6116e8565b5b60200260200101516040015161049a565b61040e565b600160028111156102f8576102f7611717565b5b81600281111561030b5761030a611717565b5b0361035b57610356858381518110610326576103256116e8565b5b602002602001015160000151868481518110610345576103446116e8565b5b602002602001015160400151610711565b61040d565b60028081111561036e5761036d611717565b5b81600281111561038157610380611717565b5b036103d1576103cc85838151811061039c5761039b6116e8565b5b6020026020010151600001518684815181106103bb576103ba6116e8565b5b602002602001015160400151610992565b61040c565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610403906117b8565b60405180910390fd5b5b5b50808061041a90611811565b915050610241565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161045693929190611b86565b60405180910390a16104688282610b1d565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b60008151116104de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d590611c3d565b60405180910390fd5b60006104e861046d565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610559576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161055090611ccf565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16036105c6576105c58285610d2f565b5b60005b835181101561070a5760008482815181106105e7576105e66116e8565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106d290611d61565b60405180910390fd5b6106e78583868a610e0a565b83806106f290611d99565b9450505050808061070290611811565b9150506105c9565b5050505050565b6000815111610755576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074c90611c3d565b60405180910390fd5b600061075f61046d565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036107d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107c790611ccf565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff160361083d5761083c8285610d2f565b5b60005b835181101561098b57600084828151811061085e5761085d6116e8565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610951576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094890611e3f565b60405180910390fd5b61095c858284610fb7565b6109688583868a610e0a565b838061097390611d99565b9450505050808061098390611811565b915050610840565b5050505050565b60008151116109d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109cd90611c3d565b60405180910390fd5b60006109e061046d565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890611ed1565b60405180910390fd5b60005b8251811015610b17576000838281518110610a7257610a716116e8565b5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610b02848284610fb7565b50508080610b0f90611811565b915050610a54565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b9a576000815114610b95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8c90611f63565b60405180910390fd5b610d2b565b6000815111610bde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd590611ff5565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610c3457610c33826040518060600160405280602881526020016122e860289139611619565b5b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610c5c9190612051565b600060405180830381855af49150503d8060008114610c97576040519150601f19603f3d011682016040523d82523d6000602084013e610c9c565b606091505b509150915081610d2857600081511115610ced57806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce491906120ac565b60405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1f90612140565b60405180910390fd5b50505b5050565b610d518160405180606001604052806024815260200161231060249139611619565b81600201805490508260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611026576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101d906121d2565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611094576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108b90612264565b60405180910390fd5b6000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905061116b9190612284565b90508082146112ff5760008560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000182815481106111cc576111cb6116e8565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018481548110611248576112476116e8565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505b8460010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805480611353576113526122b8565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff02191690555050600081036116125760006001866002018054905061143d9190612284565b905060008660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905081811461157e5760008760020183815481106114a7576114a66116e8565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808860020183815481106114eb576114ea6116e8565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818860010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505b86600201805480611592576115916122b8565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590558660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000905550505b5050505050565b6000823b9050600081118290611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165c91906120ac565b60405180910390fd5b50505050565b600082825260208201905092915050565b7f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f74206578697374600082015250565b60006116b260208361166b565b91506116bd8261167c565b602082019050919050565b600060208201905081810360008301526116e1816116a5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560008201527f74416374696f6e00000000000000000000000000000000000000000000000000602082015250565b60006117a260278361166b565b91506117ad82611746565b604082019050919050565b600060208201905081810360008301526117d181611795565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b600061181c82611807565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361184e5761184d6117d8565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006118b082611885565b9050919050565b6118c0816118a5565b82525050565b600381106118d7576118d6611717565b5b50565b60008190506118e8826118c6565b919050565b60006118f8826118da565b9050919050565b611908816118ed565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61196f8161193a565b82525050565b60006119818383611966565b60208301905092915050565b6000602082019050919050565b60006119a58261190e565b6119af8185611919565b93506119ba8361192a565b8060005b838110156119eb5781516119d28882611975565b97506119dd8361198d565b9250506001810190506119be565b5085935050505092915050565b6000606083016000830151611a1060008601826118b7565b506020830151611a2360208601826118ff565b5060408301518482036040860152611a3b828261199a565b9150508091505092915050565b6000611a5483836119f8565b905092915050565b6000602082019050919050565b6000611a7482611859565b611a7e8185611864565b935083602082028501611a9085611875565b8060005b85811015611acc5784840389528151611aad8582611a48565b9450611ab883611a5c565b925060208a01995050600181019050611a94565b50829750879550505050505092915050565b611ae7816118a5565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611b27578082015181840152602081019050611b0c565b83811115611b36576000848401525b50505050565b6000601f19601f8301169050919050565b6000611b5882611aed565b611b628185611af8565b9350611b72818560208601611b09565b611b7b81611b3c565b840191505092915050565b60006060820190508181036000830152611ba08186611a69565b9050611baf6020830185611ade565b8181036040830152611bc18184611b4d565b9050949350505050565b7f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660008201527f6163657420746f20637574000000000000000000000000000000000000000000602082015250565b6000611c27602b8361166b565b9150611c3282611bcb565b604082019050919050565b60006020820190508181036000830152611c5681611c1a565b9050919050565b7f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260008201527f6520616464726573732830290000000000000000000000000000000000000000602082015250565b6000611cb9602c8361166b565b9150611cc482611c5d565b604082019050919050565b60006020820190508181036000830152611ce881611cac565b9050919050565b7f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60008201527f6e207468617420616c7265616479206578697374730000000000000000000000602082015250565b6000611d4b60358361166b565b9150611d5682611cef565b604082019050919050565b60006020820190508181036000830152611d7a81611d3e565b9050919050565b60006bffffffffffffffffffffffff82169050919050565b6000611da482611d81565b91506bffffffffffffffffffffffff8203611dc257611dc16117d8565b5b600182019050919050565b7f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60008201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000602082015250565b6000611e2960388361166b565b9150611e3482611dcd565b604082019050919050565b60006020820190508181036000830152611e5881611e1c565b9050919050565b7f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260008201527f657373206d757374206265206164647265737328302900000000000000000000602082015250565b6000611ebb60368361166b565b9150611ec682611e5f565b604082019050919050565b60006020820190508181036000830152611eea81611eae565b9050919050565b7f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860008201527f3029206275745f63616c6c64617461206973206e6f7420656d70747900000000602082015250565b6000611f4d603c8361166b565b9150611f5882611ef1565b604082019050919050565b60006020820190508181036000830152611f7c81611f40565b9050919050565b7f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460008201527f7920627574205f696e6974206973206e6f742061646472657373283029000000602082015250565b6000611fdf603d8361166b565b9150611fea82611f83565b604082019050919050565b6000602082019050818103600083015261200e81611fd2565b9050919050565b600081905092915050565b600061202b82611aed565b6120358185612015565b9350612045818560208601611b09565b80840191505092915050565b600061205d8284612020565b915081905092915050565b600081519050919050565b600061207e82612068565b612088818561166b565b9350612098818560208601611b09565b6120a181611b3c565b840191505092915050565b600060208201905081810360008301526120c68184612073565b905092915050565b7f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e20726560008201527f7665727465640000000000000000000000000000000000000000000000000000602082015250565b600061212a60268361166b565b9150612135826120ce565b604082019050919050565b600060208201905081810360008301526121598161211d565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360008201527f74696f6e207468617420646f65736e2774206578697374000000000000000000602082015250565b60006121bc60378361166b565b91506121c782612160565b604082019050919050565b600060208201905081810360008301526121eb816121af565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560008201527f7461626c652066756e6374696f6e000000000000000000000000000000000000602082015250565b600061224e602e8361166b565b9150612259826121f2565b604082019050919050565b6000602082019050818103600083015261227d81612241565b9050919050565b600061228f82611807565b915061229a83611807565b9250828210156122ad576122ac6117d8565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a164736f6c634300080f000a", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/DiamondCutFacet.json b/deployments/neonDevnet/DiamondCutFacet.json new file mode 100644 index 00000000..ee712d25 --- /dev/null +++ b/deployments/neonDevnet/DiamondCutFacet.json @@ -0,0 +1,134 @@ +{ + "address": "0xB86fe0416161ded1370016c470622125a93a8218", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x650e66c9ac00bee56871d968b5c5c6dc0965f6d6043bc0e40cb3c9e83c9bf06d", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "93681800", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x6a100882200190c8057188d576230f003b7707723cc2ee08e9dc44ba78898cf2", + "transactionHash": "0x650e66c9ac00bee56871d968b5c5c6dc0965f6d6043bc0e40cb3c9e83c9bf06d", + "logs": [], + "blockNumber": 173997593, + "cumulativeGasUsed": "93681800", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "ae94371f40f594d6ee02698e497ed59a", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/bridges/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/bridges/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport { IDiamondCut } from \\\"../interfaces/IDiamondCut.sol\\\";\\nimport { LibDiamond } from \\\"../libs/LibDiamond.sol\\\";\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0x25097604fd77c314dbbc63792aff004f1b80188daea756555a2bd7ee0d2f26d7\",\"license\":\"MIT\"},\"src/bridges/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xc5184a3a9a2d9698572c007846bf12cf4a693dffc47425352b4b4f92beaae4db\",\"license\":\"MIT\"},\"src/bridges/libs/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress)\\n internal\\n {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x135cb5bb9fc0234dcc41a8ba75e6a95ad514cd965673f1d105103dbba18017cd\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506126ea806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004a600480360381019061004591906116ab565b61004c565b005b6100546100b6565b6100af8585906100649190611a49565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610151565b5050505050565b6100be610380565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461014f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161014690611ae1565b60405180910390fd5b565b60005b835181101561033557600084828151811061017257610171611b01565b5b60200260200101516020015190506000600281111561019457610193611b30565b5b8160028111156101a7576101a6611b30565b5b036101f7576101f28583815181106101c2576101c1611b01565b5b6020026020010151600001518684815181106101e1576101e0611b01565b5b6020026020010151604001516103ad565b610321565b6001600281111561020b5761020a611b30565b5b81600281111561021e5761021d611b30565b5b0361026e5761026985838151811061023957610238611b01565b5b60200260200101516000015186848151811061025857610257611b01565b5b602002602001015160400151610624565b610320565b60028081111561028157610280611b30565b5b81600281111561029457610293611b30565b5b036102e4576102df8583815181106102af576102ae611b01565b5b6020026020010151600001518684815181106102ce576102cd611b01565b5b6020026020010151604001516108a5565b61031f565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031690611bd1565b60405180910390fd5b5b5b50808061032d90611c2a565b915050610154565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161036993929190611f30565b60405180910390a161037b8282610a30565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b60008151116103f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e890611fe7565b60405180910390fd5b60006103fb610380565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361046c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046390612079565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16036104d9576104d88285610c42565b5b60005b835181101561061d5760008482815181106104fa576104f9611b01565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e59061210b565b60405180910390fd5b6105fa8583868a610d1d565b838061060590612143565b9450505050808061061590611c2a565b9150506104dc565b5050505050565b6000815111610668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065f90611fe7565b60405180910390fd5b6000610672610380565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036106e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106da90612079565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16036107505761074f8285610c42565b5b60005b835181101561089e57600084828151811061077157610770611b01565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610864576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085b906121e9565b60405180910390fd5b61086f858284610eca565b61087b8583868a610d1d565b838061088690612143565b9450505050808061089690611c2a565b915050610753565b5050505050565b60008151116108e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e090611fe7565b60405180910390fd5b60006108f3610380565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095b9061227b565b60405180910390fd5b60005b8251811015610a2a57600083828151811061098557610984611b01565b5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610a15848284610eca565b50508080610a2290611c2a565b915050610967565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610aad576000815114610aa8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9f9061230d565b60405180910390fd5b610c3e565b6000815111610af1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae89061239f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610b4757610b46826040518060600160405280602881526020016126926028913961152c565b5b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b6f91906123fb565b600060405180830381855af49150503d8060008114610baa576040519150601f19603f3d011682016040523d82523d6000602084013e610baf565b606091505b509150915081610c3b57600081511115610c0057806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf79190612456565b60405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c32906124ea565b60405180910390fd5b50505b5050565b610c64816040518060600160405280602481526020016126ba6024913961152c565b81600201805490508260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f309061257c565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610fa7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9e9061260e565b60405180910390fd5b6000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905061107e919061262e565b90508082146112125760008560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000182815481106110df576110de611b01565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001848154811061115b5761115a611b01565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505b8460010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000180548061126657611265612662565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff021916905550506000810361152557600060018660020180549050611350919061262e565b905060008660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490508181146114915760008760020183815481106113ba576113b9611b01565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808860020183815481106113fe576113fd611b01565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818860010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505b866002018054806114a5576114a4612662565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590558660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000905550505b5050505050565b6000823b9050600081118290611578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156f9190612456565b60405180910390fd5b50505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126115b7576115b6611592565b5b8235905067ffffffffffffffff8111156115d4576115d3611597565b5b6020830191508360208202830111156115f0576115ef61159c565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611622826115f7565b9050919050565b61163281611617565b811461163d57600080fd5b50565b60008135905061164f81611629565b92915050565b60008083601f84011261166b5761166a611592565b5b8235905067ffffffffffffffff81111561168857611687611597565b5b6020830191508360018202830111156116a4576116a361159c565b5b9250929050565b6000806000806000606086880312156116c7576116c6611588565b5b600086013567ffffffffffffffff8111156116e5576116e461158d565b5b6116f1888289016115a1565b9550955050602061170488828901611640565b935050604086013567ffffffffffffffff8111156117255761172461158d565b5b61173188828901611655565b92509250509295509295909350565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61178982611740565b810181811067ffffffffffffffff821117156117a8576117a7611751565b5b80604052505050565b60006117bb61157e565b90506117c78282611780565b919050565b600067ffffffffffffffff8211156117e7576117e6611751565b5b602082029050602081019050919050565b600080fd5b600080fd5b6003811061180f57600080fd5b50565b60008135905061182181611802565b92915050565b600067ffffffffffffffff82111561184257611841611751565b5b602082029050602081019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61188881611853565b811461189357600080fd5b50565b6000813590506118a58161187f565b92915050565b60006118be6118b984611827565b6117b1565b905080838252602082019050602084028301858111156118e1576118e061159c565b5b835b8181101561190a57806118f68882611896565b8452602084019350506020810190506118e3565b5050509392505050565b600082601f83011261192957611928611592565b5b81356119398482602086016118ab565b91505092915050565b600060608284031215611958576119576117f8565b5b61196260606117b1565b9050600061197284828501611640565b600083015250602061198684828501611812565b602083015250604082013567ffffffffffffffff8111156119aa576119a96117fd565b5b6119b684828501611914565b60408301525092915050565b60006119d56119d0846117cc565b6117b1565b905080838252602082019050602084028301858111156119f8576119f761159c565b5b835b81811015611a3f57803567ffffffffffffffff811115611a1d57611a1c611592565b5b808601611a2a8982611942565b855260208501945050506020810190506119fa565b5050509392505050565b6000611a563684846119c2565b905092915050565b600082825260208201905092915050565b7f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b6000611acb602283611a5e565b9150611ad682611a6f565b604082019050919050565b60006020820190508181036000830152611afa81611abe565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560008201527f74416374696f6e00000000000000000000000000000000000000000000000000602082015250565b6000611bbb602783611a5e565b9150611bc682611b5f565b604082019050919050565b60006020820190508181036000830152611bea81611bae565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000611c3582611c20565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c6757611c66611bf1565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ca781611617565b82525050565b60038110611cbe57611cbd611b30565b5b50565b6000819050611ccf82611cad565b919050565b6000611cdf82611cc1565b9050919050565b611cef81611cd4565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611d2a81611853565b82525050565b6000611d3c8383611d21565b60208301905092915050565b6000602082019050919050565b6000611d6082611cf5565b611d6a8185611d00565b9350611d7583611d11565b8060005b83811015611da6578151611d8d8882611d30565b9750611d9883611d48565b925050600181019050611d79565b5085935050505092915050565b6000606083016000830151611dcb6000860182611c9e565b506020830151611dde6020860182611ce6565b5060408301518482036040860152611df68282611d55565b9150508091505092915050565b6000611e0f8383611db3565b905092915050565b6000602082019050919050565b6000611e2f82611c72565b611e398185611c7d565b935083602082028501611e4b85611c8e565b8060005b85811015611e875784840389528151611e688582611e03565b9450611e7383611e17565b925060208a01995050600181019050611e4f565b50829750879550505050505092915050565b611ea281611617565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ee2578082015181840152602081019050611ec7565b83811115611ef1576000848401525b50505050565b6000611f0282611ea8565b611f0c8185611eb3565b9350611f1c818560208601611ec4565b611f2581611740565b840191505092915050565b60006060820190508181036000830152611f4a8186611e24565b9050611f596020830185611e99565b8181036040830152611f6b8184611ef7565b9050949350505050565b7f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660008201527f6163657420746f20637574000000000000000000000000000000000000000000602082015250565b6000611fd1602b83611a5e565b9150611fdc82611f75565b604082019050919050565b6000602082019050818103600083015261200081611fc4565b9050919050565b7f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260008201527f6520616464726573732830290000000000000000000000000000000000000000602082015250565b6000612063602c83611a5e565b915061206e82612007565b604082019050919050565b6000602082019050818103600083015261209281612056565b9050919050565b7f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60008201527f6e207468617420616c7265616479206578697374730000000000000000000000602082015250565b60006120f5603583611a5e565b915061210082612099565b604082019050919050565b60006020820190508181036000830152612124816120e8565b9050919050565b60006bffffffffffffffffffffffff82169050919050565b600061214e8261212b565b91506bffffffffffffffffffffffff820361216c5761216b611bf1565b5b600182019050919050565b7f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60008201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000602082015250565b60006121d3603883611a5e565b91506121de82612177565b604082019050919050565b60006020820190508181036000830152612202816121c6565b9050919050565b7f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260008201527f657373206d757374206265206164647265737328302900000000000000000000602082015250565b6000612265603683611a5e565b915061227082612209565b604082019050919050565b6000602082019050818103600083015261229481612258565b9050919050565b7f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860008201527f3029206275745f63616c6c64617461206973206e6f7420656d70747900000000602082015250565b60006122f7603c83611a5e565b91506123028261229b565b604082019050919050565b60006020820190508181036000830152612326816122ea565b9050919050565b7f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460008201527f7920627574205f696e6974206973206e6f742061646472657373283029000000602082015250565b6000612389603d83611a5e565b91506123948261232d565b604082019050919050565b600060208201905081810360008301526123b88161237c565b9050919050565b600081905092915050565b60006123d582611ea8565b6123df81856123bf565b93506123ef818560208601611ec4565b80840191505092915050565b600061240782846123ca565b915081905092915050565b600081519050919050565b600061242882612412565b6124328185611a5e565b9350612442818560208601611ec4565b61244b81611740565b840191505092915050565b60006020820190508181036000830152612470818461241d565b905092915050565b7f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e20726560008201527f7665727465640000000000000000000000000000000000000000000000000000602082015250565b60006124d4602683611a5e565b91506124df82612478565b604082019050919050565b60006020820190508181036000830152612503816124c7565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360008201527f74696f6e207468617420646f65736e2774206578697374000000000000000000602082015250565b6000612566603783611a5e565b91506125718261250a565b604082019050919050565b6000602082019050818103600083015261259581612559565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560008201527f7461626c652066756e6374696f6e000000000000000000000000000000000000602082015250565b60006125f8602e83611a5e565b91506126038261259c565b604082019050919050565b60006020820190508181036000830152612627816125eb565b9050919050565b600061263982611c20565b915061264483611c20565b92508282101561265757612656611bf1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a164736f6c634300080f000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004a600480360381019061004591906116ab565b61004c565b005b6100546100b6565b6100af8585906100649190611a49565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610151565b5050505050565b6100be610380565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461014f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161014690611ae1565b60405180910390fd5b565b60005b835181101561033557600084828151811061017257610171611b01565b5b60200260200101516020015190506000600281111561019457610193611b30565b5b8160028111156101a7576101a6611b30565b5b036101f7576101f28583815181106101c2576101c1611b01565b5b6020026020010151600001518684815181106101e1576101e0611b01565b5b6020026020010151604001516103ad565b610321565b6001600281111561020b5761020a611b30565b5b81600281111561021e5761021d611b30565b5b0361026e5761026985838151811061023957610238611b01565b5b60200260200101516000015186848151811061025857610257611b01565b5b602002602001015160400151610624565b610320565b60028081111561028157610280611b30565b5b81600281111561029457610293611b30565b5b036102e4576102df8583815181106102af576102ae611b01565b5b6020026020010151600001518684815181106102ce576102cd611b01565b5b6020026020010151604001516108a5565b61031f565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031690611bd1565b60405180910390fd5b5b5b50808061032d90611c2a565b915050610154565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161036993929190611f30565b60405180910390a161037b8282610a30565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b60008151116103f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e890611fe7565b60405180910390fd5b60006103fb610380565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361046c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046390612079565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16036104d9576104d88285610c42565b5b60005b835181101561061d5760008482815181106104fa576104f9611b01565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e59061210b565b60405180910390fd5b6105fa8583868a610d1d565b838061060590612143565b9450505050808061061590611c2a565b9150506104dc565b5050505050565b6000815111610668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065f90611fe7565b60405180910390fd5b6000610672610380565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036106e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106da90612079565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16036107505761074f8285610c42565b5b60005b835181101561089e57600084828151811061077157610770611b01565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610864576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085b906121e9565b60405180910390fd5b61086f858284610eca565b61087b8583868a610d1d565b838061088690612143565b9450505050808061089690611c2a565b915050610753565b5050505050565b60008151116108e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e090611fe7565b60405180910390fd5b60006108f3610380565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095b9061227b565b60405180910390fd5b60005b8251811015610a2a57600083828151811061098557610984611b01565b5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610a15848284610eca565b50508080610a2290611c2a565b915050610967565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610aad576000815114610aa8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9f9061230d565b60405180910390fd5b610c3e565b6000815111610af1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae89061239f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610b4757610b46826040518060600160405280602881526020016126926028913961152c565b5b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b6f91906123fb565b600060405180830381855af49150503d8060008114610baa576040519150601f19603f3d011682016040523d82523d6000602084013e610baf565b606091505b509150915081610c3b57600081511115610c0057806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf79190612456565b60405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c32906124ea565b60405180910390fd5b50505b5050565b610c64816040518060600160405280602481526020016126ba6024913961152c565b81600201805490508260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f309061257c565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610fa7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9e9061260e565b60405180910390fd5b6000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905061107e919061262e565b90508082146112125760008560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000182815481106110df576110de611b01565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001848154811061115b5761115a611b01565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505b8460010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000180548061126657611265612662565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff021916905550506000810361152557600060018660020180549050611350919061262e565b905060008660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490508181146114915760008760020183815481106113ba576113b9611b01565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808860020183815481106113fe576113fd611b01565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818860010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505b866002018054806114a5576114a4612662565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590558660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000905550505b5050505050565b6000823b9050600081118290611578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156f9190612456565b60405180910390fd5b50505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126115b7576115b6611592565b5b8235905067ffffffffffffffff8111156115d4576115d3611597565b5b6020830191508360208202830111156115f0576115ef61159c565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611622826115f7565b9050919050565b61163281611617565b811461163d57600080fd5b50565b60008135905061164f81611629565b92915050565b60008083601f84011261166b5761166a611592565b5b8235905067ffffffffffffffff81111561168857611687611597565b5b6020830191508360018202830111156116a4576116a361159c565b5b9250929050565b6000806000806000606086880312156116c7576116c6611588565b5b600086013567ffffffffffffffff8111156116e5576116e461158d565b5b6116f1888289016115a1565b9550955050602061170488828901611640565b935050604086013567ffffffffffffffff8111156117255761172461158d565b5b61173188828901611655565b92509250509295509295909350565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61178982611740565b810181811067ffffffffffffffff821117156117a8576117a7611751565b5b80604052505050565b60006117bb61157e565b90506117c78282611780565b919050565b600067ffffffffffffffff8211156117e7576117e6611751565b5b602082029050602081019050919050565b600080fd5b600080fd5b6003811061180f57600080fd5b50565b60008135905061182181611802565b92915050565b600067ffffffffffffffff82111561184257611841611751565b5b602082029050602081019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61188881611853565b811461189357600080fd5b50565b6000813590506118a58161187f565b92915050565b60006118be6118b984611827565b6117b1565b905080838252602082019050602084028301858111156118e1576118e061159c565b5b835b8181101561190a57806118f68882611896565b8452602084019350506020810190506118e3565b5050509392505050565b600082601f83011261192957611928611592565b5b81356119398482602086016118ab565b91505092915050565b600060608284031215611958576119576117f8565b5b61196260606117b1565b9050600061197284828501611640565b600083015250602061198684828501611812565b602083015250604082013567ffffffffffffffff8111156119aa576119a96117fd565b5b6119b684828501611914565b60408301525092915050565b60006119d56119d0846117cc565b6117b1565b905080838252602082019050602084028301858111156119f8576119f761159c565b5b835b81811015611a3f57803567ffffffffffffffff811115611a1d57611a1c611592565b5b808601611a2a8982611942565b855260208501945050506020810190506119fa565b5050509392505050565b6000611a563684846119c2565b905092915050565b600082825260208201905092915050565b7f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b6000611acb602283611a5e565b9150611ad682611a6f565b604082019050919050565b60006020820190508181036000830152611afa81611abe565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560008201527f74416374696f6e00000000000000000000000000000000000000000000000000602082015250565b6000611bbb602783611a5e565b9150611bc682611b5f565b604082019050919050565b60006020820190508181036000830152611bea81611bae565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000611c3582611c20565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c6757611c66611bf1565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ca781611617565b82525050565b60038110611cbe57611cbd611b30565b5b50565b6000819050611ccf82611cad565b919050565b6000611cdf82611cc1565b9050919050565b611cef81611cd4565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611d2a81611853565b82525050565b6000611d3c8383611d21565b60208301905092915050565b6000602082019050919050565b6000611d6082611cf5565b611d6a8185611d00565b9350611d7583611d11565b8060005b83811015611da6578151611d8d8882611d30565b9750611d9883611d48565b925050600181019050611d79565b5085935050505092915050565b6000606083016000830151611dcb6000860182611c9e565b506020830151611dde6020860182611ce6565b5060408301518482036040860152611df68282611d55565b9150508091505092915050565b6000611e0f8383611db3565b905092915050565b6000602082019050919050565b6000611e2f82611c72565b611e398185611c7d565b935083602082028501611e4b85611c8e565b8060005b85811015611e875784840389528151611e688582611e03565b9450611e7383611e17565b925060208a01995050600181019050611e4f565b50829750879550505050505092915050565b611ea281611617565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ee2578082015181840152602081019050611ec7565b83811115611ef1576000848401525b50505050565b6000611f0282611ea8565b611f0c8185611eb3565b9350611f1c818560208601611ec4565b611f2581611740565b840191505092915050565b60006060820190508181036000830152611f4a8186611e24565b9050611f596020830185611e99565b8181036040830152611f6b8184611ef7565b9050949350505050565b7f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660008201527f6163657420746f20637574000000000000000000000000000000000000000000602082015250565b6000611fd1602b83611a5e565b9150611fdc82611f75565b604082019050919050565b6000602082019050818103600083015261200081611fc4565b9050919050565b7f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260008201527f6520616464726573732830290000000000000000000000000000000000000000602082015250565b6000612063602c83611a5e565b915061206e82612007565b604082019050919050565b6000602082019050818103600083015261209281612056565b9050919050565b7f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60008201527f6e207468617420616c7265616479206578697374730000000000000000000000602082015250565b60006120f5603583611a5e565b915061210082612099565b604082019050919050565b60006020820190508181036000830152612124816120e8565b9050919050565b60006bffffffffffffffffffffffff82169050919050565b600061214e8261212b565b91506bffffffffffffffffffffffff820361216c5761216b611bf1565b5b600182019050919050565b7f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60008201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000602082015250565b60006121d3603883611a5e565b91506121de82612177565b604082019050919050565b60006020820190508181036000830152612202816121c6565b9050919050565b7f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260008201527f657373206d757374206265206164647265737328302900000000000000000000602082015250565b6000612265603683611a5e565b915061227082612209565b604082019050919050565b6000602082019050818103600083015261229481612258565b9050919050565b7f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860008201527f3029206275745f63616c6c64617461206973206e6f7420656d70747900000000602082015250565b60006122f7603c83611a5e565b91506123028261229b565b604082019050919050565b60006020820190508181036000830152612326816122ea565b9050919050565b7f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460008201527f7920627574205f696e6974206973206e6f742061646472657373283029000000602082015250565b6000612389603d83611a5e565b91506123948261232d565b604082019050919050565b600060208201905081810360008301526123b88161237c565b9050919050565b600081905092915050565b60006123d582611ea8565b6123df81856123bf565b93506123ef818560208601611ec4565b80840191505092915050565b600061240782846123ca565b915081905092915050565b600081519050919050565b600061242882612412565b6124328185611a5e565b9350612442818560208601611ec4565b61244b81611740565b840191505092915050565b60006020820190508181036000830152612470818461241d565b905092915050565b7f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e20726560008201527f7665727465640000000000000000000000000000000000000000000000000000602082015250565b60006124d4602683611a5e565b91506124df82612478565b604082019050919050565b60006020820190508181036000830152612503816124c7565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360008201527f74696f6e207468617420646f65736e2774206578697374000000000000000000602082015250565b6000612566603783611a5e565b91506125718261250a565b604082019050919050565b6000602082019050818103600083015261259581612559565b9050919050565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560008201527f7461626c652066756e6374696f6e000000000000000000000000000000000000602082015250565b60006125f8602e83611a5e565b91506126038261259c565b604082019050919050565b60006020820190508181036000830152612627816125eb565b9050919050565b600061263982611c20565b915061264483611c20565b92508282101561265757612656611bf1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a164736f6c634300080f000a", + "devdoc": { + "kind": "dev", + "methods": { + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_calldata": "A function call, including function selector and arguments _calldata is executed with delegatecall on _init", + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/DiamondLoupeFacet.json b/deployments/neonDevnet/DiamondLoupeFacet.json new file mode 100644 index 00000000..4f4c85ff --- /dev/null +++ b/deployments/neonDevnet/DiamondLoupeFacet.json @@ -0,0 +1,176 @@ +{ + "address": "0xF04D7fC2cB1976736f9263Ff010A048cF564b936", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x713d668c7fafa561c5c6e3b8bdce5a60e8c7ec618ac69fc1273e45b4b8270e3d", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "39500160", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8f800b34fd5914d9cfdcbfb091c79eb908a908b244b39b781dd3ffc394c32071", + "transactionHash": "0x713d668c7fafa561c5c6e3b8bdce5a60e8c7ec618ac69fc1273e45b4b8270e3d", + "logs": [], + "blockNumber": 173997605, + "cumulativeGasUsed": "39500160", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "ae94371f40f594d6ee02698e497ed59a", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/bridges/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/bridges/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport { LibDiamond } from \\\"../libs/LibDiamond.sol\\\";\\nimport { IDiamondLoupe } from \\\"../interfaces/IDiamondLoupe.sol\\\";\\nimport { IERC165 } from \\\"../interfaces/IERC165.sol\\\";\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i = 0; i < numFacets; i++) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\\n }\\n }\\n\\n /// @notice Gets all the function selectors provided by a facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(address _facet)\\n external\\n view\\n override\\n returns (bytes4[] memory facetFunctionSelectors_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = ds.facetAddresses;\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\\n }\\n\\n // This implements ERC-165.\\n function supportsInterface(bytes4 _interfaceId) external view override returns (bool) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n return ds.supportedInterfaces[_interfaceId];\\n }\\n}\\n\",\"keccak256\":\"0xe8319ecc975c64e0a6585d3656442764d7e3fea345db229c8eab88946ef0cc39\",\"license\":\"MIT\"},\"src/bridges/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xc5184a3a9a2d9698572c007846bf12cf4a693dffc47425352b4b4f92beaae4db\",\"license\":\"MIT\"},\"src/bridges/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xf68b9c6c2ac2e8d6733b5afe0ad7d145f11a2cda10bfa4d0cbce575471179f1c\",\"license\":\"MIT\"},\"src/bridges/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\",\"keccak256\":\"0x621d67a3bf5e629bbd12760c02b2eadc40c34bbe0d90acc4a762c70765f25d58\",\"license\":\"MIT\"},\"src/bridges/libs/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress)\\n internal\\n {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x135cb5bb9fc0234dcc41a8ba75e6a95ad514cd965673f1d105103dbba18017cd\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610be3806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806301ffc9a71461005c57806352ef6b2c1461008c5780637a0ed627146100aa578063adfca15e146100c8578063cdffacc6146100f8575b600080fd5b6100766004803603810190610071919061068f565b610128565b60405161008391906106d7565b60405180910390f35b61009461019e565b6040516100a191906107e2565b60405180910390f35b6100b261023b565b6040516100bf91906109c1565b60405180910390f35b6100e260048036038101906100dd9190610a0f565b61045e565b6040516100ef9190610aab565b60405180910390f35b610112600480360381019061010d919061068f565b610549565b60405161011f9190610adc565b60405180910390f35b6000806101336105d5565b9050806003016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff16915050919050565b606060006101aa6105d5565b90508060020180548060200260200160405190810160405280929190818152602001828054801561023057602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116101e6575b505050505091505090565b606060006102476105d5565b90506000816002018054905090508067ffffffffffffffff81111561026f5761026e610af7565b5b6040519080825280602002602001820160405280156102a857816020015b610295610602565b81526020019060019003908161028d5790505b50925060005b818110156104585760008360020182815481106102ce576102cd610b26565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508085838151811061030f5761030e610b26565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000180548060200260200160405190810160405280929190818152602001828054801561041d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600401906020826003010492830192600103820291508084116103ca5790505b505050505085838151811061043557610434610b26565b5b60200260200101516020018190525050808061045090610b8e565b9150506102ae565b50505090565b6060600061046a6105d5565b90508060010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000180548060200260200160405190810160405280929190818152602001828054801561053c57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600401906020826003010492830192600103820291508084116104e95790505b5050505050915050919050565b6000806105546105d5565b9050806000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61066c81610637565b811461067757600080fd5b50565b60008135905061068981610663565b92915050565b6000602082840312156106a5576106a4610632565b5b60006106b38482850161067a565b91505092915050565b60008115159050919050565b6106d1816106bc565b82525050565b60006020820190506106ec60008301846106c8565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107498261071e565b9050919050565b6107598161073e565b82525050565b600061076b8383610750565b60208301905092915050565b6000602082019050919050565b600061078f826106f2565b61079981856106fd565b93506107a48361070e565b8060005b838110156107d55781516107bc888261075f565b97506107c783610777565b9250506001810190506107a8565b5085935050505092915050565b600060208201905081810360008301526107fc8184610784565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61086581610637565b82525050565b6000610877838361085c565b60208301905092915050565b6000602082019050919050565b600061089b82610830565b6108a5818561083b565b93506108b08361084c565b8060005b838110156108e15781516108c8888261086b565b97506108d383610883565b9250506001810190506108b4565b5085935050505092915050565b60006040830160008301516109066000860182610750565b506020830151848203602086015261091e8282610890565b9150508091505092915050565b600061093783836108ee565b905092915050565b6000602082019050919050565b600061095782610804565b610961818561080f565b93508360208202850161097385610820565b8060005b858110156109af5784840389528151610990858261092b565b945061099b8361093f565b925060208a01995050600181019050610977565b50829750879550505050505092915050565b600060208201905081810360008301526109db818461094c565b905092915050565b6109ec8161073e565b81146109f757600080fd5b50565b600081359050610a09816109e3565b92915050565b600060208284031215610a2557610a24610632565b5b6000610a33848285016109fa565b91505092915050565b600082825260208201905092915050565b6000610a5882610830565b610a628185610a3c565b9350610a6d8361084c565b8060005b83811015610a9e578151610a85888261086b565b9750610a9083610883565b925050600181019050610a71565b5085935050505092915050565b60006020820190508181036000830152610ac58184610a4d565b905092915050565b610ad68161073e565b82525050565b6000602082019050610af16000830184610acd565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610b9982610b84565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610bcb57610bca610b55565b5b60018201905091905056fea164736f6c634300080f000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c806301ffc9a71461005c57806352ef6b2c1461008c5780637a0ed627146100aa578063adfca15e146100c8578063cdffacc6146100f8575b600080fd5b6100766004803603810190610071919061068f565b610128565b60405161008391906106d7565b60405180910390f35b61009461019e565b6040516100a191906107e2565b60405180910390f35b6100b261023b565b6040516100bf91906109c1565b60405180910390f35b6100e260048036038101906100dd9190610a0f565b61045e565b6040516100ef9190610aab565b60405180910390f35b610112600480360381019061010d919061068f565b610549565b60405161011f9190610adc565b60405180910390f35b6000806101336105d5565b9050806003016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff16915050919050565b606060006101aa6105d5565b90508060020180548060200260200160405190810160405280929190818152602001828054801561023057602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116101e6575b505050505091505090565b606060006102476105d5565b90506000816002018054905090508067ffffffffffffffff81111561026f5761026e610af7565b5b6040519080825280602002602001820160405280156102a857816020015b610295610602565b81526020019060019003908161028d5790505b50925060005b818110156104585760008360020182815481106102ce576102cd610b26565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508085838151811061030f5761030e610b26565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000180548060200260200160405190810160405280929190818152602001828054801561041d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600401906020826003010492830192600103820291508084116103ca5790505b505050505085838151811061043557610434610b26565b5b60200260200101516020018190525050808061045090610b8e565b9150506102ae565b50505090565b6060600061046a6105d5565b90508060010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000180548060200260200160405190810160405280929190818152602001828054801561053c57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600401906020826003010492830192600103820291508084116104e95790505b5050505050915050919050565b6000806105546105d5565b9050806000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61066c81610637565b811461067757600080fd5b50565b60008135905061068981610663565b92915050565b6000602082840312156106a5576106a4610632565b5b60006106b38482850161067a565b91505092915050565b60008115159050919050565b6106d1816106bc565b82525050565b60006020820190506106ec60008301846106c8565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107498261071e565b9050919050565b6107598161073e565b82525050565b600061076b8383610750565b60208301905092915050565b6000602082019050919050565b600061078f826106f2565b61079981856106fd565b93506107a48361070e565b8060005b838110156107d55781516107bc888261075f565b97506107c783610777565b9250506001810190506107a8565b5085935050505092915050565b600060208201905081810360008301526107fc8184610784565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61086581610637565b82525050565b6000610877838361085c565b60208301905092915050565b6000602082019050919050565b600061089b82610830565b6108a5818561083b565b93506108b08361084c565b8060005b838110156108e15781516108c8888261086b565b97506108d383610883565b9250506001810190506108b4565b5085935050505092915050565b60006040830160008301516109066000860182610750565b506020830151848203602086015261091e8282610890565b9150508091505092915050565b600061093783836108ee565b905092915050565b6000602082019050919050565b600061095782610804565b610961818561080f565b93508360208202850161097385610820565b8060005b858110156109af5784840389528151610990858261092b565b945061099b8361093f565b925060208a01995050600181019050610977565b50829750879550505050505092915050565b600060208201905081810360008301526109db818461094c565b905092915050565b6109ec8161073e565b81146109f757600080fd5b50565b600081359050610a09816109e3565b92915050565b600060208284031215610a2557610a24610632565b5b6000610a33848285016109fa565b91505092915050565b600082825260208201905092915050565b6000610a5882610830565b610a628185610a3c565b9350610a6d8361084c565b8060005b83811015610a9e578151610a85888261086b565b9750610a9083610883565b925050600181019050610a71565b5085935050505092915050565b60006020820190508181036000830152610ac58184610a4d565b905092915050565b610ad68161073e565b82525050565b6000602082019050610af16000830184610acd565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610b9982610b84565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610bcb57610bca610b55565b5b60018201905091905056fea164736f6c634300080f000a", + "devdoc": { + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "Facet" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Gets all facets and their selectors." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/ENSController.json b/deployments/neonDevnet/ENSController.json new file mode 100644 index 00000000..47cb6bc6 --- /dev/null +++ b/deployments/neonDevnet/ENSController.json @@ -0,0 +1,1152 @@ +{ + "address": "0xE23c8f8aB1Cdd56D89F181c22Bf43e5b53871E08", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "AddrChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "coinType", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "newAddress", + "type": "bytes" + } + ], + "name": "AddressChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "GuardianAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "GuardianRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "initializer", + "type": "address" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + } + ], + "name": "NameChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "NodeReleased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "NodeSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "NodeVerified", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "x", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "y", + "type": "bytes32" + } + ], + "name": "PubkeyChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "RegistryChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "string", + "name": "indexedKey", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "key", + "type": "string" + } + ], + "name": "TextChanged", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "addGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "addr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "coinType", + "type": "uint256" + } + ], + "name": "addr", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chainId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gateway", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "label", + "type": "bytes32" + } + ], + "internalType": "struct ENSController.SubNodeRegistration", + "name": "subNodeRegistration", + "type": "tuple" + } + ], + "name": "hashSubNodeRegistration", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ENSRegistry", + "name": "registry_", + "type": "address" + }, + { + "internalType": "address[]", + "name": "guardians_", + "type": "address[]" + }, + { + "internalType": "address", + "name": "gateway_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "isGuardian", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "nodeOwners", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "pubkey", + "outputs": [ + { + "internalType": "bytes32", + "name": "x", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "y", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "label", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "guardianSignature", + "type": "bytes" + } + ], + "name": "registerSubNode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "registry", + "outputs": [ + { + "internalType": "contract ENSRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "releaseNode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "removeGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "coinType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "addr_", + "type": "bytes" + } + ], + "name": "setAddr", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "name": "setAddr", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + } + ], + "name": "setName", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "x", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "y", + "type": "bytes32" + } + ], + "name": "setPubkey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ENSRegistry", + "name": "registry_", + "type": "address" + } + ], + "name": "setRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "key", + "type": "string" + }, + { + "internalType": "string", + "name": "value", + "type": "string" + } + ], + "name": "setText", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "submitNode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "syncAddr", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "key", + "type": "string" + } + ], + "name": "text", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "messageHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "verifyGuardianSignature", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "verifyNode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x24da3b71a66b5ecbc9ae73762d856309525b4e69d7735977b2e29f9f443c7869", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "162959680", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8cdaa81ead76fca6b7464a70318656cb2a4df6f7f6b1bc403a8598a11642fb29", + "transactionHash": "0x24da3b71a66b5ecbc9ae73762d856309525b4e69d7735977b2e29f9f443c7869", + "logs": [], + "blockNumber": 173996763, + "cumulativeGasUsed": "162959680", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"AddrChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"coinType\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newAddress\",\"type\":\"bytes\"}],\"name\":\"AddressChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NameChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NodeReleased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NodeSubmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"NodeVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"x\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"PubkeyChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"registry\",\"type\":\"address\"}],\"name\":\"RegistryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"indexedKey\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"TextChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"addGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"addr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"coinType\",\"type\":\"uint256\"}],\"name\":\"addr\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"label\",\"type\":\"bytes32\"}],\"internalType\":\"struct ENSController.SubNodeRegistration\",\"name\":\"subNodeRegistration\",\"type\":\"tuple\"}],\"name\":\"hashSubNodeRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"registry_\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"guardians_\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"gateway_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"isGuardian\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"nodeOwners\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"pubkey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"x\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"label\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"registerSubNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"releaseNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"removeGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"coinType\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"addr_\",\"type\":\"bytes\"}],\"name\":\"setAddr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"name\":\"setAddr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"x\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"setPubkey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"registry_\",\"type\":\"address\"}],\"name\":\"setRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setText\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"submitNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"syncAddr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"text\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"verifyGuardianSignature\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"verifyNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski \",\"details\":\"The process of adding root node consists of 3 steps: 1. `submitNode` - should be called from ENS node owner, 2. Change ENS node owner in ENS registry to ENS controller, 3. `verifyNode` - should be called from previous ENS node owner, To register sub node, `msg.sender` need to send valid signature from one of guardian key. Once registration is complete `msg.sender` becoming both node owner and `addr` record value. After registration sub node cannot be replaced.\",\"events\":{\"NodeReleased(bytes32,address)\":{\"details\":\"Emitted when new node is released\",\"params\":{\"node\":\"node name hash\",\"owner\":\"owner address\"}},\"NodeSubmitted(bytes32,address)\":{\"details\":\"Emitted when new node is submitted\",\"params\":{\"node\":\"node name hash\",\"owner\":\"owner address\"}},\"NodeVerified(bytes32)\":{\"details\":\"Emitted when the existing owner is verified\",\"params\":{\"node\":\"node name hash\"}},\"RegistryChanged(address)\":{\"details\":\"Emitted when ENS registry address is changed\",\"params\":{\"registry\":\"registry address\"}}},\"kind\":\"dev\",\"methods\":{\"addGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"constructor\":{\"details\":\"Public constructor\"},\"hashSubNodeRegistration((address,bytes32,bytes32))\":{\"params\":{\"subNodeRegistration\":\"struct\"},\"returns\":{\"_0\":\"hash\"}},\"initialize(address,address[],address)\":{\"params\":{\"gateway_\":\"gateway address\",\"registry_\":\"ENS registry address\"}},\"isGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"},\"returns\":{\"_0\":\"true when guardian exists\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}},\"registerSubNode(bytes32,bytes32,bytes)\":{\"params\":{\"guardianSignature\":\"guardian signature\",\"label\":\"label hash\",\"node\":\"node name hash\"}},\"releaseNode(bytes32)\":{\"details\":\"Should be called from the previous ENS node owner\",\"params\":{\"node\":\"node name hash\"}},\"removeGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"setRegistry(address)\":{\"params\":{\"registry_\":\"registry address\"}},\"submitNode(bytes32)\":{\"details\":\"Should be called from the current ENS node owner\",\"params\":{\"node\":\"node name hash\"}},\"syncAddr(bytes32)\":{\"params\":{\"node\":\"node name hash\"}},\"verifyGuardianSignature(bytes32,bytes)\":{\"params\":{\"messageHash\":\"message hash\",\"signature\":\"signature\"},\"returns\":{\"_0\":\"true on correct guardian signature\"}},\"verifyNode(bytes32)\":{\"details\":\"Should be called from the previous ENS node owner\",\"params\":{\"node\":\"node name hash\"}}},\"title\":\"ENS controller\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addGuardian(address)\":{\"notice\":\"Adds a new guardian\"},\"hashSubNodeRegistration((address,bytes32,bytes32))\":{\"notice\":\"Hashes `SubNodeRegistration` message payload\"},\"initialize(address,address[],address)\":{\"notice\":\"Initializes `ENSController` contract\"},\"isGuardian(address)\":{\"notice\":\"Check if guardian exists\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"},\"registerSubNode(bytes32,bytes32,bytes)\":{\"notice\":\"Registers sub node\"},\"releaseNode(bytes32)\":{\"notice\":\"Releases node\"},\"removeGuardian(address)\":{\"notice\":\"Removes the existing guardian\"},\"setRegistry(address)\":{\"notice\":\"Sets registry\"},\"submitNode(bytes32)\":{\"notice\":\"Submits node\"},\"syncAddr(bytes32)\":{\"notice\":\"Sync address\"},\"verifyGuardianSignature(bytes32,bytes)\":{\"notice\":\"Verifies guardian signature\"},\"verifyNode(bytes32)\":{\"notice\":\"Verifies node\"}},\"notice\":\"ENS subnode registrar\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/ens/ENSController.sol\":\"ENSController\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/access/Guarded.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n\\n/**\\n * @title Guarded\\n *\\n * @dev Contract module which provides a guardian-type control mechanism.\\n * It allows key accounts to have guardians and restricts specific methods to be accessible by guardians only.\\n *\\n * Each guardian account can remove other guardians\\n *\\n * Use `_initializeGuarded` to initialize the contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Guarded {\\n using ECDSALib for bytes32;\\n\\n mapping(address => bool) private guardians;\\n\\n // events\\n\\n /**\\n * @dev Emitted when a new guardian is added\\n * @param sender sender address\\n * @param guardian guardian address\\n */\\n event GuardianAdded(\\n address sender,\\n address guardian\\n );\\n\\n /**\\n * @dev Emitted when the existing guardian is removed\\n * @param sender sender address\\n * @param guardian guardian address\\n */\\n event GuardianRemoved(\\n address sender,\\n address guardian\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not a guardian account\\n */\\n modifier onlyGuardian() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n guardians[tx.origin],\\n \\\"Guarded: tx.origin is not the guardian\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor() internal {}\\n\\n // external functions\\n\\n /**\\n * @notice Adds a new guardian\\n * @param guardian guardian address\\n */\\n function addGuardian(\\n address guardian\\n )\\n external\\n onlyGuardian\\n {\\n _addGuardian(guardian);\\n }\\n\\n /**\\n * @notice Removes the existing guardian\\n * @param guardian guardian address\\n */\\n function removeGuardian(\\n address guardian\\n )\\n external\\n onlyGuardian\\n {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin != guardian,\\n \\\"Guarded: cannot remove self\\\"\\n );\\n\\n require(\\n guardians[guardian],\\n \\\"Guarded: guardian doesn't exist\\\"\\n );\\n\\n guardians[guardian] = false;\\n\\n emit GuardianRemoved(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin,\\n guardian\\n );\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if guardian exists\\n * @param guardian guardian address\\n * @return true when guardian exists\\n */\\n function isGuardian(\\n address guardian\\n )\\n external\\n view\\n returns (bool)\\n {\\n return guardians[guardian];\\n }\\n\\n /**\\n * @notice Verifies guardian signature\\n * @param messageHash message hash\\n * @param signature signature\\n * @return true on correct guardian signature\\n */\\n function verifyGuardianSignature(\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n external\\n view\\n returns (bool)\\n {\\n return _verifyGuardianSignature(\\n messageHash,\\n signature\\n );\\n }\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `Guarded` contract\\n * @dev If `guardians_` array is empty `tx.origin` is added as guardian account\\n * @param guardians_ array of guardians addresses\\n */\\n function _initializeGuarded(\\n address[] memory guardians_\\n )\\n internal\\n {\\n if (guardians_.length == 0) {\\n // solhint-disable-next-line avoid-tx-origin\\n _addGuardian(tx.origin);\\n } else {\\n uint guardiansLen = guardians_.length;\\n for (uint i = 0; i < guardiansLen; i++) {\\n _addGuardian(guardians_[i]);\\n }\\n }\\n }\\n\\n\\n // internal functions (views)\\n\\n function _verifyGuardianSignature(\\n bytes32 messageHash,\\n bytes memory signature\\n )\\n internal\\n view\\n returns (bool)\\n {\\n address guardian = messageHash.recoverAddress(signature);\\n\\n return guardians[guardian];\\n }\\n\\n // private functions\\n\\n function _addGuardian(\\n address guardian\\n )\\n private\\n {\\n require(\\n guardian != address(0),\\n \\\"Guarded: cannot add 0x0 guardian\\\"\\n );\\n\\n require(\\n !guardians[guardian],\\n \\\"Guarded: guardian already exists\\\"\\n );\\n\\n guardians[guardian] = true;\\n\\n emit GuardianAdded(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin,\\n guardian\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4a5f5670041362e87ea267d81c55fc3edc1a78e81f6f17524b13267f91f31458\",\"license\":\"MIT\"},\"src/common/libs/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Bytes library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nlibrary BytesLib {\\n /**\\n * @notice Converts bytes to address\\n * @param data data\\n * @return address\\n */\\n function toAddress(\\n bytes memory data\\n )\\n internal\\n pure\\n returns (address)\\n {\\n address result;\\n\\n require(\\n data.length == 20,\\n \\\"BytesLib: invalid data length\\\"\\n );\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := div(mload(add(data, 0x20)), 0x1000000000000000000000000)\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x64c84964ea91bfb1f2d859eea6c57fe5b4a6f269951a4adf5f58d306c54c7f76\",\"license\":\"MIT\"},\"src/common/libs/ECDSALib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ECDSA library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/cryptography/ECDSA.sol#L26\\n */\\nlibrary ECDSALib {\\n function recoverAddress(\\n bytes32 messageHash,\\n bytes memory signature\\n )\\n internal\\n pure\\n returns (address)\\n {\\n address result = address(0);\\n\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n\\n if (v < 27) {\\n v += 27;\\n }\\n\\n if (v == 27 || v == 28) {\\n result = ecrecover(messageHash, v, r, s);\\n }\\n }\\n\\n return result;\\n }\\n\\n function toEthereumSignedMessageHash(\\n bytes32 messageHash\\n )\\n internal\\n pure\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n messageHash\\n ));\\n }\\n}\\n\",\"keccak256\":\"0x3b1460d688302eb595268c2af147ab532f29dbced66520e013f48d498eed3cec\",\"license\":\"MIT\"},\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Initializable {\\n address private initializer;\\n\\n // events\\n\\n /**\\n * @dev Emitted after `onlyInitializer`\\n * @param initializer initializer address\\n */\\n event Initialized(\\n address initializer\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not the initializer\\n */\\n modifier onlyInitializer() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin == initializer,\\n \\\"Initializable: tx.origin is not the initializer\\\"\\n );\\n\\n /// @dev removes initializer\\n initializer = address(0);\\n\\n _;\\n\\n emit Initialized(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin\\n );\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n initializer = tx.origin;\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if contract is initialized\\n * @return true when contract is initialized\\n */\\n function isInitialized()\\n external\\n view\\n returns (bool)\\n {\\n return initializer == address(0);\\n }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/common/signature/SignatureValidator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n/**\\n * @title Signature validator\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract SignatureValidator {\\n using ECDSALib for bytes32;\\n\\n uint256 public chainId;\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {\\n uint256 chainId_;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n chainId_ := chainid()\\n }\\n\\n chainId = chainId_;\\n }\\n\\n // internal functions\\n\\n function _hashMessagePayload(\\n bytes32 messagePrefix,\\n bytes memory messagePayload\\n )\\n internal\\n view\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n chainId,\\n address(this),\\n messagePrefix,\\n messagePayload\\n )).toEthereumSignedMessageHash();\\n }\\n}\\n\",\"keccak256\":\"0xc1168f7ccb74aea67089941dc5e4c1d1c4aa766afca47a90c0b017b8445b8acf\",\"license\":\"MIT\"},\"src/ens/ENSController.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../common/access/Guarded.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/signature/SignatureValidator.sol\\\";\\nimport \\\"../gateway/GatewayRecipient.sol\\\";\\nimport \\\"./resolvers/ENSAddressResolver.sol\\\";\\nimport \\\"./resolvers/ENSNameResolver.sol\\\";\\nimport \\\"./resolvers/ENSPubKeyResolver.sol\\\";\\nimport \\\"./resolvers/ENSTextResolver.sol\\\";\\nimport \\\"./ENSRegistry.sol\\\";\\n\\n\\n/**\\n * @title ENS controller\\n *\\n * @notice ENS subnode registrar\\n *\\n * @dev The process of adding root node consists of 3 steps:\\n * 1. `submitNode` - should be called from ENS node owner,\\n * 2. Change ENS node owner in ENS registry to ENS controller,\\n * 3. `verifyNode` - should be called from previous ENS node owner,\\n *\\n * To register sub node, `msg.sender` need to send valid signature from one of guardian key.\\n * Once registration is complete `msg.sender` becoming both node owner and `addr` record value.\\n *\\n * After registration sub node cannot be replaced.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract ENSController is Guarded, Initializable, SignatureValidator, GatewayRecipient, ENSAddressResolver, ENSNameResolver, ENSPubKeyResolver, ENSTextResolver {\\n struct SubNodeRegistration {\\n address account;\\n bytes32 node;\\n bytes32 label;\\n }\\n\\n bytes4 private constant INTERFACE_META_ID = bytes4(keccak256(abi.encodePacked(\\\"supportsInterface(bytes4)\\\")));\\n\\n bytes32 private constant HASH_PREFIX_SUB_NODE_REGISTRATION = keccak256(\\n \\\"SubNodeRegistration(address account,bytes32 node,bytes32 label)\\\"\\n );\\n\\n ENSRegistry public registry;\\n\\n mapping(bytes32 => address) public nodeOwners;\\n\\n // events\\n\\n /**\\n * @dev Emitted when new node is submitted\\n * @param node node name hash\\n * @param owner owner address\\n */\\n event NodeSubmitted(\\n bytes32 node,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the existing owner is verified\\n * @param node node name hash\\n */\\n event NodeVerified(\\n bytes32 node\\n );\\n\\n /**\\n * @dev Emitted when new node is released\\n * @param node node name hash\\n * @param owner owner address\\n */\\n event NodeReleased(\\n bytes32 node,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when ENS registry address is changed\\n * @param registry registry address\\n */\\n event RegistryChanged(\\n address registry\\n );\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor() public Guarded() Initializable() SignatureValidator() {}\\n\\n // external functions\\n\\n /**\\n * @notice Initializes `ENSController` contract\\n * @param registry_ ENS registry address\\n * @param gateway_ gateway address\\n */\\n function initialize(\\n ENSRegistry registry_,\\n address[] calldata guardians_,\\n address gateway_\\n )\\n external\\n onlyInitializer\\n {\\n require(\\n address(registry_) != address(0),\\n \\\"ENSController: cannot set 0x0 registry\\\"\\n );\\n\\n registry = registry_;\\n\\n // Guarded\\n _initializeGuarded(guardians_);\\n\\n // GatewayRecipient\\n _initializeGatewayRecipient(gateway_);\\n }\\n\\n /**\\n * @notice Sets registry\\n * @param registry_ registry address\\n */\\n function setRegistry(\\n ENSRegistry registry_\\n )\\n external\\n onlyGuardian\\n {\\n require(\\n address(registry_) != address(0),\\n \\\"ENSController: cannot set 0x0 registry\\\"\\n );\\n\\n require(\\n registry_ != registry,\\n \\\"ENSController: registry already set\\\"\\n );\\n\\n registry = registry_;\\n\\n emit RegistryChanged(\\n address(registry)\\n );\\n }\\n\\n /**\\n * @notice Submits node\\n * @dev Should be called from the current ENS node owner\\n * @param node node name hash\\n */\\n function submitNode(\\n bytes32 node\\n )\\n external\\n {\\n address owner = _getContextAccount();\\n\\n require(\\n _addr(node) == address(0),\\n \\\"ENSController: node already exists\\\"\\n );\\n\\n require(\\n nodeOwners[node] == address(0),\\n \\\"ENSController: node already submitted\\\"\\n );\\n\\n require(\\n registry.owner(node) == owner,\\n \\\"ENSController: invalid ens node owner\\\"\\n );\\n\\n nodeOwners[node] = owner;\\n\\n emit NodeSubmitted(node, owner);\\n }\\n\\n /**\\n * @notice Verifies node\\n * @dev Should be called from the previous ENS node owner\\n * @param node node name hash\\n */\\n function verifyNode(\\n bytes32 node\\n )\\n external\\n {\\n address owner = _getContextAccount();\\n\\n require(\\n _addr(node) == address(0),\\n \\\"ENSController: node already exists\\\"\\n );\\n\\n require(\\n nodeOwners[node] == owner,\\n \\\"ENSController: invalid node owner\\\"\\n );\\n\\n require(\\n registry.owner(node) == address(this),\\n \\\"ENSController: invalid ens node owner\\\"\\n );\\n\\n _setAddr(node, address(this));\\n\\n registry.setResolver(node, address(this));\\n\\n emit NodeVerified(node);\\n }\\n\\n /**\\n * @notice Releases node\\n * @dev Should be called from the previous ENS node owner\\n * @param node node name hash\\n */\\n function releaseNode(\\n bytes32 node\\n )\\n external\\n {\\n address owner = _getContextAccount();\\n\\n require(\\n _addr(node) == address(this),\\n \\\"ENSController: node doesn't exist\\\"\\n );\\n\\n require(\\n nodeOwners[node] == owner,\\n \\\"ENSController: invalid node owner\\\"\\n );\\n\\n registry.setOwner(node, owner);\\n\\n delete nodeOwners[node];\\n\\n emit NodeReleased(node, owner);\\n }\\n\\n /**\\n * @notice Sync address\\n * @param node node name hash\\n */\\n function syncAddr(\\n bytes32 node\\n )\\n external\\n {\\n address account = _getContextAccount();\\n\\n require(\\n account == registry.owner(node),\\n \\\"ENSController: caller is not the node owner\\\"\\n );\\n\\n require(\\n registry.resolver(node) == address(this),\\n \\\"ENSController: invalid node resolver\\\"\\n );\\n\\n require(\\n _addr(node) == address(0),\\n \\\"ENSController: node already in sync\\\"\\n );\\n\\n _setAddr(node, account);\\n }\\n\\n /**\\n * @notice Registers sub node\\n * @param node node name hash\\n * @param label label hash\\n * @param guardianSignature guardian signature\\n */\\n function registerSubNode(\\n bytes32 node,\\n bytes32 label,\\n bytes calldata guardianSignature\\n )\\n external\\n {\\n address account = _getContextAccount();\\n\\n bytes32 messageHash = _hashSubNodeRegistration(\\n account,\\n node,\\n label\\n );\\n\\n require(\\n _verifyGuardianSignature(messageHash, guardianSignature),\\n \\\"ENSController: invalid guardian signature\\\"\\n );\\n\\n bytes32 subNode = keccak256(\\n abi.encodePacked(\\n node,\\n label\\n )\\n );\\n\\n require(\\n _addr(node) == address(this),\\n \\\"ENSController: invalid node\\\"\\n );\\n\\n require(\\n _addr(subNode) == address(0),\\n \\\"ENSController: label already taken\\\"\\n );\\n\\n registry.setSubnodeRecord(node, label, address(this), address(this), 0);\\n registry.setOwner(subNode, account);\\n\\n _setAddr(subNode, account);\\n }\\n\\n // external functions (pure)\\n function supportsInterface(\\n bytes4 interfaceID\\n )\\n external\\n pure\\n returns(bool)\\n {\\n return interfaceID == INTERFACE_META_ID ||\\n interfaceID == INTERFACE_ADDR_ID ||\\n interfaceID == INTERFACE_ADDRESS_ID ||\\n interfaceID == INTERFACE_NAME_ID ||\\n interfaceID == INTERFACE_PUB_KEY_ID ||\\n interfaceID == INTERFACE_TEXT_ID;\\n }\\n\\n // public functions (views)\\n\\n /**\\n * @notice Hashes `SubNodeRegistration` message payload\\n * @param subNodeRegistration struct\\n * @return hash\\n */\\n function hashSubNodeRegistration(\\n SubNodeRegistration memory subNodeRegistration\\n )\\n public\\n view\\n returns (bytes32)\\n {\\n return _hashSubNodeRegistration(\\n subNodeRegistration.account,\\n subNodeRegistration.node,\\n subNodeRegistration.label\\n );\\n }\\n\\n // internal functions (views)\\n\\n function _isNodeOwner(\\n bytes32 node\\n )\\n internal\\n override\\n view\\n returns (bool)\\n {\\n return registry.owner(node) == _getContextAccount();\\n }\\n\\n // private functions (views)\\n\\n function _hashSubNodeRegistration(\\n address account,\\n bytes32 node,\\n bytes32 label\\n )\\n private\\n view\\n returns (bytes32)\\n {\\n return _hashMessagePayload(HASH_PREFIX_SUB_NODE_REGISTRATION, abi.encodePacked(\\n account,\\n node,\\n label\\n ));\\n }\\n}\\n\",\"keccak256\":\"0x8006c066bef9625f3d103d77e8b66ff5f006187586cd4518676e73c5d3f79957\",\"license\":\"MIT\"},\"src/ens/ENSRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ENS registry\\n *\\n * @dev Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ENSRegistry.sol\\n */\\ncontract ENSRegistry {\\n struct Record {\\n address owner;\\n address resolver;\\n uint64 ttl;\\n }\\n\\n mapping (bytes32 => Record) private records;\\n mapping (address => mapping(address => bool)) private operators;\\n\\n // events\\n\\n event NewOwner(\\n bytes32 indexed node,\\n bytes32 indexed label,\\n address owner\\n );\\n\\n event Transfer(\\n bytes32 indexed node,\\n address owner\\n );\\n\\n event NewResolver(\\n bytes32 indexed node,\\n address resolver\\n );\\n\\n event NewTTL(\\n bytes32 indexed node,\\n uint64 ttl\\n );\\n\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n // modifiers\\n\\n modifier authorised(\\n bytes32 node\\n )\\n {\\n address owner = records[node].owner;\\n\\n require(\\n owner == msg.sender || operators[owner][msg.sender],\\n \\\"ENSRegistry: reverted by authorised modifier\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor()\\n public\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n records[0x0].owner = tx.origin;\\n }\\n\\n // external functions\\n\\n function setRecord(\\n bytes32 node,\\n address owner_,\\n address resolver_,\\n uint64 ttl_\\n )\\n external\\n {\\n setOwner(node, owner_);\\n\\n _setResolverAndTTL(node, resolver_, ttl_);\\n }\\n\\n function setTTL(\\n bytes32 node,\\n uint64 ttl_\\n )\\n external\\n authorised(node)\\n {\\n records[node].ttl = ttl_;\\n\\n emit NewTTL(node, ttl_);\\n }\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner_,\\n address resolver_,\\n uint64 ttl_\\n )\\n external\\n {\\n bytes32 subNode = setSubnodeOwner(node, label, owner_);\\n\\n _setResolverAndTTL(subNode, resolver_, ttl_);\\n }\\n\\n function setApprovalForAll(\\n address operator,\\n bool approved\\n )\\n external\\n {\\n operators[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(\\n msg.sender,\\n operator,\\n approved\\n );\\n }\\n\\n // external functions (views)\\n\\n function owner(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n address addr = records[node].owner;\\n\\n if (addr == address(this)) {\\n return address(0x0);\\n }\\n\\n return addr;\\n }\\n\\n function resolver(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n return records[node].resolver;\\n }\\n\\n function ttl(\\n bytes32 node\\n )\\n external\\n view\\n returns (uint64)\\n {\\n return records[node].ttl;\\n }\\n\\n function recordExists(\\n bytes32 node\\n )\\n external\\n view\\n returns (bool)\\n {\\n return records[node].owner != address(0x0);\\n }\\n\\n function isApprovedForAll(\\n address owner_,\\n address operator\\n )\\n external\\n view\\n returns (bool)\\n {\\n return operators[owner_][operator];\\n }\\n\\n // public functions\\n\\n function setOwner(\\n bytes32 node,\\n address owner_\\n )\\n public\\n authorised(node)\\n {\\n records[node].owner = owner_;\\n\\n emit Transfer(node, owner_);\\n }\\n\\n function setResolver(\\n bytes32 node,\\n address resolver_\\n )\\n public\\n authorised(node)\\n {\\n records[node].resolver = resolver_;\\n\\n emit NewResolver(node, resolver_);\\n }\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner_\\n )\\n public\\n authorised(node)\\n returns(bytes32)\\n {\\n bytes32 subNode = keccak256(abi.encodePacked(node, label));\\n\\n records[subNode].owner = owner_;\\n\\n emit NewOwner(node, label, owner_);\\n\\n return subNode;\\n }\\n\\n // private functions\\n\\n function _setResolverAndTTL(\\n bytes32 node,\\n address resolver_,\\n uint64 ttl_\\n )\\n private\\n {\\n if (resolver_ != records[node].resolver) {\\n records[node].resolver = resolver_;\\n\\n emit NewResolver(node, resolver_);\\n }\\n\\n if (ttl_ != records[node].ttl) {\\n records[node].ttl = ttl_;\\n\\n emit NewTTL(node, ttl_);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe00dbdea09d17d41c2c14266e6e1b6b95938c0d374b266bb44a91cfcf0495612\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSAbstractResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ENS abstract resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/ResolverBase.sol\\n */\\nabstract contract ENSAbstractResolver {\\n // modifiers\\n\\n modifier onlyNodeOwner(bytes32 node)\\n {\\n require(\\n _isNodeOwner(node),\\n \\\"ENSAbstractResolver: reverted by onlyNodeOwner modifier\\\"\\n );\\n\\n _;\\n }\\n\\n // internal functions (views)\\n\\n function _isNodeOwner(\\n bytes32 node\\n )\\n internal\\n virtual\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0xc67d8bdd4904684e5d3388f7ca7d18c7d407058d6b548d8c591404c758a1ac60\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract address resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/AddrResolver.sol\\n */\\nabstract contract ENSAddressResolver is ENSAbstractResolver {\\n bytes4 internal constant INTERFACE_ADDR_ID = bytes4(keccak256(abi.encodePacked(\\\"addr(bytes32)\\\")));\\n bytes4 internal constant INTERFACE_ADDRESS_ID = bytes4(keccak256(abi.encodePacked(\\\"addr(bytes32,uint)\\\")));\\n\\n uint internal constant COIN_TYPE_ETH = 60;\\n\\n mapping(bytes32 => mapping(uint => bytes)) internal resolverAddresses;\\n\\n // events\\n\\n event AddrChanged(\\n bytes32 indexed node,\\n address addr\\n );\\n\\n event AddressChanged(\\n bytes32 indexed node,\\n uint coinType,\\n bytes newAddress\\n );\\n\\n // external functions\\n\\n function setAddr(\\n bytes32 node,\\n address addr_\\n )\\n external\\n onlyNodeOwner(node)\\n {\\n _setAddr(node, addr_);\\n }\\n\\n function setAddr(\\n bytes32 node,\\n uint coinType,\\n bytes memory addr_\\n )\\n external\\n onlyNodeOwner(node)\\n {\\n _setAddr(node, coinType, addr_);\\n }\\n\\n // external functions (views)\\n\\n function addr(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n return _addr(node);\\n }\\n\\n function addr(\\n bytes32 node,\\n uint coinType\\n )\\n external\\n view\\n returns (bytes memory)\\n {\\n return resolverAddresses[node][coinType];\\n }\\n\\n // internal functions\\n\\n function _setAddr(\\n bytes32 node,\\n address addr_\\n )\\n internal\\n {\\n _setAddr(node, COIN_TYPE_ETH, _addressToBytes(addr_));\\n }\\n\\n function _setAddr(\\n bytes32 node,\\n uint coinType,\\n bytes memory addr_\\n )\\n internal\\n {\\n emit AddressChanged(node, coinType, addr_);\\n\\n if(coinType == COIN_TYPE_ETH) {\\n emit AddrChanged(node, _bytesToAddress(addr_));\\n }\\n\\n resolverAddresses[node][coinType] = addr_;\\n }\\n\\n // internal functions (views)\\n\\n function _addr(\\n bytes32 node\\n )\\n internal\\n view\\n returns (address)\\n {\\n address result;\\n\\n bytes memory addr_ = resolverAddresses[node][COIN_TYPE_ETH];\\n\\n if (addr_.length > 0) {\\n result = _bytesToAddress(addr_);\\n }\\n\\n return result;\\n }\\n\\n // private function (pure)\\n\\n function _bytesToAddress(\\n bytes memory data\\n )\\n private\\n pure\\n returns(address payable)\\n {\\n address payable result;\\n\\n require(data.length == 20);\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := div(mload(add(data, 32)), exp(256, 12))\\n }\\n\\n return result;\\n }\\n\\n function _addressToBytes(\\n address addr_\\n )\\n private\\n pure\\n returns(bytes memory)\\n {\\n bytes memory result = new bytes(20);\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n mstore(add(result, 32), mul(addr_, exp(256, 12)))\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xd2f0c5ed5f5058755512c0916496da6bcf4cf18a0026ee8d20b4306656ce5142\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSNameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract name resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/NameResolver.sol\\n */\\nabstract contract ENSNameResolver is ENSAbstractResolver {\\n bytes4 internal constant INTERFACE_NAME_ID = bytes4(keccak256(abi.encodePacked(\\\"name(bytes32)\\\")));\\n\\n mapping(bytes32 => string) internal resolverNames;\\n\\n // events\\n\\n event NameChanged(\\n bytes32 indexed node,\\n string name\\n );\\n\\n // external functions\\n\\n function setName(\\n bytes32 node,\\n string calldata name\\n )\\n external\\n onlyNodeOwner(node)\\n {\\n resolverNames[node] = name;\\n\\n emit NameChanged(node, name);\\n }\\n\\n // external functions (views)\\n\\n function name(\\n bytes32 node\\n )\\n external\\n view\\n returns (string memory)\\n {\\n return resolverNames[node];\\n }\\n}\\n\",\"keccak256\":\"0x1d2d4b21f59225fbefe0e5aaff87aff8f11afe5281745934d595e15770557ead\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSPubKeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract pub key resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/PubkeyResolver.sol\\n */\\nabstract contract ENSPubKeyResolver is ENSAbstractResolver {\\n bytes4 internal constant INTERFACE_PUB_KEY_ID = bytes4(keccak256(abi.encodePacked(\\\"pubkey(bytes32)\\\")));\\n\\n struct PubKey {\\n bytes32 x;\\n bytes32 y;\\n }\\n\\n mapping(bytes32 => PubKey) internal resolverPubKeys;\\n\\n // events\\n\\n event PubkeyChanged(\\n bytes32 indexed node,\\n bytes32 x,\\n bytes32 y\\n );\\n\\n // external functions (views)\\n\\n function setPubkey(\\n bytes32 node,\\n bytes32 x,\\n bytes32 y\\n )\\n external\\n onlyNodeOwner(node)\\n {\\n resolverPubKeys[node] = PubKey(x, y);\\n\\n emit PubkeyChanged(node, x, y);\\n }\\n\\n // external functions (views)\\n\\n function pubkey(\\n bytes32 node\\n )\\n external\\n view\\n returns (bytes32 x, bytes32 y)\\n {\\n return (resolverPubKeys[node].x, resolverPubKeys[node].y);\\n }\\n}\\n\",\"keccak256\":\"0x763a3403ded734b7fa9141c270a0aaaf4a3f1322ff4b197e51ed70adfbaf1fa1\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSTextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract text resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/TextResolver.sol\\n */\\nabstract contract ENSTextResolver is ENSAbstractResolver {\\n bytes4 internal constant INTERFACE_TEXT_ID = bytes4(keccak256(abi.encodePacked(\\\"text(bytes32,string)\\\")));\\n\\n mapping(bytes32 => mapping(string => string)) internal resolverTexts;\\n\\n // events\\n\\n event TextChanged(\\n bytes32 indexed node,\\n string indexed indexedKey,\\n string key\\n );\\n\\n // external functions (views)\\n\\n function setText(\\n bytes32 node,\\n string calldata key,\\n string calldata value\\n )\\n external\\n onlyNodeOwner(node)\\n {\\n resolverTexts[node][key] = value;\\n\\n emit TextChanged(node, key, key);\\n }\\n\\n // external functions (views)\\n\\n function text(\\n bytes32 node,\\n string calldata key\\n )\\n external\\n view\\n returns (string memory)\\n {\\n return resolverTexts[node][key];\\n }\\n}\\n\",\"keccak256\":\"0x6d13447ff9aa753320b3a93ba0b8a2cbb43385711d51e00809cfb9201136cff7\",\"license\":\"MIT\"},\"src/gateway/GatewayRecipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BytesLib.sol\\\";\\n\\n\\n/**\\n * @title Gateway recipient\\n *\\n * @notice Gateway target contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract GatewayRecipient {\\n using BytesLib for bytes;\\n\\n address public gateway;\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `GatewayRecipient` contract\\n * @param gateway_ `Gateway` contract address\\n */\\n function _initializeGatewayRecipient(\\n address gateway_\\n )\\n internal\\n {\\n gateway = gateway_;\\n }\\n\\n // internal functions (views)\\n\\n /**\\n * @notice Gets gateway context account\\n * @return context account address\\n */\\n function _getContextAccount()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(40);\\n }\\n\\n /**\\n * @notice Gets gateway context sender\\n * @return context sender address\\n */\\n function _getContextSender()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(20);\\n }\\n\\n /**\\n * @notice Gets gateway context data\\n * @return context data\\n */\\n function _getContextData()\\n internal\\n view\\n returns (bytes calldata)\\n {\\n bytes calldata result;\\n\\n if (_isGatewaySender()) {\\n result = msg.data[:msg.data.length - 40];\\n } else {\\n result = msg.data;\\n }\\n\\n return result;\\n }\\n\\n // private functions (views)\\n\\n function _getContextAddress(\\n uint256 offset\\n )\\n private\\n view\\n returns (address)\\n {\\n address result = address(0);\\n\\n if (_isGatewaySender()) {\\n uint from = msg.data.length - offset;\\n result = bytes(msg.data[from:from + 20]).toAddress();\\n } else {\\n result = msg.sender;\\n }\\n\\n return result;\\n }\\n\\n function _isGatewaySender()\\n private\\n view\\n returns (bool)\\n {\\n bool result;\\n\\n if (msg.sender == gateway) {\\n require(\\n msg.data.length >= 44,\\n \\\"GatewayRecipient: invalid msg.data\\\"\\n );\\n\\n result = true;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe3fd29479d748d67360c61a9cbaafc66eaca25f476e59a45e842472bcf5233fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5032600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600046905080600281905550506149798061006e6000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806371404156116100f9578063a91ee0dc11610097578063d0f710d611610071578063d0f710d614610512578063d5fa2b0014610542578063dc5b68a61461055e578063f1cb7e061461057a576101c4565b8063a91ee0dc146104a9578063c8690233146104c5578063c8cc2aee146104f6576101c4565b80637d0e0e7e116100d35780637d0e0e7e146104375780638b95dd71146104535780639a8a05921461046f578063a526d83b1461048d576101c4565b806371404156146103e157806377372213146103fd5780637b10399914610419576101c4565b8063392e53cd1161016657806355800f871161014057806355800f871461033557806359d1d43c14610351578063691f3431146103815780636df0cf42146103b1576101c4565b8063392e53cd146102cb5780633b3b57de146102e957806346386f7314610319576101c4565b8063116191b6116101a2578063116191b6146102455780631b3cd1421461026357806329ae6a7e1461029357806329cd62ea146102af576101c4565b806301ffc9a7146101c95780630c68ba21146101f957806310f13a8c14610229575b600080fd5b6101e360048036038101906101de91906133b4565b6105aa565b6040516101f091906141bc565b60405180910390f35b610213600480360381019061020e9190613066565b610834565b60405161022091906141bc565b60405180910390f35b610243600480360381019061023e9190613288565b610889565b005b61024d61096d565b60405161025a919061415d565b60405180910390f35b61027d600480360381019061027891906130b8565b610993565b60405161028a919061415d565b60405180910390f35b6102ad60048036038101906102a891906130b8565b6109c6565b005b6102c960048036038101906102c4919061311d565b610beb565b005b6102d3610cb3565b6040516102e091906141bc565b60405180910390f35b61030360048036038101906102fe91906130b8565b610d0b565b604051610310919061415d565b60405180910390f35b610333600480360381019061032e919061316c565b610d1d565b005b61034f600480360381019061034a91906130b8565b611017565b005b61036b60048036038101906103669190613230565b6112d8565b604051610378919061433d565b60405180910390f35b61039b600480360381019061039691906130b8565b6113ad565b6040516103a8919061433d565b60405180910390f35b6103cb60048036038101906103c69190613472565b611462565b6040516103d891906141d7565b60405180910390f35b6103fb60048036038101906103f69190613066565b611482565b005b61041760048036038101906104129190613230565b61169a565b005b610421611746565b60405161042e91906142fe565b60405180910390f35b610451600480360381019061044c91906130b8565b61176c565b005b61046d6004803603810190610468919061334d565b611a38565b005b610477611a92565b604051610484919061461f565b60405180910390f35b6104a760048036038101906104a29190613066565b611a98565b005b6104c360048036038101906104be91906133dd565b611b2f565b005b6104df60048036038101906104da91906130b8565b611d58565b6040516104ed92919061421b565b60405180910390f35b610510600480360381019061050b91906130b8565b611d92565b005b61052c600480360381019061052791906131d8565b6120a2565b60405161053991906141bc565b60405180910390f35b61055c600480360381019061055791906130e1565b6120fb565b005b61057860048036038101906105739190613406565b612153565b005b610594600480360381019061058f9190613311565b612366565b6040516105a191906142dc565b60405180910390f35b60006040516020016105bb9061406f565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061067d5750604051602001610626906140aa565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806106e95750604051602001610692906140fe565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061075557506040516020016106fe906140d4565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107c1575060405160200161076a906140e9565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061082d57506040516020016107d6906140bf565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b846108938161242d565b6108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c9906145df565b60405180910390fd5b82826007600089815260200190815260200160002087876040516108f7929190614056565b90815260200160405180910390209190610912929190612d39565b508484604051610923929190614056565b6040518091039020867fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550878760405161095d929190614319565b60405180910390a3505050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006109d0612516565b90503073ffffffffffffffffffffffffffffffffffffffff166109f283612527565b73ffffffffffffffffffffffffffffffffffffffff1614610a48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3f9061443f565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ae9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae09061437f565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c383836040518363ffffffff1660e01b8152600401610b469291906141f2565b600060405180830381600087803b158015610b6057600080fd5b505af1158015610b74573d6000803e3d6000fd5b505050506009600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690557f7803a16d95f9ca635bdec561006625e7444d8a9f8463866643cc03af011779d38282604051610bdf9291906141f2565b60405180910390a15050565b82610bf58161242d565b610c34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2b906145df565b60405180910390fd5b604051806040016040528084815260200183815250600660008681526020019081526020016000206000820151816000015560208201518160010155905050837f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e468484604051610ca592919061421b565b60405180910390a250505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b6000610d1682612527565b9050919050565b6000610d27612516565b90506000610d3682878761260c565b9050610d868185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612664565b610dc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbc9061439f565b60405180910390fd5b60008686604051602001610dda92919061402a565b6040516020818303038152906040528051906020012090503073ffffffffffffffffffffffffffffffffffffffff16610e1288612527565b73ffffffffffffffffffffffffffffffffffffffff1614610e68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5f9061441f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16610e8982612527565b73ffffffffffffffffffffffffffffffffffffffff1614610edf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed6906143bf565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ef2c7f08888303060006040518663ffffffff1660e01b8152600401610f43959493929190614244565b600060405180830381600087803b158015610f5d57600080fd5b505af1158015610f71573d6000803e3d6000fd5b50505050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c382856040518363ffffffff1660e01b8152600401610fd29291906141f2565b600060405180830381600087803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050505061100e81846126d1565b50505050505050565b6000611021612516565b9050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b815260040161107e91906141d7565b60206040518083038186803b15801561109657600080fd5b505afa1580156110aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ce919061308f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461113b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111329061447f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf846040518263ffffffff1660e01b81526004016111ad91906141d7565b60206040518083038186803b1580156111c557600080fd5b505afa1580156111d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd919061308f565b73ffffffffffffffffffffffffffffffffffffffff1614611253576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124a9061435f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1661127483612527565b73ffffffffffffffffffffffffffffffffffffffff16146112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c19061451f565b60405180910390fd5b6112d482826126d1565b5050565b60606007600085815260200190815260200160002083836040516112fd929190614056565b90815260200160405180910390208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561139f5780601f106113745761010080835404028352916020019161139f565b820191906000526020600020905b81548152906001019060200180831161138257829003601f168201915b505050505090509392505050565b6060600560008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114565780601f1061142b57610100808354040283529160200191611456565b820191906000526020600020905b81548152906001019060200180831161143957829003601f168201915b50505050509050919050565b600061147b82600001518360200151846040015161260c565b9050919050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661150d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115049061449f565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16141561157c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115739061459f565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611607576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115fe9061453f565b60405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b328260405161168f929190614193565b60405180910390a150565b826116a48161242d565b6116e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116da906145df565b60405180910390fd5b8282600560008781526020019081526020016000209190611705929190612d39565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78484604051611738929190614319565b60405180910390a250505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611776612516565b9050600073ffffffffffffffffffffffffffffffffffffffff1661179983612527565b73ffffffffffffffffffffffffffffffffffffffff16146117ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e6906144ff565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611891576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611888906144df565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b815260040161190391906141d7565b60206040518083038186803b15801561191b57600080fd5b505afa15801561192f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611953919061308f565b73ffffffffffffffffffffffffffffffffffffffff16146119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a09061455f565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc1e082a8c26f27c26e1bf5d0ce7ddd579ec7f6d7eb3ea90d8abd6c40991bae368282604051611a2c9291906141f2565b60405180910390a15050565b82611a428161242d565b611a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a78906145df565b60405180910390fd5b611a8c8484846126e9565b50505050565b60025481565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1a9061449f565b60405180910390fd5b611b2c816127ab565b50565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611bba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb19061449f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c21906144bf565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611cbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb2906145ff565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fdb0239c63d4033dcdd21bd44f8dd479a03efbae12f6bbe27c0a5f923d26514cc600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051611d4d919061415d565b60405180910390a150565b6000806006600084815260200190815260200160002060000154600660008581526020019081526020016000206001015491509150915091565b6000611d9c612516565b9050600073ffffffffffffffffffffffffffffffffffffffff16611dbf83612527565b73ffffffffffffffffffffffffffffffffffffffff1614611e15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0c906144ff565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611eb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ead9061437f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b8152600401611f2891906141d7565b60206040518083038186803b158015611f4057600080fd5b505afa158015611f54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f78919061308f565b73ffffffffffffffffffffffffffffffffffffffff1614611fce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc59061455f565b60405180910390fd5b611fd882306126d1565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a83306040518363ffffffff1660e01b81526004016120359291906141f2565b600060405180830381600087803b15801561204f57600080fd5b505af1158015612063573d6000803e3d6000fd5b505050507fcefbe9dbadcf675eef14e23810996ff38541fc26b4dd77cd6724b0eedc96f2008260405161209691906141d7565b60405180910390a15050565b60006120f28484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612664565b90509392505050565b816121058161242d565b612144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213b906145df565b60405180910390fd5b61214e83836126d1565b505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146121e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121da906143ff565b60405180910390fd5b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228c906144bf565b60405180910390fd5b83600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612320838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505061293a565b61232981612992565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516123589190614178565b60405180910390a150505050565b60606004600084815260200190815260200160002060008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156124205780601f106123f557610100808354040283529160200191612420565b820191906000526020600020905b81548152906001019060200180831161240357829003601f168201915b5050505050905092915050565b6000612437612516565b73ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b81526004016124a891906141d7565b60206040518083038186803b1580156124c057600080fd5b505afa1580156124d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f8919061308f565b73ffffffffffffffffffffffffffffffffffffffff16149050919050565b600061252260286129d6565b905090565b6000806060600460008581526020019081526020016000206000603c81526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156125e55780601f106125ba576101008083540402835291602001916125e5565b820191906000526020600020905b8154815290600101906020018083116125c857829003601f168201915b50505050509050600081511115612602576125ff81612a6b565b91505b8192505050919050565b600061265b7f621363c539a3aa1024c8837ca1dc095db03b7f9512b3a95ecb429aae7fd953ed85858560405160200161264793929190613fed565b604051602081830303815290604052612a93565b90509392505050565b60008061267a8385612ad490919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b6126e582603c6126e084612b8f565b6126e9565b5050565b827f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af752838360405161271b92919061463a565b60405180910390a2603c82141561276d57827f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd261275783612a6b565b6040516127649190614178565b60405180910390a25b8060046000858152602001908152602001600020600084815260200190815260200160002090805190602001906127a5929190612db9565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561281b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612812906143df565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156128a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289e9061457f565b60405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a328260405161292f929190614193565b60405180910390a150565b6000815114156129525761294d326127ab565b61298f565b60008151905060005b8181101561298c5761297f83828151811061297257fe5b60200260200101516127ab565b808060010191505061295b565b50505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600090506129e5612bf6565b15612a5e576000836000369050039050612a5660003683906014850192612a0e93929190614711565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612ca3565b915050612a62565b3390505b80915050919050565b6000806014835114612a7c57600080fd5b600c6101000a602084015104905080915050919050565b6000612acc600254308585604051602001612ab19493929190614113565b60405160208183030381529060405280519060200120612d09565b905092915050565b60008060009050604183511415612b855760008060006020860151925060408601519150606086015160001a9050601b8160ff161015612b1557601b810190505b601b8160ff161480612b2a5750601c8160ff16145b15612b815760018782858560405160008152602001604052604051612b529493929190614297565b6020604051602081039080840390855afa158015612b74573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b606080601467ffffffffffffffff81118015612baa57600080fd5b506040519080825280601f01601f191660200182016040528015612bdd5781602001600182028036833780820191505090505b509050600c6101000a8302602082015280915050919050565b600080600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612c9c57602c60003690501015612c97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8e9061445f565b60405180910390fd5b600190505b8091505090565b6000806014835114612cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce1906145bf565b60405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b600081604051602001612d1c9190614084565b604051602081830303815290604052805190602001209050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612d7a57803560ff1916838001178555612da8565b82800160010185558215612da8579182015b82811115612da7578235825591602001919060010190612d8c565b5b509050612db59190612e39565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612dfa57805160ff1916838001178555612e28565b82800160010185558215612e28579182015b82811115612e27578251825591602001919060010190612e0c565b5b509050612e359190612e39565b5090565b5b80821115612e52576000816000905550600101612e3a565b5090565b600081359050612e65816148f9565b92915050565b600081519050612e7a816148f9565b92915050565b60008083601f840112612e9257600080fd5b8235905067ffffffffffffffff811115612eab57600080fd5b602083019150836020820283011115612ec357600080fd5b9250929050565b600081359050612ed981614910565b92915050565b600081359050612eee81614927565b92915050565b60008083601f840112612f0657600080fd5b8235905067ffffffffffffffff811115612f1f57600080fd5b602083019150836001820283011115612f3757600080fd5b9250929050565b600082601f830112612f4f57600080fd5b8135612f62612f5d82614697565b61466a565b91508082526020830160208301858383011115612f7e57600080fd5b612f89838284614861565b50505092915050565b600081359050612fa18161493e565b92915050565b60008083601f840112612fb957600080fd5b8235905067ffffffffffffffff811115612fd257600080fd5b602083019150836001820283011115612fea57600080fd5b9250929050565b60006060828403121561300357600080fd5b61300d606061466a565b9050600061301d84828501612e56565b600083015250602061303184828501612eca565b602083015250604061304584828501612eca565b60408301525092915050565b60008135905061306081614955565b92915050565b60006020828403121561307857600080fd5b600061308684828501612e56565b91505092915050565b6000602082840312156130a157600080fd5b60006130af84828501612e6b565b91505092915050565b6000602082840312156130ca57600080fd5b60006130d884828501612eca565b91505092915050565b600080604083850312156130f457600080fd5b600061310285828601612eca565b925050602061311385828601612e56565b9150509250929050565b60008060006060848603121561313257600080fd5b600061314086828701612eca565b935050602061315186828701612eca565b925050604061316286828701612eca565b9150509250925092565b6000806000806060858703121561318257600080fd5b600061319087828801612eca565b94505060206131a187828801612eca565b935050604085013567ffffffffffffffff8111156131be57600080fd5b6131ca87828801612ef4565b925092505092959194509250565b6000806000604084860312156131ed57600080fd5b60006131fb86828701612eca565b935050602084013567ffffffffffffffff81111561321857600080fd5b61322486828701612ef4565b92509250509250925092565b60008060006040848603121561324557600080fd5b600061325386828701612eca565b935050602084013567ffffffffffffffff81111561327057600080fd5b61327c86828701612fa7565b92509250509250925092565b6000806000806000606086880312156132a057600080fd5b60006132ae88828901612eca565b955050602086013567ffffffffffffffff8111156132cb57600080fd5b6132d788828901612fa7565b9450945050604086013567ffffffffffffffff8111156132f657600080fd5b61330288828901612fa7565b92509250509295509295909350565b6000806040838503121561332457600080fd5b600061333285828601612eca565b925050602061334385828601613051565b9150509250929050565b60008060006060848603121561336257600080fd5b600061337086828701612eca565b935050602061338186828701613051565b925050604084013567ffffffffffffffff81111561339e57600080fd5b6133aa86828701612f3e565b9150509250925092565b6000602082840312156133c657600080fd5b60006133d484828501612edf565b91505092915050565b6000602082840312156133ef57600080fd5b60006133fd84828501612f92565b91505092915050565b6000806000806060858703121561341c57600080fd5b600061342a87828801612f92565b945050602085013567ffffffffffffffff81111561344757600080fd5b61345387828801612e80565b9350935050604061346687828801612e56565b91505092959194509250565b60006060828403121561348457600080fd5b600061349284828501612ff1565b91505092915050565b6134a4816147f5565b82525050565b6134b381614744565b82525050565b6134ca6134c582614744565b6148a3565b82525050565b6134d981614756565b82525050565b6134e881614762565b82525050565b6134ff6134fa82614762565b6148b5565b82525050565b6000613510826146c3565b61351a81856146d9565b935061352a818560208601614870565b613533816148db565b840191505092915050565b6000613549826146c3565b61355381856146ea565b9350613563818560208601614870565b80840191505092915050565b61357881614807565b82525050565b6135878161482b565b82525050565b600061359983856146f5565b93506135a6838584614861565b6135af836148db565b840190509392505050565b60006135c68385614706565b93506135d3838584614861565b82840190509392505050565b60006135ea826146ce565b6135f481856146f5565b9350613604818560208601614870565b61360d816148db565b840191505092915050565b6000613625601983614706565b91507f737570706f727473496e746572666163652862797465733429000000000000006000830152601982019050919050565b60006136656024836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f6465207265736f60008301527f6c766572000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136cb6021836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f6465206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137316029836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c696420677561726469616e2060008301527f7369676e617475726500000000000000000000000000000000000000000000006020830152604082019050919050565b60006137976022836146f5565b91507f454e53436f6e74726f6c6c65723a206c6162656c20616c72656164792074616b60008301527f656e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137fd601c83614706565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b600061383d6020836146f5565b91507f477561726465643a2063616e6e6f74206164642030783020677561726469616e6000830152602082019050919050565b600061387d602f836146f5565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b60006138e3600d83614706565b91507f61646472286279746573333229000000000000000000000000000000000000006000830152600d82019050919050565b6000613923601b836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f646500000000006000830152602082019050919050565b60006139636021836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520646f65736e2774206578697360008301527f74000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006139c96022836146f5565b91507f47617465776179526563697069656e743a20696e76616c6964206d73672e646160008301527f74610000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a2f601483614706565b91507f7465787428627974657333322c737472696e67290000000000000000000000006000830152601482019050919050565b6000613a6f600d83614706565b91507f6e616d65286279746573333229000000000000000000000000000000000000006000830152600d82019050919050565b6000613aaf602b836146f5565b91507f454e53436f6e74726f6c6c65723a2063616c6c6572206973206e6f742074686560008301527f206e6f6465206f776e65720000000000000000000000000000000000000000006020830152604082019050919050565b6000613b156026836146f5565b91507f477561726465643a2074782e6f726967696e206973206e6f742074686520677560008301527f61726469616e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b7b6026836146f5565b91507f454e53436f6e74726f6c6c65723a2063616e6e6f74207365742030783020726560008301527f67697374727900000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613be16025836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c7265616479207375626d60008301527f69747465640000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613c47600f83614706565b91507f7075626b657928627974657333322900000000000000000000000000000000006000830152600f82019050919050565b6000613c876022836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c7265616479206578697360008301527f74730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ced6023836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c726561647920696e207360008301527f796e6300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d53601f836146f5565b91507f477561726465643a20677561726469616e20646f65736e2774206578697374006000830152602082019050919050565b6000613d936025836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c696420656e73206e6f64652060008301527f6f776e65720000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613df96020836146f5565b91507f477561726465643a20677561726469616e20616c7265616479206578697374736000830152602082019050919050565b6000613e39601b836146f5565b91507f477561726465643a2063616e6e6f742072656d6f76652073656c6600000000006000830152602082019050919050565b6000613e79601d836146f5565b91507f42797465734c69623a20696e76616c69642064617461206c656e6774680000006000830152602082019050919050565b6000613eb96037836146f5565b91507f454e5341627374726163745265736f6c7665723a20726576657274656420627960008301527f206f6e6c794e6f64654f776e6572206d6f6469666965720000000000000000006020830152604082019050919050565b6000613f1f601283614706565b91507f6164647228627974657333322c75696e742900000000000000000000000000006000830152601282019050919050565b6000613f5f6023836146f5565b91507f454e53436f6e74726f6c6c65723a20726567697374727920616c72656164792060008301527f73657400000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b613fc1816147ca565b82525050565b613fd8613fd3826147ca565b6148d1565b82525050565b613fe7816147e8565b82525050565b6000613ff982866134b9565b60148201915061400982856134ee565b60208201915061401982846134ee565b602082019150819050949350505050565b600061403682856134ee565b60208201915061404682846134ee565b6020820191508190509392505050565b60006140638284866135ba565b91508190509392505050565b600061407a82613618565b9150819050919050565b600061408f826137f0565b915061409b82846134ee565b60208201915081905092915050565b60006140b5826138d6565b9150819050919050565b60006140ca82613a22565b9150819050919050565b60006140df82613a62565b9150819050919050565b60006140f482613c3a565b9150819050919050565b600061410982613f12565b9150819050919050565b600061411f8287613fc7565b60208201915061412f82866134b9565b60148201915061413f82856134ee565b60208201915061414f828461353e565b915081905095945050505050565b600060208201905061417260008301846134aa565b92915050565b600060208201905061418d600083018461349b565b92915050565b60006040820190506141a8600083018561349b565b6141b560208301846134aa565b9392505050565b60006020820190506141d160008301846134d0565b92915050565b60006020820190506141ec60008301846134df565b92915050565b600060408201905061420760008301856134df565b61421460208301846134aa565b9392505050565b600060408201905061423060008301856134df565b61423d60208301846134df565b9392505050565b600060a08201905061425960008301886134df565b61426660208301876134df565b61427360408301866134aa565b61428060608301856134aa565b61428d608083018461357e565b9695505050505050565b60006080820190506142ac60008301876134df565b6142b96020830186613fde565b6142c660408301856134df565b6142d360608301846134df565b95945050505050565b600060208201905081810360008301526142f68184613505565b905092915050565b6000602082019050614313600083018461356f565b92915050565b6000602082019050818103600083015261433481848661358d565b90509392505050565b6000602082019050818103600083015261435781846135df565b905092915050565b6000602082019050818103600083015261437881613658565b9050919050565b60006020820190508181036000830152614398816136be565b9050919050565b600060208201905081810360008301526143b881613724565b9050919050565b600060208201905081810360008301526143d88161378a565b9050919050565b600060208201905081810360008301526143f881613830565b9050919050565b6000602082019050818103600083015261441881613870565b9050919050565b6000602082019050818103600083015261443881613916565b9050919050565b6000602082019050818103600083015261445881613956565b9050919050565b60006020820190508181036000830152614478816139bc565b9050919050565b6000602082019050818103600083015261449881613aa2565b9050919050565b600060208201905081810360008301526144b881613b08565b9050919050565b600060208201905081810360008301526144d881613b6e565b9050919050565b600060208201905081810360008301526144f881613bd4565b9050919050565b6000602082019050818103600083015261451881613c7a565b9050919050565b6000602082019050818103600083015261453881613ce0565b9050919050565b6000602082019050818103600083015261455881613d46565b9050919050565b6000602082019050818103600083015261457881613d86565b9050919050565b6000602082019050818103600083015261459881613dec565b9050919050565b600060208201905081810360008301526145b881613e2c565b9050919050565b600060208201905081810360008301526145d881613e6c565b9050919050565b600060208201905081810360008301526145f881613eac565b9050919050565b6000602082019050818103600083015261461881613f52565b9050919050565b60006020820190506146346000830184613fb8565b92915050565b600060408201905061464f6000830185613fb8565b81810360208301526146618184613505565b90509392505050565b6000604051905081810181811067ffffffffffffffff8211171561468d57600080fd5b8060405250919050565b600067ffffffffffffffff8211156146ae57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000808585111561472157600080fd5b8386111561472e57600080fd5b6001850283019150848603905094509492505050565b600061474f826147aa565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006147a382614744565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b600060ff82169050919050565b60006148008261483d565b9050919050565b600061481282614819565b9050919050565b6000614824826147aa565b9050919050565b6000614836826147d4565b9050919050565b60006148488261484f565b9050919050565b600061485a826147aa565b9050919050565b82818337600083830152505050565b60005b8381101561488e578082015181840152602081019050614873565b8381111561489d576000848401525b50505050565b60006148ae826148bf565b9050919050565b6000819050919050565b60006148ca826148ec565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61490281614744565b811461490d57600080fd5b50565b61491981614762565b811461492457600080fd5b50565b6149308161476c565b811461493b57600080fd5b50565b61494781614798565b811461495257600080fd5b50565b61495e816147ca565b811461496957600080fd5b5056fea164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806371404156116100f9578063a91ee0dc11610097578063d0f710d611610071578063d0f710d614610512578063d5fa2b0014610542578063dc5b68a61461055e578063f1cb7e061461057a576101c4565b8063a91ee0dc146104a9578063c8690233146104c5578063c8cc2aee146104f6576101c4565b80637d0e0e7e116100d35780637d0e0e7e146104375780638b95dd71146104535780639a8a05921461046f578063a526d83b1461048d576101c4565b806371404156146103e157806377372213146103fd5780637b10399914610419576101c4565b8063392e53cd1161016657806355800f871161014057806355800f871461033557806359d1d43c14610351578063691f3431146103815780636df0cf42146103b1576101c4565b8063392e53cd146102cb5780633b3b57de146102e957806346386f7314610319576101c4565b8063116191b6116101a2578063116191b6146102455780631b3cd1421461026357806329ae6a7e1461029357806329cd62ea146102af576101c4565b806301ffc9a7146101c95780630c68ba21146101f957806310f13a8c14610229575b600080fd5b6101e360048036038101906101de91906133b4565b6105aa565b6040516101f091906141bc565b60405180910390f35b610213600480360381019061020e9190613066565b610834565b60405161022091906141bc565b60405180910390f35b610243600480360381019061023e9190613288565b610889565b005b61024d61096d565b60405161025a919061415d565b60405180910390f35b61027d600480360381019061027891906130b8565b610993565b60405161028a919061415d565b60405180910390f35b6102ad60048036038101906102a891906130b8565b6109c6565b005b6102c960048036038101906102c4919061311d565b610beb565b005b6102d3610cb3565b6040516102e091906141bc565b60405180910390f35b61030360048036038101906102fe91906130b8565b610d0b565b604051610310919061415d565b60405180910390f35b610333600480360381019061032e919061316c565b610d1d565b005b61034f600480360381019061034a91906130b8565b611017565b005b61036b60048036038101906103669190613230565b6112d8565b604051610378919061433d565b60405180910390f35b61039b600480360381019061039691906130b8565b6113ad565b6040516103a8919061433d565b60405180910390f35b6103cb60048036038101906103c69190613472565b611462565b6040516103d891906141d7565b60405180910390f35b6103fb60048036038101906103f69190613066565b611482565b005b61041760048036038101906104129190613230565b61169a565b005b610421611746565b60405161042e91906142fe565b60405180910390f35b610451600480360381019061044c91906130b8565b61176c565b005b61046d6004803603810190610468919061334d565b611a38565b005b610477611a92565b604051610484919061461f565b60405180910390f35b6104a760048036038101906104a29190613066565b611a98565b005b6104c360048036038101906104be91906133dd565b611b2f565b005b6104df60048036038101906104da91906130b8565b611d58565b6040516104ed92919061421b565b60405180910390f35b610510600480360381019061050b91906130b8565b611d92565b005b61052c600480360381019061052791906131d8565b6120a2565b60405161053991906141bc565b60405180910390f35b61055c600480360381019061055791906130e1565b6120fb565b005b61057860048036038101906105739190613406565b612153565b005b610594600480360381019061058f9190613311565b612366565b6040516105a191906142dc565b60405180910390f35b60006040516020016105bb9061406f565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061067d5750604051602001610626906140aa565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806106e95750604051602001610692906140fe565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061075557506040516020016106fe906140d4565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107c1575060405160200161076a906140e9565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061082d57506040516020016107d6906140bf565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b846108938161242d565b6108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c9906145df565b60405180910390fd5b82826007600089815260200190815260200160002087876040516108f7929190614056565b90815260200160405180910390209190610912929190612d39565b508484604051610923929190614056565b6040518091039020867fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550878760405161095d929190614319565b60405180910390a3505050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006109d0612516565b90503073ffffffffffffffffffffffffffffffffffffffff166109f283612527565b73ffffffffffffffffffffffffffffffffffffffff1614610a48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3f9061443f565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ae9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae09061437f565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c383836040518363ffffffff1660e01b8152600401610b469291906141f2565b600060405180830381600087803b158015610b6057600080fd5b505af1158015610b74573d6000803e3d6000fd5b505050506009600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690557f7803a16d95f9ca635bdec561006625e7444d8a9f8463866643cc03af011779d38282604051610bdf9291906141f2565b60405180910390a15050565b82610bf58161242d565b610c34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2b906145df565b60405180910390fd5b604051806040016040528084815260200183815250600660008681526020019081526020016000206000820151816000015560208201518160010155905050837f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e468484604051610ca592919061421b565b60405180910390a250505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b6000610d1682612527565b9050919050565b6000610d27612516565b90506000610d3682878761260c565b9050610d868185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612664565b610dc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbc9061439f565b60405180910390fd5b60008686604051602001610dda92919061402a565b6040516020818303038152906040528051906020012090503073ffffffffffffffffffffffffffffffffffffffff16610e1288612527565b73ffffffffffffffffffffffffffffffffffffffff1614610e68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5f9061441f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16610e8982612527565b73ffffffffffffffffffffffffffffffffffffffff1614610edf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed6906143bf565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ef2c7f08888303060006040518663ffffffff1660e01b8152600401610f43959493929190614244565b600060405180830381600087803b158015610f5d57600080fd5b505af1158015610f71573d6000803e3d6000fd5b50505050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c382856040518363ffffffff1660e01b8152600401610fd29291906141f2565b600060405180830381600087803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050505061100e81846126d1565b50505050505050565b6000611021612516565b9050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b815260040161107e91906141d7565b60206040518083038186803b15801561109657600080fd5b505afa1580156110aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ce919061308f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461113b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111329061447f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf846040518263ffffffff1660e01b81526004016111ad91906141d7565b60206040518083038186803b1580156111c557600080fd5b505afa1580156111d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd919061308f565b73ffffffffffffffffffffffffffffffffffffffff1614611253576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124a9061435f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1661127483612527565b73ffffffffffffffffffffffffffffffffffffffff16146112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c19061451f565b60405180910390fd5b6112d482826126d1565b5050565b60606007600085815260200190815260200160002083836040516112fd929190614056565b90815260200160405180910390208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561139f5780601f106113745761010080835404028352916020019161139f565b820191906000526020600020905b81548152906001019060200180831161138257829003601f168201915b505050505090509392505050565b6060600560008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114565780601f1061142b57610100808354040283529160200191611456565b820191906000526020600020905b81548152906001019060200180831161143957829003601f168201915b50505050509050919050565b600061147b82600001518360200151846040015161260c565b9050919050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661150d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115049061449f565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16141561157c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115739061459f565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611607576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115fe9061453f565b60405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b328260405161168f929190614193565b60405180910390a150565b826116a48161242d565b6116e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116da906145df565b60405180910390fd5b8282600560008781526020019081526020016000209190611705929190612d39565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78484604051611738929190614319565b60405180910390a250505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611776612516565b9050600073ffffffffffffffffffffffffffffffffffffffff1661179983612527565b73ffffffffffffffffffffffffffffffffffffffff16146117ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e6906144ff565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611891576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611888906144df565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b815260040161190391906141d7565b60206040518083038186803b15801561191b57600080fd5b505afa15801561192f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611953919061308f565b73ffffffffffffffffffffffffffffffffffffffff16146119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a09061455f565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc1e082a8c26f27c26e1bf5d0ce7ddd579ec7f6d7eb3ea90d8abd6c40991bae368282604051611a2c9291906141f2565b60405180910390a15050565b82611a428161242d565b611a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a78906145df565b60405180910390fd5b611a8c8484846126e9565b50505050565b60025481565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1a9061449f565b60405180910390fd5b611b2c816127ab565b50565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611bba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb19061449f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c21906144bf565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611cbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb2906145ff565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fdb0239c63d4033dcdd21bd44f8dd479a03efbae12f6bbe27c0a5f923d26514cc600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051611d4d919061415d565b60405180910390a150565b6000806006600084815260200190815260200160002060000154600660008581526020019081526020016000206001015491509150915091565b6000611d9c612516565b9050600073ffffffffffffffffffffffffffffffffffffffff16611dbf83612527565b73ffffffffffffffffffffffffffffffffffffffff1614611e15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0c906144ff565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611eb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ead9061437f565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b8152600401611f2891906141d7565b60206040518083038186803b158015611f4057600080fd5b505afa158015611f54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f78919061308f565b73ffffffffffffffffffffffffffffffffffffffff1614611fce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc59061455f565b60405180910390fd5b611fd882306126d1565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a83306040518363ffffffff1660e01b81526004016120359291906141f2565b600060405180830381600087803b15801561204f57600080fd5b505af1158015612063573d6000803e3d6000fd5b505050507fcefbe9dbadcf675eef14e23810996ff38541fc26b4dd77cd6724b0eedc96f2008260405161209691906141d7565b60405180910390a15050565b60006120f28484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612664565b90509392505050565b816121058161242d565b612144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213b906145df565b60405180910390fd5b61214e83836126d1565b505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146121e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121da906143ff565b60405180910390fd5b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228c906144bf565b60405180910390fd5b83600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612320838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505061293a565b61232981612992565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516123589190614178565b60405180910390a150505050565b60606004600084815260200190815260200160002060008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156124205780601f106123f557610100808354040283529160200191612420565b820191906000526020600020905b81548152906001019060200180831161240357829003601f168201915b5050505050905092915050565b6000612437612516565b73ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b81526004016124a891906141d7565b60206040518083038186803b1580156124c057600080fd5b505afa1580156124d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f8919061308f565b73ffffffffffffffffffffffffffffffffffffffff16149050919050565b600061252260286129d6565b905090565b6000806060600460008581526020019081526020016000206000603c81526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156125e55780601f106125ba576101008083540402835291602001916125e5565b820191906000526020600020905b8154815290600101906020018083116125c857829003601f168201915b50505050509050600081511115612602576125ff81612a6b565b91505b8192505050919050565b600061265b7f621363c539a3aa1024c8837ca1dc095db03b7f9512b3a95ecb429aae7fd953ed85858560405160200161264793929190613fed565b604051602081830303815290604052612a93565b90509392505050565b60008061267a8385612ad490919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b6126e582603c6126e084612b8f565b6126e9565b5050565b827f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af752838360405161271b92919061463a565b60405180910390a2603c82141561276d57827f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd261275783612a6b565b6040516127649190614178565b60405180910390a25b8060046000858152602001908152602001600020600084815260200190815260200160002090805190602001906127a5929190612db9565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561281b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612812906143df565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156128a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289e9061457f565b60405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a328260405161292f929190614193565b60405180910390a150565b6000815114156129525761294d326127ab565b61298f565b60008151905060005b8181101561298c5761297f83828151811061297257fe5b60200260200101516127ab565b808060010191505061295b565b50505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600090506129e5612bf6565b15612a5e576000836000369050039050612a5660003683906014850192612a0e93929190614711565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612ca3565b915050612a62565b3390505b80915050919050565b6000806014835114612a7c57600080fd5b600c6101000a602084015104905080915050919050565b6000612acc600254308585604051602001612ab19493929190614113565b60405160208183030381529060405280519060200120612d09565b905092915050565b60008060009050604183511415612b855760008060006020860151925060408601519150606086015160001a9050601b8160ff161015612b1557601b810190505b601b8160ff161480612b2a5750601c8160ff16145b15612b815760018782858560405160008152602001604052604051612b529493929190614297565b6020604051602081039080840390855afa158015612b74573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b606080601467ffffffffffffffff81118015612baa57600080fd5b506040519080825280601f01601f191660200182016040528015612bdd5781602001600182028036833780820191505090505b509050600c6101000a8302602082015280915050919050565b600080600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612c9c57602c60003690501015612c97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8e9061445f565b60405180910390fd5b600190505b8091505090565b6000806014835114612cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce1906145bf565b60405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b600081604051602001612d1c9190614084565b604051602081830303815290604052805190602001209050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612d7a57803560ff1916838001178555612da8565b82800160010185558215612da8579182015b82811115612da7578235825591602001919060010190612d8c565b5b509050612db59190612e39565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612dfa57805160ff1916838001178555612e28565b82800160010185558215612e28579182015b82811115612e27578251825591602001919060010190612e0c565b5b509050612e359190612e39565b5090565b5b80821115612e52576000816000905550600101612e3a565b5090565b600081359050612e65816148f9565b92915050565b600081519050612e7a816148f9565b92915050565b60008083601f840112612e9257600080fd5b8235905067ffffffffffffffff811115612eab57600080fd5b602083019150836020820283011115612ec357600080fd5b9250929050565b600081359050612ed981614910565b92915050565b600081359050612eee81614927565b92915050565b60008083601f840112612f0657600080fd5b8235905067ffffffffffffffff811115612f1f57600080fd5b602083019150836001820283011115612f3757600080fd5b9250929050565b600082601f830112612f4f57600080fd5b8135612f62612f5d82614697565b61466a565b91508082526020830160208301858383011115612f7e57600080fd5b612f89838284614861565b50505092915050565b600081359050612fa18161493e565b92915050565b60008083601f840112612fb957600080fd5b8235905067ffffffffffffffff811115612fd257600080fd5b602083019150836001820283011115612fea57600080fd5b9250929050565b60006060828403121561300357600080fd5b61300d606061466a565b9050600061301d84828501612e56565b600083015250602061303184828501612eca565b602083015250604061304584828501612eca565b60408301525092915050565b60008135905061306081614955565b92915050565b60006020828403121561307857600080fd5b600061308684828501612e56565b91505092915050565b6000602082840312156130a157600080fd5b60006130af84828501612e6b565b91505092915050565b6000602082840312156130ca57600080fd5b60006130d884828501612eca565b91505092915050565b600080604083850312156130f457600080fd5b600061310285828601612eca565b925050602061311385828601612e56565b9150509250929050565b60008060006060848603121561313257600080fd5b600061314086828701612eca565b935050602061315186828701612eca565b925050604061316286828701612eca565b9150509250925092565b6000806000806060858703121561318257600080fd5b600061319087828801612eca565b94505060206131a187828801612eca565b935050604085013567ffffffffffffffff8111156131be57600080fd5b6131ca87828801612ef4565b925092505092959194509250565b6000806000604084860312156131ed57600080fd5b60006131fb86828701612eca565b935050602084013567ffffffffffffffff81111561321857600080fd5b61322486828701612ef4565b92509250509250925092565b60008060006040848603121561324557600080fd5b600061325386828701612eca565b935050602084013567ffffffffffffffff81111561327057600080fd5b61327c86828701612fa7565b92509250509250925092565b6000806000806000606086880312156132a057600080fd5b60006132ae88828901612eca565b955050602086013567ffffffffffffffff8111156132cb57600080fd5b6132d788828901612fa7565b9450945050604086013567ffffffffffffffff8111156132f657600080fd5b61330288828901612fa7565b92509250509295509295909350565b6000806040838503121561332457600080fd5b600061333285828601612eca565b925050602061334385828601613051565b9150509250929050565b60008060006060848603121561336257600080fd5b600061337086828701612eca565b935050602061338186828701613051565b925050604084013567ffffffffffffffff81111561339e57600080fd5b6133aa86828701612f3e565b9150509250925092565b6000602082840312156133c657600080fd5b60006133d484828501612edf565b91505092915050565b6000602082840312156133ef57600080fd5b60006133fd84828501612f92565b91505092915050565b6000806000806060858703121561341c57600080fd5b600061342a87828801612f92565b945050602085013567ffffffffffffffff81111561344757600080fd5b61345387828801612e80565b9350935050604061346687828801612e56565b91505092959194509250565b60006060828403121561348457600080fd5b600061349284828501612ff1565b91505092915050565b6134a4816147f5565b82525050565b6134b381614744565b82525050565b6134ca6134c582614744565b6148a3565b82525050565b6134d981614756565b82525050565b6134e881614762565b82525050565b6134ff6134fa82614762565b6148b5565b82525050565b6000613510826146c3565b61351a81856146d9565b935061352a818560208601614870565b613533816148db565b840191505092915050565b6000613549826146c3565b61355381856146ea565b9350613563818560208601614870565b80840191505092915050565b61357881614807565b82525050565b6135878161482b565b82525050565b600061359983856146f5565b93506135a6838584614861565b6135af836148db565b840190509392505050565b60006135c68385614706565b93506135d3838584614861565b82840190509392505050565b60006135ea826146ce565b6135f481856146f5565b9350613604818560208601614870565b61360d816148db565b840191505092915050565b6000613625601983614706565b91507f737570706f727473496e746572666163652862797465733429000000000000006000830152601982019050919050565b60006136656024836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f6465207265736f60008301527f6c766572000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136cb6021836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f6465206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137316029836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c696420677561726469616e2060008301527f7369676e617475726500000000000000000000000000000000000000000000006020830152604082019050919050565b60006137976022836146f5565b91507f454e53436f6e74726f6c6c65723a206c6162656c20616c72656164792074616b60008301527f656e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137fd601c83614706565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b600061383d6020836146f5565b91507f477561726465643a2063616e6e6f74206164642030783020677561726469616e6000830152602082019050919050565b600061387d602f836146f5565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b60006138e3600d83614706565b91507f61646472286279746573333229000000000000000000000000000000000000006000830152600d82019050919050565b6000613923601b836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c6964206e6f646500000000006000830152602082019050919050565b60006139636021836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520646f65736e2774206578697360008301527f74000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006139c96022836146f5565b91507f47617465776179526563697069656e743a20696e76616c6964206d73672e646160008301527f74610000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a2f601483614706565b91507f7465787428627974657333322c737472696e67290000000000000000000000006000830152601482019050919050565b6000613a6f600d83614706565b91507f6e616d65286279746573333229000000000000000000000000000000000000006000830152600d82019050919050565b6000613aaf602b836146f5565b91507f454e53436f6e74726f6c6c65723a2063616c6c6572206973206e6f742074686560008301527f206e6f6465206f776e65720000000000000000000000000000000000000000006020830152604082019050919050565b6000613b156026836146f5565b91507f477561726465643a2074782e6f726967696e206973206e6f742074686520677560008301527f61726469616e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b7b6026836146f5565b91507f454e53436f6e74726f6c6c65723a2063616e6e6f74207365742030783020726560008301527f67697374727900000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613be16025836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c7265616479207375626d60008301527f69747465640000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613c47600f83614706565b91507f7075626b657928627974657333322900000000000000000000000000000000006000830152600f82019050919050565b6000613c876022836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c7265616479206578697360008301527f74730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ced6023836146f5565b91507f454e53436f6e74726f6c6c65723a206e6f646520616c726561647920696e207360008301527f796e6300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d53601f836146f5565b91507f477561726465643a20677561726469616e20646f65736e2774206578697374006000830152602082019050919050565b6000613d936025836146f5565b91507f454e53436f6e74726f6c6c65723a20696e76616c696420656e73206e6f64652060008301527f6f776e65720000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613df96020836146f5565b91507f477561726465643a20677561726469616e20616c7265616479206578697374736000830152602082019050919050565b6000613e39601b836146f5565b91507f477561726465643a2063616e6e6f742072656d6f76652073656c6600000000006000830152602082019050919050565b6000613e79601d836146f5565b91507f42797465734c69623a20696e76616c69642064617461206c656e6774680000006000830152602082019050919050565b6000613eb96037836146f5565b91507f454e5341627374726163745265736f6c7665723a20726576657274656420627960008301527f206f6e6c794e6f64654f776e6572206d6f6469666965720000000000000000006020830152604082019050919050565b6000613f1f601283614706565b91507f6164647228627974657333322c75696e742900000000000000000000000000006000830152601282019050919050565b6000613f5f6023836146f5565b91507f454e53436f6e74726f6c6c65723a20726567697374727920616c72656164792060008301527f73657400000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b613fc1816147ca565b82525050565b613fd8613fd3826147ca565b6148d1565b82525050565b613fe7816147e8565b82525050565b6000613ff982866134b9565b60148201915061400982856134ee565b60208201915061401982846134ee565b602082019150819050949350505050565b600061403682856134ee565b60208201915061404682846134ee565b6020820191508190509392505050565b60006140638284866135ba565b91508190509392505050565b600061407a82613618565b9150819050919050565b600061408f826137f0565b915061409b82846134ee565b60208201915081905092915050565b60006140b5826138d6565b9150819050919050565b60006140ca82613a22565b9150819050919050565b60006140df82613a62565b9150819050919050565b60006140f482613c3a565b9150819050919050565b600061410982613f12565b9150819050919050565b600061411f8287613fc7565b60208201915061412f82866134b9565b60148201915061413f82856134ee565b60208201915061414f828461353e565b915081905095945050505050565b600060208201905061417260008301846134aa565b92915050565b600060208201905061418d600083018461349b565b92915050565b60006040820190506141a8600083018561349b565b6141b560208301846134aa565b9392505050565b60006020820190506141d160008301846134d0565b92915050565b60006020820190506141ec60008301846134df565b92915050565b600060408201905061420760008301856134df565b61421460208301846134aa565b9392505050565b600060408201905061423060008301856134df565b61423d60208301846134df565b9392505050565b600060a08201905061425960008301886134df565b61426660208301876134df565b61427360408301866134aa565b61428060608301856134aa565b61428d608083018461357e565b9695505050505050565b60006080820190506142ac60008301876134df565b6142b96020830186613fde565b6142c660408301856134df565b6142d360608301846134df565b95945050505050565b600060208201905081810360008301526142f68184613505565b905092915050565b6000602082019050614313600083018461356f565b92915050565b6000602082019050818103600083015261433481848661358d565b90509392505050565b6000602082019050818103600083015261435781846135df565b905092915050565b6000602082019050818103600083015261437881613658565b9050919050565b60006020820190508181036000830152614398816136be565b9050919050565b600060208201905081810360008301526143b881613724565b9050919050565b600060208201905081810360008301526143d88161378a565b9050919050565b600060208201905081810360008301526143f881613830565b9050919050565b6000602082019050818103600083015261441881613870565b9050919050565b6000602082019050818103600083015261443881613916565b9050919050565b6000602082019050818103600083015261445881613956565b9050919050565b60006020820190508181036000830152614478816139bc565b9050919050565b6000602082019050818103600083015261449881613aa2565b9050919050565b600060208201905081810360008301526144b881613b08565b9050919050565b600060208201905081810360008301526144d881613b6e565b9050919050565b600060208201905081810360008301526144f881613bd4565b9050919050565b6000602082019050818103600083015261451881613c7a565b9050919050565b6000602082019050818103600083015261453881613ce0565b9050919050565b6000602082019050818103600083015261455881613d46565b9050919050565b6000602082019050818103600083015261457881613d86565b9050919050565b6000602082019050818103600083015261459881613dec565b9050919050565b600060208201905081810360008301526145b881613e2c565b9050919050565b600060208201905081810360008301526145d881613e6c565b9050919050565b600060208201905081810360008301526145f881613eac565b9050919050565b6000602082019050818103600083015261461881613f52565b9050919050565b60006020820190506146346000830184613fb8565b92915050565b600060408201905061464f6000830185613fb8565b81810360208301526146618184613505565b90509392505050565b6000604051905081810181811067ffffffffffffffff8211171561468d57600080fd5b8060405250919050565b600067ffffffffffffffff8211156146ae57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000808585111561472157600080fd5b8386111561472e57600080fd5b6001850283019150848603905094509492505050565b600061474f826147aa565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006147a382614744565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b600060ff82169050919050565b60006148008261483d565b9050919050565b600061481282614819565b9050919050565b6000614824826147aa565b9050919050565b6000614836826147d4565b9050919050565b60006148488261484f565b9050919050565b600061485a826147aa565b9050919050565b82818337600083830152505050565b60005b8381101561488e578082015181840152602081019050614873565b8381111561489d576000848401525b50505050565b60006148ae826148bf565b9050919050565b6000819050919050565b60006148ca826148ec565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61490281614744565b811461490d57600080fd5b50565b61491981614762565b811461492457600080fd5b50565b6149308161476c565b811461493b57600080fd5b50565b61494781614798565b811461495257600080fd5b50565b61495e816147ca565b811461496957600080fd5b5056fea164736f6c634300060c000a", + "devdoc": { + "author": "Stanisław Głogowski ", + "details": "The process of adding root node consists of 3 steps: 1. `submitNode` - should be called from ENS node owner, 2. Change ENS node owner in ENS registry to ENS controller, 3. `verifyNode` - should be called from previous ENS node owner, To register sub node, `msg.sender` need to send valid signature from one of guardian key. Once registration is complete `msg.sender` becoming both node owner and `addr` record value. After registration sub node cannot be replaced.", + "events": { + "NodeReleased(bytes32,address)": { + "details": "Emitted when new node is released", + "params": { + "node": "node name hash", + "owner": "owner address" + } + }, + "NodeSubmitted(bytes32,address)": { + "details": "Emitted when new node is submitted", + "params": { + "node": "node name hash", + "owner": "owner address" + } + }, + "NodeVerified(bytes32)": { + "details": "Emitted when the existing owner is verified", + "params": { + "node": "node name hash" + } + }, + "RegistryChanged(address)": { + "details": "Emitted when ENS registry address is changed", + "params": { + "registry": "registry address" + } + } + }, + "kind": "dev", + "methods": { + "addGuardian(address)": { + "params": { + "guardian": "guardian address" + } + }, + "constructor": { + "details": "Public constructor" + }, + "hashSubNodeRegistration((address,bytes32,bytes32))": { + "params": { + "subNodeRegistration": "struct" + }, + "returns": { + "_0": "hash" + } + }, + "initialize(address,address[],address)": { + "params": { + "gateway_": "gateway address", + "registry_": "ENS registry address" + } + }, + "isGuardian(address)": { + "params": { + "guardian": "guardian address" + }, + "returns": { + "_0": "true when guardian exists" + } + }, + "isInitialized()": { + "returns": { + "_0": "true when contract is initialized" + } + }, + "registerSubNode(bytes32,bytes32,bytes)": { + "params": { + "guardianSignature": "guardian signature", + "label": "label hash", + "node": "node name hash" + } + }, + "releaseNode(bytes32)": { + "details": "Should be called from the previous ENS node owner", + "params": { + "node": "node name hash" + } + }, + "removeGuardian(address)": { + "params": { + "guardian": "guardian address" + } + }, + "setRegistry(address)": { + "params": { + "registry_": "registry address" + } + }, + "submitNode(bytes32)": { + "details": "Should be called from the current ENS node owner", + "params": { + "node": "node name hash" + } + }, + "syncAddr(bytes32)": { + "params": { + "node": "node name hash" + } + }, + "verifyGuardianSignature(bytes32,bytes)": { + "params": { + "messageHash": "message hash", + "signature": "signature" + }, + "returns": { + "_0": "true on correct guardian signature" + } + }, + "verifyNode(bytes32)": { + "details": "Should be called from the previous ENS node owner", + "params": { + "node": "node name hash" + } + } + }, + "title": "ENS controller", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "addGuardian(address)": { + "notice": "Adds a new guardian" + }, + "hashSubNodeRegistration((address,bytes32,bytes32))": { + "notice": "Hashes `SubNodeRegistration` message payload" + }, + "initialize(address,address[],address)": { + "notice": "Initializes `ENSController` contract" + }, + "isGuardian(address)": { + "notice": "Check if guardian exists" + }, + "isInitialized()": { + "notice": "Check if contract is initialized" + }, + "registerSubNode(bytes32,bytes32,bytes)": { + "notice": "Registers sub node" + }, + "releaseNode(bytes32)": { + "notice": "Releases node" + }, + "removeGuardian(address)": { + "notice": "Removes the existing guardian" + }, + "setRegistry(address)": { + "notice": "Sets registry" + }, + "submitNode(bytes32)": { + "notice": "Submits node" + }, + "syncAddr(bytes32)": { + "notice": "Sync address" + }, + "verifyGuardianSignature(bytes32,bytes)": { + "notice": "Verifies guardian signature" + }, + "verifyNode(bytes32)": { + "notice": "Verifies node" + } + }, + "notice": "ENS subnode registrar", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 40, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "guardians", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 1871, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "initializer", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 1935, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "chainId", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 5197, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "gateway", + "offset": 0, + "slot": "3", + "type": "t_address" + }, + { + "astId": 3850, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "resolverAddresses", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_bytes32,t_mapping(t_uint256,t_bytes_storage))" + }, + { + "astId": 4073, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "resolverNames", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_bytes32,t_string_storage)" + }, + { + "astId": 4140, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "resolverPubKeys", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_bytes32,t_struct(PubKey)4136_storage)" + }, + { + "astId": 4220, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "resolverTexts", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_bytes32,t_mapping(t_string_memory_ptr,t_string_storage))" + }, + { + "astId": 2388, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "registry", + "offset": 0, + "slot": "8", + "type": "t_contract(ENSRegistry)3564" + }, + { + "astId": 2392, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "nodeOwners", + "offset": 0, + "slot": "9", + "type": "t_mapping(t_bytes32,t_address)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_bytes_storage": { + "encoding": "bytes", + "label": "bytes", + "numberOfBytes": "32" + }, + "t_contract(ENSRegistry)3564": { + "encoding": "inplace", + "label": "contract ENSRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_bytes32,t_address)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_bytes32,t_mapping(t_string_memory_ptr,t_string_storage))": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => mapping(string => string))", + "numberOfBytes": "32", + "value": "t_mapping(t_string_memory_ptr,t_string_storage)" + }, + "t_mapping(t_bytes32,t_mapping(t_uint256,t_bytes_storage))": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => mapping(uint256 => bytes))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint256,t_bytes_storage)" + }, + "t_mapping(t_bytes32,t_string_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => string)", + "numberOfBytes": "32", + "value": "t_string_storage" + }, + "t_mapping(t_bytes32,t_struct(PubKey)4136_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct ENSPubKeyResolver.PubKey)", + "numberOfBytes": "32", + "value": "t_struct(PubKey)4136_storage" + }, + "t_mapping(t_string_memory_ptr,t_string_storage)": { + "encoding": "mapping", + "key": "t_string_memory_ptr", + "label": "mapping(string => string)", + "numberOfBytes": "32", + "value": "t_string_storage" + }, + "t_mapping(t_uint256,t_bytes_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => bytes)", + "numberOfBytes": "32", + "value": "t_bytes_storage" + }, + "t_string_memory_ptr": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(PubKey)4136_storage": { + "encoding": "inplace", + "label": "struct ENSPubKeyResolver.PubKey", + "members": [ + { + "astId": 4133, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_bytes32" + }, + { + "astId": 4135, + "contract": "src/ens/ENSController.sol:ENSController", + "label": "y", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/ENSHelper.json b/deployments/neonDevnet/ENSHelper.json new file mode 100644 index 00000000..f048f30d --- /dev/null +++ b/deployments/neonDevnet/ENSHelper.json @@ -0,0 +1,208 @@ +{ + "address": "0xF330b17e19474762E6F408D7dCf0327264d4A2C0", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "initializer", + "type": "address" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "nodes", + "type": "bytes32[]" + } + ], + "name": "getAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "nodes", + "type": "bytes32[]" + } + ], + "name": "getNames", + "outputs": [ + { + "internalType": "string[]", + "name": "", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ENSRegistry", + "name": "registry_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "registry", + "outputs": [ + { + "internalType": "contract ENSRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x537758f8c59f5f98525af01cac5f20a29ccab5bdf76a04e327222c9c94c099bb", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "44643600", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2704290371908a4c061c3fe59d002f04a555310cd7bb5c28de6a2b8fd262cc0b", + "transactionHash": "0x537758f8c59f5f98525af01cac5f20a29ccab5bdf76a04e327222c9c94c099bb", + "logs": [], + "blockNumber": 173996784, + "cumulativeGasUsed": "44643600", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"}],\"name\":\"getAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"}],\"name\":\"getNames\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"registry_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski \",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Public constructor\"},\"getAddresses(bytes32[])\":{\"params\":{\"nodes\":\"array of nodes\"},\"returns\":{\"_0\":\"nodes addresses\"}},\"getNames(bytes32[])\":{\"params\":{\"nodes\":\"array of nodes\"},\"returns\":{\"_0\":\"nodes names\"}},\"initialize(address)\":{\"params\":{\"registry_\":\"ENS registry address\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}}},\"title\":\"ENS helper\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getAddresses(bytes32[])\":{\"notice\":\"Gets nodes addresses\"},\"getNames(bytes32[])\":{\"notice\":\"Gets nodes names\"},\"initialize(address)\":{\"notice\":\"Initializes `ENSLookupHelper` contract\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/ens/ENSHelper.sol\":\"ENSHelper\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Initializable {\\n address private initializer;\\n\\n // events\\n\\n /**\\n * @dev Emitted after `onlyInitializer`\\n * @param initializer initializer address\\n */\\n event Initialized(\\n address initializer\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not the initializer\\n */\\n modifier onlyInitializer() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin == initializer,\\n \\\"Initializable: tx.origin is not the initializer\\\"\\n );\\n\\n /// @dev removes initializer\\n initializer = address(0);\\n\\n _;\\n\\n emit Initialized(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin\\n );\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n initializer = tx.origin;\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if contract is initialized\\n * @return true when contract is initialized\\n */\\n function isInitialized()\\n external\\n view\\n returns (bool)\\n {\\n return initializer == address(0);\\n }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/ens/ENSHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"./resolvers/ENSAddressResolver.sol\\\";\\nimport \\\"./resolvers/ENSNameResolver.sol\\\";\\nimport \\\"./ENSRegistry.sol\\\";\\n\\n/**\\n * @title ENS helper\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract ENSHelper is Initializable {\\n ENSRegistry public registry;\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor() public Initializable() {}\\n\\n // external functions\\n\\n /**\\n * @notice Initializes `ENSLookupHelper` contract\\n * @param registry_ ENS registry address\\n */\\n function initialize(\\n ENSRegistry registry_\\n )\\n external\\n onlyInitializer\\n {\\n registry = registry_;\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Gets nodes addresses\\n * @param nodes array of nodes\\n * @return nodes addresses\\n */\\n function getAddresses(\\n bytes32[] memory nodes\\n )\\n external\\n view\\n returns (address[] memory)\\n {\\n uint nodesLen = nodes.length;\\n address[] memory result = new address[](nodesLen);\\n\\n for (uint i = 0; i < nodesLen; i++) {\\n result[i] = _getAddress(nodes[i]);\\n }\\n\\n return result;\\n }\\n\\n /**\\n * @notice Gets nodes names\\n * @param nodes array of nodes\\n * @return nodes names\\n */\\n function getNames(\\n bytes32[] memory nodes\\n )\\n external\\n view\\n returns (string[] memory)\\n {\\n uint nodesLen = nodes.length;\\n string[] memory result = new string[](nodesLen);\\n\\n for (uint i = 0; i < nodesLen; i++) {\\n result[i] = _getName(nodes[i]);\\n }\\n\\n return result;\\n }\\n\\n // private functions (views)\\n\\n function _getAddress(\\n bytes32 node\\n )\\n private\\n view\\n returns (address)\\n {\\n address result;\\n address resolver = registry.resolver(node);\\n\\n if (resolver != address(0)) {\\n try ENSAddressResolver(resolver).addr(node) returns (address addr) {\\n result = addr;\\n } catch {\\n //\\n }\\n }\\n\\n return result;\\n }\\n\\n function _getName(\\n bytes32 node\\n )\\n private\\n view\\n returns (string memory)\\n {\\n string memory result;\\n address resolver = registry.resolver(node);\\n\\n if (resolver != address(0)) {\\n try ENSNameResolver(resolver).name(node) returns (string memory name) {\\n result = name;\\n } catch {\\n //\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x38b9f6686c97eef1da7a015817b47f335fec507c30d4f22101d850908805e43f\",\"license\":\"MIT\"},\"src/ens/ENSRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ENS registry\\n *\\n * @dev Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ENSRegistry.sol\\n */\\ncontract ENSRegistry {\\n struct Record {\\n address owner;\\n address resolver;\\n uint64 ttl;\\n }\\n\\n mapping (bytes32 => Record) private records;\\n mapping (address => mapping(address => bool)) private operators;\\n\\n // events\\n\\n event NewOwner(\\n bytes32 indexed node,\\n bytes32 indexed label,\\n address owner\\n );\\n\\n event Transfer(\\n bytes32 indexed node,\\n address owner\\n );\\n\\n event NewResolver(\\n bytes32 indexed node,\\n address resolver\\n );\\n\\n event NewTTL(\\n bytes32 indexed node,\\n uint64 ttl\\n );\\n\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n // modifiers\\n\\n modifier authorised(\\n bytes32 node\\n )\\n {\\n address owner = records[node].owner;\\n\\n require(\\n owner == msg.sender || operators[owner][msg.sender],\\n \\\"ENSRegistry: reverted by authorised modifier\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor()\\n public\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n records[0x0].owner = tx.origin;\\n }\\n\\n // external functions\\n\\n function setRecord(\\n bytes32 node,\\n address owner_,\\n address resolver_,\\n uint64 ttl_\\n )\\n external\\n {\\n setOwner(node, owner_);\\n\\n _setResolverAndTTL(node, resolver_, ttl_);\\n }\\n\\n function setTTL(\\n bytes32 node,\\n uint64 ttl_\\n )\\n external\\n authorised(node)\\n {\\n records[node].ttl = ttl_;\\n\\n emit NewTTL(node, ttl_);\\n }\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner_,\\n address resolver_,\\n uint64 ttl_\\n )\\n external\\n {\\n bytes32 subNode = setSubnodeOwner(node, label, owner_);\\n\\n _setResolverAndTTL(subNode, resolver_, ttl_);\\n }\\n\\n function setApprovalForAll(\\n address operator,\\n bool approved\\n )\\n external\\n {\\n operators[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(\\n msg.sender,\\n operator,\\n approved\\n );\\n }\\n\\n // external functions (views)\\n\\n function owner(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n address addr = records[node].owner;\\n\\n if (addr == address(this)) {\\n return address(0x0);\\n }\\n\\n return addr;\\n }\\n\\n function resolver(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n return records[node].resolver;\\n }\\n\\n function ttl(\\n bytes32 node\\n )\\n external\\n view\\n returns (uint64)\\n {\\n return records[node].ttl;\\n }\\n\\n function recordExists(\\n bytes32 node\\n )\\n external\\n view\\n returns (bool)\\n {\\n return records[node].owner != address(0x0);\\n }\\n\\n function isApprovedForAll(\\n address owner_,\\n address operator\\n )\\n external\\n view\\n returns (bool)\\n {\\n return operators[owner_][operator];\\n }\\n\\n // public functions\\n\\n function setOwner(\\n bytes32 node,\\n address owner_\\n )\\n public\\n authorised(node)\\n {\\n records[node].owner = owner_;\\n\\n emit Transfer(node, owner_);\\n }\\n\\n function setResolver(\\n bytes32 node,\\n address resolver_\\n )\\n public\\n authorised(node)\\n {\\n records[node].resolver = resolver_;\\n\\n emit NewResolver(node, resolver_);\\n }\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner_\\n )\\n public\\n authorised(node)\\n returns(bytes32)\\n {\\n bytes32 subNode = keccak256(abi.encodePacked(node, label));\\n\\n records[subNode].owner = owner_;\\n\\n emit NewOwner(node, label, owner_);\\n\\n return subNode;\\n }\\n\\n // private functions\\n\\n function _setResolverAndTTL(\\n bytes32 node,\\n address resolver_,\\n uint64 ttl_\\n )\\n private\\n {\\n if (resolver_ != records[node].resolver) {\\n records[node].resolver = resolver_;\\n\\n emit NewResolver(node, resolver_);\\n }\\n\\n if (ttl_ != records[node].ttl) {\\n records[node].ttl = ttl_;\\n\\n emit NewTTL(node, ttl_);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe00dbdea09d17d41c2c14266e6e1b6b95938c0d374b266bb44a91cfcf0495612\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSAbstractResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ENS abstract resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/ResolverBase.sol\\n */\\nabstract contract ENSAbstractResolver {\\n // modifiers\\n\\n modifier onlyNodeOwner(bytes32 node)\\n {\\n require(\\n _isNodeOwner(node),\\n \\\"ENSAbstractResolver: reverted by onlyNodeOwner modifier\\\"\\n );\\n\\n _;\\n }\\n\\n // internal functions (views)\\n\\n function _isNodeOwner(\\n bytes32 node\\n )\\n internal\\n virtual\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0xc67d8bdd4904684e5d3388f7ca7d18c7d407058d6b548d8c591404c758a1ac60\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract address resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/AddrResolver.sol\\n */\\nabstract contract ENSAddressResolver is ENSAbstractResolver {\\n bytes4 internal constant INTERFACE_ADDR_ID = bytes4(keccak256(abi.encodePacked(\\\"addr(bytes32)\\\")));\\n bytes4 internal constant INTERFACE_ADDRESS_ID = bytes4(keccak256(abi.encodePacked(\\\"addr(bytes32,uint)\\\")));\\n\\n uint internal constant COIN_TYPE_ETH = 60;\\n\\n mapping(bytes32 => mapping(uint => bytes)) internal resolverAddresses;\\n\\n // events\\n\\n event AddrChanged(\\n bytes32 indexed node,\\n address addr\\n );\\n\\n event AddressChanged(\\n bytes32 indexed node,\\n uint coinType,\\n bytes newAddress\\n );\\n\\n // external functions\\n\\n function setAddr(\\n bytes32 node,\\n address addr_\\n )\\n external\\n onlyNodeOwner(node)\\n {\\n _setAddr(node, addr_);\\n }\\n\\n function setAddr(\\n bytes32 node,\\n uint coinType,\\n bytes memory addr_\\n )\\n external\\n onlyNodeOwner(node)\\n {\\n _setAddr(node, coinType, addr_);\\n }\\n\\n // external functions (views)\\n\\n function addr(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n return _addr(node);\\n }\\n\\n function addr(\\n bytes32 node,\\n uint coinType\\n )\\n external\\n view\\n returns (bytes memory)\\n {\\n return resolverAddresses[node][coinType];\\n }\\n\\n // internal functions\\n\\n function _setAddr(\\n bytes32 node,\\n address addr_\\n )\\n internal\\n {\\n _setAddr(node, COIN_TYPE_ETH, _addressToBytes(addr_));\\n }\\n\\n function _setAddr(\\n bytes32 node,\\n uint coinType,\\n bytes memory addr_\\n )\\n internal\\n {\\n emit AddressChanged(node, coinType, addr_);\\n\\n if(coinType == COIN_TYPE_ETH) {\\n emit AddrChanged(node, _bytesToAddress(addr_));\\n }\\n\\n resolverAddresses[node][coinType] = addr_;\\n }\\n\\n // internal functions (views)\\n\\n function _addr(\\n bytes32 node\\n )\\n internal\\n view\\n returns (address)\\n {\\n address result;\\n\\n bytes memory addr_ = resolverAddresses[node][COIN_TYPE_ETH];\\n\\n if (addr_.length > 0) {\\n result = _bytesToAddress(addr_);\\n }\\n\\n return result;\\n }\\n\\n // private function (pure)\\n\\n function _bytesToAddress(\\n bytes memory data\\n )\\n private\\n pure\\n returns(address payable)\\n {\\n address payable result;\\n\\n require(data.length == 20);\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := div(mload(add(data, 32)), exp(256, 12))\\n }\\n\\n return result;\\n }\\n\\n function _addressToBytes(\\n address addr_\\n )\\n private\\n pure\\n returns(bytes memory)\\n {\\n bytes memory result = new bytes(20);\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n mstore(add(result, 32), mul(addr_, exp(256, 12)))\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xd2f0c5ed5f5058755512c0916496da6bcf4cf18a0026ee8d20b4306656ce5142\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSNameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract name resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/NameResolver.sol\\n */\\nabstract contract ENSNameResolver is ENSAbstractResolver {\\n bytes4 internal constant INTERFACE_NAME_ID = bytes4(keccak256(abi.encodePacked(\\\"name(bytes32)\\\")));\\n\\n mapping(bytes32 => string) internal resolverNames;\\n\\n // events\\n\\n event NameChanged(\\n bytes32 indexed node,\\n string name\\n );\\n\\n // external functions\\n\\n function setName(\\n bytes32 node,\\n string calldata name\\n )\\n external\\n onlyNodeOwner(node)\\n {\\n resolverNames[node] = name;\\n\\n emit NameChanged(node, name);\\n }\\n\\n // external functions (views)\\n\\n function name(\\n bytes32 node\\n )\\n external\\n view\\n returns (string memory)\\n {\\n return resolverNames[node];\\n }\\n}\\n\",\"keccak256\":\"0x1d2d4b21f59225fbefe0e5aaff87aff8f11afe5281745934d595e15770557ead\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50326000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610e74806100606000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806338bc01b51461005c578063392e53cd1461008c5780637b103999146100aa578063c4d66de8146100c8578063dc6008e2146100e4575b600080fd5b610076600480360381019061007191906108a6565b610114565b6040516100839190610b55565b60405180910390f35b6100946101ec565b6040516100a19190610b99565b60405180910390f35b6100b2610242565b6040516100bf9190610bcf565b60405180910390f35b6100e260048036038101906100dd91906108e7565b610268565b005b6100fe60048036038101906100f991906108a6565b6103b2565b60405161010b9190610b77565b60405180910390f35b606060008251905060608167ffffffffffffffff8111801561013557600080fd5b506040519080825280602002602001820160405280156101645781602001602082028036833780820191505090505b50905060005b828110156101e15761018e85828151811061018157fe5b6020026020010151610460565b82828151811061019a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808060010191505061016a565b508092505050919050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146102f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102ed90610bea565b60405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516103a79190610b3a565b60405180910390a150565b606060008251905060608167ffffffffffffffff811180156103d357600080fd5b5060405190808252806020026020018201604052801561040757816020015b60608152602001906001900390816103f25790505b50905060005b828110156104555761043185828151811061042457fe5b60200260200101516105e1565b82828151811061043d57fe5b6020026020010181905250808060010191505061040d565b508092505050919050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf856040518263ffffffff1660e01b81526004016104c09190610bb4565b60206040518083038186803b1580156104d857600080fd5b505afa1580156104ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610510919061087d565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105d7578073ffffffffffffffffffffffffffffffffffffffff16633b3b57de856040518263ffffffff1660e01b815260040161057f9190610bb4565b60206040518083038186803b15801561059757600080fd5b505afa9250505080156105c857506040513d601f19601f820116820180604052508101906105c5919061087d565b60015b6105d1576105d6565b809250505b5b8192505050919050565b6060806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf856040518263ffffffff1660e01b81526004016106419190610bb4565b60206040518083038186803b15801561065957600080fd5b505afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610691919061087d565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461075d578073ffffffffffffffffffffffffffffffffffffffff1663691f3431856040518263ffffffff1660e01b81526004016107009190610bb4565b60006040518083038186803b15801561071857600080fd5b505afa92505050801561074e57506040513d6000823e3d601f19601f8201168201806040525081019061074b9190610910565b60015b6107575761075c565b809250505b5b8192505050919050565b60008151905061077681610e22565b92915050565b600082601f83011261078d57600080fd5b81356107a061079b82610c37565b610c0a565b915081818352602084019350602081019050838560208402820111156107c557600080fd5b60005b838110156107f557816107db88826107ff565b8452602084019350602083019250506001810190506107c8565b5050505092915050565b60008135905061080e81610e39565b92915050565b60008135905061082381610e50565b92915050565b600082601f83011261083a57600080fd5b815161084d61084882610c5f565b610c0a565b9150808252602083016020830185838301111561086957600080fd5b610874838284610dde565b50505092915050565b60006020828403121561088f57600080fd5b600061089d84828501610767565b91505092915050565b6000602082840312156108b857600080fd5b600082013567ffffffffffffffff8111156108d257600080fd5b6108de8482850161077c565b91505092915050565b6000602082840312156108f957600080fd5b600061090784828501610814565b91505092915050565b60006020828403121561092257600080fd5b600082015167ffffffffffffffff81111561093c57600080fd5b61094884828501610829565b91505092915050565b600061095d838361098c565b60208301905092915050565b60006109758383610a9b565b905092915050565b61098681610d84565b82525050565b61099581610d2a565b82525050565b60006109a682610cab565b6109b08185610ce6565b93506109bb83610c8b565b8060005b838110156109ec5781516109d38882610951565b97506109de83610ccc565b9250506001810190506109bf565b5085935050505092915050565b6000610a0482610cb6565b610a0e8185610cf7565b935083602082028501610a2085610c9b565b8060005b85811015610a5c5784840389528151610a3d8582610969565b9450610a4883610cd9565b925060208a01995050600181019050610a24565b50829750879550505050505092915050565b610a7781610d3c565b82525050565b610a8681610d48565b82525050565b610a9581610d96565b82525050565b6000610aa682610cc1565b610ab08185610d08565b9350610ac0818560208601610dde565b610ac981610e11565b840191505092915050565b6000610ae1602f83610d19565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b6000602082019050610b4f600083018461097d565b92915050565b60006020820190508181036000830152610b6f818461099b565b905092915050565b60006020820190508181036000830152610b9181846109f9565b905092915050565b6000602082019050610bae6000830184610a6e565b92915050565b6000602082019050610bc96000830184610a7d565b92915050565b6000602082019050610be46000830184610a8c565b92915050565b60006020820190508181036000830152610c0381610ad4565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610c2d57600080fd5b8060405250919050565b600067ffffffffffffffff821115610c4e57600080fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610c7657600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000610d3582610d64565b9050919050565b60008115159050919050565b6000819050919050565b6000610d5d82610d2a565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610d8f82610dba565b9050919050565b6000610da182610da8565b9050919050565b6000610db382610d64565b9050919050565b6000610dc582610dcc565b9050919050565b6000610dd782610d64565b9050919050565b60005b83811015610dfc578082015181840152602081019050610de1565b83811115610e0b576000848401525b50505050565b6000601f19601f8301169050919050565b610e2b81610d2a565b8114610e3657600080fd5b50565b610e4281610d48565b8114610e4d57600080fd5b50565b610e5981610d52565b8114610e6457600080fd5b5056fea164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c806338bc01b51461005c578063392e53cd1461008c5780637b103999146100aa578063c4d66de8146100c8578063dc6008e2146100e4575b600080fd5b610076600480360381019061007191906108a6565b610114565b6040516100839190610b55565b60405180910390f35b6100946101ec565b6040516100a19190610b99565b60405180910390f35b6100b2610242565b6040516100bf9190610bcf565b60405180910390f35b6100e260048036038101906100dd91906108e7565b610268565b005b6100fe60048036038101906100f991906108a6565b6103b2565b60405161010b9190610b77565b60405180910390f35b606060008251905060608167ffffffffffffffff8111801561013557600080fd5b506040519080825280602002602001820160405280156101645781602001602082028036833780820191505090505b50905060005b828110156101e15761018e85828151811061018157fe5b6020026020010151610460565b82828151811061019a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808060010191505061016a565b508092505050919050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146102f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102ed90610bea565b60405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516103a79190610b3a565b60405180910390a150565b606060008251905060608167ffffffffffffffff811180156103d357600080fd5b5060405190808252806020026020018201604052801561040757816020015b60608152602001906001900390816103f25790505b50905060005b828110156104555761043185828151811061042457fe5b60200260200101516105e1565b82828151811061043d57fe5b6020026020010181905250808060010191505061040d565b508092505050919050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf856040518263ffffffff1660e01b81526004016104c09190610bb4565b60206040518083038186803b1580156104d857600080fd5b505afa1580156104ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610510919061087d565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105d7578073ffffffffffffffffffffffffffffffffffffffff16633b3b57de856040518263ffffffff1660e01b815260040161057f9190610bb4565b60206040518083038186803b15801561059757600080fd5b505afa9250505080156105c857506040513d601f19601f820116820180604052508101906105c5919061087d565b60015b6105d1576105d6565b809250505b5b8192505050919050565b6060806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf856040518263ffffffff1660e01b81526004016106419190610bb4565b60206040518083038186803b15801561065957600080fd5b505afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610691919061087d565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461075d578073ffffffffffffffffffffffffffffffffffffffff1663691f3431856040518263ffffffff1660e01b81526004016107009190610bb4565b60006040518083038186803b15801561071857600080fd5b505afa92505050801561074e57506040513d6000823e3d601f19601f8201168201806040525081019061074b9190610910565b60015b6107575761075c565b809250505b5b8192505050919050565b60008151905061077681610e22565b92915050565b600082601f83011261078d57600080fd5b81356107a061079b82610c37565b610c0a565b915081818352602084019350602081019050838560208402820111156107c557600080fd5b60005b838110156107f557816107db88826107ff565b8452602084019350602083019250506001810190506107c8565b5050505092915050565b60008135905061080e81610e39565b92915050565b60008135905061082381610e50565b92915050565b600082601f83011261083a57600080fd5b815161084d61084882610c5f565b610c0a565b9150808252602083016020830185838301111561086957600080fd5b610874838284610dde565b50505092915050565b60006020828403121561088f57600080fd5b600061089d84828501610767565b91505092915050565b6000602082840312156108b857600080fd5b600082013567ffffffffffffffff8111156108d257600080fd5b6108de8482850161077c565b91505092915050565b6000602082840312156108f957600080fd5b600061090784828501610814565b91505092915050565b60006020828403121561092257600080fd5b600082015167ffffffffffffffff81111561093c57600080fd5b61094884828501610829565b91505092915050565b600061095d838361098c565b60208301905092915050565b60006109758383610a9b565b905092915050565b61098681610d84565b82525050565b61099581610d2a565b82525050565b60006109a682610cab565b6109b08185610ce6565b93506109bb83610c8b565b8060005b838110156109ec5781516109d38882610951565b97506109de83610ccc565b9250506001810190506109bf565b5085935050505092915050565b6000610a0482610cb6565b610a0e8185610cf7565b935083602082028501610a2085610c9b565b8060005b85811015610a5c5784840389528151610a3d8582610969565b9450610a4883610cd9565b925060208a01995050600181019050610a24565b50829750879550505050505092915050565b610a7781610d3c565b82525050565b610a8681610d48565b82525050565b610a9581610d96565b82525050565b6000610aa682610cc1565b610ab08185610d08565b9350610ac0818560208601610dde565b610ac981610e11565b840191505092915050565b6000610ae1602f83610d19565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b6000602082019050610b4f600083018461097d565b92915050565b60006020820190508181036000830152610b6f818461099b565b905092915050565b60006020820190508181036000830152610b9181846109f9565b905092915050565b6000602082019050610bae6000830184610a6e565b92915050565b6000602082019050610bc96000830184610a7d565b92915050565b6000602082019050610be46000830184610a8c565b92915050565b60006020820190508181036000830152610c0381610ad4565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610c2d57600080fd5b8060405250919050565b600067ffffffffffffffff821115610c4e57600080fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610c7657600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000610d3582610d64565b9050919050565b60008115159050919050565b6000819050919050565b6000610d5d82610d2a565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610d8f82610dba565b9050919050565b6000610da182610da8565b9050919050565b6000610db382610d64565b9050919050565b6000610dc582610dcc565b9050919050565b6000610dd782610d64565b9050919050565b60005b83811015610dfc578082015181840152602081019050610de1565b83811115610e0b576000848401525b50505050565b6000601f19601f8301169050919050565b610e2b81610d2a565b8114610e3657600080fd5b50565b610e4281610d48565b8114610e4d57600080fd5b50565b610e5981610d52565b8114610e6457600080fd5b5056fea164736f6c634300060c000a", + "devdoc": { + "author": "Stanisław Głogowski ", + "kind": "dev", + "methods": { + "constructor": { + "details": "Public constructor" + }, + "getAddresses(bytes32[])": { + "params": { + "nodes": "array of nodes" + }, + "returns": { + "_0": "nodes addresses" + } + }, + "getNames(bytes32[])": { + "params": { + "nodes": "array of nodes" + }, + "returns": { + "_0": "nodes names" + } + }, + "initialize(address)": { + "params": { + "registry_": "ENS registry address" + } + }, + "isInitialized()": { + "returns": { + "_0": "true when contract is initialized" + } + } + }, + "title": "ENS helper", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "getAddresses(bytes32[])": { + "notice": "Gets nodes addresses" + }, + "getNames(bytes32[])": { + "notice": "Gets nodes names" + }, + "initialize(address)": { + "notice": "Initializes `ENSLookupHelper` contract" + }, + "isInitialized()": { + "notice": "Check if contract is initialized" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1871, + "contract": "src/ens/ENSHelper.sol:ENSHelper", + "label": "initializer", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 2929, + "contract": "src/ens/ENSHelper.sol:ENSHelper", + "label": "registry", + "offset": 0, + "slot": "1", + "type": "t_contract(ENSRegistry)3564" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_contract(ENSRegistry)3564": { + "encoding": "inplace", + "label": "contract ENSRegistry", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/ENSRegistry.json b/deployments/neonDevnet/ENSRegistry.json new file mode 100644 index 00000000..1ec8b1ab --- /dev/null +++ b/deployments/neonDevnet/ENSRegistry.json @@ -0,0 +1,510 @@ +{ + "address": "0xf17BCfd10B65fD0792dEef7a17Aa08B4b0086688", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "label", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "NewOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "resolver", + "type": "address" + } + ], + "name": "NewResolver", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "ttl", + "type": "uint64" + } + ], + "name": "NewTTL", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "recordExists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "resolver", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "address", + "name": "resolver_", + "type": "address" + }, + { + "internalType": "uint64", + "name": "ttl_", + "type": "uint64" + } + ], + "name": "setRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "resolver_", + "type": "address" + } + ], + "name": "setResolver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "label", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "name": "setSubnodeOwner", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "label", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "address", + "name": "resolver_", + "type": "address" + }, + { + "internalType": "uint64", + "name": "ttl_", + "type": "uint64" + } + ], + "name": "setSubnodeRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "ttl_", + "type": "uint64" + } + ], + "name": "setTTL", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "ttl", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x8e856f881e3a281aa213b7e0dfc652b333e7c7c54a7e6cec6a1d90fd1f7733c3", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "53531520", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7d90702d236901dc75294aa712e7d3c61721c3694650e94b086b42426256e7bb", + "transactionHash": "0x8e856f881e3a281aa213b7e0dfc652b333e7c7c54a7e6cec6a1d90fd1f7733c3", + "logs": [], + "blockNumber": 173996803, + "cumulativeGasUsed": "53531520", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"label\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NewOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"NewResolver\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"NewTTL\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"recordExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"resolver\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver_\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"ttl_\",\"type\":\"uint64\"}],\"name\":\"setRecord\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"resolver_\",\"type\":\"address\"}],\"name\":\"setResolver\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"label\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"name\":\"setSubnodeOwner\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"label\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver_\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"ttl_\",\"type\":\"uint64\"}],\"name\":\"setSubnodeRecord\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"ttl_\",\"type\":\"uint64\"}],\"name\":\"setTTL\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"ttl\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ENSRegistry.sol\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Public constructor\"}},\"title\":\"ENS registry\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/ens/ENSRegistry.sol\":\"ENSRegistry\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/ens/ENSRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ENS registry\\n *\\n * @dev Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ENSRegistry.sol\\n */\\ncontract ENSRegistry {\\n struct Record {\\n address owner;\\n address resolver;\\n uint64 ttl;\\n }\\n\\n mapping (bytes32 => Record) private records;\\n mapping (address => mapping(address => bool)) private operators;\\n\\n // events\\n\\n event NewOwner(\\n bytes32 indexed node,\\n bytes32 indexed label,\\n address owner\\n );\\n\\n event Transfer(\\n bytes32 indexed node,\\n address owner\\n );\\n\\n event NewResolver(\\n bytes32 indexed node,\\n address resolver\\n );\\n\\n event NewTTL(\\n bytes32 indexed node,\\n uint64 ttl\\n );\\n\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n // modifiers\\n\\n modifier authorised(\\n bytes32 node\\n )\\n {\\n address owner = records[node].owner;\\n\\n require(\\n owner == msg.sender || operators[owner][msg.sender],\\n \\\"ENSRegistry: reverted by authorised modifier\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor()\\n public\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n records[0x0].owner = tx.origin;\\n }\\n\\n // external functions\\n\\n function setRecord(\\n bytes32 node,\\n address owner_,\\n address resolver_,\\n uint64 ttl_\\n )\\n external\\n {\\n setOwner(node, owner_);\\n\\n _setResolverAndTTL(node, resolver_, ttl_);\\n }\\n\\n function setTTL(\\n bytes32 node,\\n uint64 ttl_\\n )\\n external\\n authorised(node)\\n {\\n records[node].ttl = ttl_;\\n\\n emit NewTTL(node, ttl_);\\n }\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner_,\\n address resolver_,\\n uint64 ttl_\\n )\\n external\\n {\\n bytes32 subNode = setSubnodeOwner(node, label, owner_);\\n\\n _setResolverAndTTL(subNode, resolver_, ttl_);\\n }\\n\\n function setApprovalForAll(\\n address operator,\\n bool approved\\n )\\n external\\n {\\n operators[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(\\n msg.sender,\\n operator,\\n approved\\n );\\n }\\n\\n // external functions (views)\\n\\n function owner(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n address addr = records[node].owner;\\n\\n if (addr == address(this)) {\\n return address(0x0);\\n }\\n\\n return addr;\\n }\\n\\n function resolver(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n return records[node].resolver;\\n }\\n\\n function ttl(\\n bytes32 node\\n )\\n external\\n view\\n returns (uint64)\\n {\\n return records[node].ttl;\\n }\\n\\n function recordExists(\\n bytes32 node\\n )\\n external\\n view\\n returns (bool)\\n {\\n return records[node].owner != address(0x0);\\n }\\n\\n function isApprovedForAll(\\n address owner_,\\n address operator\\n )\\n external\\n view\\n returns (bool)\\n {\\n return operators[owner_][operator];\\n }\\n\\n // public functions\\n\\n function setOwner(\\n bytes32 node,\\n address owner_\\n )\\n public\\n authorised(node)\\n {\\n records[node].owner = owner_;\\n\\n emit Transfer(node, owner_);\\n }\\n\\n function setResolver(\\n bytes32 node,\\n address resolver_\\n )\\n public\\n authorised(node)\\n {\\n records[node].resolver = resolver_;\\n\\n emit NewResolver(node, resolver_);\\n }\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner_\\n )\\n public\\n authorised(node)\\n returns(bytes32)\\n {\\n bytes32 subNode = keccak256(abi.encodePacked(node, label));\\n\\n records[subNode].owner = owner_;\\n\\n emit NewOwner(node, label, owner_);\\n\\n return subNode;\\n }\\n\\n // private functions\\n\\n function _setResolverAndTTL(\\n bytes32 node,\\n address resolver_,\\n uint64 ttl_\\n )\\n private\\n {\\n if (resolver_ != records[node].resolver) {\\n records[node].resolver = resolver_;\\n\\n emit NewResolver(node, resolver_);\\n }\\n\\n if (ttl_ != records[node].ttl) {\\n records[node].ttl = ttl_;\\n\\n emit NewTTL(node, ttl_);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe00dbdea09d17d41c2c14266e6e1b6b95938c0d374b266bb44a91cfcf0495612\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50326000808060001b815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611253806100776000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80635b0fc9c3116100715780635b0fc9c3146102b15780635ef2c7f0146102ff578063a22cb4651461038b578063cf408823146103db578063e985e9c51461045d578063f79fe538146104d7576100b4565b80630178b8bf146100b957806302571be31461011157806306ab59231461016957806314ab9038146101d557806316a25cbd146102175780631896f70a14610263575b600080fd5b6100e5600480360360208110156100cf57600080fd5b810190808035906020019092919050505061051b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61013d6004803603602081101561012757600080fd5b810190808035906020019092919050505061055a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101bf6004803603606081101561017f57600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506105dd565b6040518082815260200191505060405180910390f35b610215600480360360408110156101eb57600080fd5b8101908080359060200190929190803567ffffffffffffffff169060200190929190505050610812565b005b6102436004803603602081101561022d57600080fd5b81019080803590602001909291905050506109e6565b604051808267ffffffffffffffff16815260200191505060405180910390f35b6102af6004803603604081101561027957600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a19565b005b6102fd600480360360408110156102c757600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c11565b005b610389600480360360a081101561031557600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190505050610e09565b005b6103d9600480360360408110156103a157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050610e2b565b005b61045b600480360360808110156103f157600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190505050610f2a565b005b6104bf6004803603604081101561047357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f45565b60405180821515815260200191505060405180910390f35b610503600480360360208110156104ed57600080fd5b8101908080359060200190929190505050610fd9565b60405180821515815260200191505060405180910390f35b600080600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60008060008084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156105d35760009150506105d8565b809150505b919050565b600083600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806106da5750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b61072f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061121b602c913960400191505060405180910390fd5b6000868660405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090508460008083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085877fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e8287604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a38093505050509392505050565b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061090d5750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610962576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061121b602c913960400191505060405180910390fd5b8260008086815260200190815260200160002060010160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550837f1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa6884604051808267ffffffffffffffff16815260200191505060405180910390a250505050565b600080600083815260200190815260200160002060010160149054906101000a900467ffffffffffffffff169050919050565b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610b145750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610b69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061121b602c913960400191505060405180910390fd5b8260008086815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550837f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a084604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250505050565b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610d0c5750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610d61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061121b602c913960400191505060405180910390fd5b8260008086815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550837fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d26684604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250505050565b6000610e168686866105dd565b9050610e23818484611047565b505050505050565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610f348484610c11565b610f3f848383611047565b50505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60008084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614611152578160008085815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550827f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a083604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a25b60008084815260200190815260200160002060010160149054906101000a900467ffffffffffffffff1667ffffffffffffffff168167ffffffffffffffff1614611215578060008085815260200190815260200160002060010160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550827f1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa6882604051808267ffffffffffffffff16815260200191505060405180910390a25b50505056fe454e5352656769737472793a20726576657274656420627920617574686f7269736564206d6f646966696572a164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80635b0fc9c3116100715780635b0fc9c3146102b15780635ef2c7f0146102ff578063a22cb4651461038b578063cf408823146103db578063e985e9c51461045d578063f79fe538146104d7576100b4565b80630178b8bf146100b957806302571be31461011157806306ab59231461016957806314ab9038146101d557806316a25cbd146102175780631896f70a14610263575b600080fd5b6100e5600480360360208110156100cf57600080fd5b810190808035906020019092919050505061051b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61013d6004803603602081101561012757600080fd5b810190808035906020019092919050505061055a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101bf6004803603606081101561017f57600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506105dd565b6040518082815260200191505060405180910390f35b610215600480360360408110156101eb57600080fd5b8101908080359060200190929190803567ffffffffffffffff169060200190929190505050610812565b005b6102436004803603602081101561022d57600080fd5b81019080803590602001909291905050506109e6565b604051808267ffffffffffffffff16815260200191505060405180910390f35b6102af6004803603604081101561027957600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a19565b005b6102fd600480360360408110156102c757600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c11565b005b610389600480360360a081101561031557600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190505050610e09565b005b6103d9600480360360408110156103a157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050610e2b565b005b61045b600480360360808110156103f157600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190505050610f2a565b005b6104bf6004803603604081101561047357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f45565b60405180821515815260200191505060405180910390f35b610503600480360360208110156104ed57600080fd5b8101908080359060200190929190505050610fd9565b60405180821515815260200191505060405180910390f35b600080600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60008060008084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156105d35760009150506105d8565b809150505b919050565b600083600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806106da5750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b61072f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061121b602c913960400191505060405180910390fd5b6000868660405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090508460008083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085877fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e8287604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a38093505050509392505050565b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061090d5750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610962576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061121b602c913960400191505060405180910390fd5b8260008086815260200190815260200160002060010160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550837f1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa6884604051808267ffffffffffffffff16815260200191505060405180910390a250505050565b600080600083815260200190815260200160002060010160149054906101000a900467ffffffffffffffff169050919050565b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610b145750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610b69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061121b602c913960400191505060405180910390fd5b8260008086815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550837f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a084604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250505050565b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610d0c5750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610d61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061121b602c913960400191505060405180910390fd5b8260008086815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550837fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d26684604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250505050565b6000610e168686866105dd565b9050610e23818484611047565b505050505050565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610f348484610c11565b610f3f848383611047565b50505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60008084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614611152578160008085815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550827f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a083604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a25b60008084815260200190815260200160002060010160149054906101000a900467ffffffffffffffff1667ffffffffffffffff168167ffffffffffffffff1614611215578060008085815260200190815260200160002060010160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550827f1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa6882604051808267ffffffffffffffff16815260200191505060405180910390a25b50505056fe454e5352656769737472793a20726576657274656420627920617574686f7269736564206d6f646966696572a164736f6c634300060c000a", + "devdoc": { + "details": "Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ENSRegistry.sol", + "kind": "dev", + "methods": { + "constructor": { + "details": "Public constructor" + } + }, + "title": "ENS registry", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 3158, + "contract": "src/ens/ENSRegistry.sol:ENSRegistry", + "label": "records", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_bytes32,t_struct(Record)3154_storage)" + }, + { + "astId": 3164, + "contract": "src/ens/ENSRegistry.sol:ENSRegistry", + "label": "operators", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" + }, + "t_mapping(t_bytes32,t_struct(Record)3154_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct ENSRegistry.Record)", + "numberOfBytes": "32", + "value": "t_struct(Record)3154_storage" + }, + "t_struct(Record)3154_storage": { + "encoding": "inplace", + "label": "struct ENSRegistry.Record", + "members": [ + { + "astId": 3149, + "contract": "src/ens/ENSRegistry.sol:ENSRegistry", + "label": "owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 3151, + "contract": "src/ens/ENSRegistry.sol:ENSRegistry", + "label": "resolver", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 3153, + "contract": "src/ens/ENSRegistry.sol:ENSRegistry", + "label": "ttl", + "offset": 20, + "slot": "1", + "type": "t_uint64" + } + ], + "numberOfBytes": "64" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/ENSReverseRegistrar.json b/deployments/neonDevnet/ENSReverseRegistrar.json new file mode 100644 index 00000000..cdc44edf --- /dev/null +++ b/deployments/neonDevnet/ENSReverseRegistrar.json @@ -0,0 +1,274 @@ +{ + "address": "0x523C92966e9d2067ba547f59D51E907c20FD8761", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "initializer", + "type": "address" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "inputs": [], + "name": "ADDR_REVERSE_NODE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "claim", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "resolver_", + "type": "address" + } + ], + "name": "claimWithResolver", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ENSRegistry", + "name": "registry_", + "type": "address" + }, + { + "internalType": "contract ENSNameResolver", + "name": "resolver_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "name": "node", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "registry", + "outputs": [ + { + "internalType": "contract ENSRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "resolver", + "outputs": [ + { + "internalType": "contract ENSNameResolver", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + } + ], + "name": "setName", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x7c0f450722b503fc6a836fdb009f5f7d30c53ebc31599b58e83082b12ee9276b", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "43669200", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x08d1f61351145e233027d39766d9e4f285dfb6b6e88d6cbf527f39e508714585", + "transactionHash": "0x7c0f450722b503fc6a836fdb009f5f7d30c53ebc31599b58e83082b12ee9276b", + "logs": [], + "blockNumber": 173996822, + "cumulativeGasUsed": "43669200", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ADDR_REVERSE_NODE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"claim\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver_\",\"type\":\"address\"}],\"name\":\"claimWithResolver\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"registry_\",\"type\":\"address\"},{\"internalType\":\"contract ENSNameResolver\",\"name\":\"resolver_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"name\":\"node\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENSRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resolver\",\"outputs\":[{\"internalType\":\"contract ENSNameResolver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ReverseRegistrar.sol\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Public constructor\"},\"initialize(address,address)\":{\"params\":{\"registry_\":\"ENS registry address\",\"resolver_\":\"ENS name resolver address\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}}},\"title\":\"ENS reverse registrar\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"initialize(address,address)\":{\"notice\":\"Initializes `ENSReverseRegistrar` contract\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/ens/ENSReverseRegistrar.sol\":\"ENSReverseRegistrar\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/libs/AddressLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Address library\\n */\\nlibrary AddressLib {\\n /**\\n * @notice Converts address into sha3 hash\\n * @param self address\\n * @return sha3 hash\\n */\\n function toSha3Hash(\\n address self\\n )\\n internal\\n pure\\n returns (bytes32)\\n {\\n bytes32 result;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let lookup := 0x3031323334353637383961626364656600000000000000000000000000000000\\n\\n for { let i := 40 } gt(i, 0) { } {\\n i := sub(i, 1)\\n mstore8(i, byte(and(self, 0xf), lookup))\\n self := div(self, 0x10)\\n i := sub(i, 1)\\n mstore8(i, byte(and(self, 0xf), lookup))\\n self := div(self, 0x10)\\n }\\n\\n result := keccak256(0, 40)\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe54172c033f0a3e59a8ec5ae72aeac02a35b4341331e2698baeb31fa5e543f5f\",\"license\":\"MIT\"},\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Initializable {\\n address private initializer;\\n\\n // events\\n\\n /**\\n * @dev Emitted after `onlyInitializer`\\n * @param initializer initializer address\\n */\\n event Initialized(\\n address initializer\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not the initializer\\n */\\n modifier onlyInitializer() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin == initializer,\\n \\\"Initializable: tx.origin is not the initializer\\\"\\n );\\n\\n /// @dev removes initializer\\n initializer = address(0);\\n\\n _;\\n\\n emit Initialized(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin\\n );\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n initializer = tx.origin;\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if contract is initialized\\n * @return true when contract is initialized\\n */\\n function isInitialized()\\n external\\n view\\n returns (bool)\\n {\\n return initializer == address(0);\\n }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/ens/ENSRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ENS registry\\n *\\n * @dev Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ENSRegistry.sol\\n */\\ncontract ENSRegistry {\\n struct Record {\\n address owner;\\n address resolver;\\n uint64 ttl;\\n }\\n\\n mapping (bytes32 => Record) private records;\\n mapping (address => mapping(address => bool)) private operators;\\n\\n // events\\n\\n event NewOwner(\\n bytes32 indexed node,\\n bytes32 indexed label,\\n address owner\\n );\\n\\n event Transfer(\\n bytes32 indexed node,\\n address owner\\n );\\n\\n event NewResolver(\\n bytes32 indexed node,\\n address resolver\\n );\\n\\n event NewTTL(\\n bytes32 indexed node,\\n uint64 ttl\\n );\\n\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n // modifiers\\n\\n modifier authorised(\\n bytes32 node\\n )\\n {\\n address owner = records[node].owner;\\n\\n require(\\n owner == msg.sender || operators[owner][msg.sender],\\n \\\"ENSRegistry: reverted by authorised modifier\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor()\\n public\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n records[0x0].owner = tx.origin;\\n }\\n\\n // external functions\\n\\n function setRecord(\\n bytes32 node,\\n address owner_,\\n address resolver_,\\n uint64 ttl_\\n )\\n external\\n {\\n setOwner(node, owner_);\\n\\n _setResolverAndTTL(node, resolver_, ttl_);\\n }\\n\\n function setTTL(\\n bytes32 node,\\n uint64 ttl_\\n )\\n external\\n authorised(node)\\n {\\n records[node].ttl = ttl_;\\n\\n emit NewTTL(node, ttl_);\\n }\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner_,\\n address resolver_,\\n uint64 ttl_\\n )\\n external\\n {\\n bytes32 subNode = setSubnodeOwner(node, label, owner_);\\n\\n _setResolverAndTTL(subNode, resolver_, ttl_);\\n }\\n\\n function setApprovalForAll(\\n address operator,\\n bool approved\\n )\\n external\\n {\\n operators[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(\\n msg.sender,\\n operator,\\n approved\\n );\\n }\\n\\n // external functions (views)\\n\\n function owner(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n address addr = records[node].owner;\\n\\n if (addr == address(this)) {\\n return address(0x0);\\n }\\n\\n return addr;\\n }\\n\\n function resolver(\\n bytes32 node\\n )\\n external\\n view\\n returns (address)\\n {\\n return records[node].resolver;\\n }\\n\\n function ttl(\\n bytes32 node\\n )\\n external\\n view\\n returns (uint64)\\n {\\n return records[node].ttl;\\n }\\n\\n function recordExists(\\n bytes32 node\\n )\\n external\\n view\\n returns (bool)\\n {\\n return records[node].owner != address(0x0);\\n }\\n\\n function isApprovedForAll(\\n address owner_,\\n address operator\\n )\\n external\\n view\\n returns (bool)\\n {\\n return operators[owner_][operator];\\n }\\n\\n // public functions\\n\\n function setOwner(\\n bytes32 node,\\n address owner_\\n )\\n public\\n authorised(node)\\n {\\n records[node].owner = owner_;\\n\\n emit Transfer(node, owner_);\\n }\\n\\n function setResolver(\\n bytes32 node,\\n address resolver_\\n )\\n public\\n authorised(node)\\n {\\n records[node].resolver = resolver_;\\n\\n emit NewResolver(node, resolver_);\\n }\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner_\\n )\\n public\\n authorised(node)\\n returns(bytes32)\\n {\\n bytes32 subNode = keccak256(abi.encodePacked(node, label));\\n\\n records[subNode].owner = owner_;\\n\\n emit NewOwner(node, label, owner_);\\n\\n return subNode;\\n }\\n\\n // private functions\\n\\n function _setResolverAndTTL(\\n bytes32 node,\\n address resolver_,\\n uint64 ttl_\\n )\\n private\\n {\\n if (resolver_ != records[node].resolver) {\\n records[node].resolver = resolver_;\\n\\n emit NewResolver(node, resolver_);\\n }\\n\\n if (ttl_ != records[node].ttl) {\\n records[node].ttl = ttl_;\\n\\n emit NewTTL(node, ttl_);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe00dbdea09d17d41c2c14266e6e1b6b95938c0d374b266bb44a91cfcf0495612\",\"license\":\"MIT\"},\"src/ens/ENSReverseRegistrar.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/AddressLib.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"./resolvers/ENSNameResolver.sol\\\";\\nimport \\\"./ENSRegistry.sol\\\";\\n\\n/**\\n * @title ENS reverse registrar\\n *\\n * @dev Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ReverseRegistrar.sol\\n */\\ncontract ENSReverseRegistrar is Initializable {\\n using AddressLib for address;\\n\\n // namehash('addr.reverse')\\n bytes32 public constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;\\n\\n ENSRegistry public registry;\\n ENSNameResolver public resolver;\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor() public Initializable() {}\\n\\n // external functions\\n\\n /**\\n * @notice Initializes `ENSReverseRegistrar` contract\\n * @param registry_ ENS registry address\\n * @param resolver_ ENS name resolver address\\n */\\n function initialize(\\n ENSRegistry registry_,\\n ENSNameResolver resolver_\\n )\\n external\\n onlyInitializer\\n {\\n registry = registry_;\\n resolver = resolver_;\\n }\\n\\n // external functions\\n\\n function claim(\\n address owner\\n )\\n public\\n returns (bytes32)\\n {\\n return _claimWithResolver(owner, address(0));\\n }\\n\\n function claimWithResolver(\\n address owner,\\n address resolver_\\n )\\n public\\n returns (bytes32)\\n {\\n return _claimWithResolver(owner, resolver_);\\n }\\n\\n function setName(\\n string memory name\\n )\\n public\\n returns (bytes32)\\n {\\n bytes32 node = _claimWithResolver(address(this), address(resolver));\\n\\n resolver.setName(node, name);\\n\\n return node;\\n }\\n\\n // external functions (pure)\\n\\n function node(\\n address addr_\\n )\\n external\\n pure\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(ADDR_REVERSE_NODE, addr_.toSha3Hash()));\\n }\\n\\n // private functions\\n\\n function _claimWithResolver(\\n address owner,\\n address resolver_\\n )\\n private\\n returns (bytes32)\\n {\\n bytes32 label = address(msg.sender).toSha3Hash();\\n bytes32 node_ = keccak256(abi.encodePacked(ADDR_REVERSE_NODE, label));\\n address currentOwner = registry.owner(node_);\\n\\n if (resolver_ != address(0x0) && resolver_ != registry.resolver(node_)) {\\n if (currentOwner != address(this)) {\\n registry.setSubnodeOwner(ADDR_REVERSE_NODE, label, address(this));\\n currentOwner = address(this);\\n }\\n\\n registry.setResolver(node_, resolver_);\\n }\\n\\n // Update the owner if required\\n if (currentOwner != owner) {\\n registry.setSubnodeOwner(ADDR_REVERSE_NODE, label, owner);\\n }\\n\\n return node_;\\n }\\n}\\n\",\"keccak256\":\"0xcedc0ece74976c6a3d22fc615baa0cb171e510ac53688a803211606c438dfdf2\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSAbstractResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ENS abstract resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/ResolverBase.sol\\n */\\nabstract contract ENSAbstractResolver {\\n // modifiers\\n\\n modifier onlyNodeOwner(bytes32 node)\\n {\\n require(\\n _isNodeOwner(node),\\n \\\"ENSAbstractResolver: reverted by onlyNodeOwner modifier\\\"\\n );\\n\\n _;\\n }\\n\\n // internal functions (views)\\n\\n function _isNodeOwner(\\n bytes32 node\\n )\\n internal\\n virtual\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0xc67d8bdd4904684e5d3388f7ca7d18c7d407058d6b548d8c591404c758a1ac60\",\"license\":\"MIT\"},\"src/ens/resolvers/ENSNameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./ENSAbstractResolver.sol\\\";\\n\\n\\n/**\\n * @title ENS abstract name resolver\\n *\\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/NameResolver.sol\\n */\\nabstract contract ENSNameResolver is ENSAbstractResolver {\\n bytes4 internal constant INTERFACE_NAME_ID = bytes4(keccak256(abi.encodePacked(\\\"name(bytes32)\\\")));\\n\\n mapping(bytes32 => string) internal resolverNames;\\n\\n // events\\n\\n event NameChanged(\\n bytes32 indexed node,\\n string name\\n );\\n\\n // external functions\\n\\n function setName(\\n bytes32 node,\\n string calldata name\\n )\\n external\\n onlyNodeOwner(node)\\n {\\n resolverNames[node] = name;\\n\\n emit NameChanged(node, name);\\n }\\n\\n // external functions (views)\\n\\n function name(\\n bytes32 node\\n )\\n external\\n view\\n returns (string memory)\\n {\\n return resolverNames[node];\\n }\\n}\\n\",\"keccak256\":\"0x1d2d4b21f59225fbefe0e5aaff87aff8f11afe5281745934d595e15770557ead\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50326000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610df8806100606000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063485cc95511610066578063485cc955146101bc5780637b103999146102205780637cf8a2eb14610254578063bffbe61c14610272578063c47f0027146102ca57610093565b806304f3bcec146100985780630f5a5466146100cc5780631e83409a14610144578063392e53cd1461019c575b600080fd5b6100a0610399565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61012e600480360360408110156100e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103bf565b6040518082815260200191505060405180910390f35b6101866004803603602081101561015a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103d3565b6040518082815260200191505060405180910390f35b6101a46103e7565b60405180821515815260200191505060405180910390f35b61021e600480360360408110156101d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061043d565b005b6102286105f5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61025c61061b565b6040518082815260200191505060405180910390f35b6102b46004803603602081101561028857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610642565b6040518082815260200191505060405180910390f35b610383600480360360208110156102e057600080fd5b81019080803590602001906401000000008111156102fd57600080fd5b82018360208201111561030f57600080fd5b8035906020019184600183028401116401000000008311171561033157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506106bb565b6040518082815260200191505060405180910390f35b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006103cb83836107ef565b905092915050565b60006103e08260006107ef565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146104e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610dbd602f913960400191505060405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e632604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b81565b60007f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b6106878373ffffffffffffffffffffffffffffffffffffffff16610d4d565b6040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050919050565b6000806106ea30600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166107ef565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637737221382856040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610781578082015181840152602081019050610766565b50505050905090810190601f1680156107ae5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156107ce57600080fd5b505af11580156107e2573d6000803e3d6000fd5b5050505080915050919050565b6000806108113373ffffffffffffffffffffffffffffffffffffffff16610d4d565b905060007f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b8260405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156108de57600080fd5b505afa1580156108f2573d6000803e3d6000fd5b505050506040513d602081101561090857600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614158015610a315750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156109c657600080fd5b505afa1580156109da573d6000803e3d6000fd5b505050506040513d60208110156109f057600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b15610c13573073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b6757600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59237f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b85306040518463ffffffff1660e01b8152600401808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050602060405180830381600087803b158015610b2757600080fd5b505af1158015610b3b573d6000803e3d6000fd5b505050506040513d6020811015610b5157600080fd5b8101908080519060200190929190505050503090505b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a83876040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015610bfa57600080fd5b505af1158015610c0e573d6000803e3d6000fd5b505050505b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d4157600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59237f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b85896040518463ffffffff1660e01b8152600401808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050602060405180830381600087803b158015610d0457600080fd5b505af1158015610d18573d6000803e3d6000fd5b505050506040513d6020811015610d2e57600080fd5b8101908080519060200190929190505050505b81935050505092915050565b6000807f303132333435363738396162636465660000000000000000000000000000000060285b6000811115610daa5760018103905081600f86161a815360108504945060018103905081600f86161a8153601085049450610d74565b5060286000209150508091505091905056fe496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742074686520696e697469616c697a6572a164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063485cc95511610066578063485cc955146101bc5780637b103999146102205780637cf8a2eb14610254578063bffbe61c14610272578063c47f0027146102ca57610093565b806304f3bcec146100985780630f5a5466146100cc5780631e83409a14610144578063392e53cd1461019c575b600080fd5b6100a0610399565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61012e600480360360408110156100e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103bf565b6040518082815260200191505060405180910390f35b6101866004803603602081101561015a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103d3565b6040518082815260200191505060405180910390f35b6101a46103e7565b60405180821515815260200191505060405180910390f35b61021e600480360360408110156101d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061043d565b005b6102286105f5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61025c61061b565b6040518082815260200191505060405180910390f35b6102b46004803603602081101561028857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610642565b6040518082815260200191505060405180910390f35b610383600480360360208110156102e057600080fd5b81019080803590602001906401000000008111156102fd57600080fd5b82018360208201111561030f57600080fd5b8035906020019184600183028401116401000000008311171561033157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506106bb565b6040518082815260200191505060405180910390f35b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006103cb83836107ef565b905092915050565b60006103e08260006107ef565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146104e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610dbd602f913960400191505060405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e632604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b81565b60007f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b6106878373ffffffffffffffffffffffffffffffffffffffff16610d4d565b6040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050919050565b6000806106ea30600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166107ef565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637737221382856040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610781578082015181840152602081019050610766565b50505050905090810190601f1680156107ae5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156107ce57600080fd5b505af11580156107e2573d6000803e3d6000fd5b5050505080915050919050565b6000806108113373ffffffffffffffffffffffffffffffffffffffff16610d4d565b905060007f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b8260405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156108de57600080fd5b505afa1580156108f2573d6000803e3d6000fd5b505050506040513d602081101561090857600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614158015610a315750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630178b8bf836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156109c657600080fd5b505afa1580156109da573d6000803e3d6000fd5b505050506040513d60208110156109f057600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b15610c13573073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b6757600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59237f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b85306040518463ffffffff1660e01b8152600401808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050602060405180830381600087803b158015610b2757600080fd5b505af1158015610b3b573d6000803e3d6000fd5b505050506040513d6020811015610b5157600080fd5b8101908080519060200190929190505050503090505b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a83876040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015610bfa57600080fd5b505af1158015610c0e573d6000803e3d6000fd5b505050505b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d4157600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59237f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260001b85896040518463ffffffff1660e01b8152600401808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050602060405180830381600087803b158015610d0457600080fd5b505af1158015610d18573d6000803e3d6000fd5b505050506040513d6020811015610d2e57600080fd5b8101908080519060200190929190505050505b81935050505092915050565b6000807f303132333435363738396162636465660000000000000000000000000000000060285b6000811115610daa5760018103905081600f86161a815360108504945060018103905081600f86161a8153601085049450610d74565b5060286000209150508091505091905056fe496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742074686520696e697469616c697a6572a164736f6c634300060c000a", + "devdoc": { + "details": "Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ReverseRegistrar.sol", + "kind": "dev", + "methods": { + "constructor": { + "details": "Public constructor" + }, + "initialize(address,address)": { + "params": { + "registry_": "ENS registry address", + "resolver_": "ENS name resolver address" + } + }, + "isInitialized()": { + "returns": { + "_0": "true when contract is initialized" + } + } + }, + "title": "ENS reverse registrar", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "initialize(address,address)": { + "notice": "Initializes `ENSReverseRegistrar` contract" + }, + "isInitialized()": { + "notice": "Check if contract is initialized" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1871, + "contract": "src/ens/ENSReverseRegistrar.sol:ENSReverseRegistrar", + "label": "initializer", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 3581, + "contract": "src/ens/ENSReverseRegistrar.sol:ENSReverseRegistrar", + "label": "registry", + "offset": 0, + "slot": "1", + "type": "t_contract(ENSRegistry)3564" + }, + { + "astId": 3583, + "contract": "src/ens/ENSReverseRegistrar.sol:ENSReverseRegistrar", + "label": "resolver", + "offset": 0, + "slot": "2", + "type": "t_contract(ENSNameResolver)4114" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_contract(ENSNameResolver)4114": { + "encoding": "inplace", + "label": "contract ENSNameResolver", + "numberOfBytes": "20" + }, + "t_contract(ENSRegistry)3564": { + "encoding": "inplace", + "label": "contract ENSRegistry", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/ExternalAccountRegistry.json b/deployments/neonDevnet/ExternalAccountRegistry.json new file mode 100644 index 00000000..32cd6b20 --- /dev/null +++ b/deployments/neonDevnet/ExternalAccountRegistry.json @@ -0,0 +1,489 @@ +{ + "address": "0x502BbBcC044d2B146c310eB24E5cd8Eba37EdbEc", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "AccountOwnerAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "AccountOwnerRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "AccountProofAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "AccountProofRemoved", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "addAccountOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "addAccountProof", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "removeAccountOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "removeAccountProof", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "verifyAccountOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "verifyAccountOwnerAtBlock", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "verifyAccountProof", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "verifyAccountProofAtBlock", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xd31152fbbb7e51f8ecdc84610a8c9c099cfd4995ea2f1f4a005a14318f12fcef", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "47733840", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x37933bb07475cdf7d0ff8f3a42ebf882188b76ad5a0338530683513515a5104a", + "transactionHash": "0xd31152fbbb7e51f8ecdc84610a8c9c099cfd4995ea2f1f4a005a14318f12fcef", + "logs": [], + "blockNumber": 173996844, + "cumulativeGasUsed": "47733840", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AccountOwnerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AccountOwnerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"AccountProofAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"AccountProofRemoved\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"addAccountOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"addAccountProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"removeAccountOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"removeAccountProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"verifyAccountOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"verifyAccountOwnerAtBlock\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"verifyAccountProof\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"verifyAccountProofAtBlock\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski \",\"details\":\"An account can call the registry to add (`addAccountOwner`) or remove (`removeAccountOwner`) its own owners. When the owner has been added, information about that fact will live in the registry forever. Removing an owner only affects the future blocks (until the owner is re-added). Given the fact, there is no way to sign the data using a contract based wallet, we created a registry to store signed by the key wallet proofs. ERC-1271 allows removing a signer after the signature was created. Thus store the signature for the later use doesn't guarantee the signer is still has access to that smart account. Because of that, the ERC1271's `isValidSignature()` cannot be used in e.g. `PaymentRegistry`.* An account can call the registry to add (`addAccountProof`) or remove (`removeAccountProof`) proof hash. When the proof has been added, information about that fact will live in the registry forever. Removing a proof only affects the future blocks (until the proof is re-added).\",\"events\":{\"AccountOwnerAdded(address,address)\":{\"details\":\"Emitted when the new owner is added\",\"params\":{\"account\":\"account address\",\"owner\":\"owner address\"}},\"AccountOwnerRemoved(address,address)\":{\"details\":\"Emitted when the existing owner is removed\",\"params\":{\"account\":\"account address\",\"owner\":\"owner address\"}},\"AccountProofAdded(address,bytes32)\":{\"details\":\"Emitted when the new proof is added\",\"params\":{\"account\":\"account address\",\"hash\":\"proof hash\"}},\"AccountProofRemoved(address,bytes32)\":{\"details\":\"Emitted when the existing proof is removed\",\"params\":{\"account\":\"account address\",\"hash\":\"proof hash\"}}},\"kind\":\"dev\",\"methods\":{\"addAccountOwner(address)\":{\"params\":{\"owner\":\"owner address\"}},\"addAccountProof(bytes32)\":{\"params\":{\"hash\":\"proof hash\"}},\"removeAccountOwner(address)\":{\"params\":{\"owner\":\"owner address\"}},\"removeAccountProof(bytes32)\":{\"params\":{\"hash\":\"proof hash\"}},\"verifyAccountOwner(address,address)\":{\"params\":{\"account\":\"account address\",\"owner\":\"owner address\"},\"returns\":{\"_0\":\"true on correct account owner\"}},\"verifyAccountOwnerAtBlock(address,address,uint256)\":{\"params\":{\"account\":\"account address\",\"blockNumber\":\"block number to verify\",\"owner\":\"owner address\"},\"returns\":{\"_0\":\"true on correct account owner\"}},\"verifyAccountProof(address,bytes32)\":{\"params\":{\"account\":\"account address\",\"hash\":\"proof hash\"},\"returns\":{\"_0\":\"true on correct account proof\"}},\"verifyAccountProofAtBlock(address,bytes32,uint256)\":{\"params\":{\"account\":\"account address\",\"blockNumber\":\"block number to verify\",\"hash\":\"proof hash\"},\"returns\":{\"_0\":\"true on correct account proof\"}}},\"title\":\"External account registry\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addAccountOwner(address)\":{\"notice\":\"Adds a new account owner\"},\"addAccountProof(bytes32)\":{\"notice\":\"Adds a new account proof\"},\"removeAccountOwner(address)\":{\"notice\":\"Removes existing account owner\"},\"removeAccountProof(bytes32)\":{\"notice\":\"Removes existing account proof\"},\"verifyAccountOwner(address,address)\":{\"notice\":\"Verifies the owner of the account at current block\"},\"verifyAccountOwnerAtBlock(address,address,uint256)\":{\"notice\":\"Verifies the owner of the account at specific block\"},\"verifyAccountProof(address,bytes32)\":{\"notice\":\"Verifies the proof of the account at current block\"},\"verifyAccountProofAtBlock(address,bytes32,uint256)\":{\"notice\":\"Verifies the proof of the account at specific block\"}},\"notice\":\"Global registry for keys and external (outside of the platform) contract based wallets\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/external/ExternalAccountRegistry.sol\":\"ExternalAccountRegistry\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/libs/BlockLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Block library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nlibrary BlockLib {\\n struct BlockRelated {\\n bool added;\\n uint256 removedAtBlockNumber;\\n }\\n\\n /**\\n * @notice Verifies self struct at current block\\n * @param self self struct\\n * @return true on correct self struct\\n */\\n function verifyAtCurrentBlock(\\n BlockRelated memory self\\n )\\n internal\\n view\\n returns (bool)\\n {\\n return verifyAtBlock(self, block.number);\\n }\\n\\n /**\\n * @notice Verifies self struct at any block\\n * @param self self struct\\n * @return true on correct self struct\\n */\\n function verifyAtAnyBlock(\\n BlockRelated memory self\\n )\\n internal\\n pure\\n returns (bool)\\n {\\n return verifyAtBlock(self, 0);\\n }\\n\\n /**\\n * @notice Verifies self struct at specific block\\n * @param self self struct\\n * @param blockNumber block number to verify\\n * @return true on correct self struct\\n */\\n function verifyAtBlock(\\n BlockRelated memory self,\\n uint256 blockNumber\\n )\\n internal\\n pure\\n returns (bool)\\n {\\n bool result = false;\\n\\n if (self.added) {\\n if (self.removedAtBlockNumber == 0) {\\n result = true;\\n } else if (blockNumber == 0) {\\n result = true;\\n } else {\\n result = self.removedAtBlockNumber > blockNumber;\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9205536bc211f86d1113118a44dddfa7a9b9772a918cf4b1575c982a05472587\",\"license\":\"MIT\"},\"src/external/ExternalAccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BlockLib.sol\\\";\\n\\n\\n/**\\n * @title External account registry\\n *\\n * @notice Global registry for keys and external (outside of the platform) contract based wallets\\n *\\n * @dev An account can call the registry to add (`addAccountOwner`) or remove (`removeAccountOwner`) its own owners.\\n * When the owner has been added, information about that fact will live in the registry forever.\\n * Removing an owner only affects the future blocks (until the owner is re-added).\\n *\\n * Given the fact, there is no way to sign the data using a contract based wallet,\\n * we created a registry to store signed by the key wallet proofs.\\n * ERC-1271 allows removing a signer after the signature was created. Thus store the signature for the later use\\n * doesn't guarantee the signer is still has access to that smart account.\\n * Because of that, the ERC1271's `isValidSignature()` cannot be used in e.g. `PaymentRegistry`.*\\n *\\n * An account can call the registry to add (`addAccountProof`) or remove (`removeAccountProof`) proof hash.\\n * When the proof has been added, information about that fact will live in the registry forever.\\n * Removing a proof only affects the future blocks (until the proof is re-added).\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract ExternalAccountRegistry {\\n using BlockLib for BlockLib.BlockRelated;\\n\\n struct Account {\\n mapping(address => BlockLib.BlockRelated) owners;\\n mapping(bytes32 => BlockLib.BlockRelated) proofs;\\n }\\n\\n mapping(address => Account) private accounts;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the new owner is added\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerAdded(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the existing owner is removed\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerRemoved(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the new proof is added\\n * @param account account address\\n * @param hash proof hash\\n */\\n event AccountProofAdded(\\n address account,\\n bytes32 hash\\n );\\n\\n /**\\n * @dev Emitted when the existing proof is removed\\n * @param account account address\\n * @param hash proof hash\\n */\\n event AccountProofRemoved(\\n address account,\\n bytes32 hash\\n );\\n\\n // external functions\\n\\n /**\\n * @notice Adds a new account owner\\n * @param owner owner address\\n */\\n function addAccountOwner(\\n address owner\\n )\\n external\\n {\\n require(\\n owner != address(0),\\n \\\"ExternalAccountRegistry: cannot add 0x0 owner\\\"\\n );\\n\\n require(\\n !accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: owner already exists\\\"\\n );\\n\\n accounts[msg.sender].owners[owner].added = true;\\n accounts[msg.sender].owners[owner].removedAtBlockNumber = 0;\\n\\n emit AccountOwnerAdded(\\n msg.sender,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Removes existing account owner\\n * @param owner owner address\\n */\\n function removeAccountOwner(\\n address owner\\n )\\n external\\n {\\n require(\\n accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: owner doesn't exist\\\"\\n );\\n\\n accounts[msg.sender].owners[owner].removedAtBlockNumber = block.number;\\n\\n emit AccountOwnerRemoved(\\n msg.sender,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Adds a new account proof\\n * @param hash proof hash\\n */\\n function addAccountProof(\\n bytes32 hash\\n )\\n external\\n {\\n require(\\n !accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: proof already exists\\\"\\n );\\n\\n accounts[msg.sender].proofs[hash].added = true;\\n accounts[msg.sender].proofs[hash].removedAtBlockNumber = 0;\\n\\n emit AccountProofAdded(\\n msg.sender,\\n hash\\n );\\n }\\n\\n /**\\n * @notice Removes existing account proof\\n * @param hash proof hash\\n */\\n function removeAccountProof(\\n bytes32 hash\\n )\\n external\\n {\\n require(\\n accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: proof doesn't exist\\\"\\n );\\n\\n accounts[msg.sender].proofs[hash].removedAtBlockNumber = block.number;\\n\\n emit AccountProofRemoved(\\n msg.sender,\\n hash\\n );\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Verifies the owner of the account at current block\\n * @param account account address\\n * @param owner owner address\\n * @return true on correct account owner\\n */\\n function verifyAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].owners[owner].verifyAtCurrentBlock();\\n }\\n\\n /**\\n * @notice Verifies the owner of the account at specific block\\n * @param account account address\\n * @param owner owner address\\n * @param blockNumber block number to verify\\n * @return true on correct account owner\\n */\\n function verifyAccountOwnerAtBlock(\\n address account,\\n address owner,\\n uint256 blockNumber\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].owners[owner].verifyAtBlock(blockNumber);\\n }\\n\\n /**\\n * @notice Verifies the proof of the account at current block\\n * @param account account address\\n * @param hash proof hash\\n * @return true on correct account proof\\n */\\n function verifyAccountProof(\\n address account,\\n bytes32 hash\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].proofs[hash].verifyAtCurrentBlock();\\n }\\n\\n /**\\n * @notice Verifies the proof of the account at specific block\\n * @param account account address\\n * @param hash proof hash\\n * @param blockNumber block number to verify\\n * @return true on correct account proof\\n */\\n function verifyAccountProofAtBlock(\\n address account,\\n bytes32 hash,\\n uint256 blockNumber\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].proofs[hash].verifyAtBlock(blockNumber);\\n }\\n}\\n\",\"keccak256\":\"0x8067b1fae41b73949f8d871a835533cbdd94b9ca3faa93b91f595c37e632ccdb\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610fff806100206000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806394000b021161005b57806394000b0214610227578063bb890d3f14610255578063d543c34a146102cf578063e278cfc6146102fd57610088565b806334d323a41461008d57806359b52ef8146101115780638a3133781461017f5780638ecc1365146101e3575b600080fd5b6100f9600480360360608110156100a357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610341565b60405180821515815260200191505060405180910390f35b6101676004803603606081101561012757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919050505061040c565b60405180821515815260200191505060405180910390f35b6101cb6004803603604081101561019557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506104ab565b60405180821515815260200191505060405180910390f35b610225600480360360208110156101f957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061053f565b005b6102536004803603602081101561023d57600080fd5b8101908080359060200190929190505050610860565b005b6102b76004803603604081101561026b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109f1565b60405180821515815260200191505060405180910390f35b6102fb600480360360208110156102e557600080fd5b8101908080359060200190929190505050610ab1565b005b61033f6004803603602081101561031357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cb2565b005b6000610403826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610eb190919063ffffffff16565b90509392505050565b60006104a2826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610eb190919063ffffffff16565b90509392505050565b60006105376000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008481526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156105c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180610f14602d913960400191505060405180910390fd5b61067b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b156106d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180610f6e602d913960400191505060405180910390fd5b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff02191690831515021790555060008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055507f27e282f7712c5b4617277759c834b86d163dfc1aad25c8c3c5926a1c9e5644683382604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150565b6108ea6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008381526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b61093f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180610fc7602c913960400191505060405180910390fd5b436000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000838152602001908152602001600020600101819055507f87dde712783ad4895642c7a875998317a71cf424a2444eb79545ce3795431ff93382604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a150565b6000610aa96000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b905092915050565b610b3b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008381526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b15610b91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180610f41602d913960400191505060405180910390fd5b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600083815260200190815260200160002060000160006101000a81548160ff02191690831515021790555060008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000838152602001908152602001600020600101819055507f4075b367eed0513a54aa39c287c66d6ae98e5df6f73ac087b26b8f89d05d1aa83382604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a150565b610d686000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b610dbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180610f9b602c913960400191505060405180910390fd5b436000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055507f1ce3cbbc43ee231e5b950332f2b0b9dd7d349291a3ee411ce5c5c7ed745661bb3382604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150565b60008060009050836000015115610ef657600084602001511415610ed85760019050610ef5565b6000831415610eea5760019050610ef4565b8284602001511190505b5b5b8091505092915050565b6000610f0c8243610eb1565b905091905056fe45787465726e616c4163636f756e7452656769737472793a2063616e6e6f742061646420307830206f776e657245787465726e616c4163636f756e7452656769737472793a2070726f6f6620616c72656164792065786973747345787465726e616c4163636f756e7452656769737472793a206f776e657220616c72656164792065786973747345787465726e616c4163636f756e7452656769737472793a206f776e657220646f65736e277420657869737445787465726e616c4163636f756e7452656769737472793a2070726f6f6620646f65736e2774206578697374a164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c806394000b021161005b57806394000b0214610227578063bb890d3f14610255578063d543c34a146102cf578063e278cfc6146102fd57610088565b806334d323a41461008d57806359b52ef8146101115780638a3133781461017f5780638ecc1365146101e3575b600080fd5b6100f9600480360360608110156100a357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610341565b60405180821515815260200191505060405180910390f35b6101676004803603606081101561012757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919050505061040c565b60405180821515815260200191505060405180910390f35b6101cb6004803603604081101561019557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506104ab565b60405180821515815260200191505060405180910390f35b610225600480360360208110156101f957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061053f565b005b6102536004803603602081101561023d57600080fd5b8101908080359060200190929190505050610860565b005b6102b76004803603604081101561026b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109f1565b60405180821515815260200191505060405180910390f35b6102fb600480360360208110156102e557600080fd5b8101908080359060200190929190505050610ab1565b005b61033f6004803603602081101561031357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cb2565b005b6000610403826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610eb190919063ffffffff16565b90509392505050565b60006104a2826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610eb190919063ffffffff16565b90509392505050565b60006105376000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008481526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156105c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180610f14602d913960400191505060405180910390fd5b61067b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b156106d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180610f6e602d913960400191505060405180910390fd5b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff02191690831515021790555060008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055507f27e282f7712c5b4617277759c834b86d163dfc1aad25c8c3c5926a1c9e5644683382604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150565b6108ea6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008381526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b61093f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180610fc7602c913960400191505060405180910390fd5b436000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000838152602001908152602001600020600101819055507f87dde712783ad4895642c7a875998317a71cf424a2444eb79545ce3795431ff93382604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a150565b6000610aa96000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b905092915050565b610b3b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008381526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b15610b91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180610f41602d913960400191505060405180910390fd5b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600083815260200190815260200160002060000160006101000a81548160ff02191690831515021790555060008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000838152602001908152602001600020600101819055507f4075b367eed0513a54aa39c287c66d6ae98e5df6f73ac087b26b8f89d05d1aa83382604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a150565b610d686000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050610f00565b610dbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180610f9b602c913960400191505060405180910390fd5b436000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055507f1ce3cbbc43ee231e5b950332f2b0b9dd7d349291a3ee411ce5c5c7ed745661bb3382604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150565b60008060009050836000015115610ef657600084602001511415610ed85760019050610ef5565b6000831415610eea5760019050610ef4565b8284602001511190505b5b5b8091505092915050565b6000610f0c8243610eb1565b905091905056fe45787465726e616c4163636f756e7452656769737472793a2063616e6e6f742061646420307830206f776e657245787465726e616c4163636f756e7452656769737472793a2070726f6f6620616c72656164792065786973747345787465726e616c4163636f756e7452656769737472793a206f776e657220616c72656164792065786973747345787465726e616c4163636f756e7452656769737472793a206f776e657220646f65736e277420657869737445787465726e616c4163636f756e7452656769737472793a2070726f6f6620646f65736e2774206578697374a164736f6c634300060c000a", + "devdoc": { + "author": "Stanisław Głogowski ", + "details": "An account can call the registry to add (`addAccountOwner`) or remove (`removeAccountOwner`) its own owners. When the owner has been added, information about that fact will live in the registry forever. Removing an owner only affects the future blocks (until the owner is re-added). Given the fact, there is no way to sign the data using a contract based wallet, we created a registry to store signed by the key wallet proofs. ERC-1271 allows removing a signer after the signature was created. Thus store the signature for the later use doesn't guarantee the signer is still has access to that smart account. Because of that, the ERC1271's `isValidSignature()` cannot be used in e.g. `PaymentRegistry`.* An account can call the registry to add (`addAccountProof`) or remove (`removeAccountProof`) proof hash. When the proof has been added, information about that fact will live in the registry forever. Removing a proof only affects the future blocks (until the proof is re-added).", + "events": { + "AccountOwnerAdded(address,address)": { + "details": "Emitted when the new owner is added", + "params": { + "account": "account address", + "owner": "owner address" + } + }, + "AccountOwnerRemoved(address,address)": { + "details": "Emitted when the existing owner is removed", + "params": { + "account": "account address", + "owner": "owner address" + } + }, + "AccountProofAdded(address,bytes32)": { + "details": "Emitted when the new proof is added", + "params": { + "account": "account address", + "hash": "proof hash" + } + }, + "AccountProofRemoved(address,bytes32)": { + "details": "Emitted when the existing proof is removed", + "params": { + "account": "account address", + "hash": "proof hash" + } + } + }, + "kind": "dev", + "methods": { + "addAccountOwner(address)": { + "params": { + "owner": "owner address" + } + }, + "addAccountProof(bytes32)": { + "params": { + "hash": "proof hash" + } + }, + "removeAccountOwner(address)": { + "params": { + "owner": "owner address" + } + }, + "removeAccountProof(bytes32)": { + "params": { + "hash": "proof hash" + } + }, + "verifyAccountOwner(address,address)": { + "params": { + "account": "account address", + "owner": "owner address" + }, + "returns": { + "_0": "true on correct account owner" + } + }, + "verifyAccountOwnerAtBlock(address,address,uint256)": { + "params": { + "account": "account address", + "blockNumber": "block number to verify", + "owner": "owner address" + }, + "returns": { + "_0": "true on correct account owner" + } + }, + "verifyAccountProof(address,bytes32)": { + "params": { + "account": "account address", + "hash": "proof hash" + }, + "returns": { + "_0": "true on correct account proof" + } + }, + "verifyAccountProofAtBlock(address,bytes32,uint256)": { + "params": { + "account": "account address", + "blockNumber": "block number to verify", + "hash": "proof hash" + }, + "returns": { + "_0": "true on correct account proof" + } + } + }, + "title": "External account registry", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "addAccountOwner(address)": { + "notice": "Adds a new account owner" + }, + "addAccountProof(bytes32)": { + "notice": "Adds a new account proof" + }, + "removeAccountOwner(address)": { + "notice": "Removes existing account owner" + }, + "removeAccountProof(bytes32)": { + "notice": "Removes existing account proof" + }, + "verifyAccountOwner(address,address)": { + "notice": "Verifies the owner of the account at current block" + }, + "verifyAccountOwnerAtBlock(address,address,uint256)": { + "notice": "Verifies the owner of the account at specific block" + }, + "verifyAccountProof(address,bytes32)": { + "notice": "Verifies the proof of the account at current block" + }, + "verifyAccountProofAtBlock(address,bytes32,uint256)": { + "notice": "Verifies the proof of the account at specific block" + } + }, + "notice": "Global registry for keys and external (outside of the platform) contract based wallets", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4292, + "contract": "src/external/ExternalAccountRegistry.sol:ExternalAccountRegistry", + "label": "accounts", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_struct(Account)4288_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_struct(Account)4288_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct ExternalAccountRegistry.Account)", + "numberOfBytes": "32", + "value": "t_struct(Account)4288_storage" + }, + "t_mapping(t_address,t_struct(BlockRelated)1382_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct BlockLib.BlockRelated)", + "numberOfBytes": "32", + "value": "t_struct(BlockRelated)1382_storage" + }, + "t_mapping(t_bytes32,t_struct(BlockRelated)1382_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct BlockLib.BlockRelated)", + "numberOfBytes": "32", + "value": "t_struct(BlockRelated)1382_storage" + }, + "t_struct(Account)4288_storage": { + "encoding": "inplace", + "label": "struct ExternalAccountRegistry.Account", + "members": [ + { + "astId": 4283, + "contract": "src/external/ExternalAccountRegistry.sol:ExternalAccountRegistry", + "label": "owners", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_struct(BlockRelated)1382_storage)" + }, + { + "astId": 4287, + "contract": "src/external/ExternalAccountRegistry.sol:ExternalAccountRegistry", + "label": "proofs", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_struct(BlockRelated)1382_storage)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(BlockRelated)1382_storage": { + "encoding": "inplace", + "label": "struct BlockLib.BlockRelated", + "members": [ + { + "astId": 1379, + "contract": "src/external/ExternalAccountRegistry.sol:ExternalAccountRegistry", + "label": "added", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1381, + "contract": "src/external/ExternalAccountRegistry.sol:ExternalAccountRegistry", + "label": "removedAtBlockNumber", + "offset": 0, + "slot": "1", + "type": "t_uint256" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/Gateway.json b/deployments/neonDevnet/Gateway.json new file mode 100644 index 00000000..45bdf811 --- /dev/null +++ b/deployments/neonDevnet/Gateway.json @@ -0,0 +1,578 @@ +{ + "address": "0x432defD2b3733e6fEBb1bD4B17Ed85D15b882163", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "batch", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bool", + "name": "succeeded", + "type": "bool" + } + ], + "name": "BatchDelegated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "initializer", + "type": "address" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "inputs": [], + "name": "chainId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "to", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + }, + { + "internalType": "bytes", + "name": "senderSignature", + "type": "bytes" + } + ], + "name": "delegateBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "to", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + }, + { + "internalType": "bytes", + "name": "senderSignature", + "type": "bytes" + } + ], + "name": "delegateBatchWithGasPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "batches", + "type": "bytes[]" + }, + { + "internalType": "bool", + "name": "revertOnFailure", + "type": "bool" + } + ], + "name": "delegateBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "externalAccountRegistry", + "outputs": [ + { + "internalType": "contract ExternalAccountRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountNextNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "to", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "internalType": "struct Gateway.DelegatedBatch", + "name": "delegatedBatch", + "type": "tuple" + } + ], + "name": "hashDelegatedBatch", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "to", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + } + ], + "internalType": "struct Gateway.DelegatedBatchWithGasPrice", + "name": "delegatedBatch", + "type": "tuple" + } + ], + "name": "hashDelegatedBatchWithGasPrice", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ExternalAccountRegistry", + "name": "externalAccountRegistry_", + "type": "address" + }, + { + "internalType": "contract PersonalAccountRegistry", + "name": "personalAccountRegistry_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "personalAccountRegistry", + "outputs": [ + { + "internalType": "contract PersonalAccountRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "to", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "sendBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address[]", + "name": "to", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "sendBatchFromAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x527b68d567e57e392dc2f25c13b067067ef03c7870f287b8eb0e3ade6aae7dbb", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "87751880", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xcc266b2fc3e13db0f6e673b86090219a1f625cf98f00df620f1114086cae9339", + "transactionHash": "0x527b68d567e57e392dc2f25c13b067067ef03c7870f287b8eb0e3ade6aae7dbb", + "logs": [], + "blockNumber": 173996859, + "cumulativeGasUsed": "87751880", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"batch\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"succeeded\",\"type\":\"bool\"}],\"name\":\"BatchDelegated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"chainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"to\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"senderSignature\",\"type\":\"bytes\"}],\"name\":\"delegateBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"to\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"senderSignature\",\"type\":\"bytes\"}],\"name\":\"delegateBatchWithGasPrice\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"batches\",\"type\":\"bytes[]\"},{\"internalType\":\"bool\",\"name\":\"revertOnFailure\",\"type\":\"bool\"}],\"name\":\"delegateBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"externalAccountRegistry\",\"outputs\":[{\"internalType\":\"contract ExternalAccountRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountNextNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"to\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"internalType\":\"struct Gateway.DelegatedBatch\",\"name\":\"delegatedBatch\",\"type\":\"tuple\"}],\"name\":\"hashDelegatedBatch\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"to\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"}],\"internalType\":\"struct Gateway.DelegatedBatchWithGasPrice\",\"name\":\"delegatedBatch\",\"type\":\"tuple\"}],\"name\":\"hashDelegatedBatchWithGasPrice\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ExternalAccountRegistry\",\"name\":\"externalAccountRegistry_\",\"type\":\"address\"},{\"internalType\":\"contract PersonalAccountRegistry\",\"name\":\"personalAccountRegistry_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"personalAccountRegistry\",\"outputs\":[{\"internalType\":\"contract PersonalAccountRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"to\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"sendBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"to\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"sendBatchFromAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski \",\"events\":{\"BatchDelegated(address,bytes,bool)\":{\"details\":\"Emitted when the single batch is delegated\",\"params\":{\"batch\":\"batch\",\"sender\":\"sender address\",\"succeeded\":\"if succeeded\"}}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Public constructor\"},\"delegateBatch(address,uint256,address[],bytes[],bytes)\":{\"details\":\"Use `hashDelegatedBatch` to create sender message payload. `GatewayRecipient` context api: `_getContextAccount` will return `account` arg `_getContextSender` will return recovered address from `senderSignature` arg\",\"params\":{\"account\":\"account address\",\"data\":\"array of batch data\",\"nonce\":\"next account nonce\",\"senderSignature\":\"sender signature\",\"to\":\"array of batch recipients contracts\"}},\"delegateBatchWithGasPrice(address,uint256,address[],bytes[],bytes)\":{\"details\":\"Use `hashDelegatedBatchWithGasPrice` to create sender message payload (tx.gasprice as gasPrice) `GatewayRecipient` context api: `_getContextAccount` will return `account` arg `_getContextSender` will return recovered address from `senderSignature` arg\",\"params\":{\"account\":\"account address\",\"data\":\"array of batch data\",\"nonce\":\"next account nonce\",\"senderSignature\":\"sender signature\",\"to\":\"array of batch recipients contracts\"}},\"delegateBatches(bytes[],bool)\":{\"details\":\"It will revert when all batches fail\",\"params\":{\"batches\":\"array of batches\",\"revertOnFailure\":\"reverts on any error\"}},\"getAccountNextNonce(address)\":{\"params\":{\"account\":\"account address\"},\"returns\":{\"_0\":\"next nonce\"}},\"hashDelegatedBatch((address,uint256,address[],bytes[]))\":{\"params\":{\"delegatedBatch\":\"struct\"},\"returns\":{\"_0\":\"hash\"}},\"hashDelegatedBatchWithGasPrice((address,uint256,address[],bytes[],uint256))\":{\"params\":{\"delegatedBatch\":\"struct\"},\"returns\":{\"_0\":\"hash\"}},\"initialize(address,address)\":{\"params\":{\"externalAccountRegistry_\":\"`ExternalAccountRegistry` contract address\",\"personalAccountRegistry_\":\"`PersonalAccountRegistry` contract address\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}},\"sendBatch(address[],bytes[])\":{\"details\":\"`GatewayRecipient` context api: `_getContextAccount` will return `msg.sender` `_getContextSender` will return `msg.sender`\",\"params\":{\"data\":\"array of batch data\",\"to\":\"array of batch recipients contracts\"}},\"sendBatchFromAccount(address,address[],bytes[])\":{\"details\":\"`GatewayRecipient` context api: `_getContextAccount` will return `account` arg `_getContextSender` will return `msg.sender`\",\"params\":{\"account\":\"account address\",\"data\":\"array of batch data\",\"to\":\"array of batch recipients contracts\"}}},\"title\":\"Gateway\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"delegateBatch(address,uint256,address[],bytes[],bytes)\":{\"notice\":\"Delegates batch from the account\"},\"delegateBatchWithGasPrice(address,uint256,address[],bytes[],bytes)\":{\"notice\":\"Delegates batch from the account (with gas price)\"},\"delegateBatches(bytes[],bool)\":{\"notice\":\"Delegates multiple batches\"},\"getAccountNextNonce(address)\":{\"notice\":\"Gets next account nonce\"},\"hashDelegatedBatch((address,uint256,address[],bytes[]))\":{\"notice\":\"Hashes `DelegatedBatch` message payload\"},\"hashDelegatedBatchWithGasPrice((address,uint256,address[],bytes[],uint256))\":{\"notice\":\"Hashes `DelegatedBatchWithGasPrice` message payload\"},\"initialize(address,address)\":{\"notice\":\"Initializes `Gateway` contract\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"},\"sendBatch(address[],bytes[])\":{\"notice\":\"Sends batch\"},\"sendBatchFromAccount(address,address[],bytes[])\":{\"notice\":\"Sends batch from the account\"}},\"notice\":\"GSN replacement\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/gateway/Gateway.sol\":\"Gateway\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/access/Controlled.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Controlled\\n *\\n * @dev Contract module which provides an access control mechanism.\\n * It ensures there is only one controlling account of the smart contract\\n * and grants that account exclusive access to specific functions.\\n *\\n * The controller account will be the one that deploys the contract.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Controlled {\\n /**\\n * @return controller account address\\n */\\n address public controller;\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if msg.sender is not the controller\\n */\\n modifier onlyController() {\\n require(\\n msg.sender == controller,\\n \\\"Controlled: msg.sender is not the controller\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n controller = msg.sender;\\n }\\n}\\n\",\"keccak256\":\"0xdf03a0b7ec644da9925c5c1b6c8a86bb1cc1b9c5018bb265a1a4c5044b877af3\",\"license\":\"MIT\"},\"src/common/access/Guarded.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n\\n/**\\n * @title Guarded\\n *\\n * @dev Contract module which provides a guardian-type control mechanism.\\n * It allows key accounts to have guardians and restricts specific methods to be accessible by guardians only.\\n *\\n * Each guardian account can remove other guardians\\n *\\n * Use `_initializeGuarded` to initialize the contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Guarded {\\n using ECDSALib for bytes32;\\n\\n mapping(address => bool) private guardians;\\n\\n // events\\n\\n /**\\n * @dev Emitted when a new guardian is added\\n * @param sender sender address\\n * @param guardian guardian address\\n */\\n event GuardianAdded(\\n address sender,\\n address guardian\\n );\\n\\n /**\\n * @dev Emitted when the existing guardian is removed\\n * @param sender sender address\\n * @param guardian guardian address\\n */\\n event GuardianRemoved(\\n address sender,\\n address guardian\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not a guardian account\\n */\\n modifier onlyGuardian() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n guardians[tx.origin],\\n \\\"Guarded: tx.origin is not the guardian\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor() internal {}\\n\\n // external functions\\n\\n /**\\n * @notice Adds a new guardian\\n * @param guardian guardian address\\n */\\n function addGuardian(\\n address guardian\\n )\\n external\\n onlyGuardian\\n {\\n _addGuardian(guardian);\\n }\\n\\n /**\\n * @notice Removes the existing guardian\\n * @param guardian guardian address\\n */\\n function removeGuardian(\\n address guardian\\n )\\n external\\n onlyGuardian\\n {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin != guardian,\\n \\\"Guarded: cannot remove self\\\"\\n );\\n\\n require(\\n guardians[guardian],\\n \\\"Guarded: guardian doesn't exist\\\"\\n );\\n\\n guardians[guardian] = false;\\n\\n emit GuardianRemoved(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin,\\n guardian\\n );\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if guardian exists\\n * @param guardian guardian address\\n * @return true when guardian exists\\n */\\n function isGuardian(\\n address guardian\\n )\\n external\\n view\\n returns (bool)\\n {\\n return guardians[guardian];\\n }\\n\\n /**\\n * @notice Verifies guardian signature\\n * @param messageHash message hash\\n * @param signature signature\\n * @return true on correct guardian signature\\n */\\n function verifyGuardianSignature(\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n external\\n view\\n returns (bool)\\n {\\n return _verifyGuardianSignature(\\n messageHash,\\n signature\\n );\\n }\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `Guarded` contract\\n * @dev If `guardians_` array is empty `tx.origin` is added as guardian account\\n * @param guardians_ array of guardians addresses\\n */\\n function _initializeGuarded(\\n address[] memory guardians_\\n )\\n internal\\n {\\n if (guardians_.length == 0) {\\n // solhint-disable-next-line avoid-tx-origin\\n _addGuardian(tx.origin);\\n } else {\\n uint guardiansLen = guardians_.length;\\n for (uint i = 0; i < guardiansLen; i++) {\\n _addGuardian(guardians_[i]);\\n }\\n }\\n }\\n\\n\\n // internal functions (views)\\n\\n function _verifyGuardianSignature(\\n bytes32 messageHash,\\n bytes memory signature\\n )\\n internal\\n view\\n returns (bool)\\n {\\n address guardian = messageHash.recoverAddress(signature);\\n\\n return guardians[guardian];\\n }\\n\\n // private functions\\n\\n function _addGuardian(\\n address guardian\\n )\\n private\\n {\\n require(\\n guardian != address(0),\\n \\\"Guarded: cannot add 0x0 guardian\\\"\\n );\\n\\n require(\\n !guardians[guardian],\\n \\\"Guarded: guardian already exists\\\"\\n );\\n\\n guardians[guardian] = true;\\n\\n emit GuardianAdded(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin,\\n guardian\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4a5f5670041362e87ea267d81c55fc3edc1a78e81f6f17524b13267f91f31458\",\"license\":\"MIT\"},\"src/common/account/Account.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../access/Controlled.sol\\\";\\nimport \\\"./AccountBase.sol\\\";\\n\\n\\n/**\\n * @title Account\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Account is Controlled, AccountBase {\\n address public implementation;\\n\\n /**\\n * @dev Public constructor\\n * @param registry_ account registry address\\n * @param implementation_ account implementation address\\n */\\n constructor(\\n address registry_,\\n address implementation_\\n )\\n public\\n Controlled()\\n {\\n registry = registry_;\\n implementation = implementation_;\\n }\\n\\n // external functions\\n\\n /**\\n * @notice Payable receive\\n */\\n receive()\\n external\\n payable\\n {\\n //\\n }\\n\\n /**\\n * @notice Fallback\\n */\\n // solhint-disable-next-line payable-fallback\\n fallback()\\n external\\n {\\n if (msg.data.length != 0) {\\n address implementation_ = implementation;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let calldedatasize := calldatasize()\\n\\n calldatacopy(0, 0, calldedatasize)\\n\\n let result := delegatecall(gas(), implementation_, 0, calldedatasize, 0, 0)\\n let returneddatasize := returndatasize()\\n\\n returndatacopy(0, 0, returneddatasize)\\n\\n switch result\\n case 0 { revert(0, returneddatasize) }\\n default { return(0, returneddatasize) }\\n }\\n }\\n }\\n\\n /**\\n * @notice Sets implementation\\n * @param implementation_ implementation address\\n */\\n function setImplementation(\\n address implementation_\\n )\\n external\\n onlyController\\n {\\n implementation = implementation_;\\n }\\n\\n /**\\n * @notice Executes transaction\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @return transaction result\\n */\\n function executeTransaction(\\n address to,\\n uint256 value,\\n bytes calldata data\\n )\\n external\\n onlyController\\n returns (bytes memory)\\n {\\n bytes memory result;\\n bool succeeded;\\n\\n // solhint-disable-next-line avoid-call-value, avoid-low-level-calls\\n (succeeded, result) = payable(to).call{value: value}(data);\\n\\n require(\\n succeeded,\\n \\\"Account: transaction reverted\\\"\\n );\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe516c999a02a65ee99487d398d0c12589500680a9ca08c852540fb9473d70a26\",\"license\":\"MIT\"},\"src/common/account/AccountBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Account base\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract AccountBase {\\n address public registry;\\n}\\n\",\"keccak256\":\"0xcadf29e389f8db823e14f3f92808fd135f07b0135eb4dcf29b89c85941b39862\",\"license\":\"MIT\"},\"src/common/account/AccountController.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./Account.sol\\\";\\n\\n\\n/**\\n * @title Account controller\\n *\\n * @dev Contract module which provides Account deployment mechanism\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract AccountController {\\n address public accountRegistry;\\n address public accountImplementation;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the account registry is updated\\n * @param accountRegistry account registry address\\n */\\n event AccountRegistryUpdated(\\n address accountRegistry\\n );\\n\\n /**\\n * @dev Emitted when the account implementation is updated\\n * @param accountImplementation account implementation address\\n */\\n event AccountImplementationUpdated(\\n address accountImplementation\\n );\\n\\n /**\\n * @dev Emitted when the account is deployed\\n * @param account account address\\n * @param accountImplementation account implementation address\\n */\\n event AccountDeployed(\\n address account,\\n address accountImplementation\\n );\\n\\n /**\\n * @dev Emitted when the account is upgraded\\n * @param account account address\\n * @param accountImplementation account implementation address\\n */\\n event AccountUpgraded(\\n address account,\\n address accountImplementation\\n );\\n\\n /**\\n * @dev Emitted when the transaction is executed\\n * @param account account address\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @param response response\\n */\\n event AccountTransactionExecuted(\\n address account,\\n address to,\\n uint256 value,\\n bytes data,\\n bytes response\\n );\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor() internal {}\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `AccountController` contract\\n * @param accountRegistry_ account registry address\\n * @param accountImplementation_ account implementation address\\n */\\n function _initializeAccountController(\\n address accountRegistry_,\\n address accountImplementation_\\n )\\n internal\\n {\\n _setAccountRegistry(accountRegistry_, false);\\n _setAccountImplementation(accountImplementation_, false);\\n }\\n\\n /**\\n * @notice Sets account registry\\n * @param accountRegistry_ account registry address\\n * @param emitEvent it will emit event when flag is set to true\\n */\\n function _setAccountRegistry(\\n address accountRegistry_,\\n bool emitEvent\\n )\\n internal\\n {\\n require(\\n accountRegistry_ != address(0),\\n \\\"AccountController: cannot set account registry to 0x0\\\"\\n );\\n\\n accountRegistry = accountRegistry_;\\n\\n if (emitEvent) {\\n emit AccountRegistryUpdated(accountRegistry);\\n }\\n }\\n\\n /**\\n * @notice Sets account implementation\\n * @param accountImplementation_ account implementation address\\n * @param emitEvent it will emit event when flag is set to true\\n */\\n function _setAccountImplementation(\\n address accountImplementation_,\\n bool emitEvent\\n )\\n internal\\n {\\n require(\\n accountImplementation_ != address(0),\\n \\\"AccountController: cannot set account Implementation to 0x0\\\"\\n );\\n\\n accountImplementation = accountImplementation_;\\n\\n if (emitEvent) {\\n emit AccountImplementationUpdated(accountImplementation);\\n }\\n }\\n\\n /**\\n * @notice Deploys account\\n * @param salt CREATE2 salt\\n * @param emitEvent it will emit event when flag is set to true\\n * @return account address\\n */\\n function _deployAccount(\\n bytes32 salt,\\n bool emitEvent\\n )\\n internal\\n returns (address)\\n {\\n address account = address(new Account{salt: salt}(\\n accountRegistry,\\n accountImplementation\\n ));\\n\\n if (emitEvent) {\\n emit AccountDeployed(\\n account,\\n accountImplementation\\n );\\n }\\n\\n return account;\\n }\\n\\n /**\\n * @notice Upgrades account\\n * @param account account address\\n * @param emitEvent it will emit event when flag is set to true\\n */\\n function _upgradeAccount(\\n address account,\\n bool emitEvent\\n )\\n internal\\n {\\n require(\\n Account(payable(account)).implementation() != accountImplementation,\\n \\\"AccountController: account already upgraded\\\"\\n );\\n\\n Account(payable(account)).setImplementation(accountImplementation);\\n\\n if (emitEvent) {\\n emit AccountUpgraded(\\n account,\\n accountImplementation\\n );\\n }\\n }\\n\\n /**\\n * @notice Executes transaction from the account\\n * @param account account address\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @param emitEvent it will emit event when flag is set to true\\n * @return transaction result\\n */\\n function _executeAccountTransaction(\\n address account,\\n address to,\\n uint256 value,\\n bytes memory data,\\n bool emitEvent\\n )\\n internal\\n returns (bytes memory)\\n {\\n require(\\n to != address(0),\\n \\\"AccountController: cannot send to 0x0\\\"\\n );\\n\\n require(\\n to != address(this),\\n \\\"AccountController: cannot send to controller\\\"\\n );\\n\\n require(\\n to != account,\\n \\\"AccountController: cannot send to self\\\"\\n );\\n\\n bytes memory response = Account(payable(account)).executeTransaction(\\n to,\\n value,\\n data\\n );\\n\\n if (emitEvent) {\\n emit AccountTransactionExecuted(\\n account,\\n to,\\n value,\\n data,\\n response\\n );\\n }\\n\\n return response;\\n }\\n\\n // internal functions (views)\\n\\n /**\\n * @notice Computes account CREATE2 address\\n * @param salt CREATE2 salt\\n * @return account address\\n */\\n function _computeAccountAddress(\\n bytes32 salt\\n )\\n internal\\n view\\n returns (address)\\n {\\n bytes memory creationCode = abi.encodePacked(\\n type(Account).creationCode,\\n bytes12(0),\\n accountRegistry,\\n bytes12(0),\\n accountImplementation\\n );\\n\\n bytes32 data = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n salt,\\n keccak256(creationCode)\\n )\\n );\\n\\n return address(uint160(uint256(data)));\\n }\\n}\\n\",\"keccak256\":\"0xe161f1f4f6ea5d3a9810f7c93764d55e473abe1054e6aa68fde791be7d70a26c\",\"license\":\"MIT\"},\"src/common/account/AccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./Account.sol\\\";\\n\\n\\n/**\\n * @title Account registry\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nabstract contract AccountRegistry {\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param messageHash message hash\\n * @param signature signature\\n * @return true if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n virtual\\n external\\n view\\n returns (bool);\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param message message\\n * @param signature signature\\n * @return true if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes calldata message,\\n bytes calldata signature\\n )\\n virtual\\n external\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0x2d40245721f5f74219e5cf88713246dbe8b6d5404e941125d3e850b1f127ec34\",\"license\":\"MIT\"},\"src/common/libs/BlockLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Block library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nlibrary BlockLib {\\n struct BlockRelated {\\n bool added;\\n uint256 removedAtBlockNumber;\\n }\\n\\n /**\\n * @notice Verifies self struct at current block\\n * @param self self struct\\n * @return true on correct self struct\\n */\\n function verifyAtCurrentBlock(\\n BlockRelated memory self\\n )\\n internal\\n view\\n returns (bool)\\n {\\n return verifyAtBlock(self, block.number);\\n }\\n\\n /**\\n * @notice Verifies self struct at any block\\n * @param self self struct\\n * @return true on correct self struct\\n */\\n function verifyAtAnyBlock(\\n BlockRelated memory self\\n )\\n internal\\n pure\\n returns (bool)\\n {\\n return verifyAtBlock(self, 0);\\n }\\n\\n /**\\n * @notice Verifies self struct at specific block\\n * @param self self struct\\n * @param blockNumber block number to verify\\n * @return true on correct self struct\\n */\\n function verifyAtBlock(\\n BlockRelated memory self,\\n uint256 blockNumber\\n )\\n internal\\n pure\\n returns (bool)\\n {\\n bool result = false;\\n\\n if (self.added) {\\n if (self.removedAtBlockNumber == 0) {\\n result = true;\\n } else if (blockNumber == 0) {\\n result = true;\\n } else {\\n result = self.removedAtBlockNumber > blockNumber;\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9205536bc211f86d1113118a44dddfa7a9b9772a918cf4b1575c982a05472587\",\"license\":\"MIT\"},\"src/common/libs/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Bytes library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nlibrary BytesLib {\\n /**\\n * @notice Converts bytes to address\\n * @param data data\\n * @return address\\n */\\n function toAddress(\\n bytes memory data\\n )\\n internal\\n pure\\n returns (address)\\n {\\n address result;\\n\\n require(\\n data.length == 20,\\n \\\"BytesLib: invalid data length\\\"\\n );\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := div(mload(add(data, 0x20)), 0x1000000000000000000000000)\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x64c84964ea91bfb1f2d859eea6c57fe5b4a6f269951a4adf5f58d306c54c7f76\",\"license\":\"MIT\"},\"src/common/libs/ECDSAExtendedLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./StringsLib.sol\\\";\\n\\n\\n/**\\n * @title ECDSA extended library\\n */\\nlibrary ECDSAExtendedLib {\\n using StringsLib for uint;\\n\\n function toEthereumSignedMessageHash(\\n bytes memory message\\n )\\n internal\\n pure\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n\\\",\\n message.length.toString(),\\n abi.encodePacked(message)\\n ));\\n }\\n}\\n\",\"keccak256\":\"0x83e6056caaba892d91de45324f4d2702ac01695fab2d34c86895d7d288547ba3\",\"license\":\"MIT\"},\"src/common/libs/ECDSALib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ECDSA library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/cryptography/ECDSA.sol#L26\\n */\\nlibrary ECDSALib {\\n function recoverAddress(\\n bytes32 messageHash,\\n bytes memory signature\\n )\\n internal\\n pure\\n returns (address)\\n {\\n address result = address(0);\\n\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n\\n if (v < 27) {\\n v += 27;\\n }\\n\\n if (v == 27 || v == 28) {\\n result = ecrecover(messageHash, v, r, s);\\n }\\n }\\n\\n return result;\\n }\\n\\n function toEthereumSignedMessageHash(\\n bytes32 messageHash\\n )\\n internal\\n pure\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n messageHash\\n ));\\n }\\n}\\n\",\"keccak256\":\"0x3b1460d688302eb595268c2af147ab532f29dbced66520e013f48d498eed3cec\",\"license\":\"MIT\"},\"src/common/libs/SafeMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Safe math library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol\\n */\\nlibrary SafeMathLib {\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n\\n require(c >= a, \\\"SafeMathLib: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMathLib: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n\\n return a - b;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n\\n require(c / a == b, \\\"SafeMathLib: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMathLib: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n\\n return a / b;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMathLib: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x6089f354ca754d9c5dd9e800ee5ed86717dbf8f9af470604e0be691ac57c0107\",\"license\":\"MIT\"},\"src/common/libs/StringsLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Strings library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/utils/Strings.sol#L12\\n */\\nlibrary StringsLib {\\n function toString(\\n uint256 value\\n )\\n internal\\n pure\\n returns (string memory)\\n {\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n\\n uint256 temp = value;\\n uint256 digits;\\n\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n\\n bytes memory buffer = new bytes(digits);\\n uint256 index = digits - 1;\\n temp = value;\\n\\n while (temp != 0) {\\n buffer[index--] = byte(uint8(48 + temp % 10));\\n temp /= 10;\\n }\\n\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x4110150d0c921fd31db34ca33672de8e81c3ae467076149a3a546f804d1f58dd\",\"license\":\"MIT\"},\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Initializable {\\n address private initializer;\\n\\n // events\\n\\n /**\\n * @dev Emitted after `onlyInitializer`\\n * @param initializer initializer address\\n */\\n event Initialized(\\n address initializer\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not the initializer\\n */\\n modifier onlyInitializer() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin == initializer,\\n \\\"Initializable: tx.origin is not the initializer\\\"\\n );\\n\\n /// @dev removes initializer\\n initializer = address(0);\\n\\n _;\\n\\n emit Initialized(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin\\n );\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n initializer = tx.origin;\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if contract is initialized\\n * @return true when contract is initialized\\n */\\n function isInitialized()\\n external\\n view\\n returns (bool)\\n {\\n return initializer == address(0);\\n }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/common/signature/SignatureValidator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n/**\\n * @title Signature validator\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract SignatureValidator {\\n using ECDSALib for bytes32;\\n\\n uint256 public chainId;\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {\\n uint256 chainId_;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n chainId_ := chainid()\\n }\\n\\n chainId = chainId_;\\n }\\n\\n // internal functions\\n\\n function _hashMessagePayload(\\n bytes32 messagePrefix,\\n bytes memory messagePayload\\n )\\n internal\\n view\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n chainId,\\n address(this),\\n messagePrefix,\\n messagePayload\\n )).toEthereumSignedMessageHash();\\n }\\n}\\n\",\"keccak256\":\"0xc1168f7ccb74aea67089941dc5e4c1d1c4aa766afca47a90c0b017b8445b8acf\",\"license\":\"MIT\"},\"src/common/token/ERC20Token.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/SafeMathLib.sol\\\";\\n\\n\\n/**\\n * @title ERC20 token\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol\\n */\\ncontract ERC20Token {\\n using SafeMathLib for uint256;\\n\\n string public name;\\n string public symbol;\\n uint8 public decimals;\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) internal balances;\\n mapping(address => mapping(address => uint256)) internal allowances;\\n\\n // events\\n\\n event Transfer(\\n address indexed from,\\n address indexed to,\\n uint256 value\\n );\\n\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // external functions\\n\\n function transfer(\\n address to,\\n uint256 value\\n )\\n external\\n returns (bool)\\n {\\n _transfer(_getSender(), to, value);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n address sender = _getSender();\\n\\n _transfer(from, to, value);\\n _approve(from, sender, allowances[from][sender].sub(value));\\n\\n return true;\\n }\\n\\n function approve(\\n address spender,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n _approve(_getSender(), spender, value);\\n\\n return true;\\n }\\n\\n // external functions (views)\\n\\n function balanceOf(\\n address owner\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return balances[owner];\\n }\\n\\n function allowance(\\n address owner,\\n address spender\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return allowances[owner][spender];\\n }\\n\\n // internal functions\\n\\n function _transfer(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n from != address(0),\\n \\\"ERC20Token: cannot transfer from 0x0 address\\\"\\n );\\n require(\\n to != address(0),\\n \\\"ERC20Token: cannot transfer to 0x0 address\\\"\\n );\\n\\n balances[from] = balances[from].sub(value);\\n balances[to] = balances[to].add(value);\\n\\n emit Transfer(from, to, value);\\n }\\n\\n function _approve(\\n address owner,\\n address spender,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot approve from 0x0 address\\\"\\n );\\n require(\\n spender != address(0),\\n \\\"ERC20Token: cannot approve to 0x0 address\\\"\\n );\\n\\n allowances[owner][spender] = value;\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function _mint(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot mint to 0x0 address\\\"\\n );\\n require(\\n value > 0,\\n \\\"ERC20Token: cannot mint 0 value\\\"\\n );\\n\\n balances[owner] = balances[owner].add(value);\\n totalSupply = totalSupply.add(value);\\n\\n emit Transfer(address(0), owner, value);\\n }\\n\\n function _burn(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot burn from 0x0 address\\\"\\n );\\n\\n balances[owner] = balances[owner].sub(\\n value,\\n \\\"ERC20Token: burn value exceeds balance\\\"\\n );\\n\\n totalSupply = totalSupply.sub(value);\\n\\n emit Transfer(owner, address(0), value);\\n }\\n\\n // internal functions (views)\\n\\n function _getSender()\\n virtual\\n internal\\n view\\n returns (address)\\n {\\n return msg.sender;\\n }\\n}\\n\",\"keccak256\":\"0x6f2b0bd08da549c6c1f5ceee85766832d587dde62c56bebc3a14bd9ea407e03d\",\"license\":\"MIT\"},\"src/external/ExternalAccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BlockLib.sol\\\";\\n\\n\\n/**\\n * @title External account registry\\n *\\n * @notice Global registry for keys and external (outside of the platform) contract based wallets\\n *\\n * @dev An account can call the registry to add (`addAccountOwner`) or remove (`removeAccountOwner`) its own owners.\\n * When the owner has been added, information about that fact will live in the registry forever.\\n * Removing an owner only affects the future blocks (until the owner is re-added).\\n *\\n * Given the fact, there is no way to sign the data using a contract based wallet,\\n * we created a registry to store signed by the key wallet proofs.\\n * ERC-1271 allows removing a signer after the signature was created. Thus store the signature for the later use\\n * doesn't guarantee the signer is still has access to that smart account.\\n * Because of that, the ERC1271's `isValidSignature()` cannot be used in e.g. `PaymentRegistry`.*\\n *\\n * An account can call the registry to add (`addAccountProof`) or remove (`removeAccountProof`) proof hash.\\n * When the proof has been added, information about that fact will live in the registry forever.\\n * Removing a proof only affects the future blocks (until the proof is re-added).\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract ExternalAccountRegistry {\\n using BlockLib for BlockLib.BlockRelated;\\n\\n struct Account {\\n mapping(address => BlockLib.BlockRelated) owners;\\n mapping(bytes32 => BlockLib.BlockRelated) proofs;\\n }\\n\\n mapping(address => Account) private accounts;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the new owner is added\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerAdded(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the existing owner is removed\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerRemoved(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the new proof is added\\n * @param account account address\\n * @param hash proof hash\\n */\\n event AccountProofAdded(\\n address account,\\n bytes32 hash\\n );\\n\\n /**\\n * @dev Emitted when the existing proof is removed\\n * @param account account address\\n * @param hash proof hash\\n */\\n event AccountProofRemoved(\\n address account,\\n bytes32 hash\\n );\\n\\n // external functions\\n\\n /**\\n * @notice Adds a new account owner\\n * @param owner owner address\\n */\\n function addAccountOwner(\\n address owner\\n )\\n external\\n {\\n require(\\n owner != address(0),\\n \\\"ExternalAccountRegistry: cannot add 0x0 owner\\\"\\n );\\n\\n require(\\n !accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: owner already exists\\\"\\n );\\n\\n accounts[msg.sender].owners[owner].added = true;\\n accounts[msg.sender].owners[owner].removedAtBlockNumber = 0;\\n\\n emit AccountOwnerAdded(\\n msg.sender,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Removes existing account owner\\n * @param owner owner address\\n */\\n function removeAccountOwner(\\n address owner\\n )\\n external\\n {\\n require(\\n accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: owner doesn't exist\\\"\\n );\\n\\n accounts[msg.sender].owners[owner].removedAtBlockNumber = block.number;\\n\\n emit AccountOwnerRemoved(\\n msg.sender,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Adds a new account proof\\n * @param hash proof hash\\n */\\n function addAccountProof(\\n bytes32 hash\\n )\\n external\\n {\\n require(\\n !accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: proof already exists\\\"\\n );\\n\\n accounts[msg.sender].proofs[hash].added = true;\\n accounts[msg.sender].proofs[hash].removedAtBlockNumber = 0;\\n\\n emit AccountProofAdded(\\n msg.sender,\\n hash\\n );\\n }\\n\\n /**\\n * @notice Removes existing account proof\\n * @param hash proof hash\\n */\\n function removeAccountProof(\\n bytes32 hash\\n )\\n external\\n {\\n require(\\n accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: proof doesn't exist\\\"\\n );\\n\\n accounts[msg.sender].proofs[hash].removedAtBlockNumber = block.number;\\n\\n emit AccountProofRemoved(\\n msg.sender,\\n hash\\n );\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Verifies the owner of the account at current block\\n * @param account account address\\n * @param owner owner address\\n * @return true on correct account owner\\n */\\n function verifyAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].owners[owner].verifyAtCurrentBlock();\\n }\\n\\n /**\\n * @notice Verifies the owner of the account at specific block\\n * @param account account address\\n * @param owner owner address\\n * @param blockNumber block number to verify\\n * @return true on correct account owner\\n */\\n function verifyAccountOwnerAtBlock(\\n address account,\\n address owner,\\n uint256 blockNumber\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].owners[owner].verifyAtBlock(blockNumber);\\n }\\n\\n /**\\n * @notice Verifies the proof of the account at current block\\n * @param account account address\\n * @param hash proof hash\\n * @return true on correct account proof\\n */\\n function verifyAccountProof(\\n address account,\\n bytes32 hash\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].proofs[hash].verifyAtCurrentBlock();\\n }\\n\\n /**\\n * @notice Verifies the proof of the account at specific block\\n * @param account account address\\n * @param hash proof hash\\n * @param blockNumber block number to verify\\n * @return true on correct account proof\\n */\\n function verifyAccountProofAtBlock(\\n address account,\\n bytes32 hash,\\n uint256 blockNumber\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].proofs[hash].verifyAtBlock(blockNumber);\\n }\\n}\\n\",\"keccak256\":\"0x8067b1fae41b73949f8d871a835533cbdd94b9ca3faa93b91f595c37e632ccdb\",\"license\":\"MIT\"},\"src/gateway/Gateway.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../common/libs/ECDSALib.sol\\\";\\nimport \\\"../common/libs/SafeMathLib.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/signature/SignatureValidator.sol\\\";\\nimport \\\"../external/ExternalAccountRegistry.sol\\\";\\nimport \\\"../personal/PersonalAccountRegistry.sol\\\";\\n\\n\\n/**\\n * @title Gateway\\n *\\n * @notice GSN replacement\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Gateway is Initializable, SignatureValidator {\\n using ECDSALib for bytes32;\\n using SafeMathLib for uint256;\\n\\n struct DelegatedBatch {\\n address account;\\n uint256 nonce;\\n address[] to;\\n bytes[] data;\\n }\\n\\n struct DelegatedBatchWithGasPrice {\\n address account;\\n uint256 nonce;\\n address[] to;\\n bytes[] data;\\n uint256 gasPrice;\\n }\\n\\n bytes32 private constant HASH_PREFIX_DELEGATED_BATCH = keccak256(\\n \\\"DelegatedBatch(address account,uint256 nonce,address[] to,bytes[] data)\\\"\\n );\\n\\n bytes32 private constant HASH_PREFIX_DELEGATED_BATCH_WITH_GAS_PRICE = keccak256(\\n \\\"DelegatedBatchWithGasPrice(address account,uint256 nonce,address[] to,bytes[] data,uint256 gasPrice)\\\"\\n );\\n\\n ExternalAccountRegistry public externalAccountRegistry;\\n PersonalAccountRegistry public personalAccountRegistry;\\n\\n mapping(address => uint256) private accountNonce;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the single batch is delegated\\n * @param sender sender address\\n * @param batch batch\\n * @param succeeded if succeeded\\n */\\n event BatchDelegated(\\n address sender,\\n bytes batch,\\n bool succeeded\\n );\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor() public Initializable() SignatureValidator() {}\\n\\n // external functions\\n\\n /**\\n * @notice Initializes `Gateway` contract\\n * @param externalAccountRegistry_ `ExternalAccountRegistry` contract address\\n * @param personalAccountRegistry_ `PersonalAccountRegistry` contract address\\n */\\n function initialize(\\n ExternalAccountRegistry externalAccountRegistry_,\\n PersonalAccountRegistry personalAccountRegistry_\\n )\\n external\\n onlyInitializer\\n {\\n externalAccountRegistry = externalAccountRegistry_;\\n personalAccountRegistry = personalAccountRegistry_;\\n }\\n\\n // public functions\\n\\n /**\\n * @notice Sends batch\\n * @dev `GatewayRecipient` context api:\\n * `_getContextAccount` will return `msg.sender`\\n * `_getContextSender` will return `msg.sender`\\n *\\n * @param to array of batch recipients contracts\\n * @param data array of batch data\\n */\\n function sendBatch(\\n address[] memory to,\\n bytes[] memory data\\n )\\n public\\n {\\n _sendBatch(\\n msg.sender,\\n msg.sender,\\n to,\\n data\\n );\\n }\\n\\n /**\\n * @notice Sends batch from the account\\n * @dev `GatewayRecipient` context api:\\n * `_getContextAccount` will return `account` arg\\n * `_getContextSender` will return `msg.sender`\\n *\\n * @param account account address\\n * @param to array of batch recipients contracts\\n * @param data array of batch data\\n */\\n function sendBatchFromAccount(\\n address account,\\n address[] memory to,\\n bytes[] memory data\\n )\\n public\\n {\\n _sendBatch(\\n account,\\n msg.sender,\\n to,\\n data\\n );\\n }\\n\\n /**\\n * @notice Delegates batch from the account\\n * @dev Use `hashDelegatedBatch` to create sender message payload.\\n *\\n * `GatewayRecipient` context api:\\n * `_getContextAccount` will return `account` arg\\n * `_getContextSender` will return recovered address from `senderSignature` arg\\n *\\n * @param account account address\\n * @param nonce next account nonce\\n * @param to array of batch recipients contracts\\n * @param data array of batch data\\n * @param senderSignature sender signature\\n */\\n function delegateBatch(\\n address account,\\n uint256 nonce,\\n address[] memory to,\\n bytes[] memory data,\\n bytes memory senderSignature\\n )\\n public\\n {\\n require(\\n nonce > accountNonce[account],\\n \\\"Gateway: nonce is lower than current account nonce\\\"\\n );\\n\\n address sender = _hashDelegatedBatch(\\n account,\\n nonce,\\n to,\\n data\\n ).recoverAddress(senderSignature);\\n\\n accountNonce[account] = nonce;\\n\\n _sendBatch(\\n account,\\n sender,\\n to,\\n data\\n );\\n }\\n\\n /**\\n * @notice Delegates batch from the account (with gas price)\\n *\\n * @dev Use `hashDelegatedBatchWithGasPrice` to create sender message payload (tx.gasprice as gasPrice)\\n *\\n * `GatewayRecipient` context api:\\n * `_getContextAccount` will return `account` arg\\n * `_getContextSender` will return recovered address from `senderSignature` arg\\n *\\n * @param account account address\\n * @param nonce next account nonce\\n * @param to array of batch recipients contracts\\n * @param data array of batch data\\n * @param senderSignature sender signature\\n */\\n function delegateBatchWithGasPrice(\\n address account,\\n uint256 nonce,\\n address[] memory to,\\n bytes[] memory data,\\n bytes memory senderSignature\\n )\\n public\\n {\\n require(\\n nonce > accountNonce[account],\\n \\\"Gateway: nonce is lower than current account nonce\\\"\\n );\\n\\n address sender = _hashDelegatedBatchWithGasPrice(\\n account,\\n nonce,\\n to,\\n data,\\n tx.gasprice\\n ).recoverAddress(senderSignature);\\n\\n accountNonce[account] = nonce;\\n\\n _sendBatch(\\n account,\\n sender,\\n to,\\n data\\n );\\n }\\n\\n /**\\n * @notice Delegates multiple batches\\n * @dev It will revert when all batches fail\\n * @param batches array of batches\\n * @param revertOnFailure reverts on any error\\n */\\n function delegateBatches(\\n bytes[] memory batches,\\n bool revertOnFailure\\n )\\n public\\n {\\n require(\\n batches.length > 0,\\n \\\"Gateway: cannot delegate empty batches\\\"\\n );\\n\\n bool anySucceeded;\\n\\n for (uint256 i = 0; i < batches.length; i++) {\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool succeeded,) = address(this).call(batches[i]);\\n\\n if (revertOnFailure) {\\n require(\\n succeeded,\\n \\\"Gateway: batch reverted\\\"\\n );\\n } else if (succeeded && !anySucceeded) {\\n anySucceeded = true;\\n }\\n\\n emit BatchDelegated(\\n msg.sender,\\n batches[i],\\n succeeded\\n );\\n }\\n\\n if (!anySucceeded) {\\n revert(\\\"Gateway: all batches reverted\\\");\\n }\\n }\\n\\n // public functions (views)\\n\\n /**\\n * @notice Hashes `DelegatedBatch` message payload\\n * @param delegatedBatch struct\\n * @return hash\\n */\\n function hashDelegatedBatch(\\n DelegatedBatch memory delegatedBatch\\n )\\n public\\n view\\n returns (bytes32)\\n {\\n return _hashDelegatedBatch(\\n delegatedBatch.account,\\n delegatedBatch.nonce,\\n delegatedBatch.to,\\n delegatedBatch.data\\n );\\n }\\n\\n /**\\n * @notice Hashes `DelegatedBatchWithGasPrice` message payload\\n * @param delegatedBatch struct\\n * @return hash\\n */\\n function hashDelegatedBatchWithGasPrice(\\n DelegatedBatchWithGasPrice memory delegatedBatch\\n )\\n public\\n view\\n returns (bytes32)\\n {\\n return _hashDelegatedBatchWithGasPrice(\\n delegatedBatch.account,\\n delegatedBatch.nonce,\\n delegatedBatch.to,\\n delegatedBatch.data,\\n delegatedBatch.gasPrice\\n );\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Gets next account nonce\\n * @param account account address\\n * @return next nonce\\n */\\n function getAccountNextNonce(\\n address account\\n )\\n external\\n view\\n returns (uint256)\\n {\\n return accountNonce[account].add(1);\\n }\\n\\n // private functions\\n\\n function _sendBatch(\\n address account,\\n address sender,\\n address[] memory to,\\n bytes[] memory data\\n )\\n private\\n {\\n require(\\n account != address(0),\\n \\\"Gateway: cannot send from 0x0 account\\\"\\n );\\n require(\\n to.length > 0,\\n \\\"Gateway: cannot send empty batch\\\"\\n );\\n require(\\n data.length == to.length,\\n \\\"Gateway: invalid batch\\\"\\n );\\n\\n if (account != sender) {\\n require(\\n personalAccountRegistry.verifyAccountOwner(account, sender) ||\\n externalAccountRegistry.verifyAccountOwner(account, sender),\\n \\\"Gateway: sender is not the account owner\\\"\\n );\\n }\\n\\n bool succeeded;\\n\\n for (uint256 i = 0; i < data.length; i++) {\\n require(\\n to[i] != address(0),\\n \\\"Gateway: cannot send to 0x0\\\"\\n );\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (succeeded,) = to[i].call(abi.encodePacked(data[i], account, sender));\\n\\n require(\\n succeeded,\\n \\\"Gateway: batch transaction reverted\\\"\\n );\\n }\\n }\\n\\n // private functions (views)\\n\\n function _hashDelegatedBatch(\\n address account,\\n uint256 nonce,\\n address[] memory to,\\n bytes[] memory data\\n )\\n private\\n view\\n returns (bytes32)\\n {\\n return _hashMessagePayload(HASH_PREFIX_DELEGATED_BATCH, abi.encodePacked(\\n account,\\n nonce,\\n to,\\n _concatBytes(data)\\n ));\\n }\\n\\n function _hashDelegatedBatchWithGasPrice(\\n address account,\\n uint256 nonce,\\n address[] memory to,\\n bytes[] memory data,\\n uint256 gasPrice\\n )\\n private\\n view\\n returns (bytes32)\\n {\\n return _hashMessagePayload(HASH_PREFIX_DELEGATED_BATCH_WITH_GAS_PRICE, abi.encodePacked(\\n account,\\n nonce,\\n to,\\n _concatBytes(data),\\n gasPrice\\n ));\\n }\\n\\n// private functions (pure)\\n\\n function _concatBytes(bytes[] memory data)\\n private\\n pure\\n returns (bytes memory)\\n {\\n bytes memory result;\\n uint dataLen = data.length;\\n\\n for (uint i = 0 ; i < dataLen ; i++) {\\n result = abi.encodePacked(result, data[i]);\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x666f10ebf96aef0a37607852871a6e1d816a271558b1dce43dda74fc73274ae4\",\"license\":\"MIT\"},\"src/gateway/GatewayRecipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BytesLib.sol\\\";\\n\\n\\n/**\\n * @title Gateway recipient\\n *\\n * @notice Gateway target contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract GatewayRecipient {\\n using BytesLib for bytes;\\n\\n address public gateway;\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `GatewayRecipient` contract\\n * @param gateway_ `Gateway` contract address\\n */\\n function _initializeGatewayRecipient(\\n address gateway_\\n )\\n internal\\n {\\n gateway = gateway_;\\n }\\n\\n // internal functions (views)\\n\\n /**\\n * @notice Gets gateway context account\\n * @return context account address\\n */\\n function _getContextAccount()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(40);\\n }\\n\\n /**\\n * @notice Gets gateway context sender\\n * @return context sender address\\n */\\n function _getContextSender()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(20);\\n }\\n\\n /**\\n * @notice Gets gateway context data\\n * @return context data\\n */\\n function _getContextData()\\n internal\\n view\\n returns (bytes calldata)\\n {\\n bytes calldata result;\\n\\n if (_isGatewaySender()) {\\n result = msg.data[:msg.data.length - 40];\\n } else {\\n result = msg.data;\\n }\\n\\n return result;\\n }\\n\\n // private functions (views)\\n\\n function _getContextAddress(\\n uint256 offset\\n )\\n private\\n view\\n returns (address)\\n {\\n address result = address(0);\\n\\n if (_isGatewaySender()) {\\n uint from = msg.data.length - offset;\\n result = bytes(msg.data[from:from + 20]).toAddress();\\n } else {\\n result = msg.sender;\\n }\\n\\n return result;\\n }\\n\\n function _isGatewaySender()\\n private\\n view\\n returns (bool)\\n {\\n bool result;\\n\\n if (msg.sender == gateway) {\\n require(\\n msg.data.length >= 44,\\n \\\"GatewayRecipient: invalid msg.data\\\"\\n );\\n\\n result = true;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe3fd29479d748d67360c61a9cbaafc66eaca25f476e59a45e842472bcf5233fc\",\"license\":\"MIT\"},\"src/personal/PersonalAccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/access/Guarded.sol\\\";\\nimport \\\"../common/account/AccountController.sol\\\";\\nimport \\\"../common/account/AccountRegistry.sol\\\";\\nimport \\\"../common/libs/BlockLib.sol\\\";\\nimport \\\"../common/libs/ECDSALib.sol\\\";\\nimport \\\"../common/libs/ECDSAExtendedLib.sol\\\";\\nimport \\\"../common/libs/SafeMathLib.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/token/ERC20Token.sol\\\";\\nimport \\\"../gateway/GatewayRecipient.sol\\\";\\n\\n\\n/**\\n * @title Personal account registry\\n *\\n * @notice A registry for personal (controlled by owners) accounts\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract PersonalAccountRegistry is Guarded, AccountController, AccountRegistry, Initializable, GatewayRecipient {\\n using BlockLib for BlockLib.BlockRelated;\\n using SafeMathLib for uint256;\\n using ECDSALib for bytes32;\\n using ECDSAExtendedLib for bytes;\\n\\n struct Account {\\n bool deployed;\\n bytes32 salt;\\n mapping(address => BlockLib.BlockRelated) owners;\\n }\\n\\n mapping(address => Account) private accounts;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the new owner is added\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerAdded(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the existing owner is removed\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerRemoved(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the call is refunded\\n * @param account account address\\n * @param beneficiary beneficiary address\\n * @param token token address\\n * @param value value\\n */\\n event AccountCallRefunded(\\n address account,\\n address beneficiary,\\n address token,\\n uint256 value\\n );\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor() public Initializable() {}\\n\\n // external functions\\n\\n /**\\n * @notice Initializes `PersonalAccountRegistry` contract\\n * @param guardians_ array of guardians addresses\\n * @param accountImplementation_ account implementation address\\n * @param gateway_ `Gateway` contract address\\n */\\n function initialize(\\n address[] calldata guardians_,\\n address accountImplementation_,\\n address gateway_\\n )\\n external\\n onlyInitializer\\n {\\n // Guarded\\n _initializeGuarded(guardians_);\\n\\n // AccountController\\n _initializeAccountController(address(this), accountImplementation_);\\n\\n // GatewayRecipient\\n _initializeGatewayRecipient(gateway_);\\n }\\n\\n /**\\n * @notice Upgrades `PersonalAccountRegistry` contract\\n * @param accountImplementation_ account implementation address\\n */\\n function upgrade(\\n address accountImplementation_\\n )\\n external\\n onlyGuardian\\n {\\n _setAccountImplementation(accountImplementation_, true);\\n }\\n\\n /**\\n * @notice Deploys account\\n * @param account account address\\n */\\n function deployAccount(\\n address account\\n )\\n external\\n {\\n _verifySender(account);\\n _deployAccount(account);\\n }\\n\\n /**\\n * @notice Upgrades account\\n * @param account account address\\n */\\n function upgradeAccount(\\n address account\\n )\\n external\\n {\\n _verifySender(account);\\n _upgradeAccount(account, true);\\n }\\n\\n /**\\n * @notice Adds a new account owner\\n * @param account account address\\n * @param owner owner address\\n */\\n function addAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n {\\n _verifySender(account);\\n\\n require(\\n owner != address(0),\\n \\\"PersonalAccountRegistry: cannot add 0x0 owner\\\"\\n );\\n\\n require(\\n !accounts[account].owners[owner].verifyAtCurrentBlock(),\\n \\\"PersonalAccountRegistry: owner already exists\\\"\\n );\\n\\n accounts[account].owners[owner].added = true;\\n accounts[account].owners[owner].removedAtBlockNumber = 0;\\n\\n emit AccountOwnerAdded(\\n account,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Removes the existing account owner\\n * @param account account address\\n * @param owner owner address\\n */\\n function removeAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n {\\n address sender = _verifySender(account);\\n\\n require(\\n owner != sender,\\n \\\"PersonalAccountRegistry: cannot remove self\\\"\\n );\\n\\n require(\\n accounts[account].owners[owner].verifyAtCurrentBlock(),\\n \\\"PersonalAccountRegistry: owner doesn't exist\\\"\\n );\\n\\n accounts[account].owners[owner].removedAtBlockNumber = block.number;\\n\\n emit AccountOwnerRemoved(\\n account,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Executes account transaction\\n * @dev Deploys an account if not deployed yet\\n * @param account account address\\n * @param to to address\\n * @param value value\\n * @param data data\\n */\\n function executeAccountTransaction(\\n address account,\\n address to,\\n uint256 value,\\n bytes calldata data\\n )\\n external\\n {\\n _verifySender(account);\\n\\n _deployAccount(account);\\n\\n _executeAccountTransaction(\\n account,\\n to,\\n value,\\n data,\\n true\\n );\\n }\\n\\n /**\\n * @notice Refunds account call\\n * @dev Deploys an account if not deployed yet\\n * @param account account address\\n * @param token token address\\n * @param value value\\n */\\n function refundAccountCall(\\n address account,\\n address token,\\n uint256 value\\n )\\n external\\n {\\n _verifySender(account);\\n\\n _deployAccount(account);\\n\\n /* solhint-disable avoid-tx-origin */\\n\\n if (token == address(0)) {\\n _executeAccountTransaction(\\n account,\\n tx.origin,\\n value,\\n new bytes(0),\\n false\\n );\\n } else {\\n bytes memory response = _executeAccountTransaction(\\n account,\\n token,\\n 0,\\n abi.encodeWithSelector(\\n ERC20Token(token).transfer.selector,\\n tx.origin,\\n value\\n ),\\n false\\n );\\n\\n if (response.length > 0) {\\n require(\\n abi.decode(response, (bool)),\\n \\\"PersonalAccountRegistry: ERC20Token transfer reverted\\\"\\n );\\n }\\n }\\n\\n emit AccountCallRefunded(\\n account,\\n tx.origin,\\n token,\\n value\\n );\\n\\n /* solhint-enable avoid-tx-origin */\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Computes account address\\n * @param saltOwner salt owner address\\n * @return account address\\n */\\n function computeAccountAddress(\\n address saltOwner\\n )\\n external\\n view\\n returns (address)\\n {\\n return _computeAccountAddress(saltOwner);\\n }\\n\\n /**\\n * @notice Checks if account is deployed\\n * @param account account address\\n * @return true when account is deployed\\n */\\n function isAccountDeployed(\\n address account\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].deployed;\\n }\\n\\n /**\\n * @notice Verifies the owner of the account at the current block\\n * @param account account address\\n * @param owner owner address\\n * @return true on correct account owner\\n */\\n function verifyAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n view\\n returns (bool)\\n {\\n return _verifyAccountOwner(account, owner);\\n }\\n\\n /**\\n * @notice Verifies the owner of the account at a specific block\\n * @param account account address\\n * @param owner owner address\\n * @param blockNumber block number to verify\\n * @return true on correct account owner\\n */\\n function verifyAccountOwnerAtBlock(\\n address account,\\n address owner,\\n uint256 blockNumber\\n )\\n external\\n view\\n returns (bool)\\n {\\n bool result = false;\\n\\n if (_verifyAccountOwner(account, owner)) {\\n result = true;\\n } else {\\n result = accounts[account].owners[owner].verifyAtBlock(blockNumber);\\n }\\n\\n return result;\\n }\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param messageHash message hash\\n * @param signature signature\\n * @return magic hash if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n override\\n external\\n view\\n returns (bool)\\n {\\n return _verifyAccountOwner(\\n account,\\n messageHash.recoverAddress(signature)\\n );\\n }\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param message message\\n * @param signature signature\\n * @return magic hash if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes calldata message,\\n bytes calldata signature\\n )\\n override\\n external\\n view\\n returns (bool)\\n {\\n return _verifyAccountOwner(\\n account,\\n message.toEthereumSignedMessageHash().recoverAddress(signature)\\n );\\n }\\n\\n // private functions\\n\\n function _verifySender(\\n address account\\n )\\n private\\n returns (address)\\n {\\n address sender = _getContextSender();\\n\\n if (accounts[account].owners[sender].added) {\\n require(\\n accounts[account].owners[sender].removedAtBlockNumber == 0,\\n \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n );\\n } else {\\n require(\\n accounts[account].salt == 0,\\n \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n );\\n\\n bytes32 salt = keccak256(\\n abi.encodePacked(sender)\\n );\\n\\n require(\\n account == _computeAccountAddress(salt),\\n \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n );\\n\\n accounts[account].salt = salt;\\n accounts[account].owners[sender].added = true;\\n\\n emit AccountOwnerAdded(\\n account,\\n sender\\n );\\n }\\n\\n return sender;\\n }\\n\\n function _deployAccount(\\n address account\\n )\\n internal\\n {\\n if (!accounts[account].deployed) {\\n _deployAccount(\\n accounts[account].salt,\\n true\\n );\\n\\n accounts[account].deployed = true;\\n }\\n }\\n\\n // private functions (views)\\n\\n function _computeAccountAddress(\\n address saltOwner\\n )\\n private\\n view\\n returns (address)\\n {\\n bytes32 salt = keccak256(\\n abi.encodePacked(saltOwner)\\n );\\n\\n return _computeAccountAddress(salt);\\n }\\n\\n function _verifyAccountOwner(\\n address account,\\n address owner\\n )\\n private\\n view\\n returns (bool)\\n {\\n bool result;\\n\\n if (accounts[account].owners[owner].added) {\\n result = accounts[account].owners[owner].removedAtBlockNumber == 0;\\n } else if (accounts[account].salt == 0) {\\n result = account == _computeAccountAddress(owner);\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xdae162610e707ab8c394b3edf924b75ef1f315520935cb88f4280b29eeaf4b61\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50326000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600046905080600181905550506123f58061006d6000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063867519c61161008c5780639f255626116100665780639f255626146101fe578063b5021b161461021a578063d2c83b9a14610236578063f92c5f7c14610254576100cf565b8063867519c6146101a657806387d31313146101c25780639a8a0592146101e0576100cf565b8063231badaf146100d4578063392e53cd146100f0578063485cc9551461010e5780635afaa7bb1461012a57806373e5a13f1461014657806376db2b4c14610176575b600080fd5b6100ee60048036038101906100e99190611438565b610284565b005b6100f861037f565b6040516101059190611e71565b60405180910390f35b610128600480360381019061012391906115e0565b6103d5565b005b610144600480360381019061013f9190611563565b610561565b005b610160600480360381019061015b919061165d565b610739565b60405161016d9190611e8c565b60405180910390f35b610190600480360381019061018b919061161c565b61075e565b60405161019d9190611e8c565b60405180910390f35b6101c060048036038101906101bb91906113b9565b610788565b005b6101ca610799565b6040516101d79190611f07565b60405180910390f35b6101e86107bf565b6040516101f591906120a2565b60405180910390f35b610218600480360381019061021391906114f7565b6107c5565b005b610234600480360381019061022f9190611438565b6107d5565b005b61023e6108d1565b60405161024b9190611eec565b60405180910390f35b61026e60048036038101906102699190611390565b6108f7565b60405161027b91906120a2565b60405180910390f35b600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548411610305576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102fc90611f82565b60405180910390fd5b60006103258261031788888888610953565b6109b690919063ffffffff16565b905084600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061037786828686610a71565b505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610463576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045a90611f42565b60405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516105559190611def565b60405180910390a15050565b60008251116105a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059c90611fc2565b60405180910390fd5b600080600090505b83518110156106f35760003073ffffffffffffffffffffffffffffffffffffffff168583815181106105db57fe5b60200260200101516040516105f09190611d0b565b6000604051808303816000865af19150503d806000811461062d576040519150601f19603f3d011682016040523d82523d6000602084013e610632565b606091505b505090508315610681578061067c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161067390611f62565b60405180910390fd5b610697565b80801561068c575082155b1561069657600192505b5b7f361c14722cc344132c73396113f7164232448b09c544a149f09048648b43d872338684815181106106c557fe5b6020026020010151836040516106dd93929190611e0a565b60405180910390a15080806001019150506105ad565b5080610734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072b90612082565b60405180910390fd5b505050565b60006107578260000151836020015184604001518560600151610953565b9050919050565b600061078182600001518360200151846040015185606001518660800151610edc565b9050919050565b61079483338484610a71565b505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60015481565b6107d133338484610a71565b5050565b600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548411610856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084d90611f82565b60405180910390fd5b600061087782610869888888883a610edc565b6109b690919063ffffffff16565b905084600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108c986828686610a71565b505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061094c6001600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610f4290919063ffffffff16565b9050919050565b60006109ac7f6848d0622081db2451400280dead7a739a080cb93852607c381af11e289769b286868661098587610f97565b6040516020016109989493929190611c6e565b604051602081830303815290604052610ffa565b9050949350505050565b60008060009050604183511415610a675760008060006020860151925060408601519150606086015160001a9050601b8160ff1610156109f757601b810190505b601b8160ff161480610a0c5750601c8160ff16145b15610a635760018782858560405160008152602001604052604051610a349493929190611ea7565b6020604051602081039080840390855afa158015610a56573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415610ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ad890611fa2565b60405180910390fd5b6000825111610b25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1c90612062565b60405180910390fd5b8151815114610b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6090612002565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610d3d57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb890d3f85856040518363ffffffff1660e01b8152600401610bf9929190611e48565b60206040518083038186803b158015610c1157600080fd5b505afa158015610c25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4991906115b7565b80610cfd5750600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb890d3f85856040518363ffffffff1660e01b8152600401610cac929190611e48565b60206040518083038186803b158015610cc457600080fd5b505afa158015610cd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfc91906115b7565b5b610d3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3390611fe2565b60405180910390fd5b5b600080600090505b8251811015610ed457600073ffffffffffffffffffffffffffffffffffffffff16848281518110610d7257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff161415610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc890611f22565b60405180910390fd5b838181518110610ddd57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16838281518110610e0757fe5b60200260200101518787604051602001610e2393929190611d22565b604051602081830303815290604052604051610e3f9190611d0b565b6000604051808303816000865af19150503d8060008114610e7c576040519150601f19603f3d011682016040523d82523d6000602084013e610e81565b606091505b50508092505081610ec7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebe90612022565b60405180910390fd5b8080600101915050610d45565b505050505050565b6000610f377f6f4e1b2b1e5e49f4269e19e16e67a00cb0a796d96d30be3e4b540d3732e8bcad878787610f0e88610f97565b87604051602001610f23959493929190611cb4565b604051602081830303815290604052610ffa565b905095945050505050565b600080828401905083811015610f8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8490612042565b60405180910390fd5b8091505092915050565b60608060008351905060005b81811015610fef5782858281518110610fb857fe5b6020026020010151604051602001610fd1929190611d5b565b60405160208183030381529060405292508080600101915050610fa3565b508192505050919050565b60006110336001543085856040516020016110189493929190611da5565b6040516020818303038152906040528051906020012061103b565b905092915050565b60008160405160200161104e9190611d7f565b604051602081830303815290604052805190602001209050919050565b60008135905061107a81612375565b92915050565b600082601f83011261109157600080fd5b81356110a461109f826120ea565b6120bd565b915081818352602084019350602081019050838560208402820111156110c957600080fd5b60005b838110156110f957816110df888261106b565b8452602084019350602083019250506001810190506110cc565b5050505092915050565b600082601f83011261111457600080fd5b813561112761112282612112565b6120bd565b9150818183526020840193506020810190508360005b8381101561116d578135860161115388826111a1565b84526020840193506020830192505060018101905061113d565b5050505092915050565b6000813590506111868161238c565b92915050565b60008151905061119b8161238c565b92915050565b600082601f8301126111b257600080fd5b81356111c56111c08261213a565b6120bd565b915080825260208301602083018583830111156111e157600080fd5b6111ec8382846122dd565b50505092915050565b600081359050611204816123a3565b92915050565b600081359050611219816123ba565b92915050565b600060a0828403121561123157600080fd5b61123b60a06120bd565b9050600061124b8482850161106b565b600083015250602061125f8482850161137b565b602083015250604082013567ffffffffffffffff81111561127f57600080fd5b61128b84828501611080565b604083015250606082013567ffffffffffffffff8111156112ab57600080fd5b6112b784828501611103565b60608301525060806112cb8482850161137b565b60808301525092915050565b6000608082840312156112e957600080fd5b6112f360806120bd565b905060006113038482850161106b565b60008301525060206113178482850161137b565b602083015250604082013567ffffffffffffffff81111561133757600080fd5b61134384828501611080565b604083015250606082013567ffffffffffffffff81111561136357600080fd5b61136f84828501611103565b60608301525092915050565b60008135905061138a816123d1565b92915050565b6000602082840312156113a257600080fd5b60006113b08482850161106b565b91505092915050565b6000806000606084860312156113ce57600080fd5b60006113dc8682870161106b565b935050602084013567ffffffffffffffff8111156113f957600080fd5b61140586828701611080565b925050604084013567ffffffffffffffff81111561142257600080fd5b61142e86828701611103565b9150509250925092565b600080600080600060a0868803121561145057600080fd5b600061145e8882890161106b565b955050602061146f8882890161137b565b945050604086013567ffffffffffffffff81111561148c57600080fd5b61149888828901611080565b935050606086013567ffffffffffffffff8111156114b557600080fd5b6114c188828901611103565b925050608086013567ffffffffffffffff8111156114de57600080fd5b6114ea888289016111a1565b9150509295509295909350565b6000806040838503121561150a57600080fd5b600083013567ffffffffffffffff81111561152457600080fd5b61153085828601611080565b925050602083013567ffffffffffffffff81111561154d57600080fd5b61155985828601611103565b9150509250929050565b6000806040838503121561157657600080fd5b600083013567ffffffffffffffff81111561159057600080fd5b61159c85828601611103565b92505060206115ad85828601611177565b9150509250929050565b6000602082840312156115c957600080fd5b60006115d78482850161118c565b91505092915050565b600080604083850312156115f357600080fd5b6000611601858286016111f5565b92505060206116128582860161120a565b9150509250929050565b60006020828403121561162e57600080fd5b600082013567ffffffffffffffff81111561164857600080fd5b6116548482850161121f565b91505092915050565b60006020828403121561166f57600080fd5b600082013567ffffffffffffffff81111561168957600080fd5b611695848285016112d7565b91505092915050565b60006116aa83836116d4565b60208301905092915050565b6116bf8161225f565b82525050565b6116ce816121dc565b82525050565b6116dd816121dc565b82525050565b6116f46116ef826121dc565b61231f565b82525050565b600061170582612176565b61170f8185612199565b935061171a83612166565b8060005b8381101561174b578151611732888261169e565b975061173d8361218c565b92505060018101905061171e565b5085935050505092915050565b611761816121ee565b82525050565b611770816121fa565b82525050565b611787611782826121fa565b612331565b82525050565b600061179882612181565b6117a281856121a4565b93506117b28185602086016122ec565b6117bb81612357565b840191505092915050565b60006117d182612181565b6117db81856121b5565b93506117eb8185602086016122ec565b80840191505092915050565b61180081612271565b82525050565b61180f81612295565b82525050565b6000611822601b836121c0565b91507f476174657761793a2063616e6e6f742073656e6420746f2030783000000000006000830152602082019050919050565b6000611862601c836121d1565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b60006118a2602f836121c0565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b60006119086017836121c0565b91507f476174657761793a2062617463682072657665727465640000000000000000006000830152602082019050919050565b60006119486032836121c0565b91507f476174657761793a206e6f6e6365206973206c6f776572207468616e2063757260008301527f72656e74206163636f756e74206e6f6e636500000000000000000000000000006020830152604082019050919050565b60006119ae6025836121c0565b91507f476174657761793a2063616e6e6f742073656e642066726f6d2030783020616360008301527f636f756e740000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611a146026836121c0565b91507f476174657761793a2063616e6e6f742064656c656761746520656d707479206260008301527f61746368657300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611a7a6028836121c0565b91507f476174657761793a2073656e646572206973206e6f7420746865206163636f7560008301527f6e74206f776e65720000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611ae06016836121c0565b91507f476174657761793a20696e76616c6964206261746368000000000000000000006000830152602082019050919050565b6000611b206023836121c0565b91507f476174657761793a206261746368207472616e73616374696f6e20726576657260008301527f74656400000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611b86601e836121c0565b91507f536166654d6174684c69623a206164646974696f6e206f766572666c6f7700006000830152602082019050919050565b6000611bc66020836121c0565b91507f476174657761793a2063616e6e6f742073656e6420656d7074792062617463686000830152602082019050919050565b6000611c06601d836121c0565b91507f476174657761793a20616c6c20626174636865732072657665727465640000006000830152602082019050919050565b611c4281612248565b82525050565b611c59611c5482612248565b61234d565b82525050565b611c6881612252565b82525050565b6000611c7a82876116e3565b601482019150611c8a8286611c48565b602082019150611c9a82856116fa565b9150611ca682846117c6565b915081905095945050505050565b6000611cc082886116e3565b601482019150611cd08287611c48565b602082019150611ce082866116fa565b9150611cec82856117c6565b9150611cf88284611c48565b6020820191508190509695505050505050565b6000611d1782846117c6565b915081905092915050565b6000611d2e82866117c6565b9150611d3a82856116e3565b601482019150611d4a82846116e3565b601482019150819050949350505050565b6000611d6782856117c6565b9150611d7382846117c6565b91508190509392505050565b6000611d8a82611855565b9150611d968284611776565b60208201915081905092915050565b6000611db18287611c48565b602082019150611dc182866116e3565b601482019150611dd18285611776565b602082019150611de182846117c6565b915081905095945050505050565b6000602082019050611e0460008301846116b6565b92915050565b6000606082019050611e1f60008301866116b6565b8181036020830152611e31818561178d565b9050611e406040830184611758565b949350505050565b6000604082019050611e5d60008301856116c5565b611e6a60208301846116c5565b9392505050565b6000602082019050611e866000830184611758565b92915050565b6000602082019050611ea16000830184611767565b92915050565b6000608082019050611ebc6000830187611767565b611ec96020830186611c5f565b611ed66040830185611767565b611ee36060830184611767565b95945050505050565b6000602082019050611f0160008301846117f7565b92915050565b6000602082019050611f1c6000830184611806565b92915050565b60006020820190508181036000830152611f3b81611815565b9050919050565b60006020820190508181036000830152611f5b81611895565b9050919050565b60006020820190508181036000830152611f7b816118fb565b9050919050565b60006020820190508181036000830152611f9b8161193b565b9050919050565b60006020820190508181036000830152611fbb816119a1565b9050919050565b60006020820190508181036000830152611fdb81611a07565b9050919050565b60006020820190508181036000830152611ffb81611a6d565b9050919050565b6000602082019050818103600083015261201b81611ad3565b9050919050565b6000602082019050818103600083015261203b81611b13565b9050919050565b6000602082019050818103600083015261205b81611b79565b9050919050565b6000602082019050818103600083015261207b81611bb9565b9050919050565b6000602082019050818103600083015261209b81611bf9565b9050919050565b60006020820190506120b76000830184611c39565b92915050565b6000604051905081810181811067ffffffffffffffff821117156120e057600080fd5b8060405250919050565b600067ffffffffffffffff82111561210157600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561212957600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561215157600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006121e782612228565b9050919050565b60008115159050919050565b6000819050919050565b600061220f826121dc565b9050919050565b6000612221826121dc565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061226a826122b9565b9050919050565b600061227c82612283565b9050919050565b600061228e82612228565b9050919050565b60006122a0826122a7565b9050919050565b60006122b282612228565b9050919050565b60006122c4826122cb565b9050919050565b60006122d682612228565b9050919050565b82818337600083830152505050565b60005b8381101561230a5780820151818401526020810190506122ef565b83811115612319576000848401525b50505050565b600061232a8261233b565b9050919050565b6000819050919050565b600061234682612368565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61237e816121dc565b811461238957600080fd5b50565b612395816121ee565b81146123a057600080fd5b50565b6123ac81612204565b81146123b757600080fd5b50565b6123c381612216565b81146123ce57600080fd5b50565b6123da81612248565b81146123e557600080fd5b5056fea164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063867519c61161008c5780639f255626116100665780639f255626146101fe578063b5021b161461021a578063d2c83b9a14610236578063f92c5f7c14610254576100cf565b8063867519c6146101a657806387d31313146101c25780639a8a0592146101e0576100cf565b8063231badaf146100d4578063392e53cd146100f0578063485cc9551461010e5780635afaa7bb1461012a57806373e5a13f1461014657806376db2b4c14610176575b600080fd5b6100ee60048036038101906100e99190611438565b610284565b005b6100f861037f565b6040516101059190611e71565b60405180910390f35b610128600480360381019061012391906115e0565b6103d5565b005b610144600480360381019061013f9190611563565b610561565b005b610160600480360381019061015b919061165d565b610739565b60405161016d9190611e8c565b60405180910390f35b610190600480360381019061018b919061161c565b61075e565b60405161019d9190611e8c565b60405180910390f35b6101c060048036038101906101bb91906113b9565b610788565b005b6101ca610799565b6040516101d79190611f07565b60405180910390f35b6101e86107bf565b6040516101f591906120a2565b60405180910390f35b610218600480360381019061021391906114f7565b6107c5565b005b610234600480360381019061022f9190611438565b6107d5565b005b61023e6108d1565b60405161024b9190611eec565b60405180910390f35b61026e60048036038101906102699190611390565b6108f7565b60405161027b91906120a2565b60405180910390f35b600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548411610305576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102fc90611f82565b60405180910390fd5b60006103258261031788888888610953565b6109b690919063ffffffff16565b905084600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061037786828686610a71565b505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610463576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045a90611f42565b60405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516105559190611def565b60405180910390a15050565b60008251116105a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059c90611fc2565b60405180910390fd5b600080600090505b83518110156106f35760003073ffffffffffffffffffffffffffffffffffffffff168583815181106105db57fe5b60200260200101516040516105f09190611d0b565b6000604051808303816000865af19150503d806000811461062d576040519150601f19603f3d011682016040523d82523d6000602084013e610632565b606091505b505090508315610681578061067c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161067390611f62565b60405180910390fd5b610697565b80801561068c575082155b1561069657600192505b5b7f361c14722cc344132c73396113f7164232448b09c544a149f09048648b43d872338684815181106106c557fe5b6020026020010151836040516106dd93929190611e0a565b60405180910390a15080806001019150506105ad565b5080610734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072b90612082565b60405180910390fd5b505050565b60006107578260000151836020015184604001518560600151610953565b9050919050565b600061078182600001518360200151846040015185606001518660800151610edc565b9050919050565b61079483338484610a71565b505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60015481565b6107d133338484610a71565b5050565b600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548411610856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084d90611f82565b60405180910390fd5b600061087782610869888888883a610edc565b6109b690919063ffffffff16565b905084600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108c986828686610a71565b505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061094c6001600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610f4290919063ffffffff16565b9050919050565b60006109ac7f6848d0622081db2451400280dead7a739a080cb93852607c381af11e289769b286868661098587610f97565b6040516020016109989493929190611c6e565b604051602081830303815290604052610ffa565b9050949350505050565b60008060009050604183511415610a675760008060006020860151925060408601519150606086015160001a9050601b8160ff1610156109f757601b810190505b601b8160ff161480610a0c5750601c8160ff16145b15610a635760018782858560405160008152602001604052604051610a349493929190611ea7565b6020604051602081039080840390855afa158015610a56573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415610ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ad890611fa2565b60405180910390fd5b6000825111610b25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1c90612062565b60405180910390fd5b8151815114610b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6090612002565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610d3d57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb890d3f85856040518363ffffffff1660e01b8152600401610bf9929190611e48565b60206040518083038186803b158015610c1157600080fd5b505afa158015610c25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4991906115b7565b80610cfd5750600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb890d3f85856040518363ffffffff1660e01b8152600401610cac929190611e48565b60206040518083038186803b158015610cc457600080fd5b505afa158015610cd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfc91906115b7565b5b610d3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3390611fe2565b60405180910390fd5b5b600080600090505b8251811015610ed457600073ffffffffffffffffffffffffffffffffffffffff16848281518110610d7257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff161415610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc890611f22565b60405180910390fd5b838181518110610ddd57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16838281518110610e0757fe5b60200260200101518787604051602001610e2393929190611d22565b604051602081830303815290604052604051610e3f9190611d0b565b6000604051808303816000865af19150503d8060008114610e7c576040519150601f19603f3d011682016040523d82523d6000602084013e610e81565b606091505b50508092505081610ec7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebe90612022565b60405180910390fd5b8080600101915050610d45565b505050505050565b6000610f377f6f4e1b2b1e5e49f4269e19e16e67a00cb0a796d96d30be3e4b540d3732e8bcad878787610f0e88610f97565b87604051602001610f23959493929190611cb4565b604051602081830303815290604052610ffa565b905095945050505050565b600080828401905083811015610f8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8490612042565b60405180910390fd5b8091505092915050565b60608060008351905060005b81811015610fef5782858281518110610fb857fe5b6020026020010151604051602001610fd1929190611d5b565b60405160208183030381529060405292508080600101915050610fa3565b508192505050919050565b60006110336001543085856040516020016110189493929190611da5565b6040516020818303038152906040528051906020012061103b565b905092915050565b60008160405160200161104e9190611d7f565b604051602081830303815290604052805190602001209050919050565b60008135905061107a81612375565b92915050565b600082601f83011261109157600080fd5b81356110a461109f826120ea565b6120bd565b915081818352602084019350602081019050838560208402820111156110c957600080fd5b60005b838110156110f957816110df888261106b565b8452602084019350602083019250506001810190506110cc565b5050505092915050565b600082601f83011261111457600080fd5b813561112761112282612112565b6120bd565b9150818183526020840193506020810190508360005b8381101561116d578135860161115388826111a1565b84526020840193506020830192505060018101905061113d565b5050505092915050565b6000813590506111868161238c565b92915050565b60008151905061119b8161238c565b92915050565b600082601f8301126111b257600080fd5b81356111c56111c08261213a565b6120bd565b915080825260208301602083018583830111156111e157600080fd5b6111ec8382846122dd565b50505092915050565b600081359050611204816123a3565b92915050565b600081359050611219816123ba565b92915050565b600060a0828403121561123157600080fd5b61123b60a06120bd565b9050600061124b8482850161106b565b600083015250602061125f8482850161137b565b602083015250604082013567ffffffffffffffff81111561127f57600080fd5b61128b84828501611080565b604083015250606082013567ffffffffffffffff8111156112ab57600080fd5b6112b784828501611103565b60608301525060806112cb8482850161137b565b60808301525092915050565b6000608082840312156112e957600080fd5b6112f360806120bd565b905060006113038482850161106b565b60008301525060206113178482850161137b565b602083015250604082013567ffffffffffffffff81111561133757600080fd5b61134384828501611080565b604083015250606082013567ffffffffffffffff81111561136357600080fd5b61136f84828501611103565b60608301525092915050565b60008135905061138a816123d1565b92915050565b6000602082840312156113a257600080fd5b60006113b08482850161106b565b91505092915050565b6000806000606084860312156113ce57600080fd5b60006113dc8682870161106b565b935050602084013567ffffffffffffffff8111156113f957600080fd5b61140586828701611080565b925050604084013567ffffffffffffffff81111561142257600080fd5b61142e86828701611103565b9150509250925092565b600080600080600060a0868803121561145057600080fd5b600061145e8882890161106b565b955050602061146f8882890161137b565b945050604086013567ffffffffffffffff81111561148c57600080fd5b61149888828901611080565b935050606086013567ffffffffffffffff8111156114b557600080fd5b6114c188828901611103565b925050608086013567ffffffffffffffff8111156114de57600080fd5b6114ea888289016111a1565b9150509295509295909350565b6000806040838503121561150a57600080fd5b600083013567ffffffffffffffff81111561152457600080fd5b61153085828601611080565b925050602083013567ffffffffffffffff81111561154d57600080fd5b61155985828601611103565b9150509250929050565b6000806040838503121561157657600080fd5b600083013567ffffffffffffffff81111561159057600080fd5b61159c85828601611103565b92505060206115ad85828601611177565b9150509250929050565b6000602082840312156115c957600080fd5b60006115d78482850161118c565b91505092915050565b600080604083850312156115f357600080fd5b6000611601858286016111f5565b92505060206116128582860161120a565b9150509250929050565b60006020828403121561162e57600080fd5b600082013567ffffffffffffffff81111561164857600080fd5b6116548482850161121f565b91505092915050565b60006020828403121561166f57600080fd5b600082013567ffffffffffffffff81111561168957600080fd5b611695848285016112d7565b91505092915050565b60006116aa83836116d4565b60208301905092915050565b6116bf8161225f565b82525050565b6116ce816121dc565b82525050565b6116dd816121dc565b82525050565b6116f46116ef826121dc565b61231f565b82525050565b600061170582612176565b61170f8185612199565b935061171a83612166565b8060005b8381101561174b578151611732888261169e565b975061173d8361218c565b92505060018101905061171e565b5085935050505092915050565b611761816121ee565b82525050565b611770816121fa565b82525050565b611787611782826121fa565b612331565b82525050565b600061179882612181565b6117a281856121a4565b93506117b28185602086016122ec565b6117bb81612357565b840191505092915050565b60006117d182612181565b6117db81856121b5565b93506117eb8185602086016122ec565b80840191505092915050565b61180081612271565b82525050565b61180f81612295565b82525050565b6000611822601b836121c0565b91507f476174657761793a2063616e6e6f742073656e6420746f2030783000000000006000830152602082019050919050565b6000611862601c836121d1565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b60006118a2602f836121c0565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b60006119086017836121c0565b91507f476174657761793a2062617463682072657665727465640000000000000000006000830152602082019050919050565b60006119486032836121c0565b91507f476174657761793a206e6f6e6365206973206c6f776572207468616e2063757260008301527f72656e74206163636f756e74206e6f6e636500000000000000000000000000006020830152604082019050919050565b60006119ae6025836121c0565b91507f476174657761793a2063616e6e6f742073656e642066726f6d2030783020616360008301527f636f756e740000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611a146026836121c0565b91507f476174657761793a2063616e6e6f742064656c656761746520656d707479206260008301527f61746368657300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611a7a6028836121c0565b91507f476174657761793a2073656e646572206973206e6f7420746865206163636f7560008301527f6e74206f776e65720000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611ae06016836121c0565b91507f476174657761793a20696e76616c6964206261746368000000000000000000006000830152602082019050919050565b6000611b206023836121c0565b91507f476174657761793a206261746368207472616e73616374696f6e20726576657260008301527f74656400000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611b86601e836121c0565b91507f536166654d6174684c69623a206164646974696f6e206f766572666c6f7700006000830152602082019050919050565b6000611bc66020836121c0565b91507f476174657761793a2063616e6e6f742073656e6420656d7074792062617463686000830152602082019050919050565b6000611c06601d836121c0565b91507f476174657761793a20616c6c20626174636865732072657665727465640000006000830152602082019050919050565b611c4281612248565b82525050565b611c59611c5482612248565b61234d565b82525050565b611c6881612252565b82525050565b6000611c7a82876116e3565b601482019150611c8a8286611c48565b602082019150611c9a82856116fa565b9150611ca682846117c6565b915081905095945050505050565b6000611cc082886116e3565b601482019150611cd08287611c48565b602082019150611ce082866116fa565b9150611cec82856117c6565b9150611cf88284611c48565b6020820191508190509695505050505050565b6000611d1782846117c6565b915081905092915050565b6000611d2e82866117c6565b9150611d3a82856116e3565b601482019150611d4a82846116e3565b601482019150819050949350505050565b6000611d6782856117c6565b9150611d7382846117c6565b91508190509392505050565b6000611d8a82611855565b9150611d968284611776565b60208201915081905092915050565b6000611db18287611c48565b602082019150611dc182866116e3565b601482019150611dd18285611776565b602082019150611de182846117c6565b915081905095945050505050565b6000602082019050611e0460008301846116b6565b92915050565b6000606082019050611e1f60008301866116b6565b8181036020830152611e31818561178d565b9050611e406040830184611758565b949350505050565b6000604082019050611e5d60008301856116c5565b611e6a60208301846116c5565b9392505050565b6000602082019050611e866000830184611758565b92915050565b6000602082019050611ea16000830184611767565b92915050565b6000608082019050611ebc6000830187611767565b611ec96020830186611c5f565b611ed66040830185611767565b611ee36060830184611767565b95945050505050565b6000602082019050611f0160008301846117f7565b92915050565b6000602082019050611f1c6000830184611806565b92915050565b60006020820190508181036000830152611f3b81611815565b9050919050565b60006020820190508181036000830152611f5b81611895565b9050919050565b60006020820190508181036000830152611f7b816118fb565b9050919050565b60006020820190508181036000830152611f9b8161193b565b9050919050565b60006020820190508181036000830152611fbb816119a1565b9050919050565b60006020820190508181036000830152611fdb81611a07565b9050919050565b60006020820190508181036000830152611ffb81611a6d565b9050919050565b6000602082019050818103600083015261201b81611ad3565b9050919050565b6000602082019050818103600083015261203b81611b13565b9050919050565b6000602082019050818103600083015261205b81611b79565b9050919050565b6000602082019050818103600083015261207b81611bb9565b9050919050565b6000602082019050818103600083015261209b81611bf9565b9050919050565b60006020820190506120b76000830184611c39565b92915050565b6000604051905081810181811067ffffffffffffffff821117156120e057600080fd5b8060405250919050565b600067ffffffffffffffff82111561210157600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561212957600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561215157600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006121e782612228565b9050919050565b60008115159050919050565b6000819050919050565b600061220f826121dc565b9050919050565b6000612221826121dc565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061226a826122b9565b9050919050565b600061227c82612283565b9050919050565b600061228e82612228565b9050919050565b60006122a0826122a7565b9050919050565b60006122b282612228565b9050919050565b60006122c4826122cb565b9050919050565b60006122d682612228565b9050919050565b82818337600083830152505050565b60005b8381101561230a5780820151818401526020810190506122ef565b83811115612319576000848401525b50505050565b600061232a8261233b565b9050919050565b6000819050919050565b600061234682612368565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61237e816121dc565b811461238957600080fd5b50565b612395816121ee565b81146123a057600080fd5b50565b6123ac81612204565b81146123b757600080fd5b50565b6123c381612216565b81146123ce57600080fd5b50565b6123da81612248565b81146123e557600080fd5b5056fea164736f6c634300060c000a", + "devdoc": { + "author": "Stanisław Głogowski ", + "events": { + "BatchDelegated(address,bytes,bool)": { + "details": "Emitted when the single batch is delegated", + "params": { + "batch": "batch", + "sender": "sender address", + "succeeded": "if succeeded" + } + } + }, + "kind": "dev", + "methods": { + "constructor": { + "details": "Public constructor" + }, + "delegateBatch(address,uint256,address[],bytes[],bytes)": { + "details": "Use `hashDelegatedBatch` to create sender message payload. `GatewayRecipient` context api: `_getContextAccount` will return `account` arg `_getContextSender` will return recovered address from `senderSignature` arg", + "params": { + "account": "account address", + "data": "array of batch data", + "nonce": "next account nonce", + "senderSignature": "sender signature", + "to": "array of batch recipients contracts" + } + }, + "delegateBatchWithGasPrice(address,uint256,address[],bytes[],bytes)": { + "details": "Use `hashDelegatedBatchWithGasPrice` to create sender message payload (tx.gasprice as gasPrice) `GatewayRecipient` context api: `_getContextAccount` will return `account` arg `_getContextSender` will return recovered address from `senderSignature` arg", + "params": { + "account": "account address", + "data": "array of batch data", + "nonce": "next account nonce", + "senderSignature": "sender signature", + "to": "array of batch recipients contracts" + } + }, + "delegateBatches(bytes[],bool)": { + "details": "It will revert when all batches fail", + "params": { + "batches": "array of batches", + "revertOnFailure": "reverts on any error" + } + }, + "getAccountNextNonce(address)": { + "params": { + "account": "account address" + }, + "returns": { + "_0": "next nonce" + } + }, + "hashDelegatedBatch((address,uint256,address[],bytes[]))": { + "params": { + "delegatedBatch": "struct" + }, + "returns": { + "_0": "hash" + } + }, + "hashDelegatedBatchWithGasPrice((address,uint256,address[],bytes[],uint256))": { + "params": { + "delegatedBatch": "struct" + }, + "returns": { + "_0": "hash" + } + }, + "initialize(address,address)": { + "params": { + "externalAccountRegistry_": "`ExternalAccountRegistry` contract address", + "personalAccountRegistry_": "`PersonalAccountRegistry` contract address" + } + }, + "isInitialized()": { + "returns": { + "_0": "true when contract is initialized" + } + }, + "sendBatch(address[],bytes[])": { + "details": "`GatewayRecipient` context api: `_getContextAccount` will return `msg.sender` `_getContextSender` will return `msg.sender`", + "params": { + "data": "array of batch data", + "to": "array of batch recipients contracts" + } + }, + "sendBatchFromAccount(address,address[],bytes[])": { + "details": "`GatewayRecipient` context api: `_getContextAccount` will return `account` arg `_getContextSender` will return `msg.sender`", + "params": { + "account": "account address", + "data": "array of batch data", + "to": "array of batch recipients contracts" + } + } + }, + "title": "Gateway", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "delegateBatch(address,uint256,address[],bytes[],bytes)": { + "notice": "Delegates batch from the account" + }, + "delegateBatchWithGasPrice(address,uint256,address[],bytes[],bytes)": { + "notice": "Delegates batch from the account (with gas price)" + }, + "delegateBatches(bytes[],bool)": { + "notice": "Delegates multiple batches" + }, + "getAccountNextNonce(address)": { + "notice": "Gets next account nonce" + }, + "hashDelegatedBatch((address,uint256,address[],bytes[]))": { + "notice": "Hashes `DelegatedBatch` message payload" + }, + "hashDelegatedBatchWithGasPrice((address,uint256,address[],bytes[],uint256))": { + "notice": "Hashes `DelegatedBatchWithGasPrice` message payload" + }, + "initialize(address,address)": { + "notice": "Initializes `Gateway` contract" + }, + "isInitialized()": { + "notice": "Check if contract is initialized" + }, + "sendBatch(address[],bytes[])": { + "notice": "Sends batch" + }, + "sendBatchFromAccount(address,address[],bytes[])": { + "notice": "Sends batch from the account" + } + }, + "notice": "GSN replacement", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1871, + "contract": "src/gateway/Gateway.sol:Gateway", + "label": "initializer", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 1935, + "contract": "src/gateway/Gateway.sol:Gateway", + "label": "chainId", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 4647, + "contract": "src/gateway/Gateway.sol:Gateway", + "label": "externalAccountRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(ExternalAccountRegistry)4591" + }, + { + "astId": 4649, + "contract": "src/gateway/Gateway.sol:Gateway", + "label": "personalAccountRegistry", + "offset": 0, + "slot": "3", + "type": "t_contract(PersonalAccountRegistry)7452" + }, + { + "astId": 4653, + "contract": "src/gateway/Gateway.sol:Gateway", + "label": "accountNonce", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_address,t_uint256)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_contract(ExternalAccountRegistry)4591": { + "encoding": "inplace", + "label": "contract ExternalAccountRegistry", + "numberOfBytes": "20" + }, + "t_contract(PersonalAccountRegistry)7452": { + "encoding": "inplace", + "label": "contract PersonalAccountRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/OwnershipFacet.json b/deployments/neonDevnet/OwnershipFacet.json new file mode 100644 index 00000000..a7de7d22 --- /dev/null +++ b/deployments/neonDevnet/OwnershipFacet.json @@ -0,0 +1,85 @@ +{ + "address": "0x4e0BaFA6f2a4299f4b19b31250970fAdA52a9515", + "abi": [ + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xf627177d138682ce38f84c295cf60692c81624170d5397b2e6d2881e57e028e4", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "23346000", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xf1cede65ff0eaa6f19f3b58fdd6713f0fcb5c8c48b94abb4365e863cbdb48c88", + "transactionHash": "0xf627177d138682ce38f84c295cf60692c81624170d5397b2e6d2881e57e028e4", + "logs": [], + "blockNumber": 173997624, + "cumulativeGasUsed": "23346000", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "ae94371f40f594d6ee02698e497ed59a", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/bridges/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/bridges/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport { LibDiamond } from \\\"../libs/LibDiamond.sol\\\";\\nimport { IERC173 } from \\\"../interfaces/IERC173.sol\\\";\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\",\"keccak256\":\"0x6623773e10e37c6122dd84797f03ec1ab6796de06694493283d2e16000e14c8b\",\"license\":\"MIT\"},\"src/bridges/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xc5184a3a9a2d9698572c007846bf12cf4a693dffc47425352b4b4f92beaae4db\",\"license\":\"MIT\"},\"src/bridges/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0x5dae03961ba5245751ab7cdc0ceb754d5925977e8a71b0b59981bd1e2a13c1f3\",\"license\":\"MIT\"},\"src/bridges/libs/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n require(\\n _functionSelectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _functionSelectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress)\\n internal\\n {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x135cb5bb9fc0234dcc41a8ba75e6a95ad514cd965673f1d105103dbba18017cd\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506103d4806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b14610059575b600080fd5b610043610075565b60405161005091906102ab565b60405180910390f35b610073600480360381019061006e91906102f7565b610084565b005b600061007f610098565b905090565b61008c6100cb565b61009581610166565b50565b60006100a261023d565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6100d361023d565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161015b906103a7565b60405180910390fd5b565b600061017061023d565b905060008160040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050828260040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102958261026a565b9050919050565b6102a58161028a565b82525050565b60006020820190506102c0600083018461029c565b92915050565b600080fd5b6102d48161028a565b81146102df57600080fd5b50565b6000813590506102f1816102cb565b92915050565b60006020828403121561030d5761030c6102c6565b5b600061031b848285016102e2565b91505092915050565b600082825260208201905092915050565b7f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b6000610391602283610324565b915061039c82610335565b604082019050919050565b600060208201905081810360008301526103c081610384565b905091905056fea164736f6c634300080f000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b14610059575b600080fd5b610043610075565b60405161005091906102ab565b60405180910390f35b610073600480360381019061006e91906102f7565b610084565b005b600061007f610098565b905090565b61008c6100cb565b61009581610166565b50565b60006100a261023d565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6100d361023d565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161015b906103a7565b60405180910390fd5b565b600061017061023d565b905060008160040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050828260040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102958261026a565b9050919050565b6102a58161028a565b82525050565b60006020820190506102c0600083018461029c565b92915050565b600080fd5b6102d48161028a565b81146102df57600080fd5b50565b6000813590506102f1816102cb565b92915050565b60006020828403121561030d5761030c6102c6565b5b600061031b848285016102e2565b91505092915050565b600082825260208201905092915050565b7f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b6000610391602283610324565b915061039c82610335565b604082019050919050565b600060208201905081810360008301526103c081610384565b905091905056fea164736f6c634300080f000a", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "returns": { + "owner_": "The address of the owner." + } + }, + "transferOwnership(address)": { + "details": "Set _newOwner to address(0) to renounce any ownership.", + "params": { + "_newOwner": "The address of the new owner of the contract" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "owner()": { + "notice": "Get the address of the owner" + }, + "transferOwnership(address)": { + "notice": "Set the address of the new owner of the contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/PaymentRegistry.json b/deployments/neonDevnet/PaymentRegistry.json new file mode 100644 index 00000000..09385455 --- /dev/null +++ b/deployments/neonDevnet/PaymentRegistry.json @@ -0,0 +1,1434 @@ +{ + "address": "0xB6900522DC23F3cdAeA61bf0Ca17a672b8Dbe312", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "depositAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "DepositAccountDeployed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "depositAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DepositExitCompleted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "depositAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "DepositExitRejected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "depositAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lockedUntil", + "type": "uint256" + } + ], + "name": "DepositExitRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "depositAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DepositWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "GuardianAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "GuardianRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "initializer", + "type": "address" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "PaymentChannelCommitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "channelHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PaymentDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "channelHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalValue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "depositValue", + "type": "uint256" + } + ], + "name": "PaymentSplit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "channelHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PaymentWithdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "addGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "chainId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "senderSignature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "guardianSignature", + "type": "bytes" + } + ], + "name": "commitPaymentChannelAndDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositPaymentValue", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "senderSignature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "guardianSignature", + "type": "bytes" + } + ], + "name": "commitPaymentChannelAndSplit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "senderSignature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "guardianSignature", + "type": "bytes" + } + ], + "name": "commitPaymentChannelAndWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "computeDepositAccountAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + } + ], + "name": "computePaymentChannelHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "deployDepositAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositExitLockPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "externalAccountRegistry", + "outputs": [ + { + "internalType": "contract ExternalAccountRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gateway", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getDepositExitLockedUntil", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getDepositWithdrawnAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "getPaymentChannelCommittedAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct PaymentRegistry.DepositWithdrawal", + "name": "depositWithdrawal", + "type": "tuple" + } + ], + "name": "hashDepositWithdrawal", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct PaymentRegistry.PaymentChannelCommit", + "name": "paymentChannelCommit", + "type": "tuple" + } + ], + "name": "hashPaymentChannelCommit", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ExternalAccountRegistry", + "name": "externalAccountRegistry_", + "type": "address" + }, + { + "internalType": "contract PersonalAccountRegistry", + "name": "personalAccountRegistry_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "depositExitLockPeriod_", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "guardians_", + "type": "address[]" + }, + { + "internalType": "address", + "name": "gateway_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "isDepositAccountDeployed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "isGuardian", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "personalAccountRegistry", + "outputs": [ + { + "internalType": "contract PersonalAccountRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "processDepositExit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "removeGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "requestDepositExit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "messageHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "verifyGuardianSignature", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "guardianSignature", + "type": "bytes" + } + ], + "name": "withdrawDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x23514b60607e2f59c56170f5a4b9060b03c153224c94f0cd0332e08edf27e019", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "168172720", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2a24188a795303c179fa6d38a5927415949023466d11842fc17526702fd11fff", + "transactionHash": "0x23514b60607e2f59c56170f5a4b9060b03c153224c94f0cd0332e08edf27e019", + "logs": [], + "blockNumber": 173996887, + "cumulativeGasUsed": "168172720", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"DepositAccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DepositExitCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"DepositExitRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockedUntil\",\"type\":\"uint256\"}],\"name\":\"DepositExitRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositAccount\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DepositWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PaymentChannelCommitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"channelHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"PaymentDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"channelHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalValue\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositValue\",\"type\":\"uint256\"}],\"name\":\"PaymentSplit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"channelHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"addGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"senderSignature\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"commitPaymentChannelAndDeposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depositPaymentValue\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"senderSignature\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"commitPaymentChannelAndSplit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"senderSignature\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"commitPaymentChannelAndWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"computeDepositAccountAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"name\":\"computePaymentChannelHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"deployDepositAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositExitLockPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"externalAccountRegistry\",\"outputs\":[{\"internalType\":\"contract ExternalAccountRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getDepositExitLockedUntil\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getDepositWithdrawnAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"getPaymentChannelCommittedAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct PaymentRegistry.DepositWithdrawal\",\"name\":\"depositWithdrawal\",\"type\":\"tuple\"}],\"name\":\"hashDepositWithdrawal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct PaymentRegistry.PaymentChannelCommit\",\"name\":\"paymentChannelCommit\",\"type\":\"tuple\"}],\"name\":\"hashPaymentChannelCommit\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ExternalAccountRegistry\",\"name\":\"externalAccountRegistry_\",\"type\":\"address\"},{\"internalType\":\"contract PersonalAccountRegistry\",\"name\":\"personalAccountRegistry_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositExitLockPeriod_\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"guardians_\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"gateway_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"isDepositAccountDeployed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"isGuardian\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"personalAccountRegistry\",\"outputs\":[{\"internalType\":\"contract PersonalAccountRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"processDepositExit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"removeGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"requestDepositExit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"verifyGuardianSignature\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"guardianSignature\",\"type\":\"bytes\"}],\"name\":\"withdrawDeposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski \",\"details\":\"the `DepositExit` process can be used in a case operator (guardian) couldn't sign commit / withdrawal message. Process will be rejected when any of senders channels will be committed.\",\"events\":{\"DepositAccountDeployed(address,address)\":{\"details\":\"Emitted when the deposit account is deployed\",\"params\":{\"depositAccount\":\"deposit account address\",\"owner\":\"owner address\"}},\"DepositExitCompleted(address,address,address,uint256)\":{\"details\":\"Emitted when the deposit exist is completed\",\"params\":{\"amount\":\"deposit exist amount\",\"depositAccount\":\"deposit account address\",\"owner\":\"owner address\",\"token\":\"token address\"}},\"DepositExitRejected(address,address,address)\":{\"details\":\"Emitted when the deposit exist is rejected\",\"params\":{\"depositAccount\":\"deposit account address\",\"owner\":\"owner address\",\"token\":\"token address\"}},\"DepositExitRequested(address,address,address,uint256)\":{\"details\":\"Emitted when the deposit exist is requested\",\"params\":{\"depositAccount\":\"deposit account address\",\"lockedUntil\":\"deposit exist locked util time\",\"owner\":\"owner address\",\"token\":\"token address\"}},\"DepositWithdrawn(address,address,address,uint256)\":{\"details\":\"Emitted when the deposit has been withdrawn\",\"params\":{\"amount\":\"withdrawn amount\",\"depositAccount\":\"deposit account address\",\"owner\":\"owner address\",\"token\":\"token address\"}},\"PaymentChannelCommitted(bytes32,address,address,address,bytes32,uint256)\":{\"details\":\"Emitted when the payment channel has been committed\",\"params\":{\"amount\":\"committed amount\",\"hash\":\"channel hash\",\"recipient\":\"recipient address\",\"sender\":\"sender address\",\"token\":\"token address\",\"uid\":\"unique channel id\"}},\"PaymentDeposited(bytes32,uint256)\":{\"details\":\"Emitted when the payment has been deposited\",\"params\":{\"channelHash\":\"channel hash\",\"value\":\"payment value\"}},\"PaymentSplit(bytes32,uint256,uint256)\":{\"details\":\"Emitted when the payment has been withdrawn and deposited (split)\",\"params\":{\"channelHash\":\"channel hash\",\"depositValue\":\"payment deposited value\",\"totalValue\":\"payment total value\"}},\"PaymentWithdrawn(bytes32,uint256)\":{\"details\":\"Emitted when the payment has been withdrawn\",\"params\":{\"channelHash\":\"channel hash\",\"value\":\"payment value\"}}},\"kind\":\"dev\",\"methods\":{\"addGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"commitPaymentChannelAndDeposit(address,address,bytes32,uint256,uint256,bytes,bytes)\":{\"params\":{\"amount\":\"amount to commit\",\"blockNumber\":\"block number\",\"guardianSignature\":\"guardian signature\",\"sender\":\"sender address\",\"senderSignature\":\"sender signature\",\"token\":\"token address\",\"uid\":\"unique channel id\"}},\"commitPaymentChannelAndSplit(address,address,bytes32,uint256,uint256,uint256,bytes,bytes)\":{\"params\":{\"amount\":\"amount to commit\",\"blockNumber\":\"block number\",\"depositPaymentValue\":\"amount to deposit\",\"guardianSignature\":\"guardian signature\",\"sender\":\"sender address\",\"senderSignature\":\"sender signature\",\"token\":\"token address\",\"uid\":\"unique channel id\"}},\"commitPaymentChannelAndWithdraw(address,address,bytes32,uint256,uint256,bytes,bytes)\":{\"params\":{\"amount\":\"amount to commit\",\"blockNumber\":\"block number\",\"guardianSignature\":\"guardian signature\",\"sender\":\"sender address\",\"senderSignature\":\"sender signature\",\"token\":\"token address\",\"uid\":\"unique channel id\"}},\"computeDepositAccountAddress(address)\":{\"params\":{\"owner\":\"owner address\"},\"returns\":{\"_0\":\"deposit account address\"}},\"computePaymentChannelHash(address,address,address,bytes32)\":{\"params\":{\"recipient\":\"recipient address\",\"sender\":\"sender address\",\"token\":\"token address\",\"uid\":\"unique channel id\"},\"returns\":{\"_0\":\"hash\"}},\"constructor\":{\"details\":\"Public constructor\"},\"deployDepositAccount(address)\":{\"params\":{\"owner\":\"owner address\"}},\"getDepositExitLockedUntil(address,address)\":{\"params\":{\"owner\":\"owner address\",\"token\":\"token address\"},\"returns\":{\"_0\":\"locked until time\"}},\"getDepositWithdrawnAmount(address,address)\":{\"params\":{\"owner\":\"owner address\",\"token\":\"token address\"},\"returns\":{\"_0\":\"withdrawn amount\"}},\"getPaymentChannelCommittedAmount(bytes32)\":{\"params\":{\"hash\":\"payment channel hash\"},\"returns\":{\"_0\":\"committed amount\"}},\"hashDepositWithdrawal((address,address,uint256))\":{\"params\":{\"depositWithdrawal\":\"struct\"},\"returns\":{\"_0\":\"hash\"}},\"hashPaymentChannelCommit((address,address,address,bytes32,uint256,uint256))\":{\"params\":{\"paymentChannelCommit\":\"struct\"},\"returns\":{\"_0\":\"hash\"}},\"initialize(address,address,uint256,address[],address)\":{\"params\":{\"depositExitLockPeriod_\":\"deposit exit lock period\",\"externalAccountRegistry_\":\"`ExternalAccountRegistry` contract address\",\"gateway_\":\"`Gateway` contract address\",\"guardians_\":\"array of guardians addresses\",\"personalAccountRegistry_\":\"`PersonalAccountRegistry` contract address\"}},\"isDepositAccountDeployed(address)\":{\"params\":{\"owner\":\"owner address\"},\"returns\":{\"_0\":\"true when deposit account is deployed\"}},\"isGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"},\"returns\":{\"_0\":\"true when guardian exists\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}},\"processDepositExit(address)\":{\"params\":{\"token\":\"token address\"}},\"removeGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"requestDepositExit(address)\":{\"params\":{\"token\":\"token address\"}},\"verifyGuardianSignature(bytes32,bytes)\":{\"params\":{\"messageHash\":\"message hash\",\"signature\":\"signature\"},\"returns\":{\"_0\":\"true on correct guardian signature\"}},\"withdrawDeposit(address,uint256,bytes)\":{\"params\":{\"amount\":\"amount to withdraw\",\"guardianSignature\":\"guardian signature\",\"token\":\"token address\"}}},\"title\":\"Payment registry\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addGuardian(address)\":{\"notice\":\"Adds a new guardian\"},\"commitPaymentChannelAndDeposit(address,address,bytes32,uint256,uint256,bytes,bytes)\":{\"notice\":\"Commits payment channel and deposit payment\"},\"commitPaymentChannelAndSplit(address,address,bytes32,uint256,uint256,uint256,bytes,bytes)\":{\"notice\":\"Commits payment channel, withdraws and deposits (split) payment\"},\"commitPaymentChannelAndWithdraw(address,address,bytes32,uint256,uint256,bytes,bytes)\":{\"notice\":\"Commits payment channel and withdraw payment\"},\"computeDepositAccountAddress(address)\":{\"notice\":\"Computes deposit account address\"},\"computePaymentChannelHash(address,address,address,bytes32)\":{\"notice\":\"Computes payment channel hash\"},\"deployDepositAccount(address)\":{\"notice\":\"Deploys deposit account\"},\"getDepositExitLockedUntil(address,address)\":{\"notice\":\"Gets deposit exit locked until time\"},\"getDepositWithdrawnAmount(address,address)\":{\"notice\":\"Gets deposit withdrawn amount\"},\"getPaymentChannelCommittedAmount(bytes32)\":{\"notice\":\"Gets payment channel committed amount\"},\"hashDepositWithdrawal((address,address,uint256))\":{\"notice\":\"Hashes `DepositWithdrawal` message payload\"},\"hashPaymentChannelCommit((address,address,address,bytes32,uint256,uint256))\":{\"notice\":\"Hashes `PaymentChannelCommit` message payload\"},\"initialize(address,address,uint256,address[],address)\":{\"notice\":\"Initialize `PaymentRegistry` contract\"},\"isDepositAccountDeployed(address)\":{\"notice\":\"Checks if deposit account is deployed\"},\"isGuardian(address)\":{\"notice\":\"Check if guardian exists\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"},\"processDepositExit(address)\":{\"notice\":\"Processes deposit exit\"},\"removeGuardian(address)\":{\"notice\":\"Removes the existing guardian\"},\"requestDepositExit(address)\":{\"notice\":\"Requests deposit exit\"},\"verifyGuardianSignature(bytes32,bytes)\":{\"notice\":\"Verifies guardian signature\"},\"withdrawDeposit(address,uint256,bytes)\":{\"notice\":\"Withdraws deposit\"}},\"notice\":\"A registry for payment and payment channels\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/payments/PaymentRegistry.sol\":\"PaymentRegistry\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/access/Controlled.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Controlled\\n *\\n * @dev Contract module which provides an access control mechanism.\\n * It ensures there is only one controlling account of the smart contract\\n * and grants that account exclusive access to specific functions.\\n *\\n * The controller account will be the one that deploys the contract.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Controlled {\\n /**\\n * @return controller account address\\n */\\n address public controller;\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if msg.sender is not the controller\\n */\\n modifier onlyController() {\\n require(\\n msg.sender == controller,\\n \\\"Controlled: msg.sender is not the controller\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n controller = msg.sender;\\n }\\n}\\n\",\"keccak256\":\"0xdf03a0b7ec644da9925c5c1b6c8a86bb1cc1b9c5018bb265a1a4c5044b877af3\",\"license\":\"MIT\"},\"src/common/access/Guarded.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n\\n/**\\n * @title Guarded\\n *\\n * @dev Contract module which provides a guardian-type control mechanism.\\n * It allows key accounts to have guardians and restricts specific methods to be accessible by guardians only.\\n *\\n * Each guardian account can remove other guardians\\n *\\n * Use `_initializeGuarded` to initialize the contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Guarded {\\n using ECDSALib for bytes32;\\n\\n mapping(address => bool) private guardians;\\n\\n // events\\n\\n /**\\n * @dev Emitted when a new guardian is added\\n * @param sender sender address\\n * @param guardian guardian address\\n */\\n event GuardianAdded(\\n address sender,\\n address guardian\\n );\\n\\n /**\\n * @dev Emitted when the existing guardian is removed\\n * @param sender sender address\\n * @param guardian guardian address\\n */\\n event GuardianRemoved(\\n address sender,\\n address guardian\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not a guardian account\\n */\\n modifier onlyGuardian() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n guardians[tx.origin],\\n \\\"Guarded: tx.origin is not the guardian\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor() internal {}\\n\\n // external functions\\n\\n /**\\n * @notice Adds a new guardian\\n * @param guardian guardian address\\n */\\n function addGuardian(\\n address guardian\\n )\\n external\\n onlyGuardian\\n {\\n _addGuardian(guardian);\\n }\\n\\n /**\\n * @notice Removes the existing guardian\\n * @param guardian guardian address\\n */\\n function removeGuardian(\\n address guardian\\n )\\n external\\n onlyGuardian\\n {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin != guardian,\\n \\\"Guarded: cannot remove self\\\"\\n );\\n\\n require(\\n guardians[guardian],\\n \\\"Guarded: guardian doesn't exist\\\"\\n );\\n\\n guardians[guardian] = false;\\n\\n emit GuardianRemoved(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin,\\n guardian\\n );\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if guardian exists\\n * @param guardian guardian address\\n * @return true when guardian exists\\n */\\n function isGuardian(\\n address guardian\\n )\\n external\\n view\\n returns (bool)\\n {\\n return guardians[guardian];\\n }\\n\\n /**\\n * @notice Verifies guardian signature\\n * @param messageHash message hash\\n * @param signature signature\\n * @return true on correct guardian signature\\n */\\n function verifyGuardianSignature(\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n external\\n view\\n returns (bool)\\n {\\n return _verifyGuardianSignature(\\n messageHash,\\n signature\\n );\\n }\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `Guarded` contract\\n * @dev If `guardians_` array is empty `tx.origin` is added as guardian account\\n * @param guardians_ array of guardians addresses\\n */\\n function _initializeGuarded(\\n address[] memory guardians_\\n )\\n internal\\n {\\n if (guardians_.length == 0) {\\n // solhint-disable-next-line avoid-tx-origin\\n _addGuardian(tx.origin);\\n } else {\\n uint guardiansLen = guardians_.length;\\n for (uint i = 0; i < guardiansLen; i++) {\\n _addGuardian(guardians_[i]);\\n }\\n }\\n }\\n\\n\\n // internal functions (views)\\n\\n function _verifyGuardianSignature(\\n bytes32 messageHash,\\n bytes memory signature\\n )\\n internal\\n view\\n returns (bool)\\n {\\n address guardian = messageHash.recoverAddress(signature);\\n\\n return guardians[guardian];\\n }\\n\\n // private functions\\n\\n function _addGuardian(\\n address guardian\\n )\\n private\\n {\\n require(\\n guardian != address(0),\\n \\\"Guarded: cannot add 0x0 guardian\\\"\\n );\\n\\n require(\\n !guardians[guardian],\\n \\\"Guarded: guardian already exists\\\"\\n );\\n\\n guardians[guardian] = true;\\n\\n emit GuardianAdded(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin,\\n guardian\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4a5f5670041362e87ea267d81c55fc3edc1a78e81f6f17524b13267f91f31458\",\"license\":\"MIT\"},\"src/common/account/Account.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../access/Controlled.sol\\\";\\nimport \\\"./AccountBase.sol\\\";\\n\\n\\n/**\\n * @title Account\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Account is Controlled, AccountBase {\\n address public implementation;\\n\\n /**\\n * @dev Public constructor\\n * @param registry_ account registry address\\n * @param implementation_ account implementation address\\n */\\n constructor(\\n address registry_,\\n address implementation_\\n )\\n public\\n Controlled()\\n {\\n registry = registry_;\\n implementation = implementation_;\\n }\\n\\n // external functions\\n\\n /**\\n * @notice Payable receive\\n */\\n receive()\\n external\\n payable\\n {\\n //\\n }\\n\\n /**\\n * @notice Fallback\\n */\\n // solhint-disable-next-line payable-fallback\\n fallback()\\n external\\n {\\n if (msg.data.length != 0) {\\n address implementation_ = implementation;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let calldedatasize := calldatasize()\\n\\n calldatacopy(0, 0, calldedatasize)\\n\\n let result := delegatecall(gas(), implementation_, 0, calldedatasize, 0, 0)\\n let returneddatasize := returndatasize()\\n\\n returndatacopy(0, 0, returneddatasize)\\n\\n switch result\\n case 0 { revert(0, returneddatasize) }\\n default { return(0, returneddatasize) }\\n }\\n }\\n }\\n\\n /**\\n * @notice Sets implementation\\n * @param implementation_ implementation address\\n */\\n function setImplementation(\\n address implementation_\\n )\\n external\\n onlyController\\n {\\n implementation = implementation_;\\n }\\n\\n /**\\n * @notice Executes transaction\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @return transaction result\\n */\\n function executeTransaction(\\n address to,\\n uint256 value,\\n bytes calldata data\\n )\\n external\\n onlyController\\n returns (bytes memory)\\n {\\n bytes memory result;\\n bool succeeded;\\n\\n // solhint-disable-next-line avoid-call-value, avoid-low-level-calls\\n (succeeded, result) = payable(to).call{value: value}(data);\\n\\n require(\\n succeeded,\\n \\\"Account: transaction reverted\\\"\\n );\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe516c999a02a65ee99487d398d0c12589500680a9ca08c852540fb9473d70a26\",\"license\":\"MIT\"},\"src/common/account/AccountBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Account base\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract AccountBase {\\n address public registry;\\n}\\n\",\"keccak256\":\"0xcadf29e389f8db823e14f3f92808fd135f07b0135eb4dcf29b89c85941b39862\",\"license\":\"MIT\"},\"src/common/account/AccountController.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./Account.sol\\\";\\n\\n\\n/**\\n * @title Account controller\\n *\\n * @dev Contract module which provides Account deployment mechanism\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract AccountController {\\n address public accountRegistry;\\n address public accountImplementation;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the account registry is updated\\n * @param accountRegistry account registry address\\n */\\n event AccountRegistryUpdated(\\n address accountRegistry\\n );\\n\\n /**\\n * @dev Emitted when the account implementation is updated\\n * @param accountImplementation account implementation address\\n */\\n event AccountImplementationUpdated(\\n address accountImplementation\\n );\\n\\n /**\\n * @dev Emitted when the account is deployed\\n * @param account account address\\n * @param accountImplementation account implementation address\\n */\\n event AccountDeployed(\\n address account,\\n address accountImplementation\\n );\\n\\n /**\\n * @dev Emitted when the account is upgraded\\n * @param account account address\\n * @param accountImplementation account implementation address\\n */\\n event AccountUpgraded(\\n address account,\\n address accountImplementation\\n );\\n\\n /**\\n * @dev Emitted when the transaction is executed\\n * @param account account address\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @param response response\\n */\\n event AccountTransactionExecuted(\\n address account,\\n address to,\\n uint256 value,\\n bytes data,\\n bytes response\\n );\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor() internal {}\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `AccountController` contract\\n * @param accountRegistry_ account registry address\\n * @param accountImplementation_ account implementation address\\n */\\n function _initializeAccountController(\\n address accountRegistry_,\\n address accountImplementation_\\n )\\n internal\\n {\\n _setAccountRegistry(accountRegistry_, false);\\n _setAccountImplementation(accountImplementation_, false);\\n }\\n\\n /**\\n * @notice Sets account registry\\n * @param accountRegistry_ account registry address\\n * @param emitEvent it will emit event when flag is set to true\\n */\\n function _setAccountRegistry(\\n address accountRegistry_,\\n bool emitEvent\\n )\\n internal\\n {\\n require(\\n accountRegistry_ != address(0),\\n \\\"AccountController: cannot set account registry to 0x0\\\"\\n );\\n\\n accountRegistry = accountRegistry_;\\n\\n if (emitEvent) {\\n emit AccountRegistryUpdated(accountRegistry);\\n }\\n }\\n\\n /**\\n * @notice Sets account implementation\\n * @param accountImplementation_ account implementation address\\n * @param emitEvent it will emit event when flag is set to true\\n */\\n function _setAccountImplementation(\\n address accountImplementation_,\\n bool emitEvent\\n )\\n internal\\n {\\n require(\\n accountImplementation_ != address(0),\\n \\\"AccountController: cannot set account Implementation to 0x0\\\"\\n );\\n\\n accountImplementation = accountImplementation_;\\n\\n if (emitEvent) {\\n emit AccountImplementationUpdated(accountImplementation);\\n }\\n }\\n\\n /**\\n * @notice Deploys account\\n * @param salt CREATE2 salt\\n * @param emitEvent it will emit event when flag is set to true\\n * @return account address\\n */\\n function _deployAccount(\\n bytes32 salt,\\n bool emitEvent\\n )\\n internal\\n returns (address)\\n {\\n address account = address(new Account{salt: salt}(\\n accountRegistry,\\n accountImplementation\\n ));\\n\\n if (emitEvent) {\\n emit AccountDeployed(\\n account,\\n accountImplementation\\n );\\n }\\n\\n return account;\\n }\\n\\n /**\\n * @notice Upgrades account\\n * @param account account address\\n * @param emitEvent it will emit event when flag is set to true\\n */\\n function _upgradeAccount(\\n address account,\\n bool emitEvent\\n )\\n internal\\n {\\n require(\\n Account(payable(account)).implementation() != accountImplementation,\\n \\\"AccountController: account already upgraded\\\"\\n );\\n\\n Account(payable(account)).setImplementation(accountImplementation);\\n\\n if (emitEvent) {\\n emit AccountUpgraded(\\n account,\\n accountImplementation\\n );\\n }\\n }\\n\\n /**\\n * @notice Executes transaction from the account\\n * @param account account address\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @param emitEvent it will emit event when flag is set to true\\n * @return transaction result\\n */\\n function _executeAccountTransaction(\\n address account,\\n address to,\\n uint256 value,\\n bytes memory data,\\n bool emitEvent\\n )\\n internal\\n returns (bytes memory)\\n {\\n require(\\n to != address(0),\\n \\\"AccountController: cannot send to 0x0\\\"\\n );\\n\\n require(\\n to != address(this),\\n \\\"AccountController: cannot send to controller\\\"\\n );\\n\\n require(\\n to != account,\\n \\\"AccountController: cannot send to self\\\"\\n );\\n\\n bytes memory response = Account(payable(account)).executeTransaction(\\n to,\\n value,\\n data\\n );\\n\\n if (emitEvent) {\\n emit AccountTransactionExecuted(\\n account,\\n to,\\n value,\\n data,\\n response\\n );\\n }\\n\\n return response;\\n }\\n\\n // internal functions (views)\\n\\n /**\\n * @notice Computes account CREATE2 address\\n * @param salt CREATE2 salt\\n * @return account address\\n */\\n function _computeAccountAddress(\\n bytes32 salt\\n )\\n internal\\n view\\n returns (address)\\n {\\n bytes memory creationCode = abi.encodePacked(\\n type(Account).creationCode,\\n bytes12(0),\\n accountRegistry,\\n bytes12(0),\\n accountImplementation\\n );\\n\\n bytes32 data = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n salt,\\n keccak256(creationCode)\\n )\\n );\\n\\n return address(uint160(uint256(data)));\\n }\\n}\\n\",\"keccak256\":\"0xe161f1f4f6ea5d3a9810f7c93764d55e473abe1054e6aa68fde791be7d70a26c\",\"license\":\"MIT\"},\"src/common/account/AccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./Account.sol\\\";\\n\\n\\n/**\\n * @title Account registry\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nabstract contract AccountRegistry {\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param messageHash message hash\\n * @param signature signature\\n * @return true if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n virtual\\n external\\n view\\n returns (bool);\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param message message\\n * @param signature signature\\n * @return true if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes calldata message,\\n bytes calldata signature\\n )\\n virtual\\n external\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0x2d40245721f5f74219e5cf88713246dbe8b6d5404e941125d3e850b1f127ec34\",\"license\":\"MIT\"},\"src/common/libs/BlockLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Block library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nlibrary BlockLib {\\n struct BlockRelated {\\n bool added;\\n uint256 removedAtBlockNumber;\\n }\\n\\n /**\\n * @notice Verifies self struct at current block\\n * @param self self struct\\n * @return true on correct self struct\\n */\\n function verifyAtCurrentBlock(\\n BlockRelated memory self\\n )\\n internal\\n view\\n returns (bool)\\n {\\n return verifyAtBlock(self, block.number);\\n }\\n\\n /**\\n * @notice Verifies self struct at any block\\n * @param self self struct\\n * @return true on correct self struct\\n */\\n function verifyAtAnyBlock(\\n BlockRelated memory self\\n )\\n internal\\n pure\\n returns (bool)\\n {\\n return verifyAtBlock(self, 0);\\n }\\n\\n /**\\n * @notice Verifies self struct at specific block\\n * @param self self struct\\n * @param blockNumber block number to verify\\n * @return true on correct self struct\\n */\\n function verifyAtBlock(\\n BlockRelated memory self,\\n uint256 blockNumber\\n )\\n internal\\n pure\\n returns (bool)\\n {\\n bool result = false;\\n\\n if (self.added) {\\n if (self.removedAtBlockNumber == 0) {\\n result = true;\\n } else if (blockNumber == 0) {\\n result = true;\\n } else {\\n result = self.removedAtBlockNumber > blockNumber;\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9205536bc211f86d1113118a44dddfa7a9b9772a918cf4b1575c982a05472587\",\"license\":\"MIT\"},\"src/common/libs/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Bytes library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nlibrary BytesLib {\\n /**\\n * @notice Converts bytes to address\\n * @param data data\\n * @return address\\n */\\n function toAddress(\\n bytes memory data\\n )\\n internal\\n pure\\n returns (address)\\n {\\n address result;\\n\\n require(\\n data.length == 20,\\n \\\"BytesLib: invalid data length\\\"\\n );\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := div(mload(add(data, 0x20)), 0x1000000000000000000000000)\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x64c84964ea91bfb1f2d859eea6c57fe5b4a6f269951a4adf5f58d306c54c7f76\",\"license\":\"MIT\"},\"src/common/libs/ECDSAExtendedLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./StringsLib.sol\\\";\\n\\n\\n/**\\n * @title ECDSA extended library\\n */\\nlibrary ECDSAExtendedLib {\\n using StringsLib for uint;\\n\\n function toEthereumSignedMessageHash(\\n bytes memory message\\n )\\n internal\\n pure\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n\\\",\\n message.length.toString(),\\n abi.encodePacked(message)\\n ));\\n }\\n}\\n\",\"keccak256\":\"0x83e6056caaba892d91de45324f4d2702ac01695fab2d34c86895d7d288547ba3\",\"license\":\"MIT\"},\"src/common/libs/ECDSALib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ECDSA library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/cryptography/ECDSA.sol#L26\\n */\\nlibrary ECDSALib {\\n function recoverAddress(\\n bytes32 messageHash,\\n bytes memory signature\\n )\\n internal\\n pure\\n returns (address)\\n {\\n address result = address(0);\\n\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n\\n if (v < 27) {\\n v += 27;\\n }\\n\\n if (v == 27 || v == 28) {\\n result = ecrecover(messageHash, v, r, s);\\n }\\n }\\n\\n return result;\\n }\\n\\n function toEthereumSignedMessageHash(\\n bytes32 messageHash\\n )\\n internal\\n pure\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n messageHash\\n ));\\n }\\n}\\n\",\"keccak256\":\"0x3b1460d688302eb595268c2af147ab532f29dbced66520e013f48d498eed3cec\",\"license\":\"MIT\"},\"src/common/libs/SafeMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Safe math library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol\\n */\\nlibrary SafeMathLib {\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n\\n require(c >= a, \\\"SafeMathLib: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMathLib: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n\\n return a - b;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n\\n require(c / a == b, \\\"SafeMathLib: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMathLib: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n\\n return a / b;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMathLib: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x6089f354ca754d9c5dd9e800ee5ed86717dbf8f9af470604e0be691ac57c0107\",\"license\":\"MIT\"},\"src/common/libs/StringsLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Strings library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/utils/Strings.sol#L12\\n */\\nlibrary StringsLib {\\n function toString(\\n uint256 value\\n )\\n internal\\n pure\\n returns (string memory)\\n {\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n\\n uint256 temp = value;\\n uint256 digits;\\n\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n\\n bytes memory buffer = new bytes(digits);\\n uint256 index = digits - 1;\\n temp = value;\\n\\n while (temp != 0) {\\n buffer[index--] = byte(uint8(48 + temp % 10));\\n temp /= 10;\\n }\\n\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x4110150d0c921fd31db34ca33672de8e81c3ae467076149a3a546f804d1f58dd\",\"license\":\"MIT\"},\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Initializable {\\n address private initializer;\\n\\n // events\\n\\n /**\\n * @dev Emitted after `onlyInitializer`\\n * @param initializer initializer address\\n */\\n event Initialized(\\n address initializer\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not the initializer\\n */\\n modifier onlyInitializer() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin == initializer,\\n \\\"Initializable: tx.origin is not the initializer\\\"\\n );\\n\\n /// @dev removes initializer\\n initializer = address(0);\\n\\n _;\\n\\n emit Initialized(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin\\n );\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n initializer = tx.origin;\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if contract is initialized\\n * @return true when contract is initialized\\n */\\n function isInitialized()\\n external\\n view\\n returns (bool)\\n {\\n return initializer == address(0);\\n }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/common/signature/SignatureValidator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n/**\\n * @title Signature validator\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract SignatureValidator {\\n using ECDSALib for bytes32;\\n\\n uint256 public chainId;\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {\\n uint256 chainId_;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n chainId_ := chainid()\\n }\\n\\n chainId = chainId_;\\n }\\n\\n // internal functions\\n\\n function _hashMessagePayload(\\n bytes32 messagePrefix,\\n bytes memory messagePayload\\n )\\n internal\\n view\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n chainId,\\n address(this),\\n messagePrefix,\\n messagePayload\\n )).toEthereumSignedMessageHash();\\n }\\n}\\n\",\"keccak256\":\"0xc1168f7ccb74aea67089941dc5e4c1d1c4aa766afca47a90c0b017b8445b8acf\",\"license\":\"MIT\"},\"src/common/token/ERC20Token.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/SafeMathLib.sol\\\";\\n\\n\\n/**\\n * @title ERC20 token\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol\\n */\\ncontract ERC20Token {\\n using SafeMathLib for uint256;\\n\\n string public name;\\n string public symbol;\\n uint8 public decimals;\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) internal balances;\\n mapping(address => mapping(address => uint256)) internal allowances;\\n\\n // events\\n\\n event Transfer(\\n address indexed from,\\n address indexed to,\\n uint256 value\\n );\\n\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // external functions\\n\\n function transfer(\\n address to,\\n uint256 value\\n )\\n external\\n returns (bool)\\n {\\n _transfer(_getSender(), to, value);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n address sender = _getSender();\\n\\n _transfer(from, to, value);\\n _approve(from, sender, allowances[from][sender].sub(value));\\n\\n return true;\\n }\\n\\n function approve(\\n address spender,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n _approve(_getSender(), spender, value);\\n\\n return true;\\n }\\n\\n // external functions (views)\\n\\n function balanceOf(\\n address owner\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return balances[owner];\\n }\\n\\n function allowance(\\n address owner,\\n address spender\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return allowances[owner][spender];\\n }\\n\\n // internal functions\\n\\n function _transfer(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n from != address(0),\\n \\\"ERC20Token: cannot transfer from 0x0 address\\\"\\n );\\n require(\\n to != address(0),\\n \\\"ERC20Token: cannot transfer to 0x0 address\\\"\\n );\\n\\n balances[from] = balances[from].sub(value);\\n balances[to] = balances[to].add(value);\\n\\n emit Transfer(from, to, value);\\n }\\n\\n function _approve(\\n address owner,\\n address spender,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot approve from 0x0 address\\\"\\n );\\n require(\\n spender != address(0),\\n \\\"ERC20Token: cannot approve to 0x0 address\\\"\\n );\\n\\n allowances[owner][spender] = value;\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function _mint(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot mint to 0x0 address\\\"\\n );\\n require(\\n value > 0,\\n \\\"ERC20Token: cannot mint 0 value\\\"\\n );\\n\\n balances[owner] = balances[owner].add(value);\\n totalSupply = totalSupply.add(value);\\n\\n emit Transfer(address(0), owner, value);\\n }\\n\\n function _burn(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot burn from 0x0 address\\\"\\n );\\n\\n balances[owner] = balances[owner].sub(\\n value,\\n \\\"ERC20Token: burn value exceeds balance\\\"\\n );\\n\\n totalSupply = totalSupply.sub(value);\\n\\n emit Transfer(owner, address(0), value);\\n }\\n\\n // internal functions (views)\\n\\n function _getSender()\\n virtual\\n internal\\n view\\n returns (address)\\n {\\n return msg.sender;\\n }\\n}\\n\",\"keccak256\":\"0x6f2b0bd08da549c6c1f5ceee85766832d587dde62c56bebc3a14bd9ea407e03d\",\"license\":\"MIT\"},\"src/external/ExternalAccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BlockLib.sol\\\";\\n\\n\\n/**\\n * @title External account registry\\n *\\n * @notice Global registry for keys and external (outside of the platform) contract based wallets\\n *\\n * @dev An account can call the registry to add (`addAccountOwner`) or remove (`removeAccountOwner`) its own owners.\\n * When the owner has been added, information about that fact will live in the registry forever.\\n * Removing an owner only affects the future blocks (until the owner is re-added).\\n *\\n * Given the fact, there is no way to sign the data using a contract based wallet,\\n * we created a registry to store signed by the key wallet proofs.\\n * ERC-1271 allows removing a signer after the signature was created. Thus store the signature for the later use\\n * doesn't guarantee the signer is still has access to that smart account.\\n * Because of that, the ERC1271's `isValidSignature()` cannot be used in e.g. `PaymentRegistry`.*\\n *\\n * An account can call the registry to add (`addAccountProof`) or remove (`removeAccountProof`) proof hash.\\n * When the proof has been added, information about that fact will live in the registry forever.\\n * Removing a proof only affects the future blocks (until the proof is re-added).\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract ExternalAccountRegistry {\\n using BlockLib for BlockLib.BlockRelated;\\n\\n struct Account {\\n mapping(address => BlockLib.BlockRelated) owners;\\n mapping(bytes32 => BlockLib.BlockRelated) proofs;\\n }\\n\\n mapping(address => Account) private accounts;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the new owner is added\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerAdded(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the existing owner is removed\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerRemoved(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the new proof is added\\n * @param account account address\\n * @param hash proof hash\\n */\\n event AccountProofAdded(\\n address account,\\n bytes32 hash\\n );\\n\\n /**\\n * @dev Emitted when the existing proof is removed\\n * @param account account address\\n * @param hash proof hash\\n */\\n event AccountProofRemoved(\\n address account,\\n bytes32 hash\\n );\\n\\n // external functions\\n\\n /**\\n * @notice Adds a new account owner\\n * @param owner owner address\\n */\\n function addAccountOwner(\\n address owner\\n )\\n external\\n {\\n require(\\n owner != address(0),\\n \\\"ExternalAccountRegistry: cannot add 0x0 owner\\\"\\n );\\n\\n require(\\n !accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: owner already exists\\\"\\n );\\n\\n accounts[msg.sender].owners[owner].added = true;\\n accounts[msg.sender].owners[owner].removedAtBlockNumber = 0;\\n\\n emit AccountOwnerAdded(\\n msg.sender,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Removes existing account owner\\n * @param owner owner address\\n */\\n function removeAccountOwner(\\n address owner\\n )\\n external\\n {\\n require(\\n accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: owner doesn't exist\\\"\\n );\\n\\n accounts[msg.sender].owners[owner].removedAtBlockNumber = block.number;\\n\\n emit AccountOwnerRemoved(\\n msg.sender,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Adds a new account proof\\n * @param hash proof hash\\n */\\n function addAccountProof(\\n bytes32 hash\\n )\\n external\\n {\\n require(\\n !accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: proof already exists\\\"\\n );\\n\\n accounts[msg.sender].proofs[hash].added = true;\\n accounts[msg.sender].proofs[hash].removedAtBlockNumber = 0;\\n\\n emit AccountProofAdded(\\n msg.sender,\\n hash\\n );\\n }\\n\\n /**\\n * @notice Removes existing account proof\\n * @param hash proof hash\\n */\\n function removeAccountProof(\\n bytes32 hash\\n )\\n external\\n {\\n require(\\n accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\\n \\\"ExternalAccountRegistry: proof doesn't exist\\\"\\n );\\n\\n accounts[msg.sender].proofs[hash].removedAtBlockNumber = block.number;\\n\\n emit AccountProofRemoved(\\n msg.sender,\\n hash\\n );\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Verifies the owner of the account at current block\\n * @param account account address\\n * @param owner owner address\\n * @return true on correct account owner\\n */\\n function verifyAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].owners[owner].verifyAtCurrentBlock();\\n }\\n\\n /**\\n * @notice Verifies the owner of the account at specific block\\n * @param account account address\\n * @param owner owner address\\n * @param blockNumber block number to verify\\n * @return true on correct account owner\\n */\\n function verifyAccountOwnerAtBlock(\\n address account,\\n address owner,\\n uint256 blockNumber\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].owners[owner].verifyAtBlock(blockNumber);\\n }\\n\\n /**\\n * @notice Verifies the proof of the account at current block\\n * @param account account address\\n * @param hash proof hash\\n * @return true on correct account proof\\n */\\n function verifyAccountProof(\\n address account,\\n bytes32 hash\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].proofs[hash].verifyAtCurrentBlock();\\n }\\n\\n /**\\n * @notice Verifies the proof of the account at specific block\\n * @param account account address\\n * @param hash proof hash\\n * @param blockNumber block number to verify\\n * @return true on correct account proof\\n */\\n function verifyAccountProofAtBlock(\\n address account,\\n bytes32 hash,\\n uint256 blockNumber\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].proofs[hash].verifyAtBlock(blockNumber);\\n }\\n}\\n\",\"keccak256\":\"0x8067b1fae41b73949f8d871a835533cbdd94b9ca3faa93b91f595c37e632ccdb\",\"license\":\"MIT\"},\"src/gateway/GatewayRecipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BytesLib.sol\\\";\\n\\n\\n/**\\n * @title Gateway recipient\\n *\\n * @notice Gateway target contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract GatewayRecipient {\\n using BytesLib for bytes;\\n\\n address public gateway;\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `GatewayRecipient` contract\\n * @param gateway_ `Gateway` contract address\\n */\\n function _initializeGatewayRecipient(\\n address gateway_\\n )\\n internal\\n {\\n gateway = gateway_;\\n }\\n\\n // internal functions (views)\\n\\n /**\\n * @notice Gets gateway context account\\n * @return context account address\\n */\\n function _getContextAccount()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(40);\\n }\\n\\n /**\\n * @notice Gets gateway context sender\\n * @return context sender address\\n */\\n function _getContextSender()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(20);\\n }\\n\\n /**\\n * @notice Gets gateway context data\\n * @return context data\\n */\\n function _getContextData()\\n internal\\n view\\n returns (bytes calldata)\\n {\\n bytes calldata result;\\n\\n if (_isGatewaySender()) {\\n result = msg.data[:msg.data.length - 40];\\n } else {\\n result = msg.data;\\n }\\n\\n return result;\\n }\\n\\n // private functions (views)\\n\\n function _getContextAddress(\\n uint256 offset\\n )\\n private\\n view\\n returns (address)\\n {\\n address result = address(0);\\n\\n if (_isGatewaySender()) {\\n uint from = msg.data.length - offset;\\n result = bytes(msg.data[from:from + 20]).toAddress();\\n } else {\\n result = msg.sender;\\n }\\n\\n return result;\\n }\\n\\n function _isGatewaySender()\\n private\\n view\\n returns (bool)\\n {\\n bool result;\\n\\n if (msg.sender == gateway) {\\n require(\\n msg.data.length >= 44,\\n \\\"GatewayRecipient: invalid msg.data\\\"\\n );\\n\\n result = true;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe3fd29479d748d67360c61a9cbaafc66eaca25f476e59a45e842472bcf5233fc\",\"license\":\"MIT\"},\"src/payments/PaymentDepositAccount.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/access/Controlled.sol\\\";\\n\\n\\n/**\\n * @title Payment deposit account\\n *\\n * @dev Simple account contract with only one method - `executeTransaction`\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract PaymentDepositAccount is Controlled {\\n /**\\n * @dev Public constructor\\n */\\n constructor() public payable Controlled() {}\\n\\n /**\\n * @notice Allow receives\\n */\\n receive()\\n external\\n payable\\n {\\n //\\n }\\n\\n // external functions\\n\\n /**\\n * @notice Executes transaction\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @return transaction result\\n */\\n function executeTransaction(\\n address to,\\n uint256 value,\\n bytes calldata data\\n )\\n external\\n onlyController\\n returns (bytes memory)\\n {\\n bytes memory result;\\n bool succeeded;\\n\\n // solhint-disable-next-line avoid-call-value, avoid-low-level-calls\\n (succeeded, result) = payable(to).call{value: value}(data);\\n\\n require(\\n succeeded,\\n \\\"Account: transaction reverted\\\"\\n );\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xeac8f6b6b1cb749d72d8d5160a622fe4100a1e18a73635e51ce30e6f11029ad1\",\"license\":\"MIT\"},\"src/payments/PaymentRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../common/access/Guarded.sol\\\";\\nimport \\\"../common/libs/ECDSALib.sol\\\";\\nimport \\\"../common/libs/SafeMathLib.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/signature/SignatureValidator.sol\\\";\\nimport \\\"../common/token/ERC20Token.sol\\\";\\nimport \\\"../external/ExternalAccountRegistry.sol\\\";\\nimport \\\"../personal/PersonalAccountRegistry.sol\\\";\\nimport \\\"../gateway/GatewayRecipient.sol\\\";\\nimport \\\"./PaymentDepositAccount.sol\\\";\\n\\n\\n/**\\n * @title Payment registry\\n *\\n * @notice A registry for payment and payment channels\\n *\\n * @dev the `DepositExit` process can be used in a case operator (guardian) couldn't sign commit / withdrawal message.\\n * Process will be rejected when any of senders channels will be committed.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract PaymentRegistry is Guarded, Initializable, SignatureValidator, GatewayRecipient {\\n using ECDSALib for bytes32;\\n using SafeMathLib for uint256;\\n\\n struct Deposit {\\n address account;\\n mapping(address => uint256) withdrawnAmount;\\n mapping(address => uint256) exitLockedUntil;\\n }\\n\\n struct PaymentChannel {\\n uint256 committedAmount;\\n }\\n\\n struct DepositWithdrawal {\\n address owner;\\n address token;\\n uint256 amount;\\n }\\n\\n struct PaymentChannelCommit {\\n address sender;\\n address recipient;\\n address token;\\n bytes32 uid;\\n uint256 blockNumber;\\n uint256 amount;\\n }\\n\\n uint256 private constant DEFAULT_DEPOSIT_EXIT_LOCK_PERIOD = 28 days;\\n\\n bytes32 private constant HASH_PREFIX_DEPOSIT_WITHDRAWAL = keccak256(\\n \\\"DepositWithdrawal(address owner,address token,uint256 amount)\\\"\\n );\\n bytes32 private constant HASH_PREFIX_PAYMENT_CHANNEL_COMMIT = keccak256(\\n \\\"PaymentChannelCommit(address sender,address recipient,address token,bytes32 uid,uint256 blockNumber,uint256 amount)\\\"\\n );\\n\\n ExternalAccountRegistry public externalAccountRegistry;\\n PersonalAccountRegistry public personalAccountRegistry;\\n\\n uint256 public depositExitLockPeriod;\\n\\n mapping(address => Deposit) private deposits;\\n mapping(bytes32 => PaymentChannel) private paymentChannels;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the deposit account is deployed\\n * @param depositAccount deposit account address\\n * @param owner owner address\\n */\\n event DepositAccountDeployed(\\n address depositAccount,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the deposit exist is requested\\n * @param depositAccount deposit account address\\n * @param owner owner address\\n * @param token token address\\n * @param lockedUntil deposit exist locked util time\\n */\\n event DepositExitRequested(\\n address depositAccount,\\n address owner,\\n address token,\\n uint256 lockedUntil\\n );\\n\\n /**\\n * @dev Emitted when the deposit exist is completed\\n * @param depositAccount deposit account address\\n * @param owner owner address\\n * @param token token address\\n * @param amount deposit exist amount\\n */\\n event DepositExitCompleted(\\n address depositAccount,\\n address owner,\\n address token,\\n uint256 amount\\n );\\n\\n /**\\n * @dev Emitted when the deposit exist is rejected\\n * @param depositAccount deposit account address\\n * @param owner owner address\\n * @param token token address\\n */\\n event DepositExitRejected(\\n address depositAccount,\\n address owner,\\n address token\\n );\\n\\n /**\\n * @dev Emitted when the deposit has been withdrawn\\n * @param depositAccount deposit account address\\n * @param owner owner address\\n * @param token token address\\n * @param amount withdrawn amount\\n */\\n event DepositWithdrawn(\\n address depositAccount,\\n address owner,\\n address token,\\n uint256 amount\\n );\\n\\n /**\\n * @dev Emitted when the payment channel has been committed\\n * @param hash channel hash\\n * @param sender sender address\\n * @param recipient recipient address\\n * @param token token address\\n * @param uid unique channel id\\n * @param amount committed amount\\n */\\n event PaymentChannelCommitted(\\n bytes32 hash,\\n address sender,\\n address recipient,\\n address token,\\n bytes32 uid,\\n uint256 amount\\n );\\n\\n /**\\n * @dev Emitted when the payment has been withdrawn\\n * @param channelHash channel hash\\n * @param value payment value\\n */\\n event PaymentWithdrawn(\\n bytes32 channelHash,\\n uint256 value\\n );\\n\\n /**\\n * @dev Emitted when the payment has been deposited\\n * @param channelHash channel hash\\n * @param value payment value\\n */\\n event PaymentDeposited(\\n bytes32 channelHash,\\n uint256 value\\n );\\n\\n /**\\n * @dev Emitted when the payment has been withdrawn and deposited (split)\\n * @param channelHash channel hash\\n * @param totalValue payment total value\\n * @param depositValue payment deposited value\\n */\\n event PaymentSplit(\\n bytes32 channelHash,\\n uint256 totalValue,\\n uint256 depositValue\\n );\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor() public Initializable() SignatureValidator() {}\\n\\n // external functions\\n\\n /**\\n * @notice Initialize `PaymentRegistry` contract\\n * @param externalAccountRegistry_ `ExternalAccountRegistry` contract address\\n * @param personalAccountRegistry_ `PersonalAccountRegistry` contract address\\n * @param depositExitLockPeriod_ deposit exit lock period\\n * @param guardians_ array of guardians addresses\\n * @param gateway_ `Gateway` contract address\\n */\\n function initialize(\\n ExternalAccountRegistry externalAccountRegistry_,\\n PersonalAccountRegistry personalAccountRegistry_,\\n uint256 depositExitLockPeriod_,\\n address[] calldata guardians_,\\n address gateway_\\n )\\n external\\n onlyInitializer\\n {\\n externalAccountRegistry = externalAccountRegistry_;\\n personalAccountRegistry = personalAccountRegistry_;\\n\\n if (depositExitLockPeriod_ == 0) {\\n depositExitLockPeriod = DEFAULT_DEPOSIT_EXIT_LOCK_PERIOD;\\n } else {\\n depositExitLockPeriod = depositExitLockPeriod_;\\n }\\n\\n // Guarded\\n _initializeGuarded(guardians_);\\n\\n // GatewayRecipient\\n _initializeGatewayRecipient(gateway_);\\n }\\n\\n /**\\n * @notice Deploys deposit account\\n * @param owner owner address\\n */\\n function deployDepositAccount(\\n address owner\\n )\\n external\\n {\\n _deployDepositAccount(owner);\\n }\\n\\n /**\\n * @notice Requests deposit exit\\n * @param token token address\\n */\\n function requestDepositExit(\\n address token\\n )\\n external\\n {\\n address owner = _getContextAccount();\\n uint256 lockedUntil = deposits[owner].exitLockedUntil[token];\\n\\n require(\\n lockedUntil == 0,\\n \\\"PaymentRegistry: deposit exit already requested\\\"\\n );\\n\\n _deployDepositAccount(owner);\\n\\n // solhint-disable-next-line not-rely-on-time\\n lockedUntil = now.add(depositExitLockPeriod);\\n\\n deposits[owner].exitLockedUntil[token] = lockedUntil;\\n\\n emit DepositExitRequested(\\n deposits[owner].account,\\n owner,\\n token,\\n lockedUntil\\n );\\n }\\n\\n /**\\n * @notice Processes deposit exit\\n * @param token token address\\n */\\n function processDepositExit(\\n address token\\n )\\n external\\n {\\n address owner = _getContextAccount();\\n uint256 lockedUntil = deposits[owner].exitLockedUntil[token];\\n\\n require(\\n lockedUntil != 0,\\n \\\"PaymentRegistry: deposit exit not requested\\\"\\n );\\n\\n require(\\n // solhint-disable-next-line not-rely-on-time\\n lockedUntil <= now,\\n \\\"PaymentRegistry: deposit exit locked\\\"\\n );\\n\\n deposits[owner].exitLockedUntil[token] = 0;\\n\\n address depositAccount = deposits[owner].account;\\n uint256 depositValue;\\n\\n if (token == address(0)) {\\n depositValue = depositAccount.balance;\\n } else {\\n depositValue = ERC20Token(token).balanceOf(depositAccount);\\n }\\n\\n _transferFromDeposit(\\n depositAccount,\\n owner,\\n token,\\n depositValue\\n );\\n\\n emit DepositExitCompleted(\\n depositAccount,\\n owner,\\n token,\\n depositValue\\n );\\n }\\n\\n /**\\n * @notice Withdraws deposit\\n * @param token token address\\n * @param amount amount to withdraw\\n * @param guardianSignature guardian signature\\n */\\n function withdrawDeposit(\\n address token,\\n uint256 amount,\\n bytes calldata guardianSignature\\n )\\n external\\n {\\n address owner = _getContextAccount();\\n uint256 value = amount.sub(deposits[owner].withdrawnAmount[token]);\\n\\n require(\\n value > 0,\\n \\\"PaymentRegistry: invalid amount\\\"\\n );\\n\\n bytes32 messageHash = _hashDepositWithdrawal(\\n owner,\\n token,\\n amount\\n );\\n\\n require(\\n _verifyGuardianSignature(messageHash, guardianSignature),\\n \\\"PaymentRegistry: invalid guardian signature\\\"\\n );\\n\\n deposits[owner].withdrawnAmount[token] = amount;\\n\\n _verifyDepositExitOrDeployAccount(owner, token);\\n\\n _transferFromDeposit(\\n deposits[owner].account,\\n owner,\\n token,\\n value\\n );\\n\\n emit DepositWithdrawn(\\n deposits[owner].account,\\n owner,\\n token,\\n amount\\n );\\n }\\n\\n /**\\n * @notice Commits payment channel and withdraw payment\\n * @param sender sender address\\n * @param token token address\\n * @param uid unique channel id\\n * @param blockNumber block number\\n * @param amount amount to commit\\n * @param senderSignature sender signature\\n * @param guardianSignature guardian signature\\n */\\n function commitPaymentChannelAndWithdraw(\\n address sender,\\n address token,\\n bytes32 uid,\\n uint256 blockNumber,\\n uint256 amount,\\n bytes calldata senderSignature,\\n bytes calldata guardianSignature\\n )\\n external\\n {\\n address recipient = _getContextAccount();\\n\\n (bytes32 hash, address depositAccount, uint256 paymentValue) = _commitPaymentChannel(\\n sender,\\n recipient,\\n token,\\n uid,\\n blockNumber,\\n amount,\\n senderSignature,\\n guardianSignature\\n );\\n\\n _transferFromDeposit(\\n depositAccount,\\n recipient,\\n token,\\n paymentValue\\n );\\n\\n emit PaymentWithdrawn(hash, paymentValue);\\n }\\n\\n /**\\n * @notice Commits payment channel and deposit payment\\n * @param sender sender address\\n * @param token token address\\n * @param uid unique channel id\\n * @param blockNumber block number\\n * @param amount amount to commit\\n * @param senderSignature sender signature\\n * @param guardianSignature guardian signature\\n */\\n function commitPaymentChannelAndDeposit(\\n address sender,\\n address token,\\n bytes32 uid,\\n uint256 blockNumber,\\n uint256 amount,\\n bytes calldata senderSignature,\\n bytes calldata guardianSignature\\n )\\n external\\n {\\n address recipient = _getContextAccount();\\n\\n (bytes32 hash, address depositAccount, uint256 paymentValue) = _commitPaymentChannel(\\n sender,\\n recipient,\\n token,\\n uid,\\n blockNumber,\\n amount,\\n senderSignature,\\n guardianSignature\\n );\\n\\n _transferFromDeposit(\\n depositAccount,\\n _computeDepositAccountAddress(recipient),\\n token,\\n paymentValue\\n );\\n\\n emit PaymentDeposited(hash, paymentValue);\\n }\\n\\n /**\\n * @notice Commits payment channel, withdraws and deposits (split) payment\\n * @param sender sender address\\n * @param token token address\\n * @param uid unique channel id\\n * @param blockNumber block number\\n * @param amount amount to commit\\n * @param depositPaymentValue amount to deposit\\n * @param senderSignature sender signature\\n * @param guardianSignature guardian signature\\n */\\n function commitPaymentChannelAndSplit(\\n address sender,\\n address token,\\n bytes32 uid,\\n uint256 blockNumber,\\n uint256 amount,\\n uint256 depositPaymentValue,\\n bytes calldata senderSignature,\\n bytes calldata guardianSignature\\n )\\n external\\n {\\n address recipient = _getContextAccount();\\n\\n (bytes32 hash, address depositAccount, uint256 paymentValue) = _commitPaymentChannel(\\n sender,\\n recipient,\\n token,\\n uid,\\n blockNumber,\\n amount,\\n senderSignature,\\n guardianSignature\\n );\\n\\n _transferSplitFromDeposit(\\n depositAccount,\\n recipient,\\n token,\\n paymentValue,\\n depositPaymentValue\\n );\\n\\n emit PaymentSplit(hash, paymentValue, depositPaymentValue);\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Computes deposit account address\\n * @param owner owner address\\n * @return deposit account address\\n */\\n function computeDepositAccountAddress(\\n address owner\\n )\\n external\\n view\\n returns (address)\\n {\\n return _computeDepositAccountAddress(owner);\\n }\\n\\n /**\\n * @notice Checks if deposit account is deployed\\n * @param owner owner address\\n * @return true when deposit account is deployed\\n */\\n function isDepositAccountDeployed(\\n address owner\\n )\\n external\\n view\\n returns (bool)\\n {\\n return deposits[owner].account != address(0);\\n }\\n\\n /**\\n * @notice Gets deposit exit locked until time\\n * @param owner owner address\\n * @param token token address\\n * @return locked until time\\n */\\n function getDepositExitLockedUntil(\\n address owner,\\n address token\\n )\\n external\\n view\\n returns (uint256)\\n {\\n return deposits[owner].exitLockedUntil[token];\\n }\\n\\n /**\\n * @notice Gets deposit withdrawn amount\\n * @param owner owner address\\n * @param token token address\\n * @return withdrawn amount\\n */\\n function getDepositWithdrawnAmount(\\n address owner,\\n address token\\n )\\n external\\n view\\n returns (uint256)\\n {\\n return deposits[owner].withdrawnAmount[token];\\n }\\n\\n /**\\n * @notice Gets payment channel committed amount\\n * @param hash payment channel hash\\n * @return committed amount\\n */\\n function getPaymentChannelCommittedAmount(\\n bytes32 hash\\n )\\n external\\n view\\n returns (uint256)\\n {\\n return paymentChannels[hash].committedAmount;\\n }\\n\\n // external functions (pure)\\n\\n /**\\n * @notice Computes payment channel hash\\n * @param sender sender address\\n * @param recipient recipient address\\n * @param token token address\\n * @param uid unique channel id\\n * @return hash\\n */\\n function computePaymentChannelHash(\\n address sender,\\n address recipient,\\n address token,\\n bytes32 uid\\n )\\n external\\n pure\\n returns (bytes32)\\n {\\n return _computePaymentChannelHash(\\n sender,\\n recipient,\\n token,\\n uid\\n );\\n }\\n\\n // public functions (views)\\n\\n /**\\n * @notice Hashes `DepositWithdrawal` message payload\\n * @param depositWithdrawal struct\\n * @return hash\\n */\\n function hashDepositWithdrawal(\\n DepositWithdrawal memory depositWithdrawal\\n )\\n public\\n view\\n returns (bytes32)\\n {\\n return _hashDepositWithdrawal(\\n depositWithdrawal.owner,\\n depositWithdrawal.token,\\n depositWithdrawal.amount\\n );\\n }\\n\\n /**\\n * @notice Hashes `PaymentChannelCommit` message payload\\n * @param paymentChannelCommit struct\\n * @return hash\\n */\\n function hashPaymentChannelCommit(\\n PaymentChannelCommit memory paymentChannelCommit\\n )\\n public\\n view\\n returns (bytes32)\\n {\\n return _hashPaymentChannelCommit(\\n paymentChannelCommit.sender,\\n paymentChannelCommit.recipient,\\n paymentChannelCommit.token,\\n paymentChannelCommit.uid,\\n paymentChannelCommit.blockNumber,\\n paymentChannelCommit.amount\\n );\\n }\\n\\n // private functions\\n\\n function _deployDepositAccount(\\n address owner\\n )\\n private\\n {\\n if (deposits[owner].account == address(0)) {\\n bytes32 salt = keccak256(\\n abi.encodePacked(\\n owner\\n )\\n );\\n\\n deposits[owner].account = address(new PaymentDepositAccount{salt: salt}());\\n\\n emit DepositAccountDeployed(\\n deposits[owner].account,\\n owner\\n );\\n }\\n }\\n\\n function _verifyDepositExitOrDeployAccount(\\n address owner,\\n address token\\n )\\n private\\n {\\n if (deposits[owner].exitLockedUntil[token] > 0) {\\n deposits[owner].exitLockedUntil[token] = 0;\\n\\n emit DepositExitRejected(\\n deposits[owner].account,\\n owner,\\n token\\n );\\n } else {\\n _deployDepositAccount(owner);\\n }\\n }\\n\\n function _commitPaymentChannel(\\n address sender,\\n address recipient,\\n address token,\\n bytes32 uid,\\n uint256 blockNumber,\\n uint256 amount,\\n bytes memory senderSignature,\\n bytes memory guardianSignature\\n )\\n private\\n returns (bytes32 hash, address depositAccount, uint256 paymentValue)\\n {\\n bytes32 messageHash = _hashPaymentChannelCommit(\\n sender,\\n recipient,\\n token,\\n uid,\\n blockNumber,\\n amount\\n );\\n\\n if (senderSignature.length == 0) {\\n require(\\n externalAccountRegistry.verifyAccountProofAtBlock(sender, messageHash, blockNumber),\\n \\\"PaymentRegistry: invalid guardian signature\\\"\\n );\\n } else {\\n address signer = messageHash.recoverAddress(senderSignature);\\n\\n if (sender != signer) {\\n require(\\n personalAccountRegistry.verifyAccountOwnerAtBlock(sender, signer, blockNumber) ||\\n externalAccountRegistry.verifyAccountOwnerAtBlock(sender, signer, blockNumber),\\n \\\"PaymentRegistry: invalid sender signature\\\"\\n );\\n }\\n }\\n\\n require(\\n _verifyGuardianSignature(messageHash, guardianSignature),\\n \\\"PaymentRegistry: invalid guardian signature\\\"\\n );\\n\\n hash = _computePaymentChannelHash(\\n sender,\\n recipient,\\n token,\\n uid\\n );\\n\\n /// @dev calc payment value\\n paymentValue = amount.sub(paymentChannels[hash].committedAmount);\\n\\n require(\\n paymentValue != 0,\\n \\\"PaymentRegistry: invalid payment value\\\"\\n );\\n\\n paymentChannels[hash].committedAmount = amount;\\n\\n _verifyDepositExitOrDeployAccount(sender, token);\\n\\n depositAccount = deposits[sender].account;\\n\\n emit PaymentChannelCommitted(\\n hash,\\n sender,\\n recipient,\\n token,\\n uid,\\n amount\\n );\\n\\n return (hash, depositAccount, paymentValue);\\n }\\n\\n function _transferFromDeposit(\\n address depositAccount,\\n address to,\\n address token,\\n uint256 value\\n )\\n private\\n {\\n if (token == address(0)) {\\n PaymentDepositAccount(payable(depositAccount)).executeTransaction(\\n to,\\n value,\\n new bytes(0)\\n );\\n } else {\\n bytes memory response = PaymentDepositAccount(payable(depositAccount)).executeTransaction(\\n token,\\n 0,\\n abi.encodeWithSelector(\\n ERC20Token(token).transfer.selector,\\n to,\\n value\\n )\\n );\\n\\n if (response.length > 0) {\\n require(\\n abi.decode(response, (bool)),\\n \\\"PaymentRegistry: ERC20Token transfer reverted\\\"\\n );\\n }\\n }\\n }\\n\\n function _transferSplitFromDeposit(\\n address depositAccount,\\n address to,\\n address token,\\n uint256 paymentValue,\\n uint256 depositValue\\n )\\n private\\n {\\n require(\\n depositValue > 0,\\n \\\"PaymentRegistry: invalid deposit value\\\"\\n );\\n\\n uint256 withdrawValue = paymentValue.sub(depositValue);\\n\\n require(\\n withdrawValue > 0,\\n \\\"PaymentRegistry: invalid withdraw value\\\"\\n );\\n\\n _transferFromDeposit(\\n depositAccount,\\n to,\\n token,\\n withdrawValue\\n );\\n\\n _transferFromDeposit(\\n depositAccount,\\n _computeDepositAccountAddress(to),\\n token,\\n depositValue\\n );\\n }\\n\\n // private functions (views)\\n\\n function _computeDepositAccountAddress(\\n address owner\\n )\\n private\\n view\\n returns (address)\\n {\\n bytes32 salt = keccak256(\\n abi.encodePacked(\\n owner\\n )\\n );\\n\\n bytes memory creationCode = type(PaymentDepositAccount).creationCode;\\n\\n bytes32 data = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n salt,\\n keccak256(creationCode)\\n )\\n );\\n\\n return address(uint160(uint256(data)));\\n }\\n\\n function _hashDepositWithdrawal(\\n address owner,\\n address token,\\n uint256 amount\\n )\\n private\\n view\\n returns (bytes32)\\n {\\n return _hashMessagePayload(HASH_PREFIX_DEPOSIT_WITHDRAWAL, abi.encodePacked(\\n owner,\\n token,\\n amount\\n ));\\n }\\n\\n function _hashPaymentChannelCommit(\\n address sender,\\n address recipient,\\n address token,\\n bytes32 uid,\\n uint256 blockNumber,\\n uint256 amount\\n )\\n private\\n view\\n returns (bytes32)\\n {\\n return _hashMessagePayload(HASH_PREFIX_PAYMENT_CHANNEL_COMMIT, abi.encodePacked(\\n sender,\\n recipient,\\n token,\\n uid,\\n blockNumber,\\n amount\\n ));\\n }\\n\\n // private functions (pure)\\n\\n function _computePaymentChannelHash(\\n address sender,\\n address recipient,\\n address token,\\n bytes32 uid\\n )\\n private\\n pure\\n returns (bytes32)\\n {\\n return keccak256(\\n abi.encodePacked(\\n sender,\\n recipient,\\n token,\\n uid\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x84d3f908a35ba0f9dcc3e37808b42cdad0b81285ec006c96d25302d8dffa2704\",\"license\":\"MIT\"},\"src/personal/PersonalAccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/access/Guarded.sol\\\";\\nimport \\\"../common/account/AccountController.sol\\\";\\nimport \\\"../common/account/AccountRegistry.sol\\\";\\nimport \\\"../common/libs/BlockLib.sol\\\";\\nimport \\\"../common/libs/ECDSALib.sol\\\";\\nimport \\\"../common/libs/ECDSAExtendedLib.sol\\\";\\nimport \\\"../common/libs/SafeMathLib.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/token/ERC20Token.sol\\\";\\nimport \\\"../gateway/GatewayRecipient.sol\\\";\\n\\n\\n/**\\n * @title Personal account registry\\n *\\n * @notice A registry for personal (controlled by owners) accounts\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract PersonalAccountRegistry is Guarded, AccountController, AccountRegistry, Initializable, GatewayRecipient {\\n using BlockLib for BlockLib.BlockRelated;\\n using SafeMathLib for uint256;\\n using ECDSALib for bytes32;\\n using ECDSAExtendedLib for bytes;\\n\\n struct Account {\\n bool deployed;\\n bytes32 salt;\\n mapping(address => BlockLib.BlockRelated) owners;\\n }\\n\\n mapping(address => Account) private accounts;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the new owner is added\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerAdded(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the existing owner is removed\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerRemoved(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the call is refunded\\n * @param account account address\\n * @param beneficiary beneficiary address\\n * @param token token address\\n * @param value value\\n */\\n event AccountCallRefunded(\\n address account,\\n address beneficiary,\\n address token,\\n uint256 value\\n );\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor() public Initializable() {}\\n\\n // external functions\\n\\n /**\\n * @notice Initializes `PersonalAccountRegistry` contract\\n * @param guardians_ array of guardians addresses\\n * @param accountImplementation_ account implementation address\\n * @param gateway_ `Gateway` contract address\\n */\\n function initialize(\\n address[] calldata guardians_,\\n address accountImplementation_,\\n address gateway_\\n )\\n external\\n onlyInitializer\\n {\\n // Guarded\\n _initializeGuarded(guardians_);\\n\\n // AccountController\\n _initializeAccountController(address(this), accountImplementation_);\\n\\n // GatewayRecipient\\n _initializeGatewayRecipient(gateway_);\\n }\\n\\n /**\\n * @notice Upgrades `PersonalAccountRegistry` contract\\n * @param accountImplementation_ account implementation address\\n */\\n function upgrade(\\n address accountImplementation_\\n )\\n external\\n onlyGuardian\\n {\\n _setAccountImplementation(accountImplementation_, true);\\n }\\n\\n /**\\n * @notice Deploys account\\n * @param account account address\\n */\\n function deployAccount(\\n address account\\n )\\n external\\n {\\n _verifySender(account);\\n _deployAccount(account);\\n }\\n\\n /**\\n * @notice Upgrades account\\n * @param account account address\\n */\\n function upgradeAccount(\\n address account\\n )\\n external\\n {\\n _verifySender(account);\\n _upgradeAccount(account, true);\\n }\\n\\n /**\\n * @notice Adds a new account owner\\n * @param account account address\\n * @param owner owner address\\n */\\n function addAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n {\\n _verifySender(account);\\n\\n require(\\n owner != address(0),\\n \\\"PersonalAccountRegistry: cannot add 0x0 owner\\\"\\n );\\n\\n require(\\n !accounts[account].owners[owner].verifyAtCurrentBlock(),\\n \\\"PersonalAccountRegistry: owner already exists\\\"\\n );\\n\\n accounts[account].owners[owner].added = true;\\n accounts[account].owners[owner].removedAtBlockNumber = 0;\\n\\n emit AccountOwnerAdded(\\n account,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Removes the existing account owner\\n * @param account account address\\n * @param owner owner address\\n */\\n function removeAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n {\\n address sender = _verifySender(account);\\n\\n require(\\n owner != sender,\\n \\\"PersonalAccountRegistry: cannot remove self\\\"\\n );\\n\\n require(\\n accounts[account].owners[owner].verifyAtCurrentBlock(),\\n \\\"PersonalAccountRegistry: owner doesn't exist\\\"\\n );\\n\\n accounts[account].owners[owner].removedAtBlockNumber = block.number;\\n\\n emit AccountOwnerRemoved(\\n account,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Executes account transaction\\n * @dev Deploys an account if not deployed yet\\n * @param account account address\\n * @param to to address\\n * @param value value\\n * @param data data\\n */\\n function executeAccountTransaction(\\n address account,\\n address to,\\n uint256 value,\\n bytes calldata data\\n )\\n external\\n {\\n _verifySender(account);\\n\\n _deployAccount(account);\\n\\n _executeAccountTransaction(\\n account,\\n to,\\n value,\\n data,\\n true\\n );\\n }\\n\\n /**\\n * @notice Refunds account call\\n * @dev Deploys an account if not deployed yet\\n * @param account account address\\n * @param token token address\\n * @param value value\\n */\\n function refundAccountCall(\\n address account,\\n address token,\\n uint256 value\\n )\\n external\\n {\\n _verifySender(account);\\n\\n _deployAccount(account);\\n\\n /* solhint-disable avoid-tx-origin */\\n\\n if (token == address(0)) {\\n _executeAccountTransaction(\\n account,\\n tx.origin,\\n value,\\n new bytes(0),\\n false\\n );\\n } else {\\n bytes memory response = _executeAccountTransaction(\\n account,\\n token,\\n 0,\\n abi.encodeWithSelector(\\n ERC20Token(token).transfer.selector,\\n tx.origin,\\n value\\n ),\\n false\\n );\\n\\n if (response.length > 0) {\\n require(\\n abi.decode(response, (bool)),\\n \\\"PersonalAccountRegistry: ERC20Token transfer reverted\\\"\\n );\\n }\\n }\\n\\n emit AccountCallRefunded(\\n account,\\n tx.origin,\\n token,\\n value\\n );\\n\\n /* solhint-enable avoid-tx-origin */\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Computes account address\\n * @param saltOwner salt owner address\\n * @return account address\\n */\\n function computeAccountAddress(\\n address saltOwner\\n )\\n external\\n view\\n returns (address)\\n {\\n return _computeAccountAddress(saltOwner);\\n }\\n\\n /**\\n * @notice Checks if account is deployed\\n * @param account account address\\n * @return true when account is deployed\\n */\\n function isAccountDeployed(\\n address account\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].deployed;\\n }\\n\\n /**\\n * @notice Verifies the owner of the account at the current block\\n * @param account account address\\n * @param owner owner address\\n * @return true on correct account owner\\n */\\n function verifyAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n view\\n returns (bool)\\n {\\n return _verifyAccountOwner(account, owner);\\n }\\n\\n /**\\n * @notice Verifies the owner of the account at a specific block\\n * @param account account address\\n * @param owner owner address\\n * @param blockNumber block number to verify\\n * @return true on correct account owner\\n */\\n function verifyAccountOwnerAtBlock(\\n address account,\\n address owner,\\n uint256 blockNumber\\n )\\n external\\n view\\n returns (bool)\\n {\\n bool result = false;\\n\\n if (_verifyAccountOwner(account, owner)) {\\n result = true;\\n } else {\\n result = accounts[account].owners[owner].verifyAtBlock(blockNumber);\\n }\\n\\n return result;\\n }\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param messageHash message hash\\n * @param signature signature\\n * @return magic hash if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n override\\n external\\n view\\n returns (bool)\\n {\\n return _verifyAccountOwner(\\n account,\\n messageHash.recoverAddress(signature)\\n );\\n }\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param message message\\n * @param signature signature\\n * @return magic hash if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes calldata message,\\n bytes calldata signature\\n )\\n override\\n external\\n view\\n returns (bool)\\n {\\n return _verifyAccountOwner(\\n account,\\n message.toEthereumSignedMessageHash().recoverAddress(signature)\\n );\\n }\\n\\n // private functions\\n\\n function _verifySender(\\n address account\\n )\\n private\\n returns (address)\\n {\\n address sender = _getContextSender();\\n\\n if (accounts[account].owners[sender].added) {\\n require(\\n accounts[account].owners[sender].removedAtBlockNumber == 0,\\n \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n );\\n } else {\\n require(\\n accounts[account].salt == 0,\\n \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n );\\n\\n bytes32 salt = keccak256(\\n abi.encodePacked(sender)\\n );\\n\\n require(\\n account == _computeAccountAddress(salt),\\n \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n );\\n\\n accounts[account].salt = salt;\\n accounts[account].owners[sender].added = true;\\n\\n emit AccountOwnerAdded(\\n account,\\n sender\\n );\\n }\\n\\n return sender;\\n }\\n\\n function _deployAccount(\\n address account\\n )\\n internal\\n {\\n if (!accounts[account].deployed) {\\n _deployAccount(\\n accounts[account].salt,\\n true\\n );\\n\\n accounts[account].deployed = true;\\n }\\n }\\n\\n // private functions (views)\\n\\n function _computeAccountAddress(\\n address saltOwner\\n )\\n private\\n view\\n returns (address)\\n {\\n bytes32 salt = keccak256(\\n abi.encodePacked(saltOwner)\\n );\\n\\n return _computeAccountAddress(salt);\\n }\\n\\n function _verifyAccountOwner(\\n address account,\\n address owner\\n )\\n private\\n view\\n returns (bool)\\n {\\n bool result;\\n\\n if (accounts[account].owners[owner].added) {\\n result = accounts[account].owners[owner].removedAtBlockNumber == 0;\\n } else if (accounts[account].salt == 0) {\\n result = account == _computeAccountAddress(owner);\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xdae162610e707ab8c394b3edf924b75ef1f315520935cb88f4280b29eeaf4b61\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5032600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060004690508060028190555050614c138061006e6000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c80639130c06e116100de578063c36326e711610097578063da1b213d11610071578063da1b213d146104bb578063dc7d6c31146104d7578063df04338014610507578063e0fe396e146105235761018e565b8063c36326e71461043d578063d0f710d61461046d578063d2c83b9a1461049d5761018e565b80639130c06e146103915780639a85fae2146103ad5780639a8a0592146103c9578063a526d83b146103e7578063b0274a7314610403578063bdff4b3b1461041f5761018e565b80636121fcfc1161014b578063714041561161012557806371404156146102f757806384389a2b1461031357806387d31313146103435780638a1773ab146103615761018e565b80636121fcfc1461028f5780636524a947146102bf5780636866da52146102db5761018e565b80630c68ba2114610193578063116191b6146101c35780632e4f161e146101e15780632e7037a014610211578063392e53cd1461024157806360bf4df21461025f575b600080fd5b6101ad60048036038101906101a89190612f83565b61053f565b6040516101ba91906140a9565b60405180910390f35b6101cb610594565b6040516101d89190613e92565b60405180910390f35b6101fb60048036038101906101f69190612fe8565b6105ba565b60405161020891906140c4565b60405180910390f35b61022b600480360381019061022691906133f5565b6105d2565b60405161023891906140c4565b60405180910390f35b6102496105f2565b60405161025691906140a9565b60405180910390f35b61027960048036038101906102749190612f83565b61064a565b6040516102869190613e92565b60405180910390f35b6102a960048036038101906102a49190612f83565b61065c565b6040516102b691906140a9565b60405180910390f35b6102d960048036038101906102d49190612f83565b6106f7565b005b6102f560048036038101906102f0919061320c565b610703565b005b610311600480360381019061030c9190612f83565b610a28565b005b61032d6004803603810190610328919061341e565b610c40565b60405161033a91906140c4565b60405180910390f35b61034b610c6f565b6040516103589190614200565b60405180910390f35b61037b600480360381019061037691906132a1565b610c95565b604051610388919061449d565b60405180910390f35b6103ab60048036038101906103a69190612f83565b610cb5565b005b6103c760048036038101906103c2919061304b565b610fe9565b005b6103d16110f4565b6040516103de919061449d565b60405180910390f35b61040160048036038101906103fc9190612f83565b6110fa565b005b61041d60048036038101906104189190612f83565b611191565b005b6104276113ac565b604051610434919061449d565b60405180910390f35b61045760048036038101906104529190612fac565b6113b2565b604051610464919061449d565b60405180910390f35b610487600480360381019061048291906132ca565b61143c565b60405161049491906140a9565b60405180910390f35b6104a5611495565b6040516104b291906141e5565b60405180910390f35b6104d560048036038101906104d09190613121565b6114bb565b005b6104f160048036038101906104ec9190612fac565b6115c2565b6040516104fe919061449d565b60405180910390f35b610521600480360381019061051c919061304b565b61164c565b005b61053d60048036038101906105389190613363565b61174f565b005b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006105c885858585611955565b9050949350505050565b60006105eb82600001518360200151846040015161198e565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b6000610655826119e6565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b61070081611a84565b50565b600061070d611c94565b905060006107a3600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205486611ca590919063ffffffff16565b9050600081116107e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107df9061435d565b60405180910390fd5b60006107f583888861198e565b90506108458186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611cd2565b610884576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087b9061447d565b60405180910390fd5b85600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506109128388611d3f565b610980600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848985611efc565b7f95f66b073d65f18e43f6b76c7ab8557787f5f766d86cab7c9c76f41be9f8abc6600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848989604051610a179493929190613f51565b60405180910390a150505050505050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610ab3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aaa9061433d565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161415610b22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b199061443d565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610bad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba4906143dd565b60405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b3282604051610c35929190613ec8565b60405180910390a150565b6000610c68826000015183602001518460400151856060015186608001518760a0015161218c565b9050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060086000838152602001908152602001600020600001549050919050565b6000610cbf611c94565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000811415610d89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d80906142fd565b60405180910390fd5b42811115610dcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc39061437d565b60405180910390fd5b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610f0d578173ffffffffffffffffffffffffffffffffffffffff16319050610f99565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401610f469190613e92565b60206040518083038186803b158015610f5e57600080fd5b505afa158015610f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f969190613447565b90505b610fa582858784611efc565b7f5300d9a2838baade7cdc628c82cb80c1298853ba5f389d51e2b47330336aeffc82858784604051610fda9493929190613f51565b60405180910390a15050505050565b6000610ff3611c94565b905060008060006110928d858e8e8e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b9250925092506110ac826110a5866119e6565b8e84611efc565b7f771bc0494e1a2fcbef19a8762845000d8c4500454c756a7370c955e39ed60fd483826040516110dd929190614140565b60405180910390a150505050505050505050505050565b60025481565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117c9061433d565b60405180910390fd5b61118e81612691565b50565b600061119b611c94565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114611264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125b9061429d565b60405180910390fd5b61126d82611a84565b6112826006544261282090919063ffffffff16565b905080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fed3c8c6cdfc6d7b91dc9db3e1f54866587c26c3c3e0f9e32cd1944974be43a50600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683858460405161139f9493929190613f51565b60405180910390a1505050565b60065481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600061148c8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611cd2565b90509392505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006114c5611c94565b905060008060006115648e858f8f8f8f8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b92509250925061157782858f848d612875565b7f8b67efde501ee9cd0e771f7436554c44a5c076239ff3a6fbb397646a4689c0f283828b6040516115aa93929190614169565b60405180910390a15050505050505050505050505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000611656611c94565b905060008060006116f58d858e8e8e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b92509250925061170782858e84611efc565b7f6675346cd43846f7d47c310d39fb5c15bc7db66b3770338cdf1f133613a5ae988382604051611738929190614140565b60405180910390a150505050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146117df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d69061427d565b60405180910390fd5b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008414156118bb576224ea006006819055506118c3565b836006819055505b61190d838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505061293a565b61191681612992565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516119459190613ead565b60405180910390a1505050505050565b60008484848460405160200161196e9493929190613cd9565b604051602081830303815290604052805190602001209050949350505050565b60006119dd7f3b3087c8f883f1f44cabe66444f5f9d96f69de6a88f364ea10959eef0331414a8585856040516020016119c993929190613d97565b6040516020818303038152906040526129d6565b90509392505050565b600080826040516020016119fa9190613cbe565b604051602081830303815290604052805190602001209050606060405180602001611a2490612cff565b6020820181038252601f19601f820116604052509050600060ff60f81b30848480519060200120604051602001611a5e9493929190613dd4565b6040516020818303038152906040528051906020012090508060001c9350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff16600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611c9157600081604051602001611b2e9190613cbe565b60405160208183030381529060405280519060200120905080604051611b5390612cff565b8190604051809103906000f5905080158015611b73573d6000803e3d6000fd5b50600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd80572c0f2f24f2d9d726d831bd860ed82b12bafaf01cfb6e4d38fb23c4347e9600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051611c87929190613ef1565b60405180910390a1505b50565b6000611ca06028612a17565b905090565b6000611cca8383604051806060016040528060218152602001614be660219139612aac565b905092915050565b600080611ce88385612b0190919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611eee576000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fa19281a6f3163da06f6b82f3ecf0130493c52aba23cdc2a312f652742f0d1801600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168383604051611ee193929190613f1a565b60405180910390a1611ef8565b611ef782611a84565b5b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612016578373ffffffffffffffffffffffffffffffffffffffff16633f579f428483600067ffffffffffffffff81118015611f6757600080fd5b506040519080825280601f01601f191660200182016040528015611f9a5781602001600182028036833780820191505090505b506040518463ffffffff1660e01b8152600401611fb99392919061406b565b600060405180830381600087803b158015611fd357600080fd5b505af1158015611fe7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906120109190613322565b50612186565b60608473ffffffffffffffffffffffffffffffffffffffff16633f579f4284600063a9059cbb60e01b8887604051602401612052929190614042565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518463ffffffff1660e01b81526004016120cd93929190614004565b600060405180830381600087803b1580156120e757600080fd5b505af11580156120fb573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121249190613322565b905060008151111561218457808060200190518101906121449190613278565b612183576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217a9061431d565b60405180910390fd5b5b505b50505050565b60006121e17f745089e29f2abf28f618236a5dc04d214ac05ead3440ba532b69e9d160ba2e728888888888886040516020016121cd96959493929190613d27565b6040516020818303038152906040526129d6565b90509695505050505050565b6000806000806122018c8c8c8c8c8c61218c565b905060008651141561230057600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359b52ef88d838b6040518463ffffffff1660e01b815260040161226c93929190613fcd565b60206040518083038186803b15801561228457600080fd5b505afa158015612298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122bc9190613278565b6122fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f29061447d565b60405180910390fd5b6124f1565b60006123158783612b0190919063ffffffff16565b90508073ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff16146124ef57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166334d323a48e838c6040518463ffffffff1660e01b81526004016123a993929190613f96565b60206040518083038186803b1580156123c157600080fd5b505afa1580156123d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f99190613278565b806124af5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166334d323a48e838c6040518463ffffffff1660e01b815260040161245e93929190613f96565b60206040518083038186803b15801561247657600080fd5b505afa15801561248a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ae9190613278565b5b6124ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e5906143bd565b60405180910390fd5b5b505b6124fb8186611cd2565b61253a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125319061447d565b60405180910390fd5b6125468c8c8c8c611955565b9350612571600860008681526020019081526020016000206000015488611ca590919063ffffffff16565b915060008214156125b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ae906142bd565b60405180910390fd5b8660086000868152602001908152602001600020600001819055506125dc8c8b611d3f565b600760008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692507f0d1cb77d1fe491f98926195d0b885509da18bc305dd1489f45610237d971ed46848d8d8d8d8c60405161267a969594939291906140df565b60405180910390a150985098509895505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612701576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f89061425d565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561278d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127849061441d565b60405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a3282604051612815929190613ec8565b60405180910390a150565b60008082840190508381101561286b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612862906143fd565b60405180910390fd5b8091505092915050565b600081116128b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128af9061423d565b60405180910390fd5b60006128cd8284611ca590919063ffffffff16565b905060008111612912576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129099061439d565b60405180910390fd5b61291e86868684611efc565b6129328661292b876119e6565b8685611efc565b505050505050565b6000815114156129525761294d32612691565b61298f565b60008151905060005b8181101561298c5761297f83828151811061297257fe5b6020026020010151612691565b808060010191505061295b565b50505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000612a0f6002543085856040516020016129f49493929190613e48565b60405160208183030381529060405280519060200120612bbc565b905092915050565b60008060009050612a26612bec565b15612a9f576000836000369050039050612a9760003683906014850192612a4f9392919061455f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612c99565b915050612aa3565b3390505b80915050919050565b6000838311158290612af4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aeb919061421b565b60405180910390fd5b5082840390509392505050565b60008060009050604183511415612bb25760008060006020860151925060408601519150606086015160001a9050601b8160ff161015612b4257601b810190505b601b8160ff161480612b575750601c8160ff16145b15612bae5760018782858560405160008152602001604052604051612b7f94939291906141a0565b6020604051602081039080840390855afa158015612ba1573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b600081604051602001612bcf9190613e22565b604051602081830303815290604052805190602001209050919050565b600080600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612c9257602c60003690501015612c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c84906142dd565b60405180910390fd5b600190505b8091505090565b6000806014835114612ce0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd79061445d565b60405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b6103f7806147ef83390190565b600081359050612d1b81614764565b92915050565b60008083601f840112612d3357600080fd5b8235905067ffffffffffffffff811115612d4c57600080fd5b602083019150836020820283011115612d6457600080fd5b9250929050565b600081519050612d7a8161477b565b92915050565b600081359050612d8f81614792565b92915050565b60008083601f840112612da757600080fd5b8235905067ffffffffffffffff811115612dc057600080fd5b602083019150836001820283011115612dd857600080fd5b9250929050565b600082601f830112612df057600080fd5b8151612e03612dfe826144e5565b6144b8565b91508082526020830160208301858383011115612e1f57600080fd5b612e2a8382846146d1565b50505092915050565b600081359050612e42816147a9565b92915050565b600081359050612e57816147c0565b92915050565b600060608284031215612e6f57600080fd5b612e7960606144b8565b90506000612e8984828501612d0c565b6000830152506020612e9d84828501612d0c565b6020830152506040612eb184828501612f59565b60408301525092915050565b600060c08284031215612ecf57600080fd5b612ed960c06144b8565b90506000612ee984828501612d0c565b6000830152506020612efd84828501612d0c565b6020830152506040612f1184828501612d0c565b6040830152506060612f2584828501612d80565b6060830152506080612f3984828501612f59565b60808301525060a0612f4d84828501612f59565b60a08301525092915050565b600081359050612f68816147d7565b92915050565b600081519050612f7d816147d7565b92915050565b600060208284031215612f9557600080fd5b6000612fa384828501612d0c565b91505092915050565b60008060408385031215612fbf57600080fd5b6000612fcd85828601612d0c565b9250506020612fde85828601612d0c565b9150509250929050565b60008060008060808587031215612ffe57600080fd5b600061300c87828801612d0c565b945050602061301d87828801612d0c565b935050604061302e87828801612d0c565b925050606061303f87828801612d80565b91505092959194509250565b600080600080600080600080600060e08a8c03121561306957600080fd5b60006130778c828d01612d0c565b99505060206130888c828d01612d0c565b98505060406130998c828d01612d80565b97505060606130aa8c828d01612f59565b96505060806130bb8c828d01612f59565b95505060a08a013567ffffffffffffffff8111156130d857600080fd5b6130e48c828d01612d95565b945094505060c08a013567ffffffffffffffff81111561310357600080fd5b61310f8c828d01612d95565b92509250509295985092959850929598565b6000806000806000806000806000806101008b8d03121561314157600080fd5b600061314f8d828e01612d0c565b9a505060206131608d828e01612d0c565b99505060406131718d828e01612d80565b98505060606131828d828e01612f59565b97505060806131938d828e01612f59565b96505060a06131a48d828e01612f59565b95505060c08b013567ffffffffffffffff8111156131c157600080fd5b6131cd8d828e01612d95565b945094505060e08b013567ffffffffffffffff8111156131ec57600080fd5b6131f88d828e01612d95565b92509250509295989b9194979a5092959850565b6000806000806060858703121561322257600080fd5b600061323087828801612d0c565b945050602061324187828801612f59565b935050604085013567ffffffffffffffff81111561325e57600080fd5b61326a87828801612d95565b925092505092959194509250565b60006020828403121561328a57600080fd5b600061329884828501612d6b565b91505092915050565b6000602082840312156132b357600080fd5b60006132c184828501612d80565b91505092915050565b6000806000604084860312156132df57600080fd5b60006132ed86828701612d80565b935050602084013567ffffffffffffffff81111561330a57600080fd5b61331686828701612d95565b92509250509250925092565b60006020828403121561333457600080fd5b600082015167ffffffffffffffff81111561334e57600080fd5b61335a84828501612ddf565b91505092915050565b60008060008060008060a0878903121561337c57600080fd5b600061338a89828a01612e33565b965050602061339b89828a01612e48565b95505060406133ac89828a01612f59565b945050606087013567ffffffffffffffff8111156133c957600080fd5b6133d589828a01612d21565b935093505060806133e889828a01612d0c565b9150509295509295509295565b60006060828403121561340757600080fd5b600061341584828501612e5d565b91505092915050565b600060c0828403121561343057600080fd5b600061343e84828501612ebd565b91505092915050565b60006020828403121561345957600080fd5b600061346784828501612f6e565b91505092915050565b61347981614641565b82525050565b61348881614592565b82525050565b61349f61349a82614592565b614704565b82525050565b6134ae816145a4565b82525050565b6134c56134c0826145b0565b614716565b82525050565b6134d4816145dc565b82525050565b6134eb6134e6826145dc565b614720565b82525050565b60006134fc82614511565b6135068185614527565b93506135168185602086016146d1565b61351f81614746565b840191505092915050565b600061353582614511565b61353f8185614538565b935061354f8185602086016146d1565b80840191505092915050565b61356481614653565b82525050565b61357381614677565b82525050565b6135828161469b565b82525050565b60006135938261451c565b61359d8185614543565b93506135ad8185602086016146d1565b6135b681614746565b840191505092915050565b60006135ce602683614543565b91507f5061796d656e7452656769737472793a20696e76616c6964206465706f73697460008301527f2076616c756500000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613634601c83614554565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b6000613674602083614543565b91507f477561726465643a2063616e6e6f74206164642030783020677561726469616e6000830152602082019050919050565b60006136b4602f83614543565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b600061371a602f83614543565b91507f5061796d656e7452656769737472793a206465706f736974206578697420616c60008301527f72656164792072657175657374656400000000000000000000000000000000006020830152604082019050919050565b6000613780602683614543565b91507f5061796d656e7452656769737472793a20696e76616c6964207061796d656e7460008301527f2076616c756500000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137e6602283614543565b91507f47617465776179526563697069656e743a20696e76616c6964206d73672e646160008301527f74610000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061384c602b83614543565b91507f5061796d656e7452656769737472793a206465706f7369742065786974206e6f60008301527f74207265717565737465640000000000000000000000000000000000000000006020830152604082019050919050565b60006138b2602d83614543565b91507f5061796d656e7452656769737472793a204552433230546f6b656e207472616e60008301527f73666572207265766572746564000000000000000000000000000000000000006020830152604082019050919050565b6000613918602683614543565b91507f477561726465643a2074782e6f726967696e206973206e6f742074686520677560008301527f61726469616e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061397e601f83614543565b91507f5061796d656e7452656769737472793a20696e76616c696420616d6f756e74006000830152602082019050919050565b60006139be602483614543565b91507f5061796d656e7452656769737472793a206465706f7369742065786974206c6f60008301527f636b6564000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a24602783614543565b91507f5061796d656e7452656769737472793a20696e76616c6964207769746864726160008301527f772076616c7565000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a8a602983614543565b91507f5061796d656e7452656769737472793a20696e76616c69642073656e6465722060008301527f7369676e617475726500000000000000000000000000000000000000000000006020830152604082019050919050565b6000613af0601f83614543565b91507f477561726465643a20677561726469616e20646f65736e2774206578697374006000830152602082019050919050565b6000613b30601e83614543565b91507f536166654d6174684c69623a206164646974696f6e206f766572666c6f7700006000830152602082019050919050565b6000613b70602083614543565b91507f477561726465643a20677561726469616e20616c7265616479206578697374736000830152602082019050919050565b6000613bb0601b83614543565b91507f477561726465643a2063616e6e6f742072656d6f76652073656c6600000000006000830152602082019050919050565b6000613bf0601d83614543565b91507f42797465734c69623a20696e76616c69642064617461206c656e6774680000006000830152602082019050919050565b6000613c30602b83614543565b91507f5061796d656e7452656769737472793a20696e76616c6964206775617264696160008301527f6e207369676e61747572650000000000000000000000000000000000000000006020830152604082019050919050565b613c928161462a565b82525050565b613ca9613ca48261462a565b61473c565b82525050565b613cb881614634565b82525050565b6000613cca828461348e565b60148201915081905092915050565b6000613ce5828761348e565b601482019150613cf5828661348e565b601482019150613d05828561348e565b601482019150613d1582846134da565b60208201915081905095945050505050565b6000613d33828961348e565b601482019150613d43828861348e565b601482019150613d53828761348e565b601482019150613d6382866134da565b602082019150613d738285613c98565b602082019150613d838284613c98565b602082019150819050979650505050505050565b6000613da3828661348e565b601482019150613db3828561348e565b601482019150613dc38284613c98565b602082019150819050949350505050565b6000613de082876134b4565b600182019150613df0828661348e565b601482019150613e0082856134da565b602082019150613e1082846134da565b60208201915081905095945050505050565b6000613e2d82613627565b9150613e3982846134da565b60208201915081905092915050565b6000613e548287613c98565b602082019150613e64828661348e565b601482019150613e7482856134da565b602082019150613e84828461352a565b915081905095945050505050565b6000602082019050613ea7600083018461347f565b92915050565b6000602082019050613ec26000830184613470565b92915050565b6000604082019050613edd6000830185613470565b613eea602083018461347f565b9392505050565b6000604082019050613f06600083018561347f565b613f13602083018461347f565b9392505050565b6000606082019050613f2f600083018661347f565b613f3c602083018561347f565b613f49604083018461347f565b949350505050565b6000608082019050613f66600083018761347f565b613f73602083018661347f565b613f80604083018561347f565b613f8d6060830184613c89565b95945050505050565b6000606082019050613fab600083018661347f565b613fb8602083018561347f565b613fc56040830184613c89565b949350505050565b6000606082019050613fe2600083018661347f565b613fef60208301856134cb565b613ffc6040830184613c89565b949350505050565b6000606082019050614019600083018661347f565b6140266020830185613579565b818103604083015261403881846134f1565b9050949350505050565b6000604082019050614057600083018561347f565b6140646020830184613c89565b9392505050565b6000606082019050614080600083018661347f565b61408d6020830185613c89565b818103604083015261409f81846134f1565b9050949350505050565b60006020820190506140be60008301846134a5565b92915050565b60006020820190506140d960008301846134cb565b92915050565b600060c0820190506140f460008301896134cb565b614101602083018861347f565b61410e604083018761347f565b61411b606083018661347f565b61412860808301856134cb565b61413560a0830184613c89565b979650505050505050565b600060408201905061415560008301856134cb565b6141626020830184613c89565b9392505050565b600060608201905061417e60008301866134cb565b61418b6020830185613c89565b6141986040830184613c89565b949350505050565b60006080820190506141b560008301876134cb565b6141c26020830186613caf565b6141cf60408301856134cb565b6141dc60608301846134cb565b95945050505050565b60006020820190506141fa600083018461355b565b92915050565b6000602082019050614215600083018461356a565b92915050565b600060208201905081810360008301526142358184613588565b905092915050565b60006020820190508181036000830152614256816135c1565b9050919050565b6000602082019050818103600083015261427681613667565b9050919050565b60006020820190508181036000830152614296816136a7565b9050919050565b600060208201905081810360008301526142b68161370d565b9050919050565b600060208201905081810360008301526142d681613773565b9050919050565b600060208201905081810360008301526142f6816137d9565b9050919050565b600060208201905081810360008301526143168161383f565b9050919050565b60006020820190508181036000830152614336816138a5565b9050919050565b600060208201905081810360008301526143568161390b565b9050919050565b6000602082019050818103600083015261437681613971565b9050919050565b60006020820190508181036000830152614396816139b1565b9050919050565b600060208201905081810360008301526143b681613a17565b9050919050565b600060208201905081810360008301526143d681613a7d565b9050919050565b600060208201905081810360008301526143f681613ae3565b9050919050565b6000602082019050818103600083015261441681613b23565b9050919050565b6000602082019050818103600083015261443681613b63565b9050919050565b6000602082019050818103600083015261445681613ba3565b9050919050565b6000602082019050818103600083015261447681613be3565b9050919050565b6000602082019050818103600083015261449681613c23565b9050919050565b60006020820190506144b26000830184613c89565b92915050565b6000604051905081810181811067ffffffffffffffff821117156144db57600080fd5b8060405250919050565b600067ffffffffffffffff8211156144fc57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000808585111561456f57600080fd5b8386111561457c57600080fd5b6001850283019150848603905094509492505050565b600061459d8261460a565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b60006145f182614592565b9050919050565b600061460382614592565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061464c826146ad565b9050919050565b600061465e82614665565b9050919050565b60006146708261460a565b9050919050565b600061468282614689565b9050919050565b60006146948261460a565b9050919050565b60006146a68261462a565b9050919050565b60006146b8826146bf565b9050919050565b60006146ca8261460a565b9050919050565b60005b838110156146ef5780820151818401526020810190506146d4565b838111156146fe576000848401525b50505050565b600061470f8261472a565b9050919050565b6000819050919050565b6000819050919050565b600061473582614757565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61476d81614592565b811461477857600080fd5b50565b614784816145a4565b811461478f57600080fd5b50565b61479b816145dc565b81146147a657600080fd5b50565b6147b2816145e6565b81146147bd57600080fd5b50565b6147c9816145f8565b81146147d457600080fd5b50565b6147e08161462a565b81146147eb57600080fd5b5056fe6080604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506103a4806100536000396000f3fe60806040526004361061002d5760003560e01c80633f579f4214610039578063f77c47911461016257610034565b3661003457005b600080fd5b34801561004557600080fd5b506100e76004803603606081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100a357600080fd5b8201836020820111156100b557600080fd5b803590602001918460018302840111640100000000831117156100d757600080fd5b90919293919293905050506101a3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561012757808201518184015260208101905061010c565b50505050905090810190601f1680156101545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016e57600080fd5b50610177610347565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061036c602c913960400191505060405180910390fd5b606060008673ffffffffffffffffffffffffffffffffffffffff1686868660405180838380828437808301925050509250505060006040518083038185875af1925050503d80600081146102b9576040519150601f19603f3d011682016040523d82523d6000602084013e6102be565b606091505b5080935081925050508061033a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4163636f756e743a207472616e73616374696f6e20726576657274656400000081525060200191505060405180910390fd5b8192505050949350505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fe436f6e74726f6c6c65643a206d73672e73656e646572206973206e6f742074686520636f6e74726f6c6c6572a164736f6c634300060c000a536166654d6174684c69623a207375627472616374696f6e206f766572666c6f77a164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c80639130c06e116100de578063c36326e711610097578063da1b213d11610071578063da1b213d146104bb578063dc7d6c31146104d7578063df04338014610507578063e0fe396e146105235761018e565b8063c36326e71461043d578063d0f710d61461046d578063d2c83b9a1461049d5761018e565b80639130c06e146103915780639a85fae2146103ad5780639a8a0592146103c9578063a526d83b146103e7578063b0274a7314610403578063bdff4b3b1461041f5761018e565b80636121fcfc1161014b578063714041561161012557806371404156146102f757806384389a2b1461031357806387d31313146103435780638a1773ab146103615761018e565b80636121fcfc1461028f5780636524a947146102bf5780636866da52146102db5761018e565b80630c68ba2114610193578063116191b6146101c35780632e4f161e146101e15780632e7037a014610211578063392e53cd1461024157806360bf4df21461025f575b600080fd5b6101ad60048036038101906101a89190612f83565b61053f565b6040516101ba91906140a9565b60405180910390f35b6101cb610594565b6040516101d89190613e92565b60405180910390f35b6101fb60048036038101906101f69190612fe8565b6105ba565b60405161020891906140c4565b60405180910390f35b61022b600480360381019061022691906133f5565b6105d2565b60405161023891906140c4565b60405180910390f35b6102496105f2565b60405161025691906140a9565b60405180910390f35b61027960048036038101906102749190612f83565b61064a565b6040516102869190613e92565b60405180910390f35b6102a960048036038101906102a49190612f83565b61065c565b6040516102b691906140a9565b60405180910390f35b6102d960048036038101906102d49190612f83565b6106f7565b005b6102f560048036038101906102f0919061320c565b610703565b005b610311600480360381019061030c9190612f83565b610a28565b005b61032d6004803603810190610328919061341e565b610c40565b60405161033a91906140c4565b60405180910390f35b61034b610c6f565b6040516103589190614200565b60405180910390f35b61037b600480360381019061037691906132a1565b610c95565b604051610388919061449d565b60405180910390f35b6103ab60048036038101906103a69190612f83565b610cb5565b005b6103c760048036038101906103c2919061304b565b610fe9565b005b6103d16110f4565b6040516103de919061449d565b60405180910390f35b61040160048036038101906103fc9190612f83565b6110fa565b005b61041d60048036038101906104189190612f83565b611191565b005b6104276113ac565b604051610434919061449d565b60405180910390f35b61045760048036038101906104529190612fac565b6113b2565b604051610464919061449d565b60405180910390f35b610487600480360381019061048291906132ca565b61143c565b60405161049491906140a9565b60405180910390f35b6104a5611495565b6040516104b291906141e5565b60405180910390f35b6104d560048036038101906104d09190613121565b6114bb565b005b6104f160048036038101906104ec9190612fac565b6115c2565b6040516104fe919061449d565b60405180910390f35b610521600480360381019061051c919061304b565b61164c565b005b61053d60048036038101906105389190613363565b61174f565b005b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006105c885858585611955565b9050949350505050565b60006105eb82600001518360200151846040015161198e565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b6000610655826119e6565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b61070081611a84565b50565b600061070d611c94565b905060006107a3600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205486611ca590919063ffffffff16565b9050600081116107e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107df9061435d565b60405180910390fd5b60006107f583888861198e565b90506108458186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611cd2565b610884576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087b9061447d565b60405180910390fd5b85600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506109128388611d3f565b610980600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848985611efc565b7f95f66b073d65f18e43f6b76c7ab8557787f5f766d86cab7c9c76f41be9f8abc6600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848989604051610a179493929190613f51565b60405180910390a150505050505050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610ab3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aaa9061433d565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161415610b22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b199061443d565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610bad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba4906143dd565b60405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b3282604051610c35929190613ec8565b60405180910390a150565b6000610c68826000015183602001518460400151856060015186608001518760a0015161218c565b9050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060086000838152602001908152602001600020600001549050919050565b6000610cbf611c94565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000811415610d89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d80906142fd565b60405180910390fd5b42811115610dcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc39061437d565b60405180910390fd5b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610f0d578173ffffffffffffffffffffffffffffffffffffffff16319050610f99565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401610f469190613e92565b60206040518083038186803b158015610f5e57600080fd5b505afa158015610f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f969190613447565b90505b610fa582858784611efc565b7f5300d9a2838baade7cdc628c82cb80c1298853ba5f389d51e2b47330336aeffc82858784604051610fda9493929190613f51565b60405180910390a15050505050565b6000610ff3611c94565b905060008060006110928d858e8e8e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b9250925092506110ac826110a5866119e6565b8e84611efc565b7f771bc0494e1a2fcbef19a8762845000d8c4500454c756a7370c955e39ed60fd483826040516110dd929190614140565b60405180910390a150505050505050505050505050565b60025481565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117c9061433d565b60405180910390fd5b61118e81612691565b50565b600061119b611c94565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114611264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125b9061429d565b60405180910390fd5b61126d82611a84565b6112826006544261282090919063ffffffff16565b905080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fed3c8c6cdfc6d7b91dc9db3e1f54866587c26c3c3e0f9e32cd1944974be43a50600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683858460405161139f9493929190613f51565b60405180910390a1505050565b60065481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600061148c8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611cd2565b90509392505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006114c5611c94565b905060008060006115648e858f8f8f8f8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b92509250925061157782858f848d612875565b7f8b67efde501ee9cd0e771f7436554c44a5c076239ff3a6fbb397646a4689c0f283828b6040516115aa93929190614169565b60405180910390a15050505050505050505050505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000611656611c94565b905060008060006116f58d858e8e8e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506121ed565b92509250925061170782858e84611efc565b7f6675346cd43846f7d47c310d39fb5c15bc7db66b3770338cdf1f133613a5ae988382604051611738929190614140565b60405180910390a150505050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146117df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d69061427d565b60405180910390fd5b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008414156118bb576224ea006006819055506118c3565b836006819055505b61190d838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505061293a565b61191681612992565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6326040516119459190613ead565b60405180910390a1505050505050565b60008484848460405160200161196e9493929190613cd9565b604051602081830303815290604052805190602001209050949350505050565b60006119dd7f3b3087c8f883f1f44cabe66444f5f9d96f69de6a88f364ea10959eef0331414a8585856040516020016119c993929190613d97565b6040516020818303038152906040526129d6565b90509392505050565b600080826040516020016119fa9190613cbe565b604051602081830303815290604052805190602001209050606060405180602001611a2490612cff565b6020820181038252601f19601f820116604052509050600060ff60f81b30848480519060200120604051602001611a5e9493929190613dd4565b6040516020818303038152906040528051906020012090508060001c9350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff16600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611c9157600081604051602001611b2e9190613cbe565b60405160208183030381529060405280519060200120905080604051611b5390612cff565b8190604051809103906000f5905080158015611b73573d6000803e3d6000fd5b50600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd80572c0f2f24f2d9d726d831bd860ed82b12bafaf01cfb6e4d38fb23c4347e9600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051611c87929190613ef1565b60405180910390a1505b50565b6000611ca06028612a17565b905090565b6000611cca8383604051806060016040528060218152602001614be660219139612aac565b905092915050565b600080611ce88385612b0190919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611eee576000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fa19281a6f3163da06f6b82f3ecf0130493c52aba23cdc2a312f652742f0d1801600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168383604051611ee193929190613f1a565b60405180910390a1611ef8565b611ef782611a84565b5b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612016578373ffffffffffffffffffffffffffffffffffffffff16633f579f428483600067ffffffffffffffff81118015611f6757600080fd5b506040519080825280601f01601f191660200182016040528015611f9a5781602001600182028036833780820191505090505b506040518463ffffffff1660e01b8152600401611fb99392919061406b565b600060405180830381600087803b158015611fd357600080fd5b505af1158015611fe7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906120109190613322565b50612186565b60608473ffffffffffffffffffffffffffffffffffffffff16633f579f4284600063a9059cbb60e01b8887604051602401612052929190614042565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518463ffffffff1660e01b81526004016120cd93929190614004565b600060405180830381600087803b1580156120e757600080fd5b505af11580156120fb573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121249190613322565b905060008151111561218457808060200190518101906121449190613278565b612183576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217a9061431d565b60405180910390fd5b5b505b50505050565b60006121e17f745089e29f2abf28f618236a5dc04d214ac05ead3440ba532b69e9d160ba2e728888888888886040516020016121cd96959493929190613d27565b6040516020818303038152906040526129d6565b90509695505050505050565b6000806000806122018c8c8c8c8c8c61218c565b905060008651141561230057600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359b52ef88d838b6040518463ffffffff1660e01b815260040161226c93929190613fcd565b60206040518083038186803b15801561228457600080fd5b505afa158015612298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122bc9190613278565b6122fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f29061447d565b60405180910390fd5b6124f1565b60006123158783612b0190919063ffffffff16565b90508073ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff16146124ef57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166334d323a48e838c6040518463ffffffff1660e01b81526004016123a993929190613f96565b60206040518083038186803b1580156123c157600080fd5b505afa1580156123d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f99190613278565b806124af5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166334d323a48e838c6040518463ffffffff1660e01b815260040161245e93929190613f96565b60206040518083038186803b15801561247657600080fd5b505afa15801561248a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ae9190613278565b5b6124ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e5906143bd565b60405180910390fd5b5b505b6124fb8186611cd2565b61253a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125319061447d565b60405180910390fd5b6125468c8c8c8c611955565b9350612571600860008681526020019081526020016000206000015488611ca590919063ffffffff16565b915060008214156125b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ae906142bd565b60405180910390fd5b8660086000868152602001908152602001600020600001819055506125dc8c8b611d3f565b600760008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692507f0d1cb77d1fe491f98926195d0b885509da18bc305dd1489f45610237d971ed46848d8d8d8d8c60405161267a969594939291906140df565b60405180910390a150985098509895505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612701576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f89061425d565b60405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561278d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127849061441d565b60405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a3282604051612815929190613ec8565b60405180910390a150565b60008082840190508381101561286b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612862906143fd565b60405180910390fd5b8091505092915050565b600081116128b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128af9061423d565b60405180910390fd5b60006128cd8284611ca590919063ffffffff16565b905060008111612912576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129099061439d565b60405180910390fd5b61291e86868684611efc565b6129328661292b876119e6565b8685611efc565b505050505050565b6000815114156129525761294d32612691565b61298f565b60008151905060005b8181101561298c5761297f83828151811061297257fe5b6020026020010151612691565b808060010191505061295b565b50505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000612a0f6002543085856040516020016129f49493929190613e48565b60405160208183030381529060405280519060200120612bbc565b905092915050565b60008060009050612a26612bec565b15612a9f576000836000369050039050612a9760003683906014850192612a4f9392919061455f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612c99565b915050612aa3565b3390505b80915050919050565b6000838311158290612af4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aeb919061421b565b60405180910390fd5b5082840390509392505050565b60008060009050604183511415612bb25760008060006020860151925060408601519150606086015160001a9050601b8160ff161015612b4257601b810190505b601b8160ff161480612b575750601c8160ff16145b15612bae5760018782858560405160008152602001604052604051612b7f94939291906141a0565b6020604051602081039080840390855afa158015612ba1573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b600081604051602001612bcf9190613e22565b604051602081830303815290604052805190602001209050919050565b600080600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612c9257602c60003690501015612c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c84906142dd565b60405180910390fd5b600190505b8091505090565b6000806014835114612ce0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd79061445d565b60405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b6103f7806147ef83390190565b600081359050612d1b81614764565b92915050565b60008083601f840112612d3357600080fd5b8235905067ffffffffffffffff811115612d4c57600080fd5b602083019150836020820283011115612d6457600080fd5b9250929050565b600081519050612d7a8161477b565b92915050565b600081359050612d8f81614792565b92915050565b60008083601f840112612da757600080fd5b8235905067ffffffffffffffff811115612dc057600080fd5b602083019150836001820283011115612dd857600080fd5b9250929050565b600082601f830112612df057600080fd5b8151612e03612dfe826144e5565b6144b8565b91508082526020830160208301858383011115612e1f57600080fd5b612e2a8382846146d1565b50505092915050565b600081359050612e42816147a9565b92915050565b600081359050612e57816147c0565b92915050565b600060608284031215612e6f57600080fd5b612e7960606144b8565b90506000612e8984828501612d0c565b6000830152506020612e9d84828501612d0c565b6020830152506040612eb184828501612f59565b60408301525092915050565b600060c08284031215612ecf57600080fd5b612ed960c06144b8565b90506000612ee984828501612d0c565b6000830152506020612efd84828501612d0c565b6020830152506040612f1184828501612d0c565b6040830152506060612f2584828501612d80565b6060830152506080612f3984828501612f59565b60808301525060a0612f4d84828501612f59565b60a08301525092915050565b600081359050612f68816147d7565b92915050565b600081519050612f7d816147d7565b92915050565b600060208284031215612f9557600080fd5b6000612fa384828501612d0c565b91505092915050565b60008060408385031215612fbf57600080fd5b6000612fcd85828601612d0c565b9250506020612fde85828601612d0c565b9150509250929050565b60008060008060808587031215612ffe57600080fd5b600061300c87828801612d0c565b945050602061301d87828801612d0c565b935050604061302e87828801612d0c565b925050606061303f87828801612d80565b91505092959194509250565b600080600080600080600080600060e08a8c03121561306957600080fd5b60006130778c828d01612d0c565b99505060206130888c828d01612d0c565b98505060406130998c828d01612d80565b97505060606130aa8c828d01612f59565b96505060806130bb8c828d01612f59565b95505060a08a013567ffffffffffffffff8111156130d857600080fd5b6130e48c828d01612d95565b945094505060c08a013567ffffffffffffffff81111561310357600080fd5b61310f8c828d01612d95565b92509250509295985092959850929598565b6000806000806000806000806000806101008b8d03121561314157600080fd5b600061314f8d828e01612d0c565b9a505060206131608d828e01612d0c565b99505060406131718d828e01612d80565b98505060606131828d828e01612f59565b97505060806131938d828e01612f59565b96505060a06131a48d828e01612f59565b95505060c08b013567ffffffffffffffff8111156131c157600080fd5b6131cd8d828e01612d95565b945094505060e08b013567ffffffffffffffff8111156131ec57600080fd5b6131f88d828e01612d95565b92509250509295989b9194979a5092959850565b6000806000806060858703121561322257600080fd5b600061323087828801612d0c565b945050602061324187828801612f59565b935050604085013567ffffffffffffffff81111561325e57600080fd5b61326a87828801612d95565b925092505092959194509250565b60006020828403121561328a57600080fd5b600061329884828501612d6b565b91505092915050565b6000602082840312156132b357600080fd5b60006132c184828501612d80565b91505092915050565b6000806000604084860312156132df57600080fd5b60006132ed86828701612d80565b935050602084013567ffffffffffffffff81111561330a57600080fd5b61331686828701612d95565b92509250509250925092565b60006020828403121561333457600080fd5b600082015167ffffffffffffffff81111561334e57600080fd5b61335a84828501612ddf565b91505092915050565b60008060008060008060a0878903121561337c57600080fd5b600061338a89828a01612e33565b965050602061339b89828a01612e48565b95505060406133ac89828a01612f59565b945050606087013567ffffffffffffffff8111156133c957600080fd5b6133d589828a01612d21565b935093505060806133e889828a01612d0c565b9150509295509295509295565b60006060828403121561340757600080fd5b600061341584828501612e5d565b91505092915050565b600060c0828403121561343057600080fd5b600061343e84828501612ebd565b91505092915050565b60006020828403121561345957600080fd5b600061346784828501612f6e565b91505092915050565b61347981614641565b82525050565b61348881614592565b82525050565b61349f61349a82614592565b614704565b82525050565b6134ae816145a4565b82525050565b6134c56134c0826145b0565b614716565b82525050565b6134d4816145dc565b82525050565b6134eb6134e6826145dc565b614720565b82525050565b60006134fc82614511565b6135068185614527565b93506135168185602086016146d1565b61351f81614746565b840191505092915050565b600061353582614511565b61353f8185614538565b935061354f8185602086016146d1565b80840191505092915050565b61356481614653565b82525050565b61357381614677565b82525050565b6135828161469b565b82525050565b60006135938261451c565b61359d8185614543565b93506135ad8185602086016146d1565b6135b681614746565b840191505092915050565b60006135ce602683614543565b91507f5061796d656e7452656769737472793a20696e76616c6964206465706f73697460008301527f2076616c756500000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613634601c83614554565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b6000613674602083614543565b91507f477561726465643a2063616e6e6f74206164642030783020677561726469616e6000830152602082019050919050565b60006136b4602f83614543565b91507f496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742060008301527f74686520696e697469616c697a657200000000000000000000000000000000006020830152604082019050919050565b600061371a602f83614543565b91507f5061796d656e7452656769737472793a206465706f736974206578697420616c60008301527f72656164792072657175657374656400000000000000000000000000000000006020830152604082019050919050565b6000613780602683614543565b91507f5061796d656e7452656769737472793a20696e76616c6964207061796d656e7460008301527f2076616c756500000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137e6602283614543565b91507f47617465776179526563697069656e743a20696e76616c6964206d73672e646160008301527f74610000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061384c602b83614543565b91507f5061796d656e7452656769737472793a206465706f7369742065786974206e6f60008301527f74207265717565737465640000000000000000000000000000000000000000006020830152604082019050919050565b60006138b2602d83614543565b91507f5061796d656e7452656769737472793a204552433230546f6b656e207472616e60008301527f73666572207265766572746564000000000000000000000000000000000000006020830152604082019050919050565b6000613918602683614543565b91507f477561726465643a2074782e6f726967696e206973206e6f742074686520677560008301527f61726469616e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061397e601f83614543565b91507f5061796d656e7452656769737472793a20696e76616c696420616d6f756e74006000830152602082019050919050565b60006139be602483614543565b91507f5061796d656e7452656769737472793a206465706f7369742065786974206c6f60008301527f636b6564000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a24602783614543565b91507f5061796d656e7452656769737472793a20696e76616c6964207769746864726160008301527f772076616c7565000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a8a602983614543565b91507f5061796d656e7452656769737472793a20696e76616c69642073656e6465722060008301527f7369676e617475726500000000000000000000000000000000000000000000006020830152604082019050919050565b6000613af0601f83614543565b91507f477561726465643a20677561726469616e20646f65736e2774206578697374006000830152602082019050919050565b6000613b30601e83614543565b91507f536166654d6174684c69623a206164646974696f6e206f766572666c6f7700006000830152602082019050919050565b6000613b70602083614543565b91507f477561726465643a20677561726469616e20616c7265616479206578697374736000830152602082019050919050565b6000613bb0601b83614543565b91507f477561726465643a2063616e6e6f742072656d6f76652073656c6600000000006000830152602082019050919050565b6000613bf0601d83614543565b91507f42797465734c69623a20696e76616c69642064617461206c656e6774680000006000830152602082019050919050565b6000613c30602b83614543565b91507f5061796d656e7452656769737472793a20696e76616c6964206775617264696160008301527f6e207369676e61747572650000000000000000000000000000000000000000006020830152604082019050919050565b613c928161462a565b82525050565b613ca9613ca48261462a565b61473c565b82525050565b613cb881614634565b82525050565b6000613cca828461348e565b60148201915081905092915050565b6000613ce5828761348e565b601482019150613cf5828661348e565b601482019150613d05828561348e565b601482019150613d1582846134da565b60208201915081905095945050505050565b6000613d33828961348e565b601482019150613d43828861348e565b601482019150613d53828761348e565b601482019150613d6382866134da565b602082019150613d738285613c98565b602082019150613d838284613c98565b602082019150819050979650505050505050565b6000613da3828661348e565b601482019150613db3828561348e565b601482019150613dc38284613c98565b602082019150819050949350505050565b6000613de082876134b4565b600182019150613df0828661348e565b601482019150613e0082856134da565b602082019150613e1082846134da565b60208201915081905095945050505050565b6000613e2d82613627565b9150613e3982846134da565b60208201915081905092915050565b6000613e548287613c98565b602082019150613e64828661348e565b601482019150613e7482856134da565b602082019150613e84828461352a565b915081905095945050505050565b6000602082019050613ea7600083018461347f565b92915050565b6000602082019050613ec26000830184613470565b92915050565b6000604082019050613edd6000830185613470565b613eea602083018461347f565b9392505050565b6000604082019050613f06600083018561347f565b613f13602083018461347f565b9392505050565b6000606082019050613f2f600083018661347f565b613f3c602083018561347f565b613f49604083018461347f565b949350505050565b6000608082019050613f66600083018761347f565b613f73602083018661347f565b613f80604083018561347f565b613f8d6060830184613c89565b95945050505050565b6000606082019050613fab600083018661347f565b613fb8602083018561347f565b613fc56040830184613c89565b949350505050565b6000606082019050613fe2600083018661347f565b613fef60208301856134cb565b613ffc6040830184613c89565b949350505050565b6000606082019050614019600083018661347f565b6140266020830185613579565b818103604083015261403881846134f1565b9050949350505050565b6000604082019050614057600083018561347f565b6140646020830184613c89565b9392505050565b6000606082019050614080600083018661347f565b61408d6020830185613c89565b818103604083015261409f81846134f1565b9050949350505050565b60006020820190506140be60008301846134a5565b92915050565b60006020820190506140d960008301846134cb565b92915050565b600060c0820190506140f460008301896134cb565b614101602083018861347f565b61410e604083018761347f565b61411b606083018661347f565b61412860808301856134cb565b61413560a0830184613c89565b979650505050505050565b600060408201905061415560008301856134cb565b6141626020830184613c89565b9392505050565b600060608201905061417e60008301866134cb565b61418b6020830185613c89565b6141986040830184613c89565b949350505050565b60006080820190506141b560008301876134cb565b6141c26020830186613caf565b6141cf60408301856134cb565b6141dc60608301846134cb565b95945050505050565b60006020820190506141fa600083018461355b565b92915050565b6000602082019050614215600083018461356a565b92915050565b600060208201905081810360008301526142358184613588565b905092915050565b60006020820190508181036000830152614256816135c1565b9050919050565b6000602082019050818103600083015261427681613667565b9050919050565b60006020820190508181036000830152614296816136a7565b9050919050565b600060208201905081810360008301526142b68161370d565b9050919050565b600060208201905081810360008301526142d681613773565b9050919050565b600060208201905081810360008301526142f6816137d9565b9050919050565b600060208201905081810360008301526143168161383f565b9050919050565b60006020820190508181036000830152614336816138a5565b9050919050565b600060208201905081810360008301526143568161390b565b9050919050565b6000602082019050818103600083015261437681613971565b9050919050565b60006020820190508181036000830152614396816139b1565b9050919050565b600060208201905081810360008301526143b681613a17565b9050919050565b600060208201905081810360008301526143d681613a7d565b9050919050565b600060208201905081810360008301526143f681613ae3565b9050919050565b6000602082019050818103600083015261441681613b23565b9050919050565b6000602082019050818103600083015261443681613b63565b9050919050565b6000602082019050818103600083015261445681613ba3565b9050919050565b6000602082019050818103600083015261447681613be3565b9050919050565b6000602082019050818103600083015261449681613c23565b9050919050565b60006020820190506144b26000830184613c89565b92915050565b6000604051905081810181811067ffffffffffffffff821117156144db57600080fd5b8060405250919050565b600067ffffffffffffffff8211156144fc57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000808585111561456f57600080fd5b8386111561457c57600080fd5b6001850283019150848603905094509492505050565b600061459d8261460a565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b60006145f182614592565b9050919050565b600061460382614592565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061464c826146ad565b9050919050565b600061465e82614665565b9050919050565b60006146708261460a565b9050919050565b600061468282614689565b9050919050565b60006146948261460a565b9050919050565b60006146a68261462a565b9050919050565b60006146b8826146bf565b9050919050565b60006146ca8261460a565b9050919050565b60005b838110156146ef5780820151818401526020810190506146d4565b838111156146fe576000848401525b50505050565b600061470f8261472a565b9050919050565b6000819050919050565b6000819050919050565b600061473582614757565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b61476d81614592565b811461477857600080fd5b50565b614784816145a4565b811461478f57600080fd5b50565b61479b816145dc565b81146147a657600080fd5b50565b6147b2816145e6565b81146147bd57600080fd5b50565b6147c9816145f8565b81146147d457600080fd5b50565b6147e08161462a565b81146147eb57600080fd5b5056fe6080604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506103a4806100536000396000f3fe60806040526004361061002d5760003560e01c80633f579f4214610039578063f77c47911461016257610034565b3661003457005b600080fd5b34801561004557600080fd5b506100e76004803603606081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100a357600080fd5b8201836020820111156100b557600080fd5b803590602001918460018302840111640100000000831117156100d757600080fd5b90919293919293905050506101a3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561012757808201518184015260208101905061010c565b50505050905090810190601f1680156101545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016e57600080fd5b50610177610347565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061036c602c913960400191505060405180910390fd5b606060008673ffffffffffffffffffffffffffffffffffffffff1686868660405180838380828437808301925050509250505060006040518083038185875af1925050503d80600081146102b9576040519150601f19603f3d011682016040523d82523d6000602084013e6102be565b606091505b5080935081925050508061033a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4163636f756e743a207472616e73616374696f6e20726576657274656400000081525060200191505060405180910390fd5b8192505050949350505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fe436f6e74726f6c6c65643a206d73672e73656e646572206973206e6f742074686520636f6e74726f6c6c6572a164736f6c634300060c000a536166654d6174684c69623a207375627472616374696f6e206f766572666c6f77a164736f6c634300060c000a", + "devdoc": { + "author": "Stanisław Głogowski ", + "details": "the `DepositExit` process can be used in a case operator (guardian) couldn't sign commit / withdrawal message. Process will be rejected when any of senders channels will be committed.", + "events": { + "DepositAccountDeployed(address,address)": { + "details": "Emitted when the deposit account is deployed", + "params": { + "depositAccount": "deposit account address", + "owner": "owner address" + } + }, + "DepositExitCompleted(address,address,address,uint256)": { + "details": "Emitted when the deposit exist is completed", + "params": { + "amount": "deposit exist amount", + "depositAccount": "deposit account address", + "owner": "owner address", + "token": "token address" + } + }, + "DepositExitRejected(address,address,address)": { + "details": "Emitted when the deposit exist is rejected", + "params": { + "depositAccount": "deposit account address", + "owner": "owner address", + "token": "token address" + } + }, + "DepositExitRequested(address,address,address,uint256)": { + "details": "Emitted when the deposit exist is requested", + "params": { + "depositAccount": "deposit account address", + "lockedUntil": "deposit exist locked util time", + "owner": "owner address", + "token": "token address" + } + }, + "DepositWithdrawn(address,address,address,uint256)": { + "details": "Emitted when the deposit has been withdrawn", + "params": { + "amount": "withdrawn amount", + "depositAccount": "deposit account address", + "owner": "owner address", + "token": "token address" + } + }, + "PaymentChannelCommitted(bytes32,address,address,address,bytes32,uint256)": { + "details": "Emitted when the payment channel has been committed", + "params": { + "amount": "committed amount", + "hash": "channel hash", + "recipient": "recipient address", + "sender": "sender address", + "token": "token address", + "uid": "unique channel id" + } + }, + "PaymentDeposited(bytes32,uint256)": { + "details": "Emitted when the payment has been deposited", + "params": { + "channelHash": "channel hash", + "value": "payment value" + } + }, + "PaymentSplit(bytes32,uint256,uint256)": { + "details": "Emitted when the payment has been withdrawn and deposited (split)", + "params": { + "channelHash": "channel hash", + "depositValue": "payment deposited value", + "totalValue": "payment total value" + } + }, + "PaymentWithdrawn(bytes32,uint256)": { + "details": "Emitted when the payment has been withdrawn", + "params": { + "channelHash": "channel hash", + "value": "payment value" + } + } + }, + "kind": "dev", + "methods": { + "addGuardian(address)": { + "params": { + "guardian": "guardian address" + } + }, + "commitPaymentChannelAndDeposit(address,address,bytes32,uint256,uint256,bytes,bytes)": { + "params": { + "amount": "amount to commit", + "blockNumber": "block number", + "guardianSignature": "guardian signature", + "sender": "sender address", + "senderSignature": "sender signature", + "token": "token address", + "uid": "unique channel id" + } + }, + "commitPaymentChannelAndSplit(address,address,bytes32,uint256,uint256,uint256,bytes,bytes)": { + "params": { + "amount": "amount to commit", + "blockNumber": "block number", + "depositPaymentValue": "amount to deposit", + "guardianSignature": "guardian signature", + "sender": "sender address", + "senderSignature": "sender signature", + "token": "token address", + "uid": "unique channel id" + } + }, + "commitPaymentChannelAndWithdraw(address,address,bytes32,uint256,uint256,bytes,bytes)": { + "params": { + "amount": "amount to commit", + "blockNumber": "block number", + "guardianSignature": "guardian signature", + "sender": "sender address", + "senderSignature": "sender signature", + "token": "token address", + "uid": "unique channel id" + } + }, + "computeDepositAccountAddress(address)": { + "params": { + "owner": "owner address" + }, + "returns": { + "_0": "deposit account address" + } + }, + "computePaymentChannelHash(address,address,address,bytes32)": { + "params": { + "recipient": "recipient address", + "sender": "sender address", + "token": "token address", + "uid": "unique channel id" + }, + "returns": { + "_0": "hash" + } + }, + "constructor": { + "details": "Public constructor" + }, + "deployDepositAccount(address)": { + "params": { + "owner": "owner address" + } + }, + "getDepositExitLockedUntil(address,address)": { + "params": { + "owner": "owner address", + "token": "token address" + }, + "returns": { + "_0": "locked until time" + } + }, + "getDepositWithdrawnAmount(address,address)": { + "params": { + "owner": "owner address", + "token": "token address" + }, + "returns": { + "_0": "withdrawn amount" + } + }, + "getPaymentChannelCommittedAmount(bytes32)": { + "params": { + "hash": "payment channel hash" + }, + "returns": { + "_0": "committed amount" + } + }, + "hashDepositWithdrawal((address,address,uint256))": { + "params": { + "depositWithdrawal": "struct" + }, + "returns": { + "_0": "hash" + } + }, + "hashPaymentChannelCommit((address,address,address,bytes32,uint256,uint256))": { + "params": { + "paymentChannelCommit": "struct" + }, + "returns": { + "_0": "hash" + } + }, + "initialize(address,address,uint256,address[],address)": { + "params": { + "depositExitLockPeriod_": "deposit exit lock period", + "externalAccountRegistry_": "`ExternalAccountRegistry` contract address", + "gateway_": "`Gateway` contract address", + "guardians_": "array of guardians addresses", + "personalAccountRegistry_": "`PersonalAccountRegistry` contract address" + } + }, + "isDepositAccountDeployed(address)": { + "params": { + "owner": "owner address" + }, + "returns": { + "_0": "true when deposit account is deployed" + } + }, + "isGuardian(address)": { + "params": { + "guardian": "guardian address" + }, + "returns": { + "_0": "true when guardian exists" + } + }, + "isInitialized()": { + "returns": { + "_0": "true when contract is initialized" + } + }, + "processDepositExit(address)": { + "params": { + "token": "token address" + } + }, + "removeGuardian(address)": { + "params": { + "guardian": "guardian address" + } + }, + "requestDepositExit(address)": { + "params": { + "token": "token address" + } + }, + "verifyGuardianSignature(bytes32,bytes)": { + "params": { + "messageHash": "message hash", + "signature": "signature" + }, + "returns": { + "_0": "true on correct guardian signature" + } + }, + "withdrawDeposit(address,uint256,bytes)": { + "params": { + "amount": "amount to withdraw", + "guardianSignature": "guardian signature", + "token": "token address" + } + } + }, + "title": "Payment registry", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "addGuardian(address)": { + "notice": "Adds a new guardian" + }, + "commitPaymentChannelAndDeposit(address,address,bytes32,uint256,uint256,bytes,bytes)": { + "notice": "Commits payment channel and deposit payment" + }, + "commitPaymentChannelAndSplit(address,address,bytes32,uint256,uint256,uint256,bytes,bytes)": { + "notice": "Commits payment channel, withdraws and deposits (split) payment" + }, + "commitPaymentChannelAndWithdraw(address,address,bytes32,uint256,uint256,bytes,bytes)": { + "notice": "Commits payment channel and withdraw payment" + }, + "computeDepositAccountAddress(address)": { + "notice": "Computes deposit account address" + }, + "computePaymentChannelHash(address,address,address,bytes32)": { + "notice": "Computes payment channel hash" + }, + "deployDepositAccount(address)": { + "notice": "Deploys deposit account" + }, + "getDepositExitLockedUntil(address,address)": { + "notice": "Gets deposit exit locked until time" + }, + "getDepositWithdrawnAmount(address,address)": { + "notice": "Gets deposit withdrawn amount" + }, + "getPaymentChannelCommittedAmount(bytes32)": { + "notice": "Gets payment channel committed amount" + }, + "hashDepositWithdrawal((address,address,uint256))": { + "notice": "Hashes `DepositWithdrawal` message payload" + }, + "hashPaymentChannelCommit((address,address,address,bytes32,uint256,uint256))": { + "notice": "Hashes `PaymentChannelCommit` message payload" + }, + "initialize(address,address,uint256,address[],address)": { + "notice": "Initialize `PaymentRegistry` contract" + }, + "isDepositAccountDeployed(address)": { + "notice": "Checks if deposit account is deployed" + }, + "isGuardian(address)": { + "notice": "Check if guardian exists" + }, + "isInitialized()": { + "notice": "Check if contract is initialized" + }, + "processDepositExit(address)": { + "notice": "Processes deposit exit" + }, + "removeGuardian(address)": { + "notice": "Removes the existing guardian" + }, + "requestDepositExit(address)": { + "notice": "Requests deposit exit" + }, + "verifyGuardianSignature(bytes32,bytes)": { + "notice": "Verifies guardian signature" + }, + "withdrawDeposit(address,uint256,bytes)": { + "notice": "Withdraws deposit" + } + }, + "notice": "A registry for payment and payment channels", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 40, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "guardians", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 1871, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "initializer", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 1935, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "chainId", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 5197, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "gateway", + "offset": 0, + "slot": "3", + "type": "t_address" + }, + { + "astId": 5526, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "externalAccountRegistry", + "offset": 0, + "slot": "4", + "type": "t_contract(ExternalAccountRegistry)4591" + }, + { + "astId": 5528, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "personalAccountRegistry", + "offset": 0, + "slot": "5", + "type": "t_contract(PersonalAccountRegistry)7452" + }, + { + "astId": 5530, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "depositExitLockPeriod", + "offset": 0, + "slot": "6", + "type": "t_uint256" + }, + { + "astId": 5534, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "deposits", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_address,t_struct(Deposit)5488_storage)" + }, + { + "astId": 5538, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "paymentChannels", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_bytes32,t_struct(PaymentChannel)5491_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(ExternalAccountRegistry)4591": { + "encoding": "inplace", + "label": "contract ExternalAccountRegistry", + "numberOfBytes": "20" + }, + "t_contract(PersonalAccountRegistry)7452": { + "encoding": "inplace", + "label": "contract PersonalAccountRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_struct(Deposit)5488_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct PaymentRegistry.Deposit)", + "numberOfBytes": "32", + "value": "t_struct(Deposit)5488_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_struct(PaymentChannel)5491_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct PaymentRegistry.PaymentChannel)", + "numberOfBytes": "32", + "value": "t_struct(PaymentChannel)5491_storage" + }, + "t_struct(Deposit)5488_storage": { + "encoding": "inplace", + "label": "struct PaymentRegistry.Deposit", + "members": [ + { + "astId": 5479, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "account", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 5483, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "withdrawnAmount", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5487, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "exitLockedUntil", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_uint256)" + } + ], + "numberOfBytes": "96" + }, + "t_struct(PaymentChannel)5491_storage": { + "encoding": "inplace", + "label": "struct PaymentRegistry.PaymentChannel", + "members": [ + { + "astId": 5490, + "contract": "src/payments/PaymentRegistry.sol:PaymentRegistry", + "label": "committedAmount", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/PersonalAccountImplementationV1.json b/deployments/neonDevnet/PersonalAccountImplementationV1.json new file mode 100644 index 00000000..f0829ffc --- /dev/null +++ b/deployments/neonDevnet/PersonalAccountImplementationV1.json @@ -0,0 +1,326 @@ +{ + "address": "0x0672aF0018fdEbACcc93c7D047D62b72CB12883A", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "initializer", + "type": "address" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "interfaceHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "canImplementInterfaceForAddress", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "registry_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "messageHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "registry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x620748c84602085f064e8d9453530f6425c1a27cc17c13c881d797735cd4573f", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "41059200", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xf35b1fad98c6553f07c0bd3b3c242c1745a13226a39f88b2ecadec5d7da22305", + "transactionHash": "0x620748c84602085f064e8d9453530f6425c1a27cc17c13c881d797735cd4573f", + "logs": [], + "blockNumber": 173996994, + "cumulativeGasUsed": "41059200", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"interfaceHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"canImplementInterfaceForAddress\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"registry_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski \",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Public constructor\"},\"initialize(address)\":{\"params\":{\"registry_\":\"registry address\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}}},\"title\":\"Personal account implementation (version 1)\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"initialize(address)\":{\"notice\":\"Initializes `AccountImplementation` contract\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/personal/PersonalAccountImplementationV1.sol\":\"PersonalAccountImplementationV1\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/access/Controlled.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Controlled\\n *\\n * @dev Contract module which provides an access control mechanism.\\n * It ensures there is only one controlling account of the smart contract\\n * and grants that account exclusive access to specific functions.\\n *\\n * The controller account will be the one that deploys the contract.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Controlled {\\n /**\\n * @return controller account address\\n */\\n address public controller;\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if msg.sender is not the controller\\n */\\n modifier onlyController() {\\n require(\\n msg.sender == controller,\\n \\\"Controlled: msg.sender is not the controller\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n controller = msg.sender;\\n }\\n}\\n\",\"keccak256\":\"0xdf03a0b7ec644da9925c5c1b6c8a86bb1cc1b9c5018bb265a1a4c5044b877af3\",\"license\":\"MIT\"},\"src/common/account/Account.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../access/Controlled.sol\\\";\\nimport \\\"./AccountBase.sol\\\";\\n\\n\\n/**\\n * @title Account\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Account is Controlled, AccountBase {\\n address public implementation;\\n\\n /**\\n * @dev Public constructor\\n * @param registry_ account registry address\\n * @param implementation_ account implementation address\\n */\\n constructor(\\n address registry_,\\n address implementation_\\n )\\n public\\n Controlled()\\n {\\n registry = registry_;\\n implementation = implementation_;\\n }\\n\\n // external functions\\n\\n /**\\n * @notice Payable receive\\n */\\n receive()\\n external\\n payable\\n {\\n //\\n }\\n\\n /**\\n * @notice Fallback\\n */\\n // solhint-disable-next-line payable-fallback\\n fallback()\\n external\\n {\\n if (msg.data.length != 0) {\\n address implementation_ = implementation;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let calldedatasize := calldatasize()\\n\\n calldatacopy(0, 0, calldedatasize)\\n\\n let result := delegatecall(gas(), implementation_, 0, calldedatasize, 0, 0)\\n let returneddatasize := returndatasize()\\n\\n returndatacopy(0, 0, returneddatasize)\\n\\n switch result\\n case 0 { revert(0, returneddatasize) }\\n default { return(0, returneddatasize) }\\n }\\n }\\n }\\n\\n /**\\n * @notice Sets implementation\\n * @param implementation_ implementation address\\n */\\n function setImplementation(\\n address implementation_\\n )\\n external\\n onlyController\\n {\\n implementation = implementation_;\\n }\\n\\n /**\\n * @notice Executes transaction\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @return transaction result\\n */\\n function executeTransaction(\\n address to,\\n uint256 value,\\n bytes calldata data\\n )\\n external\\n onlyController\\n returns (bytes memory)\\n {\\n bytes memory result;\\n bool succeeded;\\n\\n // solhint-disable-next-line avoid-call-value, avoid-low-level-calls\\n (succeeded, result) = payable(to).call{value: value}(data);\\n\\n require(\\n succeeded,\\n \\\"Account: transaction reverted\\\"\\n );\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe516c999a02a65ee99487d398d0c12589500680a9ca08c852540fb9473d70a26\",\"license\":\"MIT\"},\"src/common/account/AccountBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Account base\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract AccountBase {\\n address public registry;\\n}\\n\",\"keccak256\":\"0xcadf29e389f8db823e14f3f92808fd135f07b0135eb4dcf29b89c85941b39862\",\"license\":\"MIT\"},\"src/common/account/AccountImplementationV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../lifecycle/Initializable.sol\\\";\\nimport \\\"./AccountBase.sol\\\";\\nimport \\\"./AccountRegistry.sol\\\";\\n\\n\\n/**\\n * @title Account implementation (version 1)\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract AccountImplementationV1 is Initializable, AccountBase {\\n bytes32 constant private ERC777_TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(abi.encodePacked(\\\"ERC777TokensRecipient\\\"));\\n bytes32 constant private ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked(\\\"ERC1820_ACCEPT_MAGIC\\\"));\\n\\n bytes4 constant private ERC1271_VALID_MESSAGE_HASH_SIGNATURE = bytes4(keccak256(abi.encodePacked(\\\"isValidSignature(bytes32,bytes)\\\")));\\n bytes4 constant private ERC1271_VALID_MESSAGE_SIGNATURE = bytes4(keccak256(abi.encodePacked(\\\"isValidSignature(bytes,bytes)\\\")));\\n bytes4 constant private ERC1271_INVALID_SIGNATURE = 0xffffffff;\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor() internal Initializable() {}\\n\\n // external functions\\n\\n /**\\n * @notice Initializes `AccountImplementation` contract\\n * @param registry_ registry address\\n */\\n function initialize(\\n address registry_\\n )\\n external\\n onlyInitializer\\n {\\n registry = registry_;\\n }\\n\\n // external functions (views)\\n\\n // ERC1820\\n\\n function canImplementInterfaceForAddress(\\n bytes32 interfaceHash,\\n address addr\\n )\\n external\\n view\\n returns(bytes32)\\n {\\n bytes32 result;\\n\\n if (interfaceHash == ERC777_TOKENS_RECIPIENT_INTERFACE_HASH && addr == address(this)) {\\n result = ERC1820_ACCEPT_MAGIC;\\n }\\n\\n return result;\\n }\\n\\n // ERC1271\\n\\n function isValidSignature(\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n external\\n view\\n returns (bytes4)\\n {\\n return AccountRegistry(registry).isValidAccountSignature(address(this), messageHash, signature)\\n ? ERC1271_VALID_MESSAGE_HASH_SIGNATURE\\n : ERC1271_INVALID_SIGNATURE;\\n }\\n\\n function isValidSignature(\\n bytes calldata message,\\n bytes calldata signature\\n )\\n external\\n view\\n returns (bytes4)\\n {\\n return AccountRegistry(registry).isValidAccountSignature(address(this), message, signature)\\n ? ERC1271_VALID_MESSAGE_SIGNATURE\\n : ERC1271_INVALID_SIGNATURE;\\n }\\n\\n // external functions (pure)\\n\\n // ERC721\\n\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n )\\n external\\n pure\\n returns (bytes4)\\n {\\n return this.onERC721Received.selector;\\n }\\n\\n // ERC1155\\n\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n )\\n external\\n pure\\n returns (bytes4)\\n {\\n return this.onERC1155Received.selector;\\n }\\n\\n // ERC777\\n\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n )\\n external\\n pure\\n {}\\n}\\n\",\"keccak256\":\"0x7ec22f77f8e2c3059a9c728d463b1519f8d975b0d42d6a986cd45e22d62d59e8\",\"license\":\"MIT\"},\"src/common/account/AccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./Account.sol\\\";\\n\\n\\n/**\\n * @title Account registry\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nabstract contract AccountRegistry {\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param messageHash message hash\\n * @param signature signature\\n * @return true if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n virtual\\n external\\n view\\n returns (bool);\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param message message\\n * @param signature signature\\n * @return true if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes calldata message,\\n bytes calldata signature\\n )\\n virtual\\n external\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0x2d40245721f5f74219e5cf88713246dbe8b6d5404e941125d3e850b1f127ec34\",\"license\":\"MIT\"},\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Initializable {\\n address private initializer;\\n\\n // events\\n\\n /**\\n * @dev Emitted after `onlyInitializer`\\n * @param initializer initializer address\\n */\\n event Initialized(\\n address initializer\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not the initializer\\n */\\n modifier onlyInitializer() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin == initializer,\\n \\\"Initializable: tx.origin is not the initializer\\\"\\n );\\n\\n /// @dev removes initializer\\n initializer = address(0);\\n\\n _;\\n\\n emit Initialized(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin\\n );\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n initializer = tx.origin;\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if contract is initialized\\n * @return true when contract is initialized\\n */\\n function isInitialized()\\n external\\n view\\n returns (bool)\\n {\\n return initializer == address(0);\\n }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/personal/PersonalAccountImplementationV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/account/AccountImplementationV1.sol\\\";\\n\\n\\n/**\\n * @title Personal account implementation (version 1)\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract PersonalAccountImplementationV1 is AccountImplementationV1 {\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor() public AccountImplementationV1() {}\\n}\\n\",\"keccak256\":\"0xd5a860c49ec0863366f4ecb583f87b48696e7edc3535e61f4b635a94b7255989\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50326000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610caa806100606000396000f3fe608060405234801561001057600080fd5b50600436106100925760003560e01c8063249cb3fa11610066578063249cb3fa1461047c578063392e53cd146104de5780637b103999146104fe578063c4d66de814610532578063f23a6e611461057657610092565b806223de2914610097578063150b7a02146101cf5780631626ba7e146102c557806320c13b0b1461037b575b600080fd5b6101cd600480360360c08110156100ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561013457600080fd5b82018360208201111561014657600080fd5b8035906020019184600183028401116401000000008311171561016857600080fd5b90919293919293908035906020019064010000000081111561018957600080fd5b82018360208201111561019b57600080fd5b803590602001918460018302840111640100000000831117156101bd57600080fd5b9091929391929390505050610676565b005b610290600480360360808110156101e557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561024c57600080fd5b82018360208201111561025e57600080fd5b8035906020019184600183028401116401000000008311171561028057600080fd5b9091929391929390505050610680565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b610346600480360360408110156102db57600080fd5b81019080803590602001909291908035906020019064010000000081111561030257600080fd5b82018360208201111561031457600080fd5b8035906020019184600183028401116401000000008311171561033657600080fd5b9091929391929390505050610695565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6104476004803603604081101561039157600080fd5b81019080803590602001906401000000008111156103ae57600080fd5b8201836020820111156103c057600080fd5b803590602001918460018302840111640100000000831117156103e257600080fd5b90919293919293908035906020019064010000000081111561040357600080fd5b82018360208201111561041557600080fd5b8035906020019184600183028401116401000000008311171561043757600080fd5b90919293919293905050506107f9565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6104c86004803603604081101561049257600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061098a565b6040518082815260200191505060405180910390f35b6104e6610a66565b60405180821515815260200191505060405180910390f35b610506610abc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105746004803603602081101561054857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ae2565b005b610641600480360360a081101561058c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803590602001906401000000008111156105fd57600080fd5b82018360208201111561060f57600080fd5b8035906020019184600183028401116401000000008311171561063157600080fd5b9091929391929390505050610c58565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b5050505050505050565b600063150b7a0260e01b905095945050505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e1e382ce308686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060206040518083038186803b15801561075c57600080fd5b505afa158015610770573d6000803e3d6000fd5b505050506040513d602081101561078657600080fd5b81019080805190602001909291905050506107a85763ffffffff60e01b6107f0565b60405160200180807f697356616c69645369676e617475726528627974657333322c62797465732900815250601f019050604051602081830303815290604052805190602001205b90509392505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663124e9eb330878787876040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f82011690508083019250505097505050505050505060206040518083038186803b1580156108ec57600080fd5b505afa158015610900573d6000803e3d6000fd5b505050506040513d602081101561091657600080fd5b81019080805190602001909291905050506109385763ffffffff60e01b610980565b60405160200180807f697356616c69645369676e61747572652862797465732c627974657329000000815250601d019050604051602081830303815290604052805190602001205b9050949350505050565b60008060405160200180807f455243373737546f6b656e73526563697069656e74000000000000000000000081525060150190506040516020818303038152906040528051906020012084148015610a0d57503073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b15610a5c5760405160200180807f455243313832305f4143434550545f4d4147494300000000000000000000000081525060140190506040516020818303038152906040528051906020012090505b8091505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610c6f602f913960400191505060405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e632604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600063f23a6e6160e01b9050969550505050505056fe496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742074686520696e697469616c697a6572a164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100925760003560e01c8063249cb3fa11610066578063249cb3fa1461047c578063392e53cd146104de5780637b103999146104fe578063c4d66de814610532578063f23a6e611461057657610092565b806223de2914610097578063150b7a02146101cf5780631626ba7e146102c557806320c13b0b1461037b575b600080fd5b6101cd600480360360c08110156100ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561013457600080fd5b82018360208201111561014657600080fd5b8035906020019184600183028401116401000000008311171561016857600080fd5b90919293919293908035906020019064010000000081111561018957600080fd5b82018360208201111561019b57600080fd5b803590602001918460018302840111640100000000831117156101bd57600080fd5b9091929391929390505050610676565b005b610290600480360360808110156101e557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561024c57600080fd5b82018360208201111561025e57600080fd5b8035906020019184600183028401116401000000008311171561028057600080fd5b9091929391929390505050610680565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b610346600480360360408110156102db57600080fd5b81019080803590602001909291908035906020019064010000000081111561030257600080fd5b82018360208201111561031457600080fd5b8035906020019184600183028401116401000000008311171561033657600080fd5b9091929391929390505050610695565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6104476004803603604081101561039157600080fd5b81019080803590602001906401000000008111156103ae57600080fd5b8201836020820111156103c057600080fd5b803590602001918460018302840111640100000000831117156103e257600080fd5b90919293919293908035906020019064010000000081111561040357600080fd5b82018360208201111561041557600080fd5b8035906020019184600183028401116401000000008311171561043757600080fd5b90919293919293905050506107f9565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6104c86004803603604081101561049257600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061098a565b6040518082815260200191505060405180910390f35b6104e6610a66565b60405180821515815260200191505060405180910390f35b610506610abc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105746004803603602081101561054857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ae2565b005b610641600480360360a081101561058c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803590602001906401000000008111156105fd57600080fd5b82018360208201111561060f57600080fd5b8035906020019184600183028401116401000000008311171561063157600080fd5b9091929391929390505050610c58565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b5050505050505050565b600063150b7a0260e01b905095945050505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e1e382ce308686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060206040518083038186803b15801561075c57600080fd5b505afa158015610770573d6000803e3d6000fd5b505050506040513d602081101561078657600080fd5b81019080805190602001909291905050506107a85763ffffffff60e01b6107f0565b60405160200180807f697356616c69645369676e617475726528627974657333322c62797465732900815250601f019050604051602081830303815290604052805190602001205b90509392505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663124e9eb330878787876040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f82011690508083019250505097505050505050505060206040518083038186803b1580156108ec57600080fd5b505afa158015610900573d6000803e3d6000fd5b505050506040513d602081101561091657600080fd5b81019080805190602001909291905050506109385763ffffffff60e01b610980565b60405160200180807f697356616c69645369676e61747572652862797465732c627974657329000000815250601d019050604051602081830303815290604052805190602001205b9050949350505050565b60008060405160200180807f455243373737546f6b656e73526563697069656e74000000000000000000000081525060150190506040516020818303038152906040528051906020012084148015610a0d57503073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b15610a5c5760405160200180807f455243313832305f4143434550545f4d4147494300000000000000000000000081525060140190506040516020818303038152906040528051906020012090505b8091505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610c6f602f913960400191505060405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e632604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600063f23a6e6160e01b9050969550505050505056fe496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742074686520696e697469616c697a6572a164736f6c634300060c000a", + "devdoc": { + "author": "Stanisław Głogowski ", + "kind": "dev", + "methods": { + "constructor": { + "details": "Public constructor" + }, + "initialize(address)": { + "params": { + "registry_": "registry address" + } + }, + "isInitialized()": { + "returns": { + "_0": "true when contract is initialized" + } + } + }, + "title": "Personal account implementation (version 1)", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "initialize(address)": { + "notice": "Initializes `AccountImplementation` contract" + }, + "isInitialized()": { + "notice": "Check if contract is initialized" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1871, + "contract": "src/personal/PersonalAccountImplementationV1.sol:PersonalAccountImplementationV1", + "label": "initializer", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 383, + "contract": "src/personal/PersonalAccountImplementationV1.sol:PersonalAccountImplementationV1", + "label": "registry", + "offset": 0, + "slot": "1", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/PersonalAccountRegistry.json b/deployments/neonDevnet/PersonalAccountRegistry.json new file mode 100644 index 00000000..b4892e13 --- /dev/null +++ b/deployments/neonDevnet/PersonalAccountRegistry.json @@ -0,0 +1,1058 @@ +{ + "address": "0x7EB3A038F25B9F32f8e19A7F0De83D4916030eFa", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "AccountCallRefunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "accountImplementation", + "type": "address" + } + ], + "name": "AccountDeployed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "accountImplementation", + "type": "address" + } + ], + "name": "AccountImplementationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "AccountOwnerAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "AccountOwnerRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "accountRegistry", + "type": "address" + } + ], + "name": "AccountRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "response", + "type": "bytes" + } + ], + "name": "AccountTransactionExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "accountImplementation", + "type": "address" + } + ], + "name": "AccountUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "GuardianAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "GuardianRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "initializer", + "type": "address" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "inputs": [], + "name": "accountImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accountRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "addAccountOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "addGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "saltOwner", + "type": "address" + } + ], + "name": "computeAccountAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "deployAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "executeAccountTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "gateway", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "guardians_", + "type": "address[]" + }, + { + "internalType": "address", + "name": "accountImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "gateway_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isAccountDeployed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "isGuardian", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "isValidAccountSignature", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "messageHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "isValidAccountSignature", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "refundAccountCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "removeAccountOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "removeGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accountImplementation_", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "upgradeAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "verifyAccountOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "verifyAccountOwnerAtBlock", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "messageHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "verifyGuardianSignature", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x2a0d6342070736407eb6a3ddf0775e9b7e4c8e67ca488916a7f6b88e195fa89c", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "153626320", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1ca926a9db00fba71463b63e1748b309a6210d7bd2c63714cb442935fc9e4449", + "transactionHash": "0x2a0d6342070736407eb6a3ddf0775e9b7e4c8e67ca488916a7f6b88e195fa89c", + "logs": [], + "blockNumber": 173997006, + "cumulativeGasUsed": "153626320", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"AccountCallRefunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"accountImplementation\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"accountImplementation\",\"type\":\"address\"}],\"name\":\"AccountImplementationUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AccountOwnerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AccountOwnerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"accountRegistry\",\"type\":\"address\"}],\"name\":\"AccountRegistryUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"}],\"name\":\"AccountTransactionExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"accountImplementation\",\"type\":\"address\"}],\"name\":\"AccountUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"GuardianRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accountRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"addAccountOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"addGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"saltOwner\",\"type\":\"address\"}],\"name\":\"computeAccountAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"deployAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeAccountTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"guardians_\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"accountImplementation_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"gateway_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isAccountDeployed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"isGuardian\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"isValidAccountSignature\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"isValidAccountSignature\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"refundAccountCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"removeAccountOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guardian\",\"type\":\"address\"}],\"name\":\"removeGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accountImplementation_\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"upgradeAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"verifyAccountOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"verifyAccountOwnerAtBlock\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"verifyGuardianSignature\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski \",\"events\":{\"AccountCallRefunded(address,address,address,uint256)\":{\"details\":\"Emitted when the call is refunded\",\"params\":{\"account\":\"account address\",\"beneficiary\":\"beneficiary address\",\"token\":\"token address\",\"value\":\"value\"}},\"AccountOwnerAdded(address,address)\":{\"details\":\"Emitted when the new owner is added\",\"params\":{\"account\":\"account address\",\"owner\":\"owner address\"}},\"AccountOwnerRemoved(address,address)\":{\"details\":\"Emitted when the existing owner is removed\",\"params\":{\"account\":\"account address\",\"owner\":\"owner address\"}}},\"kind\":\"dev\",\"methods\":{\"addAccountOwner(address,address)\":{\"params\":{\"account\":\"account address\",\"owner\":\"owner address\"}},\"addGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"computeAccountAddress(address)\":{\"params\":{\"saltOwner\":\"salt owner address\"},\"returns\":{\"_0\":\"account address\"}},\"constructor\":{\"details\":\"Public constructor\"},\"deployAccount(address)\":{\"params\":{\"account\":\"account address\"}},\"executeAccountTransaction(address,address,uint256,bytes)\":{\"details\":\"Deploys an account if not deployed yet\",\"params\":{\"account\":\"account address\",\"data\":\"data\",\"to\":\"to address\",\"value\":\"value\"}},\"initialize(address[],address,address)\":{\"params\":{\"accountImplementation_\":\"account implementation address\",\"gateway_\":\"`Gateway` contract address\",\"guardians_\":\"array of guardians addresses\"}},\"isAccountDeployed(address)\":{\"params\":{\"account\":\"account address\"},\"returns\":{\"_0\":\"true when account is deployed\"}},\"isGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"},\"returns\":{\"_0\":\"true when guardian exists\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}},\"isValidAccountSignature(address,bytes,bytes)\":{\"params\":{\"account\":\"account address\",\"message\":\"message\",\"signature\":\"signature\"},\"returns\":{\"_0\":\"magic hash if valid\"}},\"isValidAccountSignature(address,bytes32,bytes)\":{\"params\":{\"account\":\"account address\",\"messageHash\":\"message hash\",\"signature\":\"signature\"},\"returns\":{\"_0\":\"magic hash if valid\"}},\"refundAccountCall(address,address,uint256)\":{\"details\":\"Deploys an account if not deployed yet\",\"params\":{\"account\":\"account address\",\"token\":\"token address\",\"value\":\"value\"}},\"removeAccountOwner(address,address)\":{\"params\":{\"account\":\"account address\",\"owner\":\"owner address\"}},\"removeGuardian(address)\":{\"params\":{\"guardian\":\"guardian address\"}},\"upgrade(address)\":{\"params\":{\"accountImplementation_\":\"account implementation address\"}},\"upgradeAccount(address)\":{\"params\":{\"account\":\"account address\"}},\"verifyAccountOwner(address,address)\":{\"params\":{\"account\":\"account address\",\"owner\":\"owner address\"},\"returns\":{\"_0\":\"true on correct account owner\"}},\"verifyAccountOwnerAtBlock(address,address,uint256)\":{\"params\":{\"account\":\"account address\",\"blockNumber\":\"block number to verify\",\"owner\":\"owner address\"},\"returns\":{\"_0\":\"true on correct account owner\"}},\"verifyGuardianSignature(bytes32,bytes)\":{\"params\":{\"messageHash\":\"message hash\",\"signature\":\"signature\"},\"returns\":{\"_0\":\"true on correct guardian signature\"}}},\"title\":\"Personal account registry\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addAccountOwner(address,address)\":{\"notice\":\"Adds a new account owner\"},\"addGuardian(address)\":{\"notice\":\"Adds a new guardian\"},\"computeAccountAddress(address)\":{\"notice\":\"Computes account address\"},\"deployAccount(address)\":{\"notice\":\"Deploys account\"},\"executeAccountTransaction(address,address,uint256,bytes)\":{\"notice\":\"Executes account transaction\"},\"initialize(address[],address,address)\":{\"notice\":\"Initializes `PersonalAccountRegistry` contract\"},\"isAccountDeployed(address)\":{\"notice\":\"Checks if account is deployed\"},\"isGuardian(address)\":{\"notice\":\"Check if guardian exists\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"},\"isValidAccountSignature(address,bytes,bytes)\":{\"notice\":\"Verifies account signature\"},\"isValidAccountSignature(address,bytes32,bytes)\":{\"notice\":\"Verifies account signature\"},\"refundAccountCall(address,address,uint256)\":{\"notice\":\"Refunds account call\"},\"removeAccountOwner(address,address)\":{\"notice\":\"Removes the existing account owner\"},\"removeGuardian(address)\":{\"notice\":\"Removes the existing guardian\"},\"upgrade(address)\":{\"notice\":\"Upgrades `PersonalAccountRegistry` contract\"},\"upgradeAccount(address)\":{\"notice\":\"Upgrades account\"},\"verifyAccountOwner(address,address)\":{\"notice\":\"Verifies the owner of the account at the current block\"},\"verifyAccountOwnerAtBlock(address,address,uint256)\":{\"notice\":\"Verifies the owner of the account at a specific block\"},\"verifyGuardianSignature(bytes32,bytes)\":{\"notice\":\"Verifies guardian signature\"}},\"notice\":\"A registry for personal (controlled by owners) accounts\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/personal/PersonalAccountRegistry.sol\":\"PersonalAccountRegistry\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/access/Controlled.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Controlled\\n *\\n * @dev Contract module which provides an access control mechanism.\\n * It ensures there is only one controlling account of the smart contract\\n * and grants that account exclusive access to specific functions.\\n *\\n * The controller account will be the one that deploys the contract.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Controlled {\\n /**\\n * @return controller account address\\n */\\n address public controller;\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if msg.sender is not the controller\\n */\\n modifier onlyController() {\\n require(\\n msg.sender == controller,\\n \\\"Controlled: msg.sender is not the controller\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n controller = msg.sender;\\n }\\n}\\n\",\"keccak256\":\"0xdf03a0b7ec644da9925c5c1b6c8a86bb1cc1b9c5018bb265a1a4c5044b877af3\",\"license\":\"MIT\"},\"src/common/access/Guarded.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/ECDSALib.sol\\\";\\n\\n\\n/**\\n * @title Guarded\\n *\\n * @dev Contract module which provides a guardian-type control mechanism.\\n * It allows key accounts to have guardians and restricts specific methods to be accessible by guardians only.\\n *\\n * Each guardian account can remove other guardians\\n *\\n * Use `_initializeGuarded` to initialize the contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Guarded {\\n using ECDSALib for bytes32;\\n\\n mapping(address => bool) private guardians;\\n\\n // events\\n\\n /**\\n * @dev Emitted when a new guardian is added\\n * @param sender sender address\\n * @param guardian guardian address\\n */\\n event GuardianAdded(\\n address sender,\\n address guardian\\n );\\n\\n /**\\n * @dev Emitted when the existing guardian is removed\\n * @param sender sender address\\n * @param guardian guardian address\\n */\\n event GuardianRemoved(\\n address sender,\\n address guardian\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not a guardian account\\n */\\n modifier onlyGuardian() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n guardians[tx.origin],\\n \\\"Guarded: tx.origin is not the guardian\\\"\\n );\\n\\n _;\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor() internal {}\\n\\n // external functions\\n\\n /**\\n * @notice Adds a new guardian\\n * @param guardian guardian address\\n */\\n function addGuardian(\\n address guardian\\n )\\n external\\n onlyGuardian\\n {\\n _addGuardian(guardian);\\n }\\n\\n /**\\n * @notice Removes the existing guardian\\n * @param guardian guardian address\\n */\\n function removeGuardian(\\n address guardian\\n )\\n external\\n onlyGuardian\\n {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin != guardian,\\n \\\"Guarded: cannot remove self\\\"\\n );\\n\\n require(\\n guardians[guardian],\\n \\\"Guarded: guardian doesn't exist\\\"\\n );\\n\\n guardians[guardian] = false;\\n\\n emit GuardianRemoved(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin,\\n guardian\\n );\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if guardian exists\\n * @param guardian guardian address\\n * @return true when guardian exists\\n */\\n function isGuardian(\\n address guardian\\n )\\n external\\n view\\n returns (bool)\\n {\\n return guardians[guardian];\\n }\\n\\n /**\\n * @notice Verifies guardian signature\\n * @param messageHash message hash\\n * @param signature signature\\n * @return true on correct guardian signature\\n */\\n function verifyGuardianSignature(\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n external\\n view\\n returns (bool)\\n {\\n return _verifyGuardianSignature(\\n messageHash,\\n signature\\n );\\n }\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `Guarded` contract\\n * @dev If `guardians_` array is empty `tx.origin` is added as guardian account\\n * @param guardians_ array of guardians addresses\\n */\\n function _initializeGuarded(\\n address[] memory guardians_\\n )\\n internal\\n {\\n if (guardians_.length == 0) {\\n // solhint-disable-next-line avoid-tx-origin\\n _addGuardian(tx.origin);\\n } else {\\n uint guardiansLen = guardians_.length;\\n for (uint i = 0; i < guardiansLen; i++) {\\n _addGuardian(guardians_[i]);\\n }\\n }\\n }\\n\\n\\n // internal functions (views)\\n\\n function _verifyGuardianSignature(\\n bytes32 messageHash,\\n bytes memory signature\\n )\\n internal\\n view\\n returns (bool)\\n {\\n address guardian = messageHash.recoverAddress(signature);\\n\\n return guardians[guardian];\\n }\\n\\n // private functions\\n\\n function _addGuardian(\\n address guardian\\n )\\n private\\n {\\n require(\\n guardian != address(0),\\n \\\"Guarded: cannot add 0x0 guardian\\\"\\n );\\n\\n require(\\n !guardians[guardian],\\n \\\"Guarded: guardian already exists\\\"\\n );\\n\\n guardians[guardian] = true;\\n\\n emit GuardianAdded(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin,\\n guardian\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4a5f5670041362e87ea267d81c55fc3edc1a78e81f6f17524b13267f91f31458\",\"license\":\"MIT\"},\"src/common/account/Account.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../access/Controlled.sol\\\";\\nimport \\\"./AccountBase.sol\\\";\\n\\n\\n/**\\n * @title Account\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Account is Controlled, AccountBase {\\n address public implementation;\\n\\n /**\\n * @dev Public constructor\\n * @param registry_ account registry address\\n * @param implementation_ account implementation address\\n */\\n constructor(\\n address registry_,\\n address implementation_\\n )\\n public\\n Controlled()\\n {\\n registry = registry_;\\n implementation = implementation_;\\n }\\n\\n // external functions\\n\\n /**\\n * @notice Payable receive\\n */\\n receive()\\n external\\n payable\\n {\\n //\\n }\\n\\n /**\\n * @notice Fallback\\n */\\n // solhint-disable-next-line payable-fallback\\n fallback()\\n external\\n {\\n if (msg.data.length != 0) {\\n address implementation_ = implementation;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let calldedatasize := calldatasize()\\n\\n calldatacopy(0, 0, calldedatasize)\\n\\n let result := delegatecall(gas(), implementation_, 0, calldedatasize, 0, 0)\\n let returneddatasize := returndatasize()\\n\\n returndatacopy(0, 0, returneddatasize)\\n\\n switch result\\n case 0 { revert(0, returneddatasize) }\\n default { return(0, returneddatasize) }\\n }\\n }\\n }\\n\\n /**\\n * @notice Sets implementation\\n * @param implementation_ implementation address\\n */\\n function setImplementation(\\n address implementation_\\n )\\n external\\n onlyController\\n {\\n implementation = implementation_;\\n }\\n\\n /**\\n * @notice Executes transaction\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @return transaction result\\n */\\n function executeTransaction(\\n address to,\\n uint256 value,\\n bytes calldata data\\n )\\n external\\n onlyController\\n returns (bytes memory)\\n {\\n bytes memory result;\\n bool succeeded;\\n\\n // solhint-disable-next-line avoid-call-value, avoid-low-level-calls\\n (succeeded, result) = payable(to).call{value: value}(data);\\n\\n require(\\n succeeded,\\n \\\"Account: transaction reverted\\\"\\n );\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe516c999a02a65ee99487d398d0c12589500680a9ca08c852540fb9473d70a26\",\"license\":\"MIT\"},\"src/common/account/AccountBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Account base\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract AccountBase {\\n address public registry;\\n}\\n\",\"keccak256\":\"0xcadf29e389f8db823e14f3f92808fd135f07b0135eb4dcf29b89c85941b39862\",\"license\":\"MIT\"},\"src/common/account/AccountController.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./Account.sol\\\";\\n\\n\\n/**\\n * @title Account controller\\n *\\n * @dev Contract module which provides Account deployment mechanism\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract AccountController {\\n address public accountRegistry;\\n address public accountImplementation;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the account registry is updated\\n * @param accountRegistry account registry address\\n */\\n event AccountRegistryUpdated(\\n address accountRegistry\\n );\\n\\n /**\\n * @dev Emitted when the account implementation is updated\\n * @param accountImplementation account implementation address\\n */\\n event AccountImplementationUpdated(\\n address accountImplementation\\n );\\n\\n /**\\n * @dev Emitted when the account is deployed\\n * @param account account address\\n * @param accountImplementation account implementation address\\n */\\n event AccountDeployed(\\n address account,\\n address accountImplementation\\n );\\n\\n /**\\n * @dev Emitted when the account is upgraded\\n * @param account account address\\n * @param accountImplementation account implementation address\\n */\\n event AccountUpgraded(\\n address account,\\n address accountImplementation\\n );\\n\\n /**\\n * @dev Emitted when the transaction is executed\\n * @param account account address\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @param response response\\n */\\n event AccountTransactionExecuted(\\n address account,\\n address to,\\n uint256 value,\\n bytes data,\\n bytes response\\n );\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor() internal {}\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `AccountController` contract\\n * @param accountRegistry_ account registry address\\n * @param accountImplementation_ account implementation address\\n */\\n function _initializeAccountController(\\n address accountRegistry_,\\n address accountImplementation_\\n )\\n internal\\n {\\n _setAccountRegistry(accountRegistry_, false);\\n _setAccountImplementation(accountImplementation_, false);\\n }\\n\\n /**\\n * @notice Sets account registry\\n * @param accountRegistry_ account registry address\\n * @param emitEvent it will emit event when flag is set to true\\n */\\n function _setAccountRegistry(\\n address accountRegistry_,\\n bool emitEvent\\n )\\n internal\\n {\\n require(\\n accountRegistry_ != address(0),\\n \\\"AccountController: cannot set account registry to 0x0\\\"\\n );\\n\\n accountRegistry = accountRegistry_;\\n\\n if (emitEvent) {\\n emit AccountRegistryUpdated(accountRegistry);\\n }\\n }\\n\\n /**\\n * @notice Sets account implementation\\n * @param accountImplementation_ account implementation address\\n * @param emitEvent it will emit event when flag is set to true\\n */\\n function _setAccountImplementation(\\n address accountImplementation_,\\n bool emitEvent\\n )\\n internal\\n {\\n require(\\n accountImplementation_ != address(0),\\n \\\"AccountController: cannot set account Implementation to 0x0\\\"\\n );\\n\\n accountImplementation = accountImplementation_;\\n\\n if (emitEvent) {\\n emit AccountImplementationUpdated(accountImplementation);\\n }\\n }\\n\\n /**\\n * @notice Deploys account\\n * @param salt CREATE2 salt\\n * @param emitEvent it will emit event when flag is set to true\\n * @return account address\\n */\\n function _deployAccount(\\n bytes32 salt,\\n bool emitEvent\\n )\\n internal\\n returns (address)\\n {\\n address account = address(new Account{salt: salt}(\\n accountRegistry,\\n accountImplementation\\n ));\\n\\n if (emitEvent) {\\n emit AccountDeployed(\\n account,\\n accountImplementation\\n );\\n }\\n\\n return account;\\n }\\n\\n /**\\n * @notice Upgrades account\\n * @param account account address\\n * @param emitEvent it will emit event when flag is set to true\\n */\\n function _upgradeAccount(\\n address account,\\n bool emitEvent\\n )\\n internal\\n {\\n require(\\n Account(payable(account)).implementation() != accountImplementation,\\n \\\"AccountController: account already upgraded\\\"\\n );\\n\\n Account(payable(account)).setImplementation(accountImplementation);\\n\\n if (emitEvent) {\\n emit AccountUpgraded(\\n account,\\n accountImplementation\\n );\\n }\\n }\\n\\n /**\\n * @notice Executes transaction from the account\\n * @param account account address\\n * @param to to address\\n * @param value value\\n * @param data data\\n * @param emitEvent it will emit event when flag is set to true\\n * @return transaction result\\n */\\n function _executeAccountTransaction(\\n address account,\\n address to,\\n uint256 value,\\n bytes memory data,\\n bool emitEvent\\n )\\n internal\\n returns (bytes memory)\\n {\\n require(\\n to != address(0),\\n \\\"AccountController: cannot send to 0x0\\\"\\n );\\n\\n require(\\n to != address(this),\\n \\\"AccountController: cannot send to controller\\\"\\n );\\n\\n require(\\n to != account,\\n \\\"AccountController: cannot send to self\\\"\\n );\\n\\n bytes memory response = Account(payable(account)).executeTransaction(\\n to,\\n value,\\n data\\n );\\n\\n if (emitEvent) {\\n emit AccountTransactionExecuted(\\n account,\\n to,\\n value,\\n data,\\n response\\n );\\n }\\n\\n return response;\\n }\\n\\n // internal functions (views)\\n\\n /**\\n * @notice Computes account CREATE2 address\\n * @param salt CREATE2 salt\\n * @return account address\\n */\\n function _computeAccountAddress(\\n bytes32 salt\\n )\\n internal\\n view\\n returns (address)\\n {\\n bytes memory creationCode = abi.encodePacked(\\n type(Account).creationCode,\\n bytes12(0),\\n accountRegistry,\\n bytes12(0),\\n accountImplementation\\n );\\n\\n bytes32 data = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n salt,\\n keccak256(creationCode)\\n )\\n );\\n\\n return address(uint160(uint256(data)));\\n }\\n}\\n\",\"keccak256\":\"0xe161f1f4f6ea5d3a9810f7c93764d55e473abe1054e6aa68fde791be7d70a26c\",\"license\":\"MIT\"},\"src/common/account/AccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./Account.sol\\\";\\n\\n\\n/**\\n * @title Account registry\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nabstract contract AccountRegistry {\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param messageHash message hash\\n * @param signature signature\\n * @return true if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n virtual\\n external\\n view\\n returns (bool);\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param message message\\n * @param signature signature\\n * @return true if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes calldata message,\\n bytes calldata signature\\n )\\n virtual\\n external\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0x2d40245721f5f74219e5cf88713246dbe8b6d5404e941125d3e850b1f127ec34\",\"license\":\"MIT\"},\"src/common/libs/BlockLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Block library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nlibrary BlockLib {\\n struct BlockRelated {\\n bool added;\\n uint256 removedAtBlockNumber;\\n }\\n\\n /**\\n * @notice Verifies self struct at current block\\n * @param self self struct\\n * @return true on correct self struct\\n */\\n function verifyAtCurrentBlock(\\n BlockRelated memory self\\n )\\n internal\\n view\\n returns (bool)\\n {\\n return verifyAtBlock(self, block.number);\\n }\\n\\n /**\\n * @notice Verifies self struct at any block\\n * @param self self struct\\n * @return true on correct self struct\\n */\\n function verifyAtAnyBlock(\\n BlockRelated memory self\\n )\\n internal\\n pure\\n returns (bool)\\n {\\n return verifyAtBlock(self, 0);\\n }\\n\\n /**\\n * @notice Verifies self struct at specific block\\n * @param self self struct\\n * @param blockNumber block number to verify\\n * @return true on correct self struct\\n */\\n function verifyAtBlock(\\n BlockRelated memory self,\\n uint256 blockNumber\\n )\\n internal\\n pure\\n returns (bool)\\n {\\n bool result = false;\\n\\n if (self.added) {\\n if (self.removedAtBlockNumber == 0) {\\n result = true;\\n } else if (blockNumber == 0) {\\n result = true;\\n } else {\\n result = self.removedAtBlockNumber > blockNumber;\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9205536bc211f86d1113118a44dddfa7a9b9772a918cf4b1575c982a05472587\",\"license\":\"MIT\"},\"src/common/libs/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Bytes library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nlibrary BytesLib {\\n /**\\n * @notice Converts bytes to address\\n * @param data data\\n * @return address\\n */\\n function toAddress(\\n bytes memory data\\n )\\n internal\\n pure\\n returns (address)\\n {\\n address result;\\n\\n require(\\n data.length == 20,\\n \\\"BytesLib: invalid data length\\\"\\n );\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := div(mload(add(data, 0x20)), 0x1000000000000000000000000)\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x64c84964ea91bfb1f2d859eea6c57fe5b4a6f269951a4adf5f58d306c54c7f76\",\"license\":\"MIT\"},\"src/common/libs/ECDSAExtendedLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"./StringsLib.sol\\\";\\n\\n\\n/**\\n * @title ECDSA extended library\\n */\\nlibrary ECDSAExtendedLib {\\n using StringsLib for uint;\\n\\n function toEthereumSignedMessageHash(\\n bytes memory message\\n )\\n internal\\n pure\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n\\\",\\n message.length.toString(),\\n abi.encodePacked(message)\\n ));\\n }\\n}\\n\",\"keccak256\":\"0x83e6056caaba892d91de45324f4d2702ac01695fab2d34c86895d7d288547ba3\",\"license\":\"MIT\"},\"src/common/libs/ECDSALib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title ECDSA library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/cryptography/ECDSA.sol#L26\\n */\\nlibrary ECDSALib {\\n function recoverAddress(\\n bytes32 messageHash,\\n bytes memory signature\\n )\\n internal\\n pure\\n returns (address)\\n {\\n address result = address(0);\\n\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n\\n if (v < 27) {\\n v += 27;\\n }\\n\\n if (v == 27 || v == 28) {\\n result = ecrecover(messageHash, v, r, s);\\n }\\n }\\n\\n return result;\\n }\\n\\n function toEthereumSignedMessageHash(\\n bytes32 messageHash\\n )\\n internal\\n pure\\n returns (bytes32)\\n {\\n return keccak256(abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n messageHash\\n ));\\n }\\n}\\n\",\"keccak256\":\"0x3b1460d688302eb595268c2af147ab532f29dbced66520e013f48d498eed3cec\",\"license\":\"MIT\"},\"src/common/libs/SafeMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Safe math library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol\\n */\\nlibrary SafeMathLib {\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n\\n require(c >= a, \\\"SafeMathLib: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMathLib: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n\\n return a - b;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n\\n require(c / a == b, \\\"SafeMathLib: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMathLib: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n\\n return a / b;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMathLib: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x6089f354ca754d9c5dd9e800ee5ed86717dbf8f9af470604e0be691ac57c0107\",\"license\":\"MIT\"},\"src/common/libs/StringsLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Strings library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/utils/Strings.sol#L12\\n */\\nlibrary StringsLib {\\n function toString(\\n uint256 value\\n )\\n internal\\n pure\\n returns (string memory)\\n {\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n\\n uint256 temp = value;\\n uint256 digits;\\n\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n\\n bytes memory buffer = new bytes(digits);\\n uint256 index = digits - 1;\\n temp = value;\\n\\n while (temp != 0) {\\n buffer[index--] = byte(uint8(48 + temp % 10));\\n temp /= 10;\\n }\\n\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x4110150d0c921fd31db34ca33672de8e81c3ae467076149a3a546f804d1f58dd\",\"license\":\"MIT\"},\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Initializable {\\n address private initializer;\\n\\n // events\\n\\n /**\\n * @dev Emitted after `onlyInitializer`\\n * @param initializer initializer address\\n */\\n event Initialized(\\n address initializer\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not the initializer\\n */\\n modifier onlyInitializer() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin == initializer,\\n \\\"Initializable: tx.origin is not the initializer\\\"\\n );\\n\\n /// @dev removes initializer\\n initializer = address(0);\\n\\n _;\\n\\n emit Initialized(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin\\n );\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n initializer = tx.origin;\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if contract is initialized\\n * @return true when contract is initialized\\n */\\n function isInitialized()\\n external\\n view\\n returns (bool)\\n {\\n return initializer == address(0);\\n }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/common/token/ERC20Token.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/SafeMathLib.sol\\\";\\n\\n\\n/**\\n * @title ERC20 token\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol\\n */\\ncontract ERC20Token {\\n using SafeMathLib for uint256;\\n\\n string public name;\\n string public symbol;\\n uint8 public decimals;\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) internal balances;\\n mapping(address => mapping(address => uint256)) internal allowances;\\n\\n // events\\n\\n event Transfer(\\n address indexed from,\\n address indexed to,\\n uint256 value\\n );\\n\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // external functions\\n\\n function transfer(\\n address to,\\n uint256 value\\n )\\n external\\n returns (bool)\\n {\\n _transfer(_getSender(), to, value);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n address sender = _getSender();\\n\\n _transfer(from, to, value);\\n _approve(from, sender, allowances[from][sender].sub(value));\\n\\n return true;\\n }\\n\\n function approve(\\n address spender,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n _approve(_getSender(), spender, value);\\n\\n return true;\\n }\\n\\n // external functions (views)\\n\\n function balanceOf(\\n address owner\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return balances[owner];\\n }\\n\\n function allowance(\\n address owner,\\n address spender\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return allowances[owner][spender];\\n }\\n\\n // internal functions\\n\\n function _transfer(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n from != address(0),\\n \\\"ERC20Token: cannot transfer from 0x0 address\\\"\\n );\\n require(\\n to != address(0),\\n \\\"ERC20Token: cannot transfer to 0x0 address\\\"\\n );\\n\\n balances[from] = balances[from].sub(value);\\n balances[to] = balances[to].add(value);\\n\\n emit Transfer(from, to, value);\\n }\\n\\n function _approve(\\n address owner,\\n address spender,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot approve from 0x0 address\\\"\\n );\\n require(\\n spender != address(0),\\n \\\"ERC20Token: cannot approve to 0x0 address\\\"\\n );\\n\\n allowances[owner][spender] = value;\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function _mint(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot mint to 0x0 address\\\"\\n );\\n require(\\n value > 0,\\n \\\"ERC20Token: cannot mint 0 value\\\"\\n );\\n\\n balances[owner] = balances[owner].add(value);\\n totalSupply = totalSupply.add(value);\\n\\n emit Transfer(address(0), owner, value);\\n }\\n\\n function _burn(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot burn from 0x0 address\\\"\\n );\\n\\n balances[owner] = balances[owner].sub(\\n value,\\n \\\"ERC20Token: burn value exceeds balance\\\"\\n );\\n\\n totalSupply = totalSupply.sub(value);\\n\\n emit Transfer(owner, address(0), value);\\n }\\n\\n // internal functions (views)\\n\\n function _getSender()\\n virtual\\n internal\\n view\\n returns (address)\\n {\\n return msg.sender;\\n }\\n}\\n\",\"keccak256\":\"0x6f2b0bd08da549c6c1f5ceee85766832d587dde62c56bebc3a14bd9ea407e03d\",\"license\":\"MIT\"},\"src/gateway/GatewayRecipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BytesLib.sol\\\";\\n\\n\\n/**\\n * @title Gateway recipient\\n *\\n * @notice Gateway target contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract GatewayRecipient {\\n using BytesLib for bytes;\\n\\n address public gateway;\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `GatewayRecipient` contract\\n * @param gateway_ `Gateway` contract address\\n */\\n function _initializeGatewayRecipient(\\n address gateway_\\n )\\n internal\\n {\\n gateway = gateway_;\\n }\\n\\n // internal functions (views)\\n\\n /**\\n * @notice Gets gateway context account\\n * @return context account address\\n */\\n function _getContextAccount()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(40);\\n }\\n\\n /**\\n * @notice Gets gateway context sender\\n * @return context sender address\\n */\\n function _getContextSender()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(20);\\n }\\n\\n /**\\n * @notice Gets gateway context data\\n * @return context data\\n */\\n function _getContextData()\\n internal\\n view\\n returns (bytes calldata)\\n {\\n bytes calldata result;\\n\\n if (_isGatewaySender()) {\\n result = msg.data[:msg.data.length - 40];\\n } else {\\n result = msg.data;\\n }\\n\\n return result;\\n }\\n\\n // private functions (views)\\n\\n function _getContextAddress(\\n uint256 offset\\n )\\n private\\n view\\n returns (address)\\n {\\n address result = address(0);\\n\\n if (_isGatewaySender()) {\\n uint from = msg.data.length - offset;\\n result = bytes(msg.data[from:from + 20]).toAddress();\\n } else {\\n result = msg.sender;\\n }\\n\\n return result;\\n }\\n\\n function _isGatewaySender()\\n private\\n view\\n returns (bool)\\n {\\n bool result;\\n\\n if (msg.sender == gateway) {\\n require(\\n msg.data.length >= 44,\\n \\\"GatewayRecipient: invalid msg.data\\\"\\n );\\n\\n result = true;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe3fd29479d748d67360c61a9cbaafc66eaca25f476e59a45e842472bcf5233fc\",\"license\":\"MIT\"},\"src/personal/PersonalAccountRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/access/Guarded.sol\\\";\\nimport \\\"../common/account/AccountController.sol\\\";\\nimport \\\"../common/account/AccountRegistry.sol\\\";\\nimport \\\"../common/libs/BlockLib.sol\\\";\\nimport \\\"../common/libs/ECDSALib.sol\\\";\\nimport \\\"../common/libs/ECDSAExtendedLib.sol\\\";\\nimport \\\"../common/libs/SafeMathLib.sol\\\";\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/token/ERC20Token.sol\\\";\\nimport \\\"../gateway/GatewayRecipient.sol\\\";\\n\\n\\n/**\\n * @title Personal account registry\\n *\\n * @notice A registry for personal (controlled by owners) accounts\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract PersonalAccountRegistry is Guarded, AccountController, AccountRegistry, Initializable, GatewayRecipient {\\n using BlockLib for BlockLib.BlockRelated;\\n using SafeMathLib for uint256;\\n using ECDSALib for bytes32;\\n using ECDSAExtendedLib for bytes;\\n\\n struct Account {\\n bool deployed;\\n bytes32 salt;\\n mapping(address => BlockLib.BlockRelated) owners;\\n }\\n\\n mapping(address => Account) private accounts;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the new owner is added\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerAdded(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the existing owner is removed\\n * @param account account address\\n * @param owner owner address\\n */\\n event AccountOwnerRemoved(\\n address account,\\n address owner\\n );\\n\\n /**\\n * @dev Emitted when the call is refunded\\n * @param account account address\\n * @param beneficiary beneficiary address\\n * @param token token address\\n * @param value value\\n */\\n event AccountCallRefunded(\\n address account,\\n address beneficiary,\\n address token,\\n uint256 value\\n );\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor() public Initializable() {}\\n\\n // external functions\\n\\n /**\\n * @notice Initializes `PersonalAccountRegistry` contract\\n * @param guardians_ array of guardians addresses\\n * @param accountImplementation_ account implementation address\\n * @param gateway_ `Gateway` contract address\\n */\\n function initialize(\\n address[] calldata guardians_,\\n address accountImplementation_,\\n address gateway_\\n )\\n external\\n onlyInitializer\\n {\\n // Guarded\\n _initializeGuarded(guardians_);\\n\\n // AccountController\\n _initializeAccountController(address(this), accountImplementation_);\\n\\n // GatewayRecipient\\n _initializeGatewayRecipient(gateway_);\\n }\\n\\n /**\\n * @notice Upgrades `PersonalAccountRegistry` contract\\n * @param accountImplementation_ account implementation address\\n */\\n function upgrade(\\n address accountImplementation_\\n )\\n external\\n onlyGuardian\\n {\\n _setAccountImplementation(accountImplementation_, true);\\n }\\n\\n /**\\n * @notice Deploys account\\n * @param account account address\\n */\\n function deployAccount(\\n address account\\n )\\n external\\n {\\n _verifySender(account);\\n _deployAccount(account);\\n }\\n\\n /**\\n * @notice Upgrades account\\n * @param account account address\\n */\\n function upgradeAccount(\\n address account\\n )\\n external\\n {\\n _verifySender(account);\\n _upgradeAccount(account, true);\\n }\\n\\n /**\\n * @notice Adds a new account owner\\n * @param account account address\\n * @param owner owner address\\n */\\n function addAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n {\\n _verifySender(account);\\n\\n require(\\n owner != address(0),\\n \\\"PersonalAccountRegistry: cannot add 0x0 owner\\\"\\n );\\n\\n require(\\n !accounts[account].owners[owner].verifyAtCurrentBlock(),\\n \\\"PersonalAccountRegistry: owner already exists\\\"\\n );\\n\\n accounts[account].owners[owner].added = true;\\n accounts[account].owners[owner].removedAtBlockNumber = 0;\\n\\n emit AccountOwnerAdded(\\n account,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Removes the existing account owner\\n * @param account account address\\n * @param owner owner address\\n */\\n function removeAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n {\\n address sender = _verifySender(account);\\n\\n require(\\n owner != sender,\\n \\\"PersonalAccountRegistry: cannot remove self\\\"\\n );\\n\\n require(\\n accounts[account].owners[owner].verifyAtCurrentBlock(),\\n \\\"PersonalAccountRegistry: owner doesn't exist\\\"\\n );\\n\\n accounts[account].owners[owner].removedAtBlockNumber = block.number;\\n\\n emit AccountOwnerRemoved(\\n account,\\n owner\\n );\\n }\\n\\n /**\\n * @notice Executes account transaction\\n * @dev Deploys an account if not deployed yet\\n * @param account account address\\n * @param to to address\\n * @param value value\\n * @param data data\\n */\\n function executeAccountTransaction(\\n address account,\\n address to,\\n uint256 value,\\n bytes calldata data\\n )\\n external\\n {\\n _verifySender(account);\\n\\n _deployAccount(account);\\n\\n _executeAccountTransaction(\\n account,\\n to,\\n value,\\n data,\\n true\\n );\\n }\\n\\n /**\\n * @notice Refunds account call\\n * @dev Deploys an account if not deployed yet\\n * @param account account address\\n * @param token token address\\n * @param value value\\n */\\n function refundAccountCall(\\n address account,\\n address token,\\n uint256 value\\n )\\n external\\n {\\n _verifySender(account);\\n\\n _deployAccount(account);\\n\\n /* solhint-disable avoid-tx-origin */\\n\\n if (token == address(0)) {\\n _executeAccountTransaction(\\n account,\\n tx.origin,\\n value,\\n new bytes(0),\\n false\\n );\\n } else {\\n bytes memory response = _executeAccountTransaction(\\n account,\\n token,\\n 0,\\n abi.encodeWithSelector(\\n ERC20Token(token).transfer.selector,\\n tx.origin,\\n value\\n ),\\n false\\n );\\n\\n if (response.length > 0) {\\n require(\\n abi.decode(response, (bool)),\\n \\\"PersonalAccountRegistry: ERC20Token transfer reverted\\\"\\n );\\n }\\n }\\n\\n emit AccountCallRefunded(\\n account,\\n tx.origin,\\n token,\\n value\\n );\\n\\n /* solhint-enable avoid-tx-origin */\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Computes account address\\n * @param saltOwner salt owner address\\n * @return account address\\n */\\n function computeAccountAddress(\\n address saltOwner\\n )\\n external\\n view\\n returns (address)\\n {\\n return _computeAccountAddress(saltOwner);\\n }\\n\\n /**\\n * @notice Checks if account is deployed\\n * @param account account address\\n * @return true when account is deployed\\n */\\n function isAccountDeployed(\\n address account\\n )\\n external\\n view\\n returns (bool)\\n {\\n return accounts[account].deployed;\\n }\\n\\n /**\\n * @notice Verifies the owner of the account at the current block\\n * @param account account address\\n * @param owner owner address\\n * @return true on correct account owner\\n */\\n function verifyAccountOwner(\\n address account,\\n address owner\\n )\\n external\\n view\\n returns (bool)\\n {\\n return _verifyAccountOwner(account, owner);\\n }\\n\\n /**\\n * @notice Verifies the owner of the account at a specific block\\n * @param account account address\\n * @param owner owner address\\n * @param blockNumber block number to verify\\n * @return true on correct account owner\\n */\\n function verifyAccountOwnerAtBlock(\\n address account,\\n address owner,\\n uint256 blockNumber\\n )\\n external\\n view\\n returns (bool)\\n {\\n bool result = false;\\n\\n if (_verifyAccountOwner(account, owner)) {\\n result = true;\\n } else {\\n result = accounts[account].owners[owner].verifyAtBlock(blockNumber);\\n }\\n\\n return result;\\n }\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param messageHash message hash\\n * @param signature signature\\n * @return magic hash if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes32 messageHash,\\n bytes calldata signature\\n )\\n override\\n external\\n view\\n returns (bool)\\n {\\n return _verifyAccountOwner(\\n account,\\n messageHash.recoverAddress(signature)\\n );\\n }\\n\\n /**\\n * @notice Verifies account signature\\n * @param account account address\\n * @param message message\\n * @param signature signature\\n * @return magic hash if valid\\n */\\n function isValidAccountSignature(\\n address account,\\n bytes calldata message,\\n bytes calldata signature\\n )\\n override\\n external\\n view\\n returns (bool)\\n {\\n return _verifyAccountOwner(\\n account,\\n message.toEthereumSignedMessageHash().recoverAddress(signature)\\n );\\n }\\n\\n // private functions\\n\\n function _verifySender(\\n address account\\n )\\n private\\n returns (address)\\n {\\n address sender = _getContextSender();\\n\\n if (accounts[account].owners[sender].added) {\\n require(\\n accounts[account].owners[sender].removedAtBlockNumber == 0,\\n \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n );\\n } else {\\n require(\\n accounts[account].salt == 0,\\n \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n );\\n\\n bytes32 salt = keccak256(\\n abi.encodePacked(sender)\\n );\\n\\n require(\\n account == _computeAccountAddress(salt),\\n \\\"PersonalAccountRegistry: sender is not the account owner\\\"\\n );\\n\\n accounts[account].salt = salt;\\n accounts[account].owners[sender].added = true;\\n\\n emit AccountOwnerAdded(\\n account,\\n sender\\n );\\n }\\n\\n return sender;\\n }\\n\\n function _deployAccount(\\n address account\\n )\\n internal\\n {\\n if (!accounts[account].deployed) {\\n _deployAccount(\\n accounts[account].salt,\\n true\\n );\\n\\n accounts[account].deployed = true;\\n }\\n }\\n\\n // private functions (views)\\n\\n function _computeAccountAddress(\\n address saltOwner\\n )\\n private\\n view\\n returns (address)\\n {\\n bytes32 salt = keccak256(\\n abi.encodePacked(saltOwner)\\n );\\n\\n return _computeAccountAddress(salt);\\n }\\n\\n function _verifyAccountOwner(\\n address account,\\n address owner\\n )\\n private\\n view\\n returns (bool)\\n {\\n bool result;\\n\\n if (accounts[account].owners[owner].added) {\\n result = accounts[account].owners[owner].removedAtBlockNumber == 0;\\n } else if (accounts[account].salt == 0) {\\n result = account == _computeAccountAddress(owner);\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xdae162610e707ab8c394b3edf924b75ef1f315520935cb88f4280b29eeaf4b61\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5032600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506144d1806100616000396000f3fe608060405234801561001057600080fd5b50600436106101425760003560e01c806390482d72116100b8578063d0f710d61161007c578063d0f710d61461075e578063da9fc1ae146107f7578063db63f5821461083b578063e1e382ce1461089f578063e5c7278f14610958578063f4876c7414610a1b57610142565b806390482d7214610545578063a526d83b146105fe578063bb890d3f14610642578063cade6a5d146106bc578063d089e11a1461072a57610142565b80631a8414031161010a5780631a841403146103515780633164b5e1146103bf57806334d323a414610419578063392e53cd1461049d57806343013c24146104bd578063714041561461050157610142565b80630900f010146101475780630c68ba211461018b57806311464fbe146101e5578063116191b614610219578063124e9eb31461024d575b600080fd5b6101896004803603602081101561015d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a7f565b005b6101cd600480360360208110156101a157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b2e565b60405180821515815260200191505060405180910390f35b6101ed610b83565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610221610ba9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103396004803603606081101561026357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156102a057600080fd5b8201836020820111156102b257600080fd5b803590602001918460018302840111640100000000831117156102d457600080fd5b9091929391929390803590602001906401000000008111156102f557600080fd5b82018360208201111561030757600080fd5b8035906020019184600183028401116401000000008311171561032957600080fd5b9091929391929390505050610bcf565b60405180821515815260200191505060405180910390f35b6103bd6004803603606081101561036757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c88565b005b610401600480360360208110156103d557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ef3565b60405180821515815260200191505060405180910390f35b6104856004803603606081101561042f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f4c565b60405180821515815260200191505060405180910390f35b6104a561103a565b60405180821515815260200191505060405180910390f35b6104ff600480360360208110156104d357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611092565b005b6105436004803603602081101561051757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506110aa565b005b6105fc6004803603606081101561055b57600080fd5b810190808035906020019064010000000081111561057857600080fd5b82018360208201111561058a57600080fd5b803590602001918460208302840111640100000000831117156105ac57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611370565b005b6106406004803603602081101561061457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611508565b005b6106a46004803603604081101561065857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115b5565b60405180821515815260200191505060405180910390f35b6106fe600480360360208110156106d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115c9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107326115db565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107df6004803603604081101561077457600080fd5b81019080803590602001909291908035906020019064010000000081111561079b57600080fd5b8201836020820111156107ad57600080fd5b803590602001918460018302840111640100000000831117156107cf57600080fd5b9091929391929390505050611601565b60405180821515815260200191505060405180910390f35b6108396004803603602081101561080d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061165a565b005b61089d6004803603604081101561085157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611670565b005b610940600480360360608110156108b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156108fc57600080fd5b82018360208201111561090e57600080fd5b8035906020019184600183028401116401000000008311171561093057600080fd5b9091929391929390505050611905565b60405180821515815260200191505060405180910390f35b610a196004803603608081101561096e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109d557600080fd5b8201836020820111156109e757600080fd5b80359060200191846001830284011164010000000083111715610a0957600080fd5b9091929391929390505050611971565b005b610a7d60048036036040811015610a3157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119de565b005b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610b20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806143e46026913960400191505060405180910390fd5b610b2b816001611d0d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610c7d86610c7885858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c6a89898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611e4e565b611fb790919063ffffffff16565b612087565b905095945050505050565b610c918361223e565b50610c9b83612685565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610d2f57610d29833283600067ffffffffffffffff81118015610cee57600080fd5b506040519080825280601f01601f191660200182016040528015610d215781602001600182028036833780820191505090505b506000612786565b50610e5d565b6060610dd38484600063a9059cbb60e01b3287604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506000612786565b9050600081511115610e5b57808060200190516020811015610df457600080fd5b8101908080519060200190929190505050610e5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603581526020018061440a6035913960400191505060405180910390fd5b5b505b7feb5511fbef89123439f12682f0e9d0fc9696913b26eee55434c77d62c30aa7ca83328484604051808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390a1505050565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b60008060009050610f5d8585612087565b15610f6b576001905061102f565b61102c83600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050612c5490919063ffffffff16565b90505b809150509392505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b61109b8161223e565b506110a7816001612ca3565b50565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661114b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806143e46026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614156111ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f477561726465643a2063616e6e6f742072656d6f76652073656c66000000000081525060200191505060405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166112ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f477561726465643a20677561726469616e20646f65736e27742065786973740081525060200191505060405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b3282604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614318602f913960400191505060405180910390fd5b6000600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506114a2848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050612f05565b6114ac3083612f5d565b6114b581612f77565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e632604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150505050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166115a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806143e46026913960400191505060405180910390fd5b6115b281612fbb565b50565b60006115c18383612087565b905092915050565b60006115d4826131e2565b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006116518484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613238565b90509392505050565b6116638161223e565b5061166d81612685565b50565b600061167b8361223e565b90508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611702576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806143b9602b913960400191505060405180910390fd5b6117b9600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff161515151581526020016001820154815250506132a5565b61180e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806142b7602c913960400191505060405180910390fd5b43600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055507f1ce3cbbc43ee231e5b950332f2b0b9dd7d349291a3ee411ce5c5c7ed745661bb8383604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a1505050565b60006119678561196285858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087611fb790919063ffffffff16565b612087565b9050949350505050565b61197a8561223e565b5061198485612685565b6119d685858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001612786565b505050505050565b6119e78261223e565b50600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611a6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180614498602d913960400191505060405180910390fd5b611b25600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff161515151581526020016001820154815250506132a5565b15611b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d81526020018061446b602d913960400191505060405180910390fd5b6001600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055507f27e282f7712c5b4617277759c834b86d163dfc1aad25c8c3c5926a1c9e5644688282604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b81526020018061421e603b913960400191505060405180910390fd5b81600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508015611e4a577f70d9f5a076620216a6050e493f3ce69749de0b68fa4b839ba2518660ba8b9cf0600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5050565b6000611e5a82516132b8565b826040516020018082805190602001908083835b60208310611e915780518252602082019150602081019050602083039250611e6e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405260405160200180807f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250601a0183805190602001908083835b60208310611f235780518252602082019150602081019050602083039250611f00565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b60208310611f745780518252602082019150602081019050602083039250611f51565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052805190602001209050919050565b6000806000905060418351141561207d5760008060006020860151925060408601519150606086015160001a9050601b8160ff161015611ff857601b810190505b601b8160ff16148061200d5750601c8160ff16145b156120795760018782858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561206c573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b600080600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16156121ac576000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154149050612234565b6000801b600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154141561223357612202836131e2565b73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505b5b8091505092915050565b6000806122496133ff565b9050600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16156123c0576000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154146123bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806142596038913960400191505060405180910390fd5b61267c565b6000801b600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101541461245d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806142596038913960400191505060405180910390fd5b600081604051602001808273ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040528051906020012090506124aa81613410565b73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461252d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806142596038913960400191505060405180910390fd5b80600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055507f27e282f7712c5b4617277759c834b86d163dfc1aad25c8c3c5926a1c9e5644688483604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a1505b80915050919050565b600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1661278357612726600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101546001613606565b506001600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055505b50565b6060600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141561280e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806143476025913960400191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415612893576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061443f602c913960400191505060405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415612918576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806142916026913960400191505060405180910390fd5b60608673ffffffffffffffffffffffffffffffffffffffff16633f579f428787876040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156129aa57808201518184015260208101905061298f565b50505050905090810190601f1680156129d75780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156129f857600080fd5b505af1158015612a0c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015612a3657600080fd5b8101908080516040519392919084640100000000821115612a5657600080fd5b83820191506020820185811115612a6c57600080fd5b8251866001820283011164010000000082111715612a8957600080fd5b8083526020830192505050908051906020019080838360005b83811015612abd578082015181840152602081019050612aa2565b50505050905090810190601f168015612aea5780820380516001836020036101000a031916815260200191505b5060405250505090508215612c47577f99eeae1fb8801e2e878e060ec5e5b3557b3c4f8106e35d88cb573f293dae4e248787878785604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015612ba1578082015181840152602081019050612b86565b50505050905090810190601f168015612bce5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015612c07578082015181840152602081019050612bec565b50505050905090810190601f168015612c345780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a15b8091505095945050505050565b60008060009050836000015115612c9957600084602001511415612c7b5760019050612c98565b6000831415612c8d5760019050612c97565b8284602001511190505b5b5b8091505092915050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d2257600080fd5b505afa158015612d36573d6000803e3d6000fd5b505050506040513d6020811015612d4c57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415612dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b81526020018061438e602b913960400191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663d784d426600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b158015612e5557600080fd5b505af1158015612e69573d6000803e3d6000fd5b505050508015612f01577feec27cdb8bd6f55c2c537deb52ab094a2437e85ef5197e6f064f90bff3ff563f82600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b5050565b600081511415612f1d57612f1832612fbb565b612f5a565b60008151905060005b81811015612f5757612f4a838281518110612f3d57fe5b6020026020010151612fbb565b8080600101915050612f26565b50505b50565b612f6882600061375a565b612f73816000611d0d565b5050565b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561305e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f477561726465643a2063616e6e6f74206164642030783020677561726469616e81525060200191505060405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561311d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f477561726465643a20677561726469616e20616c72656164792065786973747381525060200191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a3282604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150565b60008082604051602001808273ffffffffffffffffffffffffffffffffffffffff1660601b815260140191505060405160208183030381529060405280519060200120905061323081613410565b915050919050565b60008061324e8385611fb790919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b60006132b18243612c54565b9050919050565b60606000821415613300576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506133fa565b600082905060005b6000821461332a578080600101915050600a828161332257fe5b049150613308565b60608167ffffffffffffffff8111801561334357600080fd5b506040519080825280601f01601f1916602001820160405280156133765781602001600182028036833780820191505090505b50905060006001830390508593505b600084146133f257600a848161339757fe5b0660300160f81b828280600190039350815181106133b157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84816133ea57fe5b049350613385565b819450505050505b919050565b600061340b601461389b565b905090565b600060606040518060200161342490613a8c565b6020820181038252601f19601f82011660405250600060a01b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600060a01b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516020018086805190602001908083835b602083106134be578051825260208201915060208101905060208303925061349b565b6001836020036101000a0380198251168184511680821785525050505050509050018573ffffffffffffffffffffffffffffffffffffffff19168152600c018473ffffffffffffffffffffffffffffffffffffffff1660601b81526014018373ffffffffffffffffffffffffffffffffffffffff19168152600c018273ffffffffffffffffffffffffffffffffffffffff1660601b8152601401955050505050506040516020818303038152906040529050600060ff60f81b3085848051906020012060405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018473ffffffffffffffffffffffffffffffffffffffff1660601b81526014018381526020018281526020019450505050506040516020818303038152906040528051906020012090508060001c92505050919050565b60008083600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405161365c90613a8c565b808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff168152602001925050508190604051809103906000f59050801580156136b9573d6000803e3d6000fd5b5090508215613750577f2682a218602b9036c9869f006c5405ee4a1a65267653eb7e286123e5e1afde4c81600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156137e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001806142e36035913960400191505060405180910390fd5b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508015613897577f02e3c47057b8dc27a0929d3c394c314c73aa002d46939c31c9f71d1e77e86c10600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5050565b600080600090506138aa613930565b1561392357600083600036905003905061391b600036839060148501926138d393929190613a99565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506139f3565b915050613927565b3390505b80915050919050565b600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156139ec57602c600036905010156139e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061436c6022913960400191505060405180910390fd5b600190505b8091505090565b6000806014835114613a6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f42797465734c69623a20696e76616c69642064617461206c656e67746800000081525060200191505060405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b61075180613acd83390190565b60008085851115613aa957600080fd5b83861115613ab657600080fd5b600185028301915084860390509450949250505056fe608060405234801561001057600080fd5b506040516107513803806107518339818101604052604081101561003357600080fd5b810190808051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050610630806101216000396000f3fe60806040526004361061004e5760003560e01c80633f579f42146100be5780635c60da1b146101e75780637b10399914610228578063d784d42614610269578063f77c4791146102ba57610055565b3661005557005b34801561006157600080fd5b50600080369050146100bc576000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050368060008037600080826000855af43d806000803e81600081146100b757816000f35b816000fd5b005b3480156100ca57600080fd5b5061016c600480360360608110156100e157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561012857600080fd5b82018360208201111561013a57600080fd5b8035906020019184600183028401116401000000008311171561015c57600080fd5b90919293919293905050506102fb565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101ac578082015181840152602081019050610191565b50505050905090810190601f1680156101d95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101f357600080fd5b506101fc61049f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561023457600080fd5b5061023d6104c5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561027557600080fd5b506102b86004803603602081101561028c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104eb565b005b3480156102c657600080fd5b506102cf6105d3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806105f8602c913960400191505060405180910390fd5b606060008673ffffffffffffffffffffffffffffffffffffffff1686868660405180838380828437808301925050509250505060006040518083038185875af1925050503d8060008114610411576040519150601f19603f3d011682016040523d82523d6000602084013e610416565b606091505b50809350819250505080610492576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4163636f756e743a207472616e73616374696f6e20726576657274656400000081525060200191505060405180910390fd5b8192505050949350505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461058f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806105f8602c913960400191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fe436f6e74726f6c6c65643a206d73672e73656e646572206973206e6f742074686520636f6e74726f6c6c6572a164736f6c634300060c000a4163636f756e74436f6e74726f6c6c65723a2063616e6e6f7420736574206163636f756e7420496d706c656d656e746174696f6e20746f20307830506572736f6e616c4163636f756e7452656769737472793a2073656e646572206973206e6f7420746865206163636f756e74206f776e65724163636f756e74436f6e74726f6c6c65723a2063616e6e6f742073656e6420746f2073656c66506572736f6e616c4163636f756e7452656769737472793a206f776e657220646f65736e27742065786973744163636f756e74436f6e74726f6c6c65723a2063616e6e6f7420736574206163636f756e7420726567697374727920746f20307830496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742074686520696e697469616c697a65724163636f756e74436f6e74726f6c6c65723a2063616e6e6f742073656e6420746f2030783047617465776179526563697069656e743a20696e76616c6964206d73672e646174614163636f756e74436f6e74726f6c6c65723a206163636f756e7420616c7265616479207570677261646564506572736f6e616c4163636f756e7452656769737472793a2063616e6e6f742072656d6f76652073656c66477561726465643a2074782e6f726967696e206973206e6f742074686520677561726469616e506572736f6e616c4163636f756e7452656769737472793a204552433230546f6b656e207472616e736665722072657665727465644163636f756e74436f6e74726f6c6c65723a2063616e6e6f742073656e6420746f20636f6e74726f6c6c6572506572736f6e616c4163636f756e7452656769737472793a206f776e657220616c726561647920657869737473506572736f6e616c4163636f756e7452656769737472793a2063616e6e6f742061646420307830206f776e6572a164736f6c634300060c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101425760003560e01c806390482d72116100b8578063d0f710d61161007c578063d0f710d61461075e578063da9fc1ae146107f7578063db63f5821461083b578063e1e382ce1461089f578063e5c7278f14610958578063f4876c7414610a1b57610142565b806390482d7214610545578063a526d83b146105fe578063bb890d3f14610642578063cade6a5d146106bc578063d089e11a1461072a57610142565b80631a8414031161010a5780631a841403146103515780633164b5e1146103bf57806334d323a414610419578063392e53cd1461049d57806343013c24146104bd578063714041561461050157610142565b80630900f010146101475780630c68ba211461018b57806311464fbe146101e5578063116191b614610219578063124e9eb31461024d575b600080fd5b6101896004803603602081101561015d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a7f565b005b6101cd600480360360208110156101a157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b2e565b60405180821515815260200191505060405180910390f35b6101ed610b83565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610221610ba9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103396004803603606081101561026357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156102a057600080fd5b8201836020820111156102b257600080fd5b803590602001918460018302840111640100000000831117156102d457600080fd5b9091929391929390803590602001906401000000008111156102f557600080fd5b82018360208201111561030757600080fd5b8035906020019184600183028401116401000000008311171561032957600080fd5b9091929391929390505050610bcf565b60405180821515815260200191505060405180910390f35b6103bd6004803603606081101561036757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c88565b005b610401600480360360208110156103d557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ef3565b60405180821515815260200191505060405180910390f35b6104856004803603606081101561042f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f4c565b60405180821515815260200191505060405180910390f35b6104a561103a565b60405180821515815260200191505060405180910390f35b6104ff600480360360208110156104d357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611092565b005b6105436004803603602081101561051757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506110aa565b005b6105fc6004803603606081101561055b57600080fd5b810190808035906020019064010000000081111561057857600080fd5b82018360208201111561058a57600080fd5b803590602001918460208302840111640100000000831117156105ac57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611370565b005b6106406004803603602081101561061457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611508565b005b6106a46004803603604081101561065857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115b5565b60405180821515815260200191505060405180910390f35b6106fe600480360360208110156106d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115c9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107326115db565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107df6004803603604081101561077457600080fd5b81019080803590602001909291908035906020019064010000000081111561079b57600080fd5b8201836020820111156107ad57600080fd5b803590602001918460018302840111640100000000831117156107cf57600080fd5b9091929391929390505050611601565b60405180821515815260200191505060405180910390f35b6108396004803603602081101561080d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061165a565b005b61089d6004803603604081101561085157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611670565b005b610940600480360360608110156108b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156108fc57600080fd5b82018360208201111561090e57600080fd5b8035906020019184600183028401116401000000008311171561093057600080fd5b9091929391929390505050611905565b60405180821515815260200191505060405180910390f35b610a196004803603608081101561096e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109d557600080fd5b8201836020820111156109e757600080fd5b80359060200191846001830284011164010000000083111715610a0957600080fd5b9091929391929390505050611971565b005b610a7d60048036036040811015610a3157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119de565b005b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610b20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806143e46026913960400191505060405180910390fd5b610b2b816001611d0d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610c7d86610c7885858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c6a89898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611e4e565b611fb790919063ffffffff16565b612087565b905095945050505050565b610c918361223e565b50610c9b83612685565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610d2f57610d29833283600067ffffffffffffffff81118015610cee57600080fd5b506040519080825280601f01601f191660200182016040528015610d215781602001600182028036833780820191505090505b506000612786565b50610e5d565b6060610dd38484600063a9059cbb60e01b3287604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506000612786565b9050600081511115610e5b57808060200190516020811015610df457600080fd5b8101908080519060200190929190505050610e5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603581526020018061440a6035913960400191505060405180910390fd5b5b505b7feb5511fbef89123439f12682f0e9d0fc9696913b26eee55434c77d62c30aa7ca83328484604051808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390a1505050565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b60008060009050610f5d8585612087565b15610f6b576001905061102f565b61102c83600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff16151515158152602001600182015481525050612c5490919063ffffffff16565b90505b809150509392505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b61109b8161223e565b506110a7816001612ca3565b50565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661114b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806143e46026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614156111ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f477561726465643a2063616e6e6f742072656d6f76652073656c66000000000081525060200191505060405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166112ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f477561726465643a20677561726469616e20646f65736e27742065786973740081525060200191505060405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fee943cdb81826d5909c559c6b1ae6908fcaf2dbc16c4b730346736b486283e8b3282604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614318602f913960400191505060405180910390fd5b6000600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506114a2848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050612f05565b6114ac3083612f5d565b6114b581612f77565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e632604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150505050565b6000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166115a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806143e46026913960400191505060405180910390fd5b6115b281612fbb565b50565b60006115c18383612087565b905092915050565b60006115d4826131e2565b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006116518484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613238565b90509392505050565b6116638161223e565b5061166d81612685565b50565b600061167b8361223e565b90508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611702576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806143b9602b913960400191505060405180910390fd5b6117b9600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff161515151581526020016001820154815250506132a5565b61180e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806142b7602c913960400191505060405180910390fd5b43600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055507f1ce3cbbc43ee231e5b950332f2b0b9dd7d349291a3ee411ce5c5c7ed745661bb8383604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a1505050565b60006119678561196285858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087611fb790919063ffffffff16565b612087565b9050949350505050565b61197a8561223e565b5061198485612685565b6119d685858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001612786565b505050505050565b6119e78261223e565b50600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611a6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180614498602d913960400191505060405180910390fd5b611b25600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff161515151581526020016001820154815250506132a5565b15611b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d81526020018061446b602d913960400191505060405180910390fd5b6001600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055507f27e282f7712c5b4617277759c834b86d163dfc1aad25c8c3c5926a1c9e5644688282604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b81526020018061421e603b913960400191505060405180910390fd5b81600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508015611e4a577f70d9f5a076620216a6050e493f3ce69749de0b68fa4b839ba2518660ba8b9cf0600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5050565b6000611e5a82516132b8565b826040516020018082805190602001908083835b60208310611e915780518252602082019150602081019050602083039250611e6e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405260405160200180807f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250601a0183805190602001908083835b60208310611f235780518252602082019150602081019050602083039250611f00565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b60208310611f745780518252602082019150602081019050602083039250611f51565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052805190602001209050919050565b6000806000905060418351141561207d5760008060006020860151925060408601519150606086015160001a9050601b8160ff161015611ff857601b810190505b601b8160ff16148061200d5750601c8160ff16145b156120795760018782858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561206c573d6000803e3d6000fd5b5050506020604051035193505b5050505b8091505092915050565b600080600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16156121ac576000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154149050612234565b6000801b600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154141561223357612202836131e2565b73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505b5b8091505092915050565b6000806122496133ff565b9050600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16156123c0576000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154146123bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806142596038913960400191505060405180910390fd5b61267c565b6000801b600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101541461245d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806142596038913960400191505060405180910390fd5b600081604051602001808273ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040528051906020012090506124aa81613410565b73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461252d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806142596038913960400191505060405180910390fd5b80600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055507f27e282f7712c5b4617277759c834b86d163dfc1aad25c8c3c5926a1c9e5644688483604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a1505b80915050919050565b600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1661278357612726600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101546001613606565b506001600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055505b50565b6060600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141561280e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806143476025913960400191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415612893576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061443f602c913960400191505060405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415612918576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806142916026913960400191505060405180910390fd5b60608673ffffffffffffffffffffffffffffffffffffffff16633f579f428787876040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156129aa57808201518184015260208101905061298f565b50505050905090810190601f1680156129d75780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156129f857600080fd5b505af1158015612a0c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015612a3657600080fd5b8101908080516040519392919084640100000000821115612a5657600080fd5b83820191506020820185811115612a6c57600080fd5b8251866001820283011164010000000082111715612a8957600080fd5b8083526020830192505050908051906020019080838360005b83811015612abd578082015181840152602081019050612aa2565b50505050905090810190601f168015612aea5780820380516001836020036101000a031916815260200191505b5060405250505090508215612c47577f99eeae1fb8801e2e878e060ec5e5b3557b3c4f8106e35d88cb573f293dae4e248787878785604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015612ba1578082015181840152602081019050612b86565b50505050905090810190601f168015612bce5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015612c07578082015181840152602081019050612bec565b50505050905090810190601f168015612c345780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a15b8091505095945050505050565b60008060009050836000015115612c9957600084602001511415612c7b5760019050612c98565b6000831415612c8d5760019050612c97565b8284602001511190505b5b5b8091505092915050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d2257600080fd5b505afa158015612d36573d6000803e3d6000fd5b505050506040513d6020811015612d4c57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415612dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b81526020018061438e602b913960400191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663d784d426600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b158015612e5557600080fd5b505af1158015612e69573d6000803e3d6000fd5b505050508015612f01577feec27cdb8bd6f55c2c537deb52ab094a2437e85ef5197e6f064f90bff3ff563f82600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b5050565b600081511415612f1d57612f1832612fbb565b612f5a565b60008151905060005b81811015612f5757612f4a838281518110612f3d57fe5b6020026020010151612fbb565b8080600101915050612f26565b50505b50565b612f6882600061375a565b612f73816000611d0d565b5050565b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561305e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f477561726465643a2063616e6e6f74206164642030783020677561726469616e81525060200191505060405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561311d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f477561726465643a20677561726469616e20616c72656164792065786973747381525060200191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fbc3292102fa77e083913064b282926717cdfaede4d35f553d66366c0a3da755a3282604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150565b60008082604051602001808273ffffffffffffffffffffffffffffffffffffffff1660601b815260140191505060405160208183030381529060405280519060200120905061323081613410565b915050919050565b60008061324e8385611fb790919063ffffffff16565b90506000808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b60006132b18243612c54565b9050919050565b60606000821415613300576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506133fa565b600082905060005b6000821461332a578080600101915050600a828161332257fe5b049150613308565b60608167ffffffffffffffff8111801561334357600080fd5b506040519080825280601f01601f1916602001820160405280156133765781602001600182028036833780820191505090505b50905060006001830390508593505b600084146133f257600a848161339757fe5b0660300160f81b828280600190039350815181106133b157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84816133ea57fe5b049350613385565b819450505050505b919050565b600061340b601461389b565b905090565b600060606040518060200161342490613a8c565b6020820181038252601f19601f82011660405250600060a01b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600060a01b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516020018086805190602001908083835b602083106134be578051825260208201915060208101905060208303925061349b565b6001836020036101000a0380198251168184511680821785525050505050509050018573ffffffffffffffffffffffffffffffffffffffff19168152600c018473ffffffffffffffffffffffffffffffffffffffff1660601b81526014018373ffffffffffffffffffffffffffffffffffffffff19168152600c018273ffffffffffffffffffffffffffffffffffffffff1660601b8152601401955050505050506040516020818303038152906040529050600060ff60f81b3085848051906020012060405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018473ffffffffffffffffffffffffffffffffffffffff1660601b81526014018381526020018281526020019450505050506040516020818303038152906040528051906020012090508060001c92505050919050565b60008083600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405161365c90613a8c565b808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff168152602001925050508190604051809103906000f59050801580156136b9573d6000803e3d6000fd5b5090508215613750577f2682a218602b9036c9869f006c5405ee4a1a65267653eb7e286123e5e1afde4c81600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156137e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001806142e36035913960400191505060405180910390fd5b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508015613897577f02e3c47057b8dc27a0929d3c394c314c73aa002d46939c31c9f71d1e77e86c10600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5050565b600080600090506138aa613930565b1561392357600083600036905003905061391b600036839060148501926138d393929190613a99565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506139f3565b915050613927565b3390505b80915050919050565b600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156139ec57602c600036905010156139e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061436c6022913960400191505060405180910390fd5b600190505b8091505090565b6000806014835114613a6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f42797465734c69623a20696e76616c69642064617461206c656e67746800000081525060200191505060405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b61075180613acd83390190565b60008085851115613aa957600080fd5b83861115613ab657600080fd5b600185028301915084860390509450949250505056fe608060405234801561001057600080fd5b506040516107513803806107518339818101604052604081101561003357600080fd5b810190808051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050610630806101216000396000f3fe60806040526004361061004e5760003560e01c80633f579f42146100be5780635c60da1b146101e75780637b10399914610228578063d784d42614610269578063f77c4791146102ba57610055565b3661005557005b34801561006157600080fd5b50600080369050146100bc576000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050368060008037600080826000855af43d806000803e81600081146100b757816000f35b816000fd5b005b3480156100ca57600080fd5b5061016c600480360360608110156100e157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561012857600080fd5b82018360208201111561013a57600080fd5b8035906020019184600183028401116401000000008311171561015c57600080fd5b90919293919293905050506102fb565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101ac578082015181840152602081019050610191565b50505050905090810190601f1680156101d95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101f357600080fd5b506101fc61049f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561023457600080fd5b5061023d6104c5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561027557600080fd5b506102b86004803603602081101561028c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104eb565b005b3480156102c657600080fd5b506102cf6105d3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806105f8602c913960400191505060405180910390fd5b606060008673ffffffffffffffffffffffffffffffffffffffff1686868660405180838380828437808301925050509250505060006040518083038185875af1925050503d8060008114610411576040519150601f19603f3d011682016040523d82523d6000602084013e610416565b606091505b50809350819250505080610492576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4163636f756e743a207472616e73616374696f6e20726576657274656400000081525060200191505060405180910390fd5b8192505050949350505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461058f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806105f8602c913960400191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fe436f6e74726f6c6c65643a206d73672e73656e646572206973206e6f742074686520636f6e74726f6c6c6572a164736f6c634300060c000a4163636f756e74436f6e74726f6c6c65723a2063616e6e6f7420736574206163636f756e7420496d706c656d656e746174696f6e20746f20307830506572736f6e616c4163636f756e7452656769737472793a2073656e646572206973206e6f7420746865206163636f756e74206f776e65724163636f756e74436f6e74726f6c6c65723a2063616e6e6f742073656e6420746f2073656c66506572736f6e616c4163636f756e7452656769737472793a206f776e657220646f65736e27742065786973744163636f756e74436f6e74726f6c6c65723a2063616e6e6f7420736574206163636f756e7420726567697374727920746f20307830496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742074686520696e697469616c697a65724163636f756e74436f6e74726f6c6c65723a2063616e6e6f742073656e6420746f2030783047617465776179526563697069656e743a20696e76616c6964206d73672e646174614163636f756e74436f6e74726f6c6c65723a206163636f756e7420616c7265616479207570677261646564506572736f6e616c4163636f756e7452656769737472793a2063616e6e6f742072656d6f76652073656c66477561726465643a2074782e6f726967696e206973206e6f742074686520677561726469616e506572736f6e616c4163636f756e7452656769737472793a204552433230546f6b656e207472616e736665722072657665727465644163636f756e74436f6e74726f6c6c65723a2063616e6e6f742073656e6420746f20636f6e74726f6c6c6572506572736f6e616c4163636f756e7452656769737472793a206f776e657220616c726561647920657869737473506572736f6e616c4163636f756e7452656769737472793a2063616e6e6f742061646420307830206f776e6572a164736f6c634300060c000a", + "devdoc": { + "author": "Stanisław Głogowski ", + "events": { + "AccountCallRefunded(address,address,address,uint256)": { + "details": "Emitted when the call is refunded", + "params": { + "account": "account address", + "beneficiary": "beneficiary address", + "token": "token address", + "value": "value" + } + }, + "AccountOwnerAdded(address,address)": { + "details": "Emitted when the new owner is added", + "params": { + "account": "account address", + "owner": "owner address" + } + }, + "AccountOwnerRemoved(address,address)": { + "details": "Emitted when the existing owner is removed", + "params": { + "account": "account address", + "owner": "owner address" + } + } + }, + "kind": "dev", + "methods": { + "addAccountOwner(address,address)": { + "params": { + "account": "account address", + "owner": "owner address" + } + }, + "addGuardian(address)": { + "params": { + "guardian": "guardian address" + } + }, + "computeAccountAddress(address)": { + "params": { + "saltOwner": "salt owner address" + }, + "returns": { + "_0": "account address" + } + }, + "constructor": { + "details": "Public constructor" + }, + "deployAccount(address)": { + "params": { + "account": "account address" + } + }, + "executeAccountTransaction(address,address,uint256,bytes)": { + "details": "Deploys an account if not deployed yet", + "params": { + "account": "account address", + "data": "data", + "to": "to address", + "value": "value" + } + }, + "initialize(address[],address,address)": { + "params": { + "accountImplementation_": "account implementation address", + "gateway_": "`Gateway` contract address", + "guardians_": "array of guardians addresses" + } + }, + "isAccountDeployed(address)": { + "params": { + "account": "account address" + }, + "returns": { + "_0": "true when account is deployed" + } + }, + "isGuardian(address)": { + "params": { + "guardian": "guardian address" + }, + "returns": { + "_0": "true when guardian exists" + } + }, + "isInitialized()": { + "returns": { + "_0": "true when contract is initialized" + } + }, + "isValidAccountSignature(address,bytes,bytes)": { + "params": { + "account": "account address", + "message": "message", + "signature": "signature" + }, + "returns": { + "_0": "magic hash if valid" + } + }, + "isValidAccountSignature(address,bytes32,bytes)": { + "params": { + "account": "account address", + "messageHash": "message hash", + "signature": "signature" + }, + "returns": { + "_0": "magic hash if valid" + } + }, + "refundAccountCall(address,address,uint256)": { + "details": "Deploys an account if not deployed yet", + "params": { + "account": "account address", + "token": "token address", + "value": "value" + } + }, + "removeAccountOwner(address,address)": { + "params": { + "account": "account address", + "owner": "owner address" + } + }, + "removeGuardian(address)": { + "params": { + "guardian": "guardian address" + } + }, + "upgrade(address)": { + "params": { + "accountImplementation_": "account implementation address" + } + }, + "upgradeAccount(address)": { + "params": { + "account": "account address" + } + }, + "verifyAccountOwner(address,address)": { + "params": { + "account": "account address", + "owner": "owner address" + }, + "returns": { + "_0": "true on correct account owner" + } + }, + "verifyAccountOwnerAtBlock(address,address,uint256)": { + "params": { + "account": "account address", + "blockNumber": "block number to verify", + "owner": "owner address" + }, + "returns": { + "_0": "true on correct account owner" + } + }, + "verifyGuardianSignature(bytes32,bytes)": { + "params": { + "messageHash": "message hash", + "signature": "signature" + }, + "returns": { + "_0": "true on correct guardian signature" + } + } + }, + "title": "Personal account registry", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "addAccountOwner(address,address)": { + "notice": "Adds a new account owner" + }, + "addGuardian(address)": { + "notice": "Adds a new guardian" + }, + "computeAccountAddress(address)": { + "notice": "Computes account address" + }, + "deployAccount(address)": { + "notice": "Deploys account" + }, + "executeAccountTransaction(address,address,uint256,bytes)": { + "notice": "Executes account transaction" + }, + "initialize(address[],address,address)": { + "notice": "Initializes `PersonalAccountRegistry` contract" + }, + "isAccountDeployed(address)": { + "notice": "Checks if account is deployed" + }, + "isGuardian(address)": { + "notice": "Check if guardian exists" + }, + "isInitialized()": { + "notice": "Check if contract is initialized" + }, + "isValidAccountSignature(address,bytes,bytes)": { + "notice": "Verifies account signature" + }, + "isValidAccountSignature(address,bytes32,bytes)": { + "notice": "Verifies account signature" + }, + "refundAccountCall(address,address,uint256)": { + "notice": "Refunds account call" + }, + "removeAccountOwner(address,address)": { + "notice": "Removes the existing account owner" + }, + "removeGuardian(address)": { + "notice": "Removes the existing guardian" + }, + "upgrade(address)": { + "notice": "Upgrades `PersonalAccountRegistry` contract" + }, + "upgradeAccount(address)": { + "notice": "Upgrades account" + }, + "verifyAccountOwner(address,address)": { + "notice": "Verifies the owner of the account at the current block" + }, + "verifyAccountOwnerAtBlock(address,address,uint256)": { + "notice": "Verifies the owner of the account at a specific block" + }, + "verifyGuardianSignature(bytes32,bytes)": { + "notice": "Verifies guardian signature" + } + }, + "notice": "A registry for personal (controlled by owners) accounts", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 40, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "guardians", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 390, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "accountRegistry", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 392, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "accountImplementation", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 1871, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "initializer", + "offset": 0, + "slot": "3", + "type": "t_address" + }, + { + "astId": 5197, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "gateway", + "offset": 0, + "slot": "4", + "type": "t_address" + }, + { + "astId": 6799, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "accounts", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_struct(Account)6795_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_struct(Account)6795_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct PersonalAccountRegistry.Account)", + "numberOfBytes": "32", + "value": "t_struct(Account)6795_storage" + }, + "t_mapping(t_address,t_struct(BlockRelated)1382_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct BlockLib.BlockRelated)", + "numberOfBytes": "32", + "value": "t_struct(BlockRelated)1382_storage" + }, + "t_struct(Account)6795_storage": { + "encoding": "inplace", + "label": "struct PersonalAccountRegistry.Account", + "members": [ + { + "astId": 6788, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "deployed", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 6790, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "salt", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + }, + { + "astId": 6794, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "owners", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_struct(BlockRelated)1382_storage)" + } + ], + "numberOfBytes": "96" + }, + "t_struct(BlockRelated)1382_storage": { + "encoding": "inplace", + "label": "struct BlockLib.BlockRelated", + "members": [ + { + "astId": 1379, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "added", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1381, + "contract": "src/personal/PersonalAccountRegistry.sol:PersonalAccountRegistry", + "label": "removedAtBlockNumber", + "offset": 0, + "slot": "1", + "type": "t_uint256" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/WrappedWeiToken.json b/deployments/neonDevnet/WrappedWeiToken.json new file mode 100644 index 00000000..7087889f --- /dev/null +++ b/deployments/neonDevnet/WrappedWeiToken.json @@ -0,0 +1,670 @@ +{ + "address": "0x8e5ea4368fcd17A4efF851C5ffa6cd03bBDeb616", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "consumer", + "type": "address" + } + ], + "name": "ConsumerAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "consumer", + "type": "address" + } + ], + "name": "ConsumerRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "initializer", + "type": "address" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "depositTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "gateway", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "consumers_", + "type": "address[]" + }, + { + "internalType": "address", + "name": "gateway_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "consumer", + "type": "address" + } + ], + "name": "isConsumer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startConsuming", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stopConsuming", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdrawAllTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "withdrawTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x914aca830634bfd34953e0964b78873ddce6d6c0a62161b7a5501b4b5ca196f5", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x53fE9288897e254698175740aa359E19E26c10af", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "81195560", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xa6eb5a102c551f2f14cde19e773b53c0e0422e6c79720d013e265428f734e169", + "transactionHash": "0x914aca830634bfd34953e0964b78873ddce6d6c0a62161b7a5501b4b5ca196f5", + "logs": [], + "blockNumber": 173997050, + "cumulativeGasUsed": "81195560", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "1bdf84d4bd28700579af1cc4796e2cae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"ConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"ConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers_\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"gateway_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"isConsumer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startConsuming\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopConsuming\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawAllTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Stanis\\u0142aw G\\u0142ogowski \",\"details\":\"After the transfer to consumer's account is done, the token will be automatically burned and withdrawn. Use `startConsuming` to become a consumer.\",\"events\":{\"ConsumerAdded(address)\":{\"details\":\"Emitted when the new consumer is added\",\"params\":{\"consumer\":\"consumer address\"}},\"ConsumerRemoved(address)\":{\"details\":\"Emitted when the existing consumer is removed\",\"params\":{\"consumer\":\"consumer address\"}}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Public constructor\"},\"depositTo(address)\":{\"params\":{\"to\":\"to address\"}},\"initialize(address[],address)\":{\"params\":{\"consumers_\":\"array of consumers addresses\",\"gateway_\":\"`Gateway` contract address\"}},\"isConsumer(address)\":{\"params\":{\"consumer\":\"consumer address\"},\"returns\":{\"_0\":\"true if consumer exists\"}},\"isInitialized()\":{\"returns\":{\"_0\":\"true when contract is initialized\"}},\"startConsuming()\":{\"details\":\"Add caller as a consumer\"},\"stopConsuming()\":{\"details\":\"Remove caller from consumers\"},\"withdraw(uint256)\":{\"params\":{\"value\":\"value to withdraw\"}},\"withdrawAllTo(address)\":{\"params\":{\"to\":\"to address\"}},\"withdrawTo(address,uint256)\":{\"params\":{\"to\":\"to address\",\"value\":\"value to withdraw\"}}},\"title\":\"Wrapped wei token\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"depositTo(address)\":{\"notice\":\"Deposits `msg.value` to address\"},\"initialize(address[],address)\":{\"notice\":\"Initializes `WrappedWeiToken` contract\"},\"isConsumer(address)\":{\"notice\":\"Checks if consumer exists\"},\"isInitialized()\":{\"notice\":\"Check if contract is initialized\"},\"startConsuming()\":{\"notice\":\"Starts consuming\"},\"stopConsuming()\":{\"notice\":\"Stops consuming\"},\"withdraw(uint256)\":{\"notice\":\"Withdraws\"},\"withdrawAll()\":{\"notice\":\"Withdraws all\"},\"withdrawAllTo(address)\":{\"notice\":\"Withdraws all to address\"},\"withdrawTo(address,uint256)\":{\"notice\":\"Withdraws to address\"}},\"notice\":\"One to one wei consumable ERC20 token\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/tokens/WrappedWeiToken.sol\":\"WrappedWeiToken\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/common/libs/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Bytes library\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\nlibrary BytesLib {\\n /**\\n * @notice Converts bytes to address\\n * @param data data\\n * @return address\\n */\\n function toAddress(\\n bytes memory data\\n )\\n internal\\n pure\\n returns (address)\\n {\\n address result;\\n\\n require(\\n data.length == 20,\\n \\\"BytesLib: invalid data length\\\"\\n );\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := div(mload(add(data, 0x20)), 0x1000000000000000000000000)\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x64c84964ea91bfb1f2d859eea6c57fe5b4a6f269951a4adf5f58d306c54c7f76\",\"license\":\"MIT\"},\"src/common/libs/SafeMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Safe math library\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol\\n */\\nlibrary SafeMathLib {\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n\\n require(c >= a, \\\"SafeMathLib: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMathLib: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n\\n return a - b;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n\\n require(c / a == b, \\\"SafeMathLib: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMathLib: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n\\n return a / b;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMathLib: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x6089f354ca754d9c5dd9e800ee5ed86717dbf8f9af470604e0be691ac57c0107\",\"license\":\"MIT\"},\"src/common/lifecycle/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Contract module which provides access control mechanism, where\\n * there is the initializer account that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\\n * Use `onlyInitializer` modifier on contract initialize process.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract Initializable {\\n address private initializer;\\n\\n // events\\n\\n /**\\n * @dev Emitted after `onlyInitializer`\\n * @param initializer initializer address\\n */\\n event Initialized(\\n address initializer\\n );\\n\\n // modifiers\\n\\n /**\\n * @dev Throws if tx.origin is not the initializer\\n */\\n modifier onlyInitializer() {\\n require(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin == initializer,\\n \\\"Initializable: tx.origin is not the initializer\\\"\\n );\\n\\n /// @dev removes initializer\\n initializer = address(0);\\n\\n _;\\n\\n emit Initialized(\\n // solhint-disable-next-line avoid-tx-origin\\n tx.origin\\n );\\n }\\n\\n /**\\n * @dev Internal constructor\\n */\\n constructor()\\n internal\\n {\\n // solhint-disable-next-line avoid-tx-origin\\n initializer = tx.origin;\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Check if contract is initialized\\n * @return true when contract is initialized\\n */\\n function isInitialized()\\n external\\n view\\n returns (bool)\\n {\\n return initializer == address(0);\\n }\\n}\\n\",\"keccak256\":\"0x3d47b2864dde5bde245917f7ac416a9e9715cdf1d226897e49838eb3186ee067\",\"license\":\"MIT\"},\"src/common/token/ERC20Token.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../libs/SafeMathLib.sol\\\";\\n\\n\\n/**\\n * @title ERC20 token\\n *\\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol\\n */\\ncontract ERC20Token {\\n using SafeMathLib for uint256;\\n\\n string public name;\\n string public symbol;\\n uint8 public decimals;\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) internal balances;\\n mapping(address => mapping(address => uint256)) internal allowances;\\n\\n // events\\n\\n event Transfer(\\n address indexed from,\\n address indexed to,\\n uint256 value\\n );\\n\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // external functions\\n\\n function transfer(\\n address to,\\n uint256 value\\n )\\n external\\n returns (bool)\\n {\\n _transfer(_getSender(), to, value);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n address sender = _getSender();\\n\\n _transfer(from, to, value);\\n _approve(from, sender, allowances[from][sender].sub(value));\\n\\n return true;\\n }\\n\\n function approve(\\n address spender,\\n uint256 value\\n )\\n virtual\\n external\\n returns (bool)\\n {\\n _approve(_getSender(), spender, value);\\n\\n return true;\\n }\\n\\n // external functions (views)\\n\\n function balanceOf(\\n address owner\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return balances[owner];\\n }\\n\\n function allowance(\\n address owner,\\n address spender\\n )\\n virtual\\n external\\n view\\n returns (uint256)\\n {\\n return allowances[owner][spender];\\n }\\n\\n // internal functions\\n\\n function _transfer(\\n address from,\\n address to,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n from != address(0),\\n \\\"ERC20Token: cannot transfer from 0x0 address\\\"\\n );\\n require(\\n to != address(0),\\n \\\"ERC20Token: cannot transfer to 0x0 address\\\"\\n );\\n\\n balances[from] = balances[from].sub(value);\\n balances[to] = balances[to].add(value);\\n\\n emit Transfer(from, to, value);\\n }\\n\\n function _approve(\\n address owner,\\n address spender,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot approve from 0x0 address\\\"\\n );\\n require(\\n spender != address(0),\\n \\\"ERC20Token: cannot approve to 0x0 address\\\"\\n );\\n\\n allowances[owner][spender] = value;\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function _mint(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot mint to 0x0 address\\\"\\n );\\n require(\\n value > 0,\\n \\\"ERC20Token: cannot mint 0 value\\\"\\n );\\n\\n balances[owner] = balances[owner].add(value);\\n totalSupply = totalSupply.add(value);\\n\\n emit Transfer(address(0), owner, value);\\n }\\n\\n function _burn(\\n address owner,\\n uint256 value\\n )\\n virtual\\n internal\\n {\\n require(\\n owner != address(0),\\n \\\"ERC20Token: cannot burn from 0x0 address\\\"\\n );\\n\\n balances[owner] = balances[owner].sub(\\n value,\\n \\\"ERC20Token: burn value exceeds balance\\\"\\n );\\n\\n totalSupply = totalSupply.sub(value);\\n\\n emit Transfer(owner, address(0), value);\\n }\\n\\n // internal functions (views)\\n\\n function _getSender()\\n virtual\\n internal\\n view\\n returns (address)\\n {\\n return msg.sender;\\n }\\n}\\n\",\"keccak256\":\"0x6f2b0bd08da549c6c1f5ceee85766832d587dde62c56bebc3a14bd9ea407e03d\",\"license\":\"MIT\"},\"src/gateway/GatewayRecipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/libs/BytesLib.sol\\\";\\n\\n\\n/**\\n * @title Gateway recipient\\n *\\n * @notice Gateway target contract\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract GatewayRecipient {\\n using BytesLib for bytes;\\n\\n address public gateway;\\n\\n /**\\n * @dev internal constructor\\n */\\n constructor() internal {}\\n\\n // internal functions\\n\\n /**\\n * @notice Initializes `GatewayRecipient` contract\\n * @param gateway_ `Gateway` contract address\\n */\\n function _initializeGatewayRecipient(\\n address gateway_\\n )\\n internal\\n {\\n gateway = gateway_;\\n }\\n\\n // internal functions (views)\\n\\n /**\\n * @notice Gets gateway context account\\n * @return context account address\\n */\\n function _getContextAccount()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(40);\\n }\\n\\n /**\\n * @notice Gets gateway context sender\\n * @return context sender address\\n */\\n function _getContextSender()\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAddress(20);\\n }\\n\\n /**\\n * @notice Gets gateway context data\\n * @return context data\\n */\\n function _getContextData()\\n internal\\n view\\n returns (bytes calldata)\\n {\\n bytes calldata result;\\n\\n if (_isGatewaySender()) {\\n result = msg.data[:msg.data.length - 40];\\n } else {\\n result = msg.data;\\n }\\n\\n return result;\\n }\\n\\n // private functions (views)\\n\\n function _getContextAddress(\\n uint256 offset\\n )\\n private\\n view\\n returns (address)\\n {\\n address result = address(0);\\n\\n if (_isGatewaySender()) {\\n uint from = msg.data.length - offset;\\n result = bytes(msg.data[from:from + 20]).toAddress();\\n } else {\\n result = msg.sender;\\n }\\n\\n return result;\\n }\\n\\n function _isGatewaySender()\\n private\\n view\\n returns (bool)\\n {\\n bool result;\\n\\n if (msg.sender == gateway) {\\n require(\\n msg.data.length >= 44,\\n \\\"GatewayRecipient: invalid msg.data\\\"\\n );\\n\\n result = true;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xe3fd29479d748d67360c61a9cbaafc66eaca25f476e59a45e842472bcf5233fc\",\"license\":\"MIT\"},\"src/tokens/WrappedWeiToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.6.12;\\n\\nimport \\\"../common/lifecycle/Initializable.sol\\\";\\nimport \\\"../common/token/ERC20Token.sol\\\";\\nimport \\\"../gateway/GatewayRecipient.sol\\\";\\n\\n\\n/**\\n * @title Wrapped wei token\\n *\\n * @notice One to one wei consumable ERC20 token\\n *\\n * @dev After the transfer to consumer's account is done, the token will be automatically burned and withdrawn.\\n *\\n * Use `startConsuming` to become a consumer.\\n *\\n * @author Stanis\\u0142aw G\\u0142ogowski \\n */\\ncontract WrappedWeiToken is Initializable, ERC20Token, GatewayRecipient {\\n mapping(address => bool) private consumers;\\n\\n // events\\n\\n /**\\n * @dev Emitted when the new consumer is added\\n * @param consumer consumer address\\n */\\n event ConsumerAdded(\\n address consumer\\n );\\n\\n /**\\n * @dev Emitted when the existing consumer is removed\\n * @param consumer consumer address\\n */\\n event ConsumerRemoved(\\n address consumer\\n );\\n\\n /**\\n * @dev Public constructor\\n */\\n constructor()\\n public\\n Initializable()\\n {\\n name = \\\"Wrapped Wei\\\";\\n symbol = \\\"WWEI\\\";\\n }\\n\\n /**\\n * @notice Receive fallback\\n */\\n receive()\\n external\\n payable\\n {\\n _mint(_getSender(), msg.value);\\n }\\n\\n // external functions\\n\\n /**\\n * @notice Initializes `WrappedWeiToken` contract\\n * @param consumers_ array of consumers addresses\\n * @param gateway_ `Gateway` contract address\\n */\\n function initialize(\\n address[] calldata consumers_,\\n address gateway_\\n )\\n external\\n onlyInitializer\\n {\\n if (consumers_.length != 0) {\\n uint consumersLen = consumers_.length;\\n for (uint i = 0; i < consumersLen; i++) {\\n _addConsumer(consumers_[i]);\\n }\\n }\\n\\n _initializeGatewayRecipient(gateway_);\\n }\\n\\n /**\\n * @notice Starts consuming\\n * @dev Add caller as a consumer\\n */\\n function startConsuming()\\n external\\n {\\n _addConsumer(_getSender());\\n }\\n\\n /**\\n * @notice Stops consuming\\n * @dev Remove caller from consumers\\n */\\n function stopConsuming()\\n external\\n {\\n address consumer = _getSender();\\n\\n require(\\n consumers[consumer],\\n \\\"WrappedWeiToken: consumer doesn't exist\\\"\\n );\\n\\n consumers[consumer] = false;\\n\\n emit ConsumerRemoved(consumer);\\n }\\n\\n /**\\n * @notice Deposits `msg.value` to address\\n * @param to to address\\n */\\n function depositTo(\\n address to\\n )\\n external\\n payable\\n {\\n _mint(to, msg.value);\\n }\\n\\n /**\\n * @notice Withdraws\\n * @param value value to withdraw\\n */\\n function withdraw(\\n uint256 value\\n )\\n external\\n {\\n _withdraw(_getSender(), _getSender(), value);\\n }\\n\\n /**\\n * @notice Withdraws to address\\n * @param to to address\\n * @param value value to withdraw\\n */\\n function withdrawTo(\\n address to,\\n uint256 value\\n )\\n external\\n {\\n _withdraw(_getSender(), to, value);\\n }\\n\\n /**\\n * @notice Withdraws all\\n */\\n function withdrawAll()\\n external\\n {\\n address sender = _getSender();\\n\\n _withdraw(sender, sender, balances[sender]);\\n }\\n\\n /**\\n * @notice Withdraws all to address\\n * @param to to address\\n */\\n function withdrawAllTo(\\n address to\\n )\\n external\\n {\\n address sender = _getSender();\\n\\n _withdraw(sender, to, balances[sender]);\\n }\\n\\n // external functions (views)\\n\\n /**\\n * @notice Checks if consumer exists\\n * @param consumer consumer address\\n * @return true if consumer exists\\n */\\n function isConsumer(\\n address consumer\\n )\\n external\\n view\\n returns (bool)\\n {\\n return consumers[consumer];\\n }\\n\\n // internal functions\\n\\n function _transfer(\\n address from,\\n address to,\\n uint256 value\\n )\\n override\\n internal\\n {\\n if (consumers[to]) {\\n _withdraw(from, to, value);\\n } else {\\n super._transfer(from, to, value);\\n }\\n }\\n\\n // internal functions (views)\\n\\n function _getSender()\\n override\\n internal\\n view\\n returns (address)\\n {\\n return _getContextAccount();\\n }\\n\\n // private functions\\n\\n function _addConsumer(\\n address consumer\\n )\\n private\\n {\\n require(\\n !consumers[consumer],\\n \\\"WrappedWeiToken: consumer already exists\\\"\\n );\\n\\n consumers[consumer] = true;\\n\\n emit ConsumerAdded(consumer);\\n }\\n\\n function _withdraw(\\n address from,\\n address to,\\n uint256 value\\n )\\n private\\n {\\n _burn(from, value);\\n\\n require(\\n // solhint-disable-next-line check-send-result\\n payable(to).send(value),\\n \\\"WrappedWeiToken: transaction reverted\\\"\\n );\\n }\\n}\\n\",\"keccak256\":\"0xa4e1ef99b7ce5b92cedb73387e5954824815e13ac23acef38d7fcf234d8fc017\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50326000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060400160405280600b81526020017f5772617070656420576569000000000000000000000000000000000000000000815250600190805190602001906200009f929190620000f4565b506040518060400160405280600481526020017f575745490000000000000000000000000000000000000000000000000000000081525060029080519060200190620000ed929190620000f4565b506200019a565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200013757805160ff191683800117855562000168565b8280016001018555821562000168579182015b82811115620001675782518255916020019190600101906200014a565b5b5090506200017791906200017b565b5090565b5b80821115620001965760008160009055506001016200017c565b5090565b6120b080620001aa6000396000f3fe6080604052600436106101235760003560e01c806356a3b64b116100a0578063a9059cbb11610064578063a9059cbb1461065f578063b760faf9146106d0578063ca9add8f14610714578063dd62ed3e14610765578063f55647e0146107ea5761013b565b806356a3b64b146104d557806370a08231146104ec578063834ff73914610551578063853828b6146105b857806395d89b41146105cf5761013b565b806323b872dd116100e757806323b872dd146103085780632e1a7d4d14610399578063313ce567146103d4578063392e53cd14610402578063462d0b2e1461042f5761013b565b806306fdde0314610140578063095ea7b3146101d0578063116191b61461024157806318160ddd14610282578063205c2878146102ad5761013b565b3661013b57610139610133610801565b34610810565b005b600080fd5b34801561014c57600080fd5b50610155610a26565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561019557808201518184015260208101905061017a565b50505050905090810190601f1680156101c25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101dc57600080fd5b50610229600480360360408110156101f357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ac4565b60405180821515815260200191505060405180910390f35b34801561024d57600080fd5b50610256610ae2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561028e57600080fd5b50610297610b08565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b50610306600480360360408110156102d057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b0e565b005b34801561031457600080fd5b506103816004803603606081101561032b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b24565b60405180821515815260200191505060405180910390f35b3480156103a557600080fd5b506103d2600480360360208110156103bc57600080fd5b8101908080359060200190929190505050610be1565b005b3480156103e057600080fd5b506103e9610bfd565b604051808260ff16815260200191505060405180910390f35b34801561040e57600080fd5b50610417610c10565b60405180821515815260200191505060405180910390f35b34801561043b57600080fd5b506104d36004803603604081101561045257600080fd5b810190808035906020019064010000000081111561046f57600080fd5b82018360208201111561048157600080fd5b803590602001918460208302840111640100000000831117156104a357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c66565b005b3480156104e157600080fd5b506104ea610e05565b005b3480156104f857600080fd5b5061053b6004803603602081101561050f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e17565b6040518082815260200191505060405180910390f35b34801561055d57600080fd5b506105a06004803603602081101561057457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e60565b60405180821515815260200191505060405180910390f35b3480156105c457600080fd5b506105cd610eb6565b005b3480156105db57600080fd5b506105e4610f0f565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610624578082015181840152602081019050610609565b50505050905090810190601f1680156106515780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561066b57600080fd5b506106b86004803603604081101561068257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610fad565b60405180821515815260200191505060405180910390f35b610712600480360360208110156106e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fcb565b005b34801561072057600080fd5b506107636004803603602081101561073757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fd8565b005b34801561077157600080fd5b506107d46004803603604081101561078857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611032565b6040518082815260200191505060405180910390f35b3480156107f657600080fd5b506107ff6110b9565b005b600061080b61120f565b905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610896576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180611fb66026913960400191505060405180910390fd5b6000811161090c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4552433230546f6b656e3a2063616e6e6f74206d696e7420302076616c75650081525060200191505060405180910390fd5b61095e81600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461122090919063ffffffff16565b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506109b68160045461122090919063ffffffff16565b6004819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610abc5780601f10610a9157610100808354040283529160200191610abc565b820191906000526020600020905b815481529060010190602001808311610a9f57829003601f168201915b505050505081565b6000610ad8610ad1610801565b84846112a8565b6001905092915050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60045481565b610b20610b19610801565b838361149f565b5050565b600080610b2f610801565b9050610b3c858585611538565b610bd58582610bd086600660008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115ab90919063ffffffff16565b6112a8565b60019150509392505050565b610bfa610bec610801565b610bf4610801565b8361149f565b50565b600360009054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180611ec8602f913960400191505060405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008383905014610daa57600083839050905060005b81811015610da757610d9a858583818110610d7857fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff166115d8565b8080600101915050610d61565b50505b610db381611723565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e632604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b610e15610e10610801565b6115d8565b565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000610ec0610801565b9050610f0c8182600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461149f565b50565b60028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610fa55780601f10610f7a57610100808354040283529160200191610fa5565b820191906000526020600020905b815481529060010190602001808311610f8857829003601f168201915b505050505081565b6000610fc1610fba610801565b8484611538565b6001905092915050565b610fd58134610810565b50565b6000610fe2610801565b905061102e8183600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461149f565b5050565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60006110c3610801565b9050600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611167576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806120066027913960400191505060405180910390fd5b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fe3f5ed5f263f1f01764a96edfc7d025f511ec5f7d180e8816908b78bcf74f09881604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600061121b6028611767565b905090565b60008082840190508381101561129e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174684c69623a206164646974696f6e206f766572666c6f77000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561132e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180611f8b602b913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156113b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180611f416029913960400191505060405180910390fd5b80600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b6114a983826117fc565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602581526020018061202d6025913960400191505060405180910390fd5b505050565b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561159a5761159583838361149f565b6115a6565b6115a58383836119b6565b5b505050565b60006115d08383604051806060016040528060218152602001611f6a60219139611c56565b905092915050565b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561167b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180611ef76028913960400191505060405180910390fd5b6001600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f28b26e7a3d20aedbc5f8f2ebf7da671c0491723a2b78f47a097b0e46dee0714281604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009050611776611d10565b156117ef5760008360003690500390506117e76000368390601485019261179f93929190611e6c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611dd3565b9150506117f3565b3390505b80915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611882576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180611ea06028913960400191505060405180910390fd5b6118ee8160405180606001604052806026815260200161205260269139600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c569092919063ffffffff16565b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611946816004546115ab90919063ffffffff16565b600481905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180612078602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ac2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180611fdc602a913960400191505060405180910390fd5b611b1481600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115ab90919063ffffffff16565b600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611ba981600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461122090919063ffffffff16565b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290611d03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611cc8578082015181840152602081019050611cad565b50505050905090810190601f168015611cf55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b600080600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415611dcc57602c60003690501015611dc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180611f1f6022913960400191505060405180910390fd5b600190505b8091505090565b6000806014835114611e4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f42797465734c69623a20696e76616c69642064617461206c656e67746800000081525060200191505060405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b60008085851115611e7c57600080fd5b83861115611e8957600080fd5b600185028301915084860390509450949250505056fe4552433230546f6b656e3a2063616e6e6f74206275726e2066726f6d203078302061646472657373496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742074686520696e697469616c697a657257726170706564576569546f6b656e3a20636f6e73756d657220616c72656164792065786973747347617465776179526563697069656e743a20696e76616c6964206d73672e646174614552433230546f6b656e3a2063616e6e6f7420617070726f766520746f203078302061646472657373536166654d6174684c69623a207375627472616374696f6e206f766572666c6f774552433230546f6b656e3a2063616e6e6f7420617070726f76652066726f6d2030783020616464726573734552433230546f6b656e3a2063616e6e6f74206d696e7420746f2030783020616464726573734552433230546f6b656e3a2063616e6e6f74207472616e7366657220746f20307830206164647265737357726170706564576569546f6b656e3a20636f6e73756d657220646f65736e277420657869737457726170706564576569546f6b656e3a207472616e73616374696f6e2072657665727465644552433230546f6b656e3a206275726e2076616c756520657863656564732062616c616e63654552433230546f6b656e3a2063616e6e6f74207472616e736665722066726f6d203078302061646472657373a164736f6c634300060c000a", + "deployedBytecode": "0x6080604052600436106101235760003560e01c806356a3b64b116100a0578063a9059cbb11610064578063a9059cbb1461065f578063b760faf9146106d0578063ca9add8f14610714578063dd62ed3e14610765578063f55647e0146107ea5761013b565b806356a3b64b146104d557806370a08231146104ec578063834ff73914610551578063853828b6146105b857806395d89b41146105cf5761013b565b806323b872dd116100e757806323b872dd146103085780632e1a7d4d14610399578063313ce567146103d4578063392e53cd14610402578063462d0b2e1461042f5761013b565b806306fdde0314610140578063095ea7b3146101d0578063116191b61461024157806318160ddd14610282578063205c2878146102ad5761013b565b3661013b57610139610133610801565b34610810565b005b600080fd5b34801561014c57600080fd5b50610155610a26565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561019557808201518184015260208101905061017a565b50505050905090810190601f1680156101c25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101dc57600080fd5b50610229600480360360408110156101f357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ac4565b60405180821515815260200191505060405180910390f35b34801561024d57600080fd5b50610256610ae2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561028e57600080fd5b50610297610b08565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b50610306600480360360408110156102d057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b0e565b005b34801561031457600080fd5b506103816004803603606081101561032b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b24565b60405180821515815260200191505060405180910390f35b3480156103a557600080fd5b506103d2600480360360208110156103bc57600080fd5b8101908080359060200190929190505050610be1565b005b3480156103e057600080fd5b506103e9610bfd565b604051808260ff16815260200191505060405180910390f35b34801561040e57600080fd5b50610417610c10565b60405180821515815260200191505060405180910390f35b34801561043b57600080fd5b506104d36004803603604081101561045257600080fd5b810190808035906020019064010000000081111561046f57600080fd5b82018360208201111561048157600080fd5b803590602001918460208302840111640100000000831117156104a357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c66565b005b3480156104e157600080fd5b506104ea610e05565b005b3480156104f857600080fd5b5061053b6004803603602081101561050f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e17565b6040518082815260200191505060405180910390f35b34801561055d57600080fd5b506105a06004803603602081101561057457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e60565b60405180821515815260200191505060405180910390f35b3480156105c457600080fd5b506105cd610eb6565b005b3480156105db57600080fd5b506105e4610f0f565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610624578082015181840152602081019050610609565b50505050905090810190601f1680156106515780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561066b57600080fd5b506106b86004803603604081101561068257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610fad565b60405180821515815260200191505060405180910390f35b610712600480360360208110156106e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fcb565b005b34801561072057600080fd5b506107636004803603602081101561073757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fd8565b005b34801561077157600080fd5b506107d46004803603604081101561078857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611032565b6040518082815260200191505060405180910390f35b3480156107f657600080fd5b506107ff6110b9565b005b600061080b61120f565b905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610896576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180611fb66026913960400191505060405180910390fd5b6000811161090c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4552433230546f6b656e3a2063616e6e6f74206d696e7420302076616c75650081525060200191505060405180910390fd5b61095e81600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461122090919063ffffffff16565b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506109b68160045461122090919063ffffffff16565b6004819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610abc5780601f10610a9157610100808354040283529160200191610abc565b820191906000526020600020905b815481529060010190602001808311610a9f57829003601f168201915b505050505081565b6000610ad8610ad1610801565b84846112a8565b6001905092915050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60045481565b610b20610b19610801565b838361149f565b5050565b600080610b2f610801565b9050610b3c858585611538565b610bd58582610bd086600660008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115ab90919063ffffffff16565b6112a8565b60019150509392505050565b610bfa610bec610801565b610bf4610801565b8361149f565b50565b600360009054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180611ec8602f913960400191505060405180910390fd5b60008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008383905014610daa57600083839050905060005b81811015610da757610d9a858583818110610d7857fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff166115d8565b8080600101915050610d61565b50505b610db381611723565b7f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e632604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b610e15610e10610801565b6115d8565b565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000610ec0610801565b9050610f0c8182600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461149f565b50565b60028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610fa55780601f10610f7a57610100808354040283529160200191610fa5565b820191906000526020600020905b815481529060010190602001808311610f8857829003601f168201915b505050505081565b6000610fc1610fba610801565b8484611538565b6001905092915050565b610fd58134610810565b50565b6000610fe2610801565b905061102e8183600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461149f565b5050565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60006110c3610801565b9050600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611167576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806120066027913960400191505060405180910390fd5b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fe3f5ed5f263f1f01764a96edfc7d025f511ec5f7d180e8816908b78bcf74f09881604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600061121b6028611767565b905090565b60008082840190508381101561129e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174684c69623a206164646974696f6e206f766572666c6f77000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561132e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180611f8b602b913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156113b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180611f416029913960400191505060405180910390fd5b80600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b6114a983826117fc565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602581526020018061202d6025913960400191505060405180910390fd5b505050565b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561159a5761159583838361149f565b6115a6565b6115a58383836119b6565b5b505050565b60006115d08383604051806060016040528060218152602001611f6a60219139611c56565b905092915050565b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561167b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180611ef76028913960400191505060405180910390fd5b6001600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f28b26e7a3d20aedbc5f8f2ebf7da671c0491723a2b78f47a097b0e46dee0714281604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009050611776611d10565b156117ef5760008360003690500390506117e76000368390601485019261179f93929190611e6c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611dd3565b9150506117f3565b3390505b80915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611882576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180611ea06028913960400191505060405180910390fd5b6118ee8160405180606001604052806026815260200161205260269139600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c569092919063ffffffff16565b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611946816004546115ab90919063ffffffff16565b600481905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180612078602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ac2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180611fdc602a913960400191505060405180910390fd5b611b1481600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115ab90919063ffffffff16565b600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611ba981600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461122090919063ffffffff16565b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290611d03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611cc8578082015181840152602081019050611cad565b50505050905090810190601f168015611cf55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b600080600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415611dcc57602c60003690501015611dc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180611f1f6022913960400191505060405180910390fd5b600190505b8091505090565b6000806014835114611e4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f42797465734c69623a20696e76616c69642064617461206c656e67746800000081525060200191505060405180910390fd5b6c01000000000000000000000000602084015104905080915050919050565b60008085851115611e7c57600080fd5b83861115611e8957600080fd5b600185028301915084860390509450949250505056fe4552433230546f6b656e3a2063616e6e6f74206275726e2066726f6d203078302061646472657373496e697469616c697a61626c653a2074782e6f726967696e206973206e6f742074686520696e697469616c697a657257726170706564576569546f6b656e3a20636f6e73756d657220616c72656164792065786973747347617465776179526563697069656e743a20696e76616c6964206d73672e646174614552433230546f6b656e3a2063616e6e6f7420617070726f766520746f203078302061646472657373536166654d6174684c69623a207375627472616374696f6e206f766572666c6f774552433230546f6b656e3a2063616e6e6f7420617070726f76652066726f6d2030783020616464726573734552433230546f6b656e3a2063616e6e6f74206d696e7420746f2030783020616464726573734552433230546f6b656e3a2063616e6e6f74207472616e7366657220746f20307830206164647265737357726170706564576569546f6b656e3a20636f6e73756d657220646f65736e277420657869737457726170706564576569546f6b656e3a207472616e73616374696f6e2072657665727465644552433230546f6b656e3a206275726e2076616c756520657863656564732062616c616e63654552433230546f6b656e3a2063616e6e6f74207472616e736665722066726f6d203078302061646472657373a164736f6c634300060c000a", + "devdoc": { + "author": "Stanisław Głogowski ", + "details": "After the transfer to consumer's account is done, the token will be automatically burned and withdrawn. Use `startConsuming` to become a consumer.", + "events": { + "ConsumerAdded(address)": { + "details": "Emitted when the new consumer is added", + "params": { + "consumer": "consumer address" + } + }, + "ConsumerRemoved(address)": { + "details": "Emitted when the existing consumer is removed", + "params": { + "consumer": "consumer address" + } + } + }, + "kind": "dev", + "methods": { + "constructor": { + "details": "Public constructor" + }, + "depositTo(address)": { + "params": { + "to": "to address" + } + }, + "initialize(address[],address)": { + "params": { + "consumers_": "array of consumers addresses", + "gateway_": "`Gateway` contract address" + } + }, + "isConsumer(address)": { + "params": { + "consumer": "consumer address" + }, + "returns": { + "_0": "true if consumer exists" + } + }, + "isInitialized()": { + "returns": { + "_0": "true when contract is initialized" + } + }, + "startConsuming()": { + "details": "Add caller as a consumer" + }, + "stopConsuming()": { + "details": "Remove caller from consumers" + }, + "withdraw(uint256)": { + "params": { + "value": "value to withdraw" + } + }, + "withdrawAllTo(address)": { + "params": { + "to": "to address" + } + }, + "withdrawTo(address,uint256)": { + "params": { + "to": "to address", + "value": "value to withdraw" + } + } + }, + "title": "Wrapped wei token", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "depositTo(address)": { + "notice": "Deposits `msg.value` to address" + }, + "initialize(address[],address)": { + "notice": "Initializes `WrappedWeiToken` contract" + }, + "isConsumer(address)": { + "notice": "Checks if consumer exists" + }, + "isInitialized()": { + "notice": "Check if contract is initialized" + }, + "startConsuming()": { + "notice": "Starts consuming" + }, + "stopConsuming()": { + "notice": "Stops consuming" + }, + "withdraw(uint256)": { + "notice": "Withdraws" + }, + "withdrawAll()": { + "notice": "Withdraws all" + }, + "withdrawAllTo(address)": { + "notice": "Withdraws all to address" + }, + "withdrawTo(address,uint256)": { + "notice": "Withdraws to address" + } + }, + "notice": "One to one wei consumable ERC20 token", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1871, + "contract": "src/tokens/WrappedWeiToken.sol:WrappedWeiToken", + "label": "initializer", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 1983, + "contract": "src/tokens/WrappedWeiToken.sol:WrappedWeiToken", + "label": "name", + "offset": 0, + "slot": "1", + "type": "t_string_storage" + }, + { + "astId": 1985, + "contract": "src/tokens/WrappedWeiToken.sol:WrappedWeiToken", + "label": "symbol", + "offset": 0, + "slot": "2", + "type": "t_string_storage" + }, + { + "astId": 1987, + "contract": "src/tokens/WrappedWeiToken.sol:WrappedWeiToken", + "label": "decimals", + "offset": 0, + "slot": "3", + "type": "t_uint8" + }, + { + "astId": 1989, + "contract": "src/tokens/WrappedWeiToken.sol:WrappedWeiToken", + "label": "totalSupply", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 1993, + "contract": "src/tokens/WrappedWeiToken.sol:WrappedWeiToken", + "label": "balances", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 1999, + "contract": "src/tokens/WrappedWeiToken.sol:WrappedWeiToken", + "label": "allowances", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5197, + "contract": "src/tokens/WrappedWeiToken.sol:WrappedWeiToken", + "label": "gateway", + "offset": 0, + "slot": "7", + "type": "t_address" + }, + { + "astId": 7468, + "contract": "src/tokens/WrappedWeiToken.sol:WrappedWeiToken", + "label": "consumers", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_address,t_bool)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/solcInputs/1bdf84d4bd28700579af1cc4796e2cae.json b/deployments/neonDevnet/solcInputs/1bdf84d4bd28700579af1cc4796e2cae.json new file mode 100644 index 00000000..e1114a03 --- /dev/null +++ b/deployments/neonDevnet/solcInputs/1bdf84d4bd28700579af1cc4796e2cae.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "src/common/access/Controlled.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title Controlled\n *\n * @dev Contract module which provides an access control mechanism.\n * It ensures there is only one controlling account of the smart contract\n * and grants that account exclusive access to specific functions.\n *\n * The controller account will be the one that deploys the contract.\n *\n * @author Stanisław Głogowski \n */\ncontract Controlled {\n /**\n * @return controller account address\n */\n address public controller;\n\n // modifiers\n\n /**\n * @dev Throws if msg.sender is not the controller\n */\n modifier onlyController() {\n require(\n msg.sender == controller,\n \"Controlled: msg.sender is not the controller\"\n );\n\n _;\n }\n\n /**\n * @dev Internal constructor\n */\n constructor()\n internal\n {\n controller = msg.sender;\n }\n}\n" + }, + "src/payments/PaymentDepositAccount.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../common/access/Controlled.sol\";\n\n\n/**\n * @title Payment deposit account\n *\n * @dev Simple account contract with only one method - `executeTransaction`\n *\n * @author Stanisław Głogowski \n */\ncontract PaymentDepositAccount is Controlled {\n /**\n * @dev Public constructor\n */\n constructor() public payable Controlled() {}\n\n /**\n * @notice Allow receives\n */\n receive()\n external\n payable\n {\n //\n }\n\n // external functions\n\n /**\n * @notice Executes transaction\n * @param to to address\n * @param value value\n * @param data data\n * @return transaction result\n */\n function executeTransaction(\n address to,\n uint256 value,\n bytes calldata data\n )\n external\n onlyController\n returns (bytes memory)\n {\n bytes memory result;\n bool succeeded;\n\n // solhint-disable-next-line avoid-call-value, avoid-low-level-calls\n (succeeded, result) = payable(to).call{value: value}(data);\n\n require(\n succeeded,\n \"Account: transaction reverted\"\n );\n\n return result;\n }\n}\n" + }, + "src/payments/PaymentRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../common/access/Guarded.sol\";\nimport \"../common/libs/ECDSALib.sol\";\nimport \"../common/libs/SafeMathLib.sol\";\nimport \"../common/lifecycle/Initializable.sol\";\nimport \"../common/signature/SignatureValidator.sol\";\nimport \"../common/token/ERC20Token.sol\";\nimport \"../external/ExternalAccountRegistry.sol\";\nimport \"../personal/PersonalAccountRegistry.sol\";\nimport \"../gateway/GatewayRecipient.sol\";\nimport \"./PaymentDepositAccount.sol\";\n\n\n/**\n * @title Payment registry\n *\n * @notice A registry for payment and payment channels\n *\n * @dev the `DepositExit` process can be used in a case operator (guardian) couldn't sign commit / withdrawal message.\n * Process will be rejected when any of senders channels will be committed.\n *\n * @author Stanisław Głogowski \n */\ncontract PaymentRegistry is Guarded, Initializable, SignatureValidator, GatewayRecipient {\n using ECDSALib for bytes32;\n using SafeMathLib for uint256;\n\n struct Deposit {\n address account;\n mapping(address => uint256) withdrawnAmount;\n mapping(address => uint256) exitLockedUntil;\n }\n\n struct PaymentChannel {\n uint256 committedAmount;\n }\n\n struct DepositWithdrawal {\n address owner;\n address token;\n uint256 amount;\n }\n\n struct PaymentChannelCommit {\n address sender;\n address recipient;\n address token;\n bytes32 uid;\n uint256 blockNumber;\n uint256 amount;\n }\n\n uint256 private constant DEFAULT_DEPOSIT_EXIT_LOCK_PERIOD = 28 days;\n\n bytes32 private constant HASH_PREFIX_DEPOSIT_WITHDRAWAL = keccak256(\n \"DepositWithdrawal(address owner,address token,uint256 amount)\"\n );\n bytes32 private constant HASH_PREFIX_PAYMENT_CHANNEL_COMMIT = keccak256(\n \"PaymentChannelCommit(address sender,address recipient,address token,bytes32 uid,uint256 blockNumber,uint256 amount)\"\n );\n\n ExternalAccountRegistry public externalAccountRegistry;\n PersonalAccountRegistry public personalAccountRegistry;\n\n uint256 public depositExitLockPeriod;\n\n mapping(address => Deposit) private deposits;\n mapping(bytes32 => PaymentChannel) private paymentChannels;\n\n // events\n\n /**\n * @dev Emitted when the deposit account is deployed\n * @param depositAccount deposit account address\n * @param owner owner address\n */\n event DepositAccountDeployed(\n address depositAccount,\n address owner\n );\n\n /**\n * @dev Emitted when the deposit exist is requested\n * @param depositAccount deposit account address\n * @param owner owner address\n * @param token token address\n * @param lockedUntil deposit exist locked util time\n */\n event DepositExitRequested(\n address depositAccount,\n address owner,\n address token,\n uint256 lockedUntil\n );\n\n /**\n * @dev Emitted when the deposit exist is completed\n * @param depositAccount deposit account address\n * @param owner owner address\n * @param token token address\n * @param amount deposit exist amount\n */\n event DepositExitCompleted(\n address depositAccount,\n address owner,\n address token,\n uint256 amount\n );\n\n /**\n * @dev Emitted when the deposit exist is rejected\n * @param depositAccount deposit account address\n * @param owner owner address\n * @param token token address\n */\n event DepositExitRejected(\n address depositAccount,\n address owner,\n address token\n );\n\n /**\n * @dev Emitted when the deposit has been withdrawn\n * @param depositAccount deposit account address\n * @param owner owner address\n * @param token token address\n * @param amount withdrawn amount\n */\n event DepositWithdrawn(\n address depositAccount,\n address owner,\n address token,\n uint256 amount\n );\n\n /**\n * @dev Emitted when the payment channel has been committed\n * @param hash channel hash\n * @param sender sender address\n * @param recipient recipient address\n * @param token token address\n * @param uid unique channel id\n * @param amount committed amount\n */\n event PaymentChannelCommitted(\n bytes32 hash,\n address sender,\n address recipient,\n address token,\n bytes32 uid,\n uint256 amount\n );\n\n /**\n * @dev Emitted when the payment has been withdrawn\n * @param channelHash channel hash\n * @param value payment value\n */\n event PaymentWithdrawn(\n bytes32 channelHash,\n uint256 value\n );\n\n /**\n * @dev Emitted when the payment has been deposited\n * @param channelHash channel hash\n * @param value payment value\n */\n event PaymentDeposited(\n bytes32 channelHash,\n uint256 value\n );\n\n /**\n * @dev Emitted when the payment has been withdrawn and deposited (split)\n * @param channelHash channel hash\n * @param totalValue payment total value\n * @param depositValue payment deposited value\n */\n event PaymentSplit(\n bytes32 channelHash,\n uint256 totalValue,\n uint256 depositValue\n );\n\n /**\n * @dev Public constructor\n */\n constructor() public Initializable() SignatureValidator() {}\n\n // external functions\n\n /**\n * @notice Initialize `PaymentRegistry` contract\n * @param externalAccountRegistry_ `ExternalAccountRegistry` contract address\n * @param personalAccountRegistry_ `PersonalAccountRegistry` contract address\n * @param depositExitLockPeriod_ deposit exit lock period\n * @param guardians_ array of guardians addresses\n * @param gateway_ `Gateway` contract address\n */\n function initialize(\n ExternalAccountRegistry externalAccountRegistry_,\n PersonalAccountRegistry personalAccountRegistry_,\n uint256 depositExitLockPeriod_,\n address[] calldata guardians_,\n address gateway_\n )\n external\n onlyInitializer\n {\n externalAccountRegistry = externalAccountRegistry_;\n personalAccountRegistry = personalAccountRegistry_;\n\n if (depositExitLockPeriod_ == 0) {\n depositExitLockPeriod = DEFAULT_DEPOSIT_EXIT_LOCK_PERIOD;\n } else {\n depositExitLockPeriod = depositExitLockPeriod_;\n }\n\n // Guarded\n _initializeGuarded(guardians_);\n\n // GatewayRecipient\n _initializeGatewayRecipient(gateway_);\n }\n\n /**\n * @notice Deploys deposit account\n * @param owner owner address\n */\n function deployDepositAccount(\n address owner\n )\n external\n {\n _deployDepositAccount(owner);\n }\n\n /**\n * @notice Requests deposit exit\n * @param token token address\n */\n function requestDepositExit(\n address token\n )\n external\n {\n address owner = _getContextAccount();\n uint256 lockedUntil = deposits[owner].exitLockedUntil[token];\n\n require(\n lockedUntil == 0,\n \"PaymentRegistry: deposit exit already requested\"\n );\n\n _deployDepositAccount(owner);\n\n // solhint-disable-next-line not-rely-on-time\n lockedUntil = now.add(depositExitLockPeriod);\n\n deposits[owner].exitLockedUntil[token] = lockedUntil;\n\n emit DepositExitRequested(\n deposits[owner].account,\n owner,\n token,\n lockedUntil\n );\n }\n\n /**\n * @notice Processes deposit exit\n * @param token token address\n */\n function processDepositExit(\n address token\n )\n external\n {\n address owner = _getContextAccount();\n uint256 lockedUntil = deposits[owner].exitLockedUntil[token];\n\n require(\n lockedUntil != 0,\n \"PaymentRegistry: deposit exit not requested\"\n );\n\n require(\n // solhint-disable-next-line not-rely-on-time\n lockedUntil <= now,\n \"PaymentRegistry: deposit exit locked\"\n );\n\n deposits[owner].exitLockedUntil[token] = 0;\n\n address depositAccount = deposits[owner].account;\n uint256 depositValue;\n\n if (token == address(0)) {\n depositValue = depositAccount.balance;\n } else {\n depositValue = ERC20Token(token).balanceOf(depositAccount);\n }\n\n _transferFromDeposit(\n depositAccount,\n owner,\n token,\n depositValue\n );\n\n emit DepositExitCompleted(\n depositAccount,\n owner,\n token,\n depositValue\n );\n }\n\n /**\n * @notice Withdraws deposit\n * @param token token address\n * @param amount amount to withdraw\n * @param guardianSignature guardian signature\n */\n function withdrawDeposit(\n address token,\n uint256 amount,\n bytes calldata guardianSignature\n )\n external\n {\n address owner = _getContextAccount();\n uint256 value = amount.sub(deposits[owner].withdrawnAmount[token]);\n\n require(\n value > 0,\n \"PaymentRegistry: invalid amount\"\n );\n\n bytes32 messageHash = _hashDepositWithdrawal(\n owner,\n token,\n amount\n );\n\n require(\n _verifyGuardianSignature(messageHash, guardianSignature),\n \"PaymentRegistry: invalid guardian signature\"\n );\n\n deposits[owner].withdrawnAmount[token] = amount;\n\n _verifyDepositExitOrDeployAccount(owner, token);\n\n _transferFromDeposit(\n deposits[owner].account,\n owner,\n token,\n value\n );\n\n emit DepositWithdrawn(\n deposits[owner].account,\n owner,\n token,\n amount\n );\n }\n\n /**\n * @notice Commits payment channel and withdraw payment\n * @param sender sender address\n * @param token token address\n * @param uid unique channel id\n * @param blockNumber block number\n * @param amount amount to commit\n * @param senderSignature sender signature\n * @param guardianSignature guardian signature\n */\n function commitPaymentChannelAndWithdraw(\n address sender,\n address token,\n bytes32 uid,\n uint256 blockNumber,\n uint256 amount,\n bytes calldata senderSignature,\n bytes calldata guardianSignature\n )\n external\n {\n address recipient = _getContextAccount();\n\n (bytes32 hash, address depositAccount, uint256 paymentValue) = _commitPaymentChannel(\n sender,\n recipient,\n token,\n uid,\n blockNumber,\n amount,\n senderSignature,\n guardianSignature\n );\n\n _transferFromDeposit(\n depositAccount,\n recipient,\n token,\n paymentValue\n );\n\n emit PaymentWithdrawn(hash, paymentValue);\n }\n\n /**\n * @notice Commits payment channel and deposit payment\n * @param sender sender address\n * @param token token address\n * @param uid unique channel id\n * @param blockNumber block number\n * @param amount amount to commit\n * @param senderSignature sender signature\n * @param guardianSignature guardian signature\n */\n function commitPaymentChannelAndDeposit(\n address sender,\n address token,\n bytes32 uid,\n uint256 blockNumber,\n uint256 amount,\n bytes calldata senderSignature,\n bytes calldata guardianSignature\n )\n external\n {\n address recipient = _getContextAccount();\n\n (bytes32 hash, address depositAccount, uint256 paymentValue) = _commitPaymentChannel(\n sender,\n recipient,\n token,\n uid,\n blockNumber,\n amount,\n senderSignature,\n guardianSignature\n );\n\n _transferFromDeposit(\n depositAccount,\n _computeDepositAccountAddress(recipient),\n token,\n paymentValue\n );\n\n emit PaymentDeposited(hash, paymentValue);\n }\n\n /**\n * @notice Commits payment channel, withdraws and deposits (split) payment\n * @param sender sender address\n * @param token token address\n * @param uid unique channel id\n * @param blockNumber block number\n * @param amount amount to commit\n * @param depositPaymentValue amount to deposit\n * @param senderSignature sender signature\n * @param guardianSignature guardian signature\n */\n function commitPaymentChannelAndSplit(\n address sender,\n address token,\n bytes32 uid,\n uint256 blockNumber,\n uint256 amount,\n uint256 depositPaymentValue,\n bytes calldata senderSignature,\n bytes calldata guardianSignature\n )\n external\n {\n address recipient = _getContextAccount();\n\n (bytes32 hash, address depositAccount, uint256 paymentValue) = _commitPaymentChannel(\n sender,\n recipient,\n token,\n uid,\n blockNumber,\n amount,\n senderSignature,\n guardianSignature\n );\n\n _transferSplitFromDeposit(\n depositAccount,\n recipient,\n token,\n paymentValue,\n depositPaymentValue\n );\n\n emit PaymentSplit(hash, paymentValue, depositPaymentValue);\n }\n\n // external functions (views)\n\n /**\n * @notice Computes deposit account address\n * @param owner owner address\n * @return deposit account address\n */\n function computeDepositAccountAddress(\n address owner\n )\n external\n view\n returns (address)\n {\n return _computeDepositAccountAddress(owner);\n }\n\n /**\n * @notice Checks if deposit account is deployed\n * @param owner owner address\n * @return true when deposit account is deployed\n */\n function isDepositAccountDeployed(\n address owner\n )\n external\n view\n returns (bool)\n {\n return deposits[owner].account != address(0);\n }\n\n /**\n * @notice Gets deposit exit locked until time\n * @param owner owner address\n * @param token token address\n * @return locked until time\n */\n function getDepositExitLockedUntil(\n address owner,\n address token\n )\n external\n view\n returns (uint256)\n {\n return deposits[owner].exitLockedUntil[token];\n }\n\n /**\n * @notice Gets deposit withdrawn amount\n * @param owner owner address\n * @param token token address\n * @return withdrawn amount\n */\n function getDepositWithdrawnAmount(\n address owner,\n address token\n )\n external\n view\n returns (uint256)\n {\n return deposits[owner].withdrawnAmount[token];\n }\n\n /**\n * @notice Gets payment channel committed amount\n * @param hash payment channel hash\n * @return committed amount\n */\n function getPaymentChannelCommittedAmount(\n bytes32 hash\n )\n external\n view\n returns (uint256)\n {\n return paymentChannels[hash].committedAmount;\n }\n\n // external functions (pure)\n\n /**\n * @notice Computes payment channel hash\n * @param sender sender address\n * @param recipient recipient address\n * @param token token address\n * @param uid unique channel id\n * @return hash\n */\n function computePaymentChannelHash(\n address sender,\n address recipient,\n address token,\n bytes32 uid\n )\n external\n pure\n returns (bytes32)\n {\n return _computePaymentChannelHash(\n sender,\n recipient,\n token,\n uid\n );\n }\n\n // public functions (views)\n\n /**\n * @notice Hashes `DepositWithdrawal` message payload\n * @param depositWithdrawal struct\n * @return hash\n */\n function hashDepositWithdrawal(\n DepositWithdrawal memory depositWithdrawal\n )\n public\n view\n returns (bytes32)\n {\n return _hashDepositWithdrawal(\n depositWithdrawal.owner,\n depositWithdrawal.token,\n depositWithdrawal.amount\n );\n }\n\n /**\n * @notice Hashes `PaymentChannelCommit` message payload\n * @param paymentChannelCommit struct\n * @return hash\n */\n function hashPaymentChannelCommit(\n PaymentChannelCommit memory paymentChannelCommit\n )\n public\n view\n returns (bytes32)\n {\n return _hashPaymentChannelCommit(\n paymentChannelCommit.sender,\n paymentChannelCommit.recipient,\n paymentChannelCommit.token,\n paymentChannelCommit.uid,\n paymentChannelCommit.blockNumber,\n paymentChannelCommit.amount\n );\n }\n\n // private functions\n\n function _deployDepositAccount(\n address owner\n )\n private\n {\n if (deposits[owner].account == address(0)) {\n bytes32 salt = keccak256(\n abi.encodePacked(\n owner\n )\n );\n\n deposits[owner].account = address(new PaymentDepositAccount{salt: salt}());\n\n emit DepositAccountDeployed(\n deposits[owner].account,\n owner\n );\n }\n }\n\n function _verifyDepositExitOrDeployAccount(\n address owner,\n address token\n )\n private\n {\n if (deposits[owner].exitLockedUntil[token] > 0) {\n deposits[owner].exitLockedUntil[token] = 0;\n\n emit DepositExitRejected(\n deposits[owner].account,\n owner,\n token\n );\n } else {\n _deployDepositAccount(owner);\n }\n }\n\n function _commitPaymentChannel(\n address sender,\n address recipient,\n address token,\n bytes32 uid,\n uint256 blockNumber,\n uint256 amount,\n bytes memory senderSignature,\n bytes memory guardianSignature\n )\n private\n returns (bytes32 hash, address depositAccount, uint256 paymentValue)\n {\n bytes32 messageHash = _hashPaymentChannelCommit(\n sender,\n recipient,\n token,\n uid,\n blockNumber,\n amount\n );\n\n if (senderSignature.length == 0) {\n require(\n externalAccountRegistry.verifyAccountProofAtBlock(sender, messageHash, blockNumber),\n \"PaymentRegistry: invalid guardian signature\"\n );\n } else {\n address signer = messageHash.recoverAddress(senderSignature);\n\n if (sender != signer) {\n require(\n personalAccountRegistry.verifyAccountOwnerAtBlock(sender, signer, blockNumber) ||\n externalAccountRegistry.verifyAccountOwnerAtBlock(sender, signer, blockNumber),\n \"PaymentRegistry: invalid sender signature\"\n );\n }\n }\n\n require(\n _verifyGuardianSignature(messageHash, guardianSignature),\n \"PaymentRegistry: invalid guardian signature\"\n );\n\n hash = _computePaymentChannelHash(\n sender,\n recipient,\n token,\n uid\n );\n\n /// @dev calc payment value\n paymentValue = amount.sub(paymentChannels[hash].committedAmount);\n\n require(\n paymentValue != 0,\n \"PaymentRegistry: invalid payment value\"\n );\n\n paymentChannels[hash].committedAmount = amount;\n\n _verifyDepositExitOrDeployAccount(sender, token);\n\n depositAccount = deposits[sender].account;\n\n emit PaymentChannelCommitted(\n hash,\n sender,\n recipient,\n token,\n uid,\n amount\n );\n\n return (hash, depositAccount, paymentValue);\n }\n\n function _transferFromDeposit(\n address depositAccount,\n address to,\n address token,\n uint256 value\n )\n private\n {\n if (token == address(0)) {\n PaymentDepositAccount(payable(depositAccount)).executeTransaction(\n to,\n value,\n new bytes(0)\n );\n } else {\n bytes memory response = PaymentDepositAccount(payable(depositAccount)).executeTransaction(\n token,\n 0,\n abi.encodeWithSelector(\n ERC20Token(token).transfer.selector,\n to,\n value\n )\n );\n\n if (response.length > 0) {\n require(\n abi.decode(response, (bool)),\n \"PaymentRegistry: ERC20Token transfer reverted\"\n );\n }\n }\n }\n\n function _transferSplitFromDeposit(\n address depositAccount,\n address to,\n address token,\n uint256 paymentValue,\n uint256 depositValue\n )\n private\n {\n require(\n depositValue > 0,\n \"PaymentRegistry: invalid deposit value\"\n );\n\n uint256 withdrawValue = paymentValue.sub(depositValue);\n\n require(\n withdrawValue > 0,\n \"PaymentRegistry: invalid withdraw value\"\n );\n\n _transferFromDeposit(\n depositAccount,\n to,\n token,\n withdrawValue\n );\n\n _transferFromDeposit(\n depositAccount,\n _computeDepositAccountAddress(to),\n token,\n depositValue\n );\n }\n\n // private functions (views)\n\n function _computeDepositAccountAddress(\n address owner\n )\n private\n view\n returns (address)\n {\n bytes32 salt = keccak256(\n abi.encodePacked(\n owner\n )\n );\n\n bytes memory creationCode = type(PaymentDepositAccount).creationCode;\n\n bytes32 data = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n salt,\n keccak256(creationCode)\n )\n );\n\n return address(uint160(uint256(data)));\n }\n\n function _hashDepositWithdrawal(\n address owner,\n address token,\n uint256 amount\n )\n private\n view\n returns (bytes32)\n {\n return _hashMessagePayload(HASH_PREFIX_DEPOSIT_WITHDRAWAL, abi.encodePacked(\n owner,\n token,\n amount\n ));\n }\n\n function _hashPaymentChannelCommit(\n address sender,\n address recipient,\n address token,\n bytes32 uid,\n uint256 blockNumber,\n uint256 amount\n )\n private\n view\n returns (bytes32)\n {\n return _hashMessagePayload(HASH_PREFIX_PAYMENT_CHANNEL_COMMIT, abi.encodePacked(\n sender,\n recipient,\n token,\n uid,\n blockNumber,\n amount\n ));\n }\n\n // private functions (pure)\n\n function _computePaymentChannelHash(\n address sender,\n address recipient,\n address token,\n bytes32 uid\n )\n private\n pure\n returns (bytes32)\n {\n return keccak256(\n abi.encodePacked(\n sender,\n recipient,\n token,\n uid\n )\n );\n }\n}\n" + }, + "src/common/access/Guarded.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../libs/ECDSALib.sol\";\n\n\n/**\n * @title Guarded\n *\n * @dev Contract module which provides a guardian-type control mechanism.\n * It allows key accounts to have guardians and restricts specific methods to be accessible by guardians only.\n *\n * Each guardian account can remove other guardians\n *\n * Use `_initializeGuarded` to initialize the contract\n *\n * @author Stanisław Głogowski \n */\ncontract Guarded {\n using ECDSALib for bytes32;\n\n mapping(address => bool) private guardians;\n\n // events\n\n /**\n * @dev Emitted when a new guardian is added\n * @param sender sender address\n * @param guardian guardian address\n */\n event GuardianAdded(\n address sender,\n address guardian\n );\n\n /**\n * @dev Emitted when the existing guardian is removed\n * @param sender sender address\n * @param guardian guardian address\n */\n event GuardianRemoved(\n address sender,\n address guardian\n );\n\n // modifiers\n\n /**\n * @dev Throws if tx.origin is not a guardian account\n */\n modifier onlyGuardian() {\n require(\n // solhint-disable-next-line avoid-tx-origin\n guardians[tx.origin],\n \"Guarded: tx.origin is not the guardian\"\n );\n\n _;\n }\n\n /**\n * @dev Internal constructor\n */\n constructor() internal {}\n\n // external functions\n\n /**\n * @notice Adds a new guardian\n * @param guardian guardian address\n */\n function addGuardian(\n address guardian\n )\n external\n onlyGuardian\n {\n _addGuardian(guardian);\n }\n\n /**\n * @notice Removes the existing guardian\n * @param guardian guardian address\n */\n function removeGuardian(\n address guardian\n )\n external\n onlyGuardian\n {\n require(\n // solhint-disable-next-line avoid-tx-origin\n tx.origin != guardian,\n \"Guarded: cannot remove self\"\n );\n\n require(\n guardians[guardian],\n \"Guarded: guardian doesn't exist\"\n );\n\n guardians[guardian] = false;\n\n emit GuardianRemoved(\n // solhint-disable-next-line avoid-tx-origin\n tx.origin,\n guardian\n );\n }\n\n // external functions (views)\n\n /**\n * @notice Check if guardian exists\n * @param guardian guardian address\n * @return true when guardian exists\n */\n function isGuardian(\n address guardian\n )\n external\n view\n returns (bool)\n {\n return guardians[guardian];\n }\n\n /**\n * @notice Verifies guardian signature\n * @param messageHash message hash\n * @param signature signature\n * @return true on correct guardian signature\n */\n function verifyGuardianSignature(\n bytes32 messageHash,\n bytes calldata signature\n )\n external\n view\n returns (bool)\n {\n return _verifyGuardianSignature(\n messageHash,\n signature\n );\n }\n\n // internal functions\n\n /**\n * @notice Initializes `Guarded` contract\n * @dev If `guardians_` array is empty `tx.origin` is added as guardian account\n * @param guardians_ array of guardians addresses\n */\n function _initializeGuarded(\n address[] memory guardians_\n )\n internal\n {\n if (guardians_.length == 0) {\n // solhint-disable-next-line avoid-tx-origin\n _addGuardian(tx.origin);\n } else {\n uint guardiansLen = guardians_.length;\n for (uint i = 0; i < guardiansLen; i++) {\n _addGuardian(guardians_[i]);\n }\n }\n }\n\n\n // internal functions (views)\n\n function _verifyGuardianSignature(\n bytes32 messageHash,\n bytes memory signature\n )\n internal\n view\n returns (bool)\n {\n address guardian = messageHash.recoverAddress(signature);\n\n return guardians[guardian];\n }\n\n // private functions\n\n function _addGuardian(\n address guardian\n )\n private\n {\n require(\n guardian != address(0),\n \"Guarded: cannot add 0x0 guardian\"\n );\n\n require(\n !guardians[guardian],\n \"Guarded: guardian already exists\"\n );\n\n guardians[guardian] = true;\n\n emit GuardianAdded(\n // solhint-disable-next-line avoid-tx-origin\n tx.origin,\n guardian\n );\n }\n}\n" + }, + "src/common/libs/ECDSALib.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title ECDSA library\n *\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/cryptography/ECDSA.sol#L26\n */\nlibrary ECDSALib {\n function recoverAddress(\n bytes32 messageHash,\n bytes memory signature\n )\n internal\n pure\n returns (address)\n {\n address result = address(0);\n\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n\n if (v < 27) {\n v += 27;\n }\n\n if (v == 27 || v == 28) {\n result = ecrecover(messageHash, v, r, s);\n }\n }\n\n return result;\n }\n\n function toEthereumSignedMessageHash(\n bytes32 messageHash\n )\n internal\n pure\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n messageHash\n ));\n }\n}\n" + }, + "src/common/libs/SafeMathLib.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title Safe math library\n *\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol\n */\nlibrary SafeMathLib {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n\n require(c >= a, \"SafeMathLib: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMathLib: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n\n return a - b;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n\n require(c / a == b, \"SafeMathLib: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMathLib: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n\n return a / b;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMathLib: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n\n return a % b;\n }\n}\n" + }, + "src/common/lifecycle/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title Initializable\n *\n * @dev Contract module which provides access control mechanism, where\n * there is the initializer account that can be granted exclusive access to\n * specific functions.\n *\n * The initializer account will be tx.origin during contract deployment and will be removed on first use.\n * Use `onlyInitializer` modifier on contract initialize process.\n *\n * @author Stanisław Głogowski \n */\ncontract Initializable {\n address private initializer;\n\n // events\n\n /**\n * @dev Emitted after `onlyInitializer`\n * @param initializer initializer address\n */\n event Initialized(\n address initializer\n );\n\n // modifiers\n\n /**\n * @dev Throws if tx.origin is not the initializer\n */\n modifier onlyInitializer() {\n require(\n // solhint-disable-next-line avoid-tx-origin\n tx.origin == initializer,\n \"Initializable: tx.origin is not the initializer\"\n );\n\n /// @dev removes initializer\n initializer = address(0);\n\n _;\n\n emit Initialized(\n // solhint-disable-next-line avoid-tx-origin\n tx.origin\n );\n }\n\n /**\n * @dev Internal constructor\n */\n constructor()\n internal\n {\n // solhint-disable-next-line avoid-tx-origin\n initializer = tx.origin;\n }\n\n // external functions (views)\n\n /**\n * @notice Check if contract is initialized\n * @return true when contract is initialized\n */\n function isInitialized()\n external\n view\n returns (bool)\n {\n return initializer == address(0);\n }\n}\n" + }, + "src/common/signature/SignatureValidator.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../libs/ECDSALib.sol\";\n\n/**\n * @title Signature validator\n *\n * @author Stanisław Głogowski \n */\ncontract SignatureValidator {\n using ECDSALib for bytes32;\n\n uint256 public chainId;\n\n /**\n * @dev internal constructor\n */\n constructor() internal {\n uint256 chainId_;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n chainId_ := chainid()\n }\n\n chainId = chainId_;\n }\n\n // internal functions\n\n function _hashMessagePayload(\n bytes32 messagePrefix,\n bytes memory messagePayload\n )\n internal\n view\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(\n chainId,\n address(this),\n messagePrefix,\n messagePayload\n )).toEthereumSignedMessageHash();\n }\n}\n" + }, + "src/common/token/ERC20Token.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../libs/SafeMathLib.sol\";\n\n\n/**\n * @title ERC20 token\n *\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol\n */\ncontract ERC20Token {\n using SafeMathLib for uint256;\n\n string public name;\n string public symbol;\n uint8 public decimals;\n uint256 public totalSupply;\n\n mapping(address => uint256) internal balances;\n mapping(address => mapping(address => uint256)) internal allowances;\n\n // events\n\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 value\n );\n\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev internal constructor\n */\n constructor() internal {}\n\n // external functions\n\n function transfer(\n address to,\n uint256 value\n )\n external\n returns (bool)\n {\n _transfer(_getSender(), to, value);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n )\n virtual\n external\n returns (bool)\n {\n address sender = _getSender();\n\n _transfer(from, to, value);\n _approve(from, sender, allowances[from][sender].sub(value));\n\n return true;\n }\n\n function approve(\n address spender,\n uint256 value\n )\n virtual\n external\n returns (bool)\n {\n _approve(_getSender(), spender, value);\n\n return true;\n }\n\n // external functions (views)\n\n function balanceOf(\n address owner\n )\n virtual\n external\n view\n returns (uint256)\n {\n return balances[owner];\n }\n\n function allowance(\n address owner,\n address spender\n )\n virtual\n external\n view\n returns (uint256)\n {\n return allowances[owner][spender];\n }\n\n // internal functions\n\n function _transfer(\n address from,\n address to,\n uint256 value\n )\n virtual\n internal\n {\n require(\n from != address(0),\n \"ERC20Token: cannot transfer from 0x0 address\"\n );\n require(\n to != address(0),\n \"ERC20Token: cannot transfer to 0x0 address\"\n );\n\n balances[from] = balances[from].sub(value);\n balances[to] = balances[to].add(value);\n\n emit Transfer(from, to, value);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 value\n )\n virtual\n internal\n {\n require(\n owner != address(0),\n \"ERC20Token: cannot approve from 0x0 address\"\n );\n require(\n spender != address(0),\n \"ERC20Token: cannot approve to 0x0 address\"\n );\n\n allowances[owner][spender] = value;\n\n emit Approval(owner, spender, value);\n }\n\n function _mint(\n address owner,\n uint256 value\n )\n virtual\n internal\n {\n require(\n owner != address(0),\n \"ERC20Token: cannot mint to 0x0 address\"\n );\n require(\n value > 0,\n \"ERC20Token: cannot mint 0 value\"\n );\n\n balances[owner] = balances[owner].add(value);\n totalSupply = totalSupply.add(value);\n\n emit Transfer(address(0), owner, value);\n }\n\n function _burn(\n address owner,\n uint256 value\n )\n virtual\n internal\n {\n require(\n owner != address(0),\n \"ERC20Token: cannot burn from 0x0 address\"\n );\n\n balances[owner] = balances[owner].sub(\n value,\n \"ERC20Token: burn value exceeds balance\"\n );\n\n totalSupply = totalSupply.sub(value);\n\n emit Transfer(owner, address(0), value);\n }\n\n // internal functions (views)\n\n function _getSender()\n virtual\n internal\n view\n returns (address)\n {\n return msg.sender;\n }\n}\n" + }, + "src/external/ExternalAccountRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../common/libs/BlockLib.sol\";\n\n\n/**\n * @title External account registry\n *\n * @notice Global registry for keys and external (outside of the platform) contract based wallets\n *\n * @dev An account can call the registry to add (`addAccountOwner`) or remove (`removeAccountOwner`) its own owners.\n * When the owner has been added, information about that fact will live in the registry forever.\n * Removing an owner only affects the future blocks (until the owner is re-added).\n *\n * Given the fact, there is no way to sign the data using a contract based wallet,\n * we created a registry to store signed by the key wallet proofs.\n * ERC-1271 allows removing a signer after the signature was created. Thus store the signature for the later use\n * doesn't guarantee the signer is still has access to that smart account.\n * Because of that, the ERC1271's `isValidSignature()` cannot be used in e.g. `PaymentRegistry`.*\n *\n * An account can call the registry to add (`addAccountProof`) or remove (`removeAccountProof`) proof hash.\n * When the proof has been added, information about that fact will live in the registry forever.\n * Removing a proof only affects the future blocks (until the proof is re-added).\n *\n * @author Stanisław Głogowski \n */\ncontract ExternalAccountRegistry {\n using BlockLib for BlockLib.BlockRelated;\n\n struct Account {\n mapping(address => BlockLib.BlockRelated) owners;\n mapping(bytes32 => BlockLib.BlockRelated) proofs;\n }\n\n mapping(address => Account) private accounts;\n\n // events\n\n /**\n * @dev Emitted when the new owner is added\n * @param account account address\n * @param owner owner address\n */\n event AccountOwnerAdded(\n address account,\n address owner\n );\n\n /**\n * @dev Emitted when the existing owner is removed\n * @param account account address\n * @param owner owner address\n */\n event AccountOwnerRemoved(\n address account,\n address owner\n );\n\n /**\n * @dev Emitted when the new proof is added\n * @param account account address\n * @param hash proof hash\n */\n event AccountProofAdded(\n address account,\n bytes32 hash\n );\n\n /**\n * @dev Emitted when the existing proof is removed\n * @param account account address\n * @param hash proof hash\n */\n event AccountProofRemoved(\n address account,\n bytes32 hash\n );\n\n // external functions\n\n /**\n * @notice Adds a new account owner\n * @param owner owner address\n */\n function addAccountOwner(\n address owner\n )\n external\n {\n require(\n owner != address(0),\n \"ExternalAccountRegistry: cannot add 0x0 owner\"\n );\n\n require(\n !accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\n \"ExternalAccountRegistry: owner already exists\"\n );\n\n accounts[msg.sender].owners[owner].added = true;\n accounts[msg.sender].owners[owner].removedAtBlockNumber = 0;\n\n emit AccountOwnerAdded(\n msg.sender,\n owner\n );\n }\n\n /**\n * @notice Removes existing account owner\n * @param owner owner address\n */\n function removeAccountOwner(\n address owner\n )\n external\n {\n require(\n accounts[msg.sender].owners[owner].verifyAtCurrentBlock(),\n \"ExternalAccountRegistry: owner doesn't exist\"\n );\n\n accounts[msg.sender].owners[owner].removedAtBlockNumber = block.number;\n\n emit AccountOwnerRemoved(\n msg.sender,\n owner\n );\n }\n\n /**\n * @notice Adds a new account proof\n * @param hash proof hash\n */\n function addAccountProof(\n bytes32 hash\n )\n external\n {\n require(\n !accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\n \"ExternalAccountRegistry: proof already exists\"\n );\n\n accounts[msg.sender].proofs[hash].added = true;\n accounts[msg.sender].proofs[hash].removedAtBlockNumber = 0;\n\n emit AccountProofAdded(\n msg.sender,\n hash\n );\n }\n\n /**\n * @notice Removes existing account proof\n * @param hash proof hash\n */\n function removeAccountProof(\n bytes32 hash\n )\n external\n {\n require(\n accounts[msg.sender].proofs[hash].verifyAtCurrentBlock(),\n \"ExternalAccountRegistry: proof doesn't exist\"\n );\n\n accounts[msg.sender].proofs[hash].removedAtBlockNumber = block.number;\n\n emit AccountProofRemoved(\n msg.sender,\n hash\n );\n }\n\n // external functions (views)\n\n /**\n * @notice Verifies the owner of the account at current block\n * @param account account address\n * @param owner owner address\n * @return true on correct account owner\n */\n function verifyAccountOwner(\n address account,\n address owner\n )\n external\n view\n returns (bool)\n {\n return accounts[account].owners[owner].verifyAtCurrentBlock();\n }\n\n /**\n * @notice Verifies the owner of the account at specific block\n * @param account account address\n * @param owner owner address\n * @param blockNumber block number to verify\n * @return true on correct account owner\n */\n function verifyAccountOwnerAtBlock(\n address account,\n address owner,\n uint256 blockNumber\n )\n external\n view\n returns (bool)\n {\n return accounts[account].owners[owner].verifyAtBlock(blockNumber);\n }\n\n /**\n * @notice Verifies the proof of the account at current block\n * @param account account address\n * @param hash proof hash\n * @return true on correct account proof\n */\n function verifyAccountProof(\n address account,\n bytes32 hash\n )\n external\n view\n returns (bool)\n {\n return accounts[account].proofs[hash].verifyAtCurrentBlock();\n }\n\n /**\n * @notice Verifies the proof of the account at specific block\n * @param account account address\n * @param hash proof hash\n * @param blockNumber block number to verify\n * @return true on correct account proof\n */\n function verifyAccountProofAtBlock(\n address account,\n bytes32 hash,\n uint256 blockNumber\n )\n external\n view\n returns (bool)\n {\n return accounts[account].proofs[hash].verifyAtBlock(blockNumber);\n }\n}\n" + }, + "src/personal/PersonalAccountRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../common/access/Guarded.sol\";\nimport \"../common/account/AccountController.sol\";\nimport \"../common/account/AccountRegistry.sol\";\nimport \"../common/libs/BlockLib.sol\";\nimport \"../common/libs/ECDSALib.sol\";\nimport \"../common/libs/ECDSAExtendedLib.sol\";\nimport \"../common/libs/SafeMathLib.sol\";\nimport \"../common/lifecycle/Initializable.sol\";\nimport \"../common/token/ERC20Token.sol\";\nimport \"../gateway/GatewayRecipient.sol\";\n\n\n/**\n * @title Personal account registry\n *\n * @notice A registry for personal (controlled by owners) accounts\n *\n * @author Stanisław Głogowski \n */\ncontract PersonalAccountRegistry is Guarded, AccountController, AccountRegistry, Initializable, GatewayRecipient {\n using BlockLib for BlockLib.BlockRelated;\n using SafeMathLib for uint256;\n using ECDSALib for bytes32;\n using ECDSAExtendedLib for bytes;\n\n struct Account {\n bool deployed;\n bytes32 salt;\n mapping(address => BlockLib.BlockRelated) owners;\n }\n\n mapping(address => Account) private accounts;\n\n // events\n\n /**\n * @dev Emitted when the new owner is added\n * @param account account address\n * @param owner owner address\n */\n event AccountOwnerAdded(\n address account,\n address owner\n );\n\n /**\n * @dev Emitted when the existing owner is removed\n * @param account account address\n * @param owner owner address\n */\n event AccountOwnerRemoved(\n address account,\n address owner\n );\n\n /**\n * @dev Emitted when the call is refunded\n * @param account account address\n * @param beneficiary beneficiary address\n * @param token token address\n * @param value value\n */\n event AccountCallRefunded(\n address account,\n address beneficiary,\n address token,\n uint256 value\n );\n\n /**\n * @dev Public constructor\n */\n constructor() public Initializable() {}\n\n // external functions\n\n /**\n * @notice Initializes `PersonalAccountRegistry` contract\n * @param guardians_ array of guardians addresses\n * @param accountImplementation_ account implementation address\n * @param gateway_ `Gateway` contract address\n */\n function initialize(\n address[] calldata guardians_,\n address accountImplementation_,\n address gateway_\n )\n external\n onlyInitializer\n {\n // Guarded\n _initializeGuarded(guardians_);\n\n // AccountController\n _initializeAccountController(address(this), accountImplementation_);\n\n // GatewayRecipient\n _initializeGatewayRecipient(gateway_);\n }\n\n /**\n * @notice Upgrades `PersonalAccountRegistry` contract\n * @param accountImplementation_ account implementation address\n */\n function upgrade(\n address accountImplementation_\n )\n external\n onlyGuardian\n {\n _setAccountImplementation(accountImplementation_, true);\n }\n\n /**\n * @notice Deploys account\n * @param account account address\n */\n function deployAccount(\n address account\n )\n external\n {\n _verifySender(account);\n _deployAccount(account);\n }\n\n /**\n * @notice Upgrades account\n * @param account account address\n */\n function upgradeAccount(\n address account\n )\n external\n {\n _verifySender(account);\n _upgradeAccount(account, true);\n }\n\n /**\n * @notice Adds a new account owner\n * @param account account address\n * @param owner owner address\n */\n function addAccountOwner(\n address account,\n address owner\n )\n external\n {\n _verifySender(account);\n\n require(\n owner != address(0),\n \"PersonalAccountRegistry: cannot add 0x0 owner\"\n );\n\n require(\n !accounts[account].owners[owner].verifyAtCurrentBlock(),\n \"PersonalAccountRegistry: owner already exists\"\n );\n\n accounts[account].owners[owner].added = true;\n accounts[account].owners[owner].removedAtBlockNumber = 0;\n\n emit AccountOwnerAdded(\n account,\n owner\n );\n }\n\n /**\n * @notice Removes the existing account owner\n * @param account account address\n * @param owner owner address\n */\n function removeAccountOwner(\n address account,\n address owner\n )\n external\n {\n address sender = _verifySender(account);\n\n require(\n owner != sender,\n \"PersonalAccountRegistry: cannot remove self\"\n );\n\n require(\n accounts[account].owners[owner].verifyAtCurrentBlock(),\n \"PersonalAccountRegistry: owner doesn't exist\"\n );\n\n accounts[account].owners[owner].removedAtBlockNumber = block.number;\n\n emit AccountOwnerRemoved(\n account,\n owner\n );\n }\n\n /**\n * @notice Executes account transaction\n * @dev Deploys an account if not deployed yet\n * @param account account address\n * @param to to address\n * @param value value\n * @param data data\n */\n function executeAccountTransaction(\n address account,\n address to,\n uint256 value,\n bytes calldata data\n )\n external\n {\n _verifySender(account);\n\n _deployAccount(account);\n\n _executeAccountTransaction(\n account,\n to,\n value,\n data,\n true\n );\n }\n\n /**\n * @notice Refunds account call\n * @dev Deploys an account if not deployed yet\n * @param account account address\n * @param token token address\n * @param value value\n */\n function refundAccountCall(\n address account,\n address token,\n uint256 value\n )\n external\n {\n _verifySender(account);\n\n _deployAccount(account);\n\n /* solhint-disable avoid-tx-origin */\n\n if (token == address(0)) {\n _executeAccountTransaction(\n account,\n tx.origin,\n value,\n new bytes(0),\n false\n );\n } else {\n bytes memory response = _executeAccountTransaction(\n account,\n token,\n 0,\n abi.encodeWithSelector(\n ERC20Token(token).transfer.selector,\n tx.origin,\n value\n ),\n false\n );\n\n if (response.length > 0) {\n require(\n abi.decode(response, (bool)),\n \"PersonalAccountRegistry: ERC20Token transfer reverted\"\n );\n }\n }\n\n emit AccountCallRefunded(\n account,\n tx.origin,\n token,\n value\n );\n\n /* solhint-enable avoid-tx-origin */\n }\n\n // external functions (views)\n\n /**\n * @notice Computes account address\n * @param saltOwner salt owner address\n * @return account address\n */\n function computeAccountAddress(\n address saltOwner\n )\n external\n view\n returns (address)\n {\n return _computeAccountAddress(saltOwner);\n }\n\n /**\n * @notice Checks if account is deployed\n * @param account account address\n * @return true when account is deployed\n */\n function isAccountDeployed(\n address account\n )\n external\n view\n returns (bool)\n {\n return accounts[account].deployed;\n }\n\n /**\n * @notice Verifies the owner of the account at the current block\n * @param account account address\n * @param owner owner address\n * @return true on correct account owner\n */\n function verifyAccountOwner(\n address account,\n address owner\n )\n external\n view\n returns (bool)\n {\n return _verifyAccountOwner(account, owner);\n }\n\n /**\n * @notice Verifies the owner of the account at a specific block\n * @param account account address\n * @param owner owner address\n * @param blockNumber block number to verify\n * @return true on correct account owner\n */\n function verifyAccountOwnerAtBlock(\n address account,\n address owner,\n uint256 blockNumber\n )\n external\n view\n returns (bool)\n {\n bool result = false;\n\n if (_verifyAccountOwner(account, owner)) {\n result = true;\n } else {\n result = accounts[account].owners[owner].verifyAtBlock(blockNumber);\n }\n\n return result;\n }\n\n /**\n * @notice Verifies account signature\n * @param account account address\n * @param messageHash message hash\n * @param signature signature\n * @return magic hash if valid\n */\n function isValidAccountSignature(\n address account,\n bytes32 messageHash,\n bytes calldata signature\n )\n override\n external\n view\n returns (bool)\n {\n return _verifyAccountOwner(\n account,\n messageHash.recoverAddress(signature)\n );\n }\n\n /**\n * @notice Verifies account signature\n * @param account account address\n * @param message message\n * @param signature signature\n * @return magic hash if valid\n */\n function isValidAccountSignature(\n address account,\n bytes calldata message,\n bytes calldata signature\n )\n override\n external\n view\n returns (bool)\n {\n return _verifyAccountOwner(\n account,\n message.toEthereumSignedMessageHash().recoverAddress(signature)\n );\n }\n\n // private functions\n\n function _verifySender(\n address account\n )\n private\n returns (address)\n {\n address sender = _getContextSender();\n\n if (accounts[account].owners[sender].added) {\n require(\n accounts[account].owners[sender].removedAtBlockNumber == 0,\n \"PersonalAccountRegistry: sender is not the account owner\"\n );\n } else {\n require(\n accounts[account].salt == 0,\n \"PersonalAccountRegistry: sender is not the account owner\"\n );\n\n bytes32 salt = keccak256(\n abi.encodePacked(sender)\n );\n\n require(\n account == _computeAccountAddress(salt),\n \"PersonalAccountRegistry: sender is not the account owner\"\n );\n\n accounts[account].salt = salt;\n accounts[account].owners[sender].added = true;\n\n emit AccountOwnerAdded(\n account,\n sender\n );\n }\n\n return sender;\n }\n\n function _deployAccount(\n address account\n )\n internal\n {\n if (!accounts[account].deployed) {\n _deployAccount(\n accounts[account].salt,\n true\n );\n\n accounts[account].deployed = true;\n }\n }\n\n // private functions (views)\n\n function _computeAccountAddress(\n address saltOwner\n )\n private\n view\n returns (address)\n {\n bytes32 salt = keccak256(\n abi.encodePacked(saltOwner)\n );\n\n return _computeAccountAddress(salt);\n }\n\n function _verifyAccountOwner(\n address account,\n address owner\n )\n private\n view\n returns (bool)\n {\n bool result;\n\n if (accounts[account].owners[owner].added) {\n result = accounts[account].owners[owner].removedAtBlockNumber == 0;\n } else if (accounts[account].salt == 0) {\n result = account == _computeAccountAddress(owner);\n }\n\n return result;\n }\n}\n" + }, + "src/gateway/GatewayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../common/libs/BytesLib.sol\";\n\n\n/**\n * @title Gateway recipient\n *\n * @notice Gateway target contract\n *\n * @author Stanisław Głogowski \n */\ncontract GatewayRecipient {\n using BytesLib for bytes;\n\n address public gateway;\n\n /**\n * @dev internal constructor\n */\n constructor() internal {}\n\n // internal functions\n\n /**\n * @notice Initializes `GatewayRecipient` contract\n * @param gateway_ `Gateway` contract address\n */\n function _initializeGatewayRecipient(\n address gateway_\n )\n internal\n {\n gateway = gateway_;\n }\n\n // internal functions (views)\n\n /**\n * @notice Gets gateway context account\n * @return context account address\n */\n function _getContextAccount()\n internal\n view\n returns (address)\n {\n return _getContextAddress(40);\n }\n\n /**\n * @notice Gets gateway context sender\n * @return context sender address\n */\n function _getContextSender()\n internal\n view\n returns (address)\n {\n return _getContextAddress(20);\n }\n\n /**\n * @notice Gets gateway context data\n * @return context data\n */\n function _getContextData()\n internal\n view\n returns (bytes calldata)\n {\n bytes calldata result;\n\n if (_isGatewaySender()) {\n result = msg.data[:msg.data.length - 40];\n } else {\n result = msg.data;\n }\n\n return result;\n }\n\n // private functions (views)\n\n function _getContextAddress(\n uint256 offset\n )\n private\n view\n returns (address)\n {\n address result = address(0);\n\n if (_isGatewaySender()) {\n uint from = msg.data.length - offset;\n result = bytes(msg.data[from:from + 20]).toAddress();\n } else {\n result = msg.sender;\n }\n\n return result;\n }\n\n function _isGatewaySender()\n private\n view\n returns (bool)\n {\n bool result;\n\n if (msg.sender == gateway) {\n require(\n msg.data.length >= 44,\n \"GatewayRecipient: invalid msg.data\"\n );\n\n result = true;\n }\n\n return result;\n }\n}\n" + }, + "src/common/libs/BlockLib.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title Block library\n *\n * @author Stanisław Głogowski \n */\nlibrary BlockLib {\n struct BlockRelated {\n bool added;\n uint256 removedAtBlockNumber;\n }\n\n /**\n * @notice Verifies self struct at current block\n * @param self self struct\n * @return true on correct self struct\n */\n function verifyAtCurrentBlock(\n BlockRelated memory self\n )\n internal\n view\n returns (bool)\n {\n return verifyAtBlock(self, block.number);\n }\n\n /**\n * @notice Verifies self struct at any block\n * @param self self struct\n * @return true on correct self struct\n */\n function verifyAtAnyBlock(\n BlockRelated memory self\n )\n internal\n pure\n returns (bool)\n {\n return verifyAtBlock(self, 0);\n }\n\n /**\n * @notice Verifies self struct at specific block\n * @param self self struct\n * @param blockNumber block number to verify\n * @return true on correct self struct\n */\n function verifyAtBlock(\n BlockRelated memory self,\n uint256 blockNumber\n )\n internal\n pure\n returns (bool)\n {\n bool result = false;\n\n if (self.added) {\n if (self.removedAtBlockNumber == 0) {\n result = true;\n } else if (blockNumber == 0) {\n result = true;\n } else {\n result = self.removedAtBlockNumber > blockNumber;\n }\n }\n\n return result;\n }\n}\n" + }, + "src/common/account/AccountController.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"./Account.sol\";\n\n\n/**\n * @title Account controller\n *\n * @dev Contract module which provides Account deployment mechanism\n *\n * @author Stanisław Głogowski \n */\ncontract AccountController {\n address public accountRegistry;\n address public accountImplementation;\n\n // events\n\n /**\n * @dev Emitted when the account registry is updated\n * @param accountRegistry account registry address\n */\n event AccountRegistryUpdated(\n address accountRegistry\n );\n\n /**\n * @dev Emitted when the account implementation is updated\n * @param accountImplementation account implementation address\n */\n event AccountImplementationUpdated(\n address accountImplementation\n );\n\n /**\n * @dev Emitted when the account is deployed\n * @param account account address\n * @param accountImplementation account implementation address\n */\n event AccountDeployed(\n address account,\n address accountImplementation\n );\n\n /**\n * @dev Emitted when the account is upgraded\n * @param account account address\n * @param accountImplementation account implementation address\n */\n event AccountUpgraded(\n address account,\n address accountImplementation\n );\n\n /**\n * @dev Emitted when the transaction is executed\n * @param account account address\n * @param to to address\n * @param value value\n * @param data data\n * @param response response\n */\n event AccountTransactionExecuted(\n address account,\n address to,\n uint256 value,\n bytes data,\n bytes response\n );\n\n /**\n * @dev Internal constructor\n */\n constructor() internal {}\n\n // internal functions\n\n /**\n * @notice Initializes `AccountController` contract\n * @param accountRegistry_ account registry address\n * @param accountImplementation_ account implementation address\n */\n function _initializeAccountController(\n address accountRegistry_,\n address accountImplementation_\n )\n internal\n {\n _setAccountRegistry(accountRegistry_, false);\n _setAccountImplementation(accountImplementation_, false);\n }\n\n /**\n * @notice Sets account registry\n * @param accountRegistry_ account registry address\n * @param emitEvent it will emit event when flag is set to true\n */\n function _setAccountRegistry(\n address accountRegistry_,\n bool emitEvent\n )\n internal\n {\n require(\n accountRegistry_ != address(0),\n \"AccountController: cannot set account registry to 0x0\"\n );\n\n accountRegistry = accountRegistry_;\n\n if (emitEvent) {\n emit AccountRegistryUpdated(accountRegistry);\n }\n }\n\n /**\n * @notice Sets account implementation\n * @param accountImplementation_ account implementation address\n * @param emitEvent it will emit event when flag is set to true\n */\n function _setAccountImplementation(\n address accountImplementation_,\n bool emitEvent\n )\n internal\n {\n require(\n accountImplementation_ != address(0),\n \"AccountController: cannot set account Implementation to 0x0\"\n );\n\n accountImplementation = accountImplementation_;\n\n if (emitEvent) {\n emit AccountImplementationUpdated(accountImplementation);\n }\n }\n\n /**\n * @notice Deploys account\n * @param salt CREATE2 salt\n * @param emitEvent it will emit event when flag is set to true\n * @return account address\n */\n function _deployAccount(\n bytes32 salt,\n bool emitEvent\n )\n internal\n returns (address)\n {\n address account = address(new Account{salt: salt}(\n accountRegistry,\n accountImplementation\n ));\n\n if (emitEvent) {\n emit AccountDeployed(\n account,\n accountImplementation\n );\n }\n\n return account;\n }\n\n /**\n * @notice Upgrades account\n * @param account account address\n * @param emitEvent it will emit event when flag is set to true\n */\n function _upgradeAccount(\n address account,\n bool emitEvent\n )\n internal\n {\n require(\n Account(payable(account)).implementation() != accountImplementation,\n \"AccountController: account already upgraded\"\n );\n\n Account(payable(account)).setImplementation(accountImplementation);\n\n if (emitEvent) {\n emit AccountUpgraded(\n account,\n accountImplementation\n );\n }\n }\n\n /**\n * @notice Executes transaction from the account\n * @param account account address\n * @param to to address\n * @param value value\n * @param data data\n * @param emitEvent it will emit event when flag is set to true\n * @return transaction result\n */\n function _executeAccountTransaction(\n address account,\n address to,\n uint256 value,\n bytes memory data,\n bool emitEvent\n )\n internal\n returns (bytes memory)\n {\n require(\n to != address(0),\n \"AccountController: cannot send to 0x0\"\n );\n\n require(\n to != address(this),\n \"AccountController: cannot send to controller\"\n );\n\n require(\n to != account,\n \"AccountController: cannot send to self\"\n );\n\n bytes memory response = Account(payable(account)).executeTransaction(\n to,\n value,\n data\n );\n\n if (emitEvent) {\n emit AccountTransactionExecuted(\n account,\n to,\n value,\n data,\n response\n );\n }\n\n return response;\n }\n\n // internal functions (views)\n\n /**\n * @notice Computes account CREATE2 address\n * @param salt CREATE2 salt\n * @return account address\n */\n function _computeAccountAddress(\n bytes32 salt\n )\n internal\n view\n returns (address)\n {\n bytes memory creationCode = abi.encodePacked(\n type(Account).creationCode,\n bytes12(0),\n accountRegistry,\n bytes12(0),\n accountImplementation\n );\n\n bytes32 data = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n salt,\n keccak256(creationCode)\n )\n );\n\n return address(uint160(uint256(data)));\n }\n}\n" + }, + "src/common/account/AccountRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"./Account.sol\";\n\n\n/**\n * @title Account registry\n *\n * @author Stanisław Głogowski \n */\nabstract contract AccountRegistry {\n /**\n * @notice Verifies account signature\n * @param account account address\n * @param messageHash message hash\n * @param signature signature\n * @return true if valid\n */\n function isValidAccountSignature(\n address account,\n bytes32 messageHash,\n bytes calldata signature\n )\n virtual\n external\n view\n returns (bool);\n\n /**\n * @notice Verifies account signature\n * @param account account address\n * @param message message\n * @param signature signature\n * @return true if valid\n */\n function isValidAccountSignature(\n address account,\n bytes calldata message,\n bytes calldata signature\n )\n virtual\n external\n view\n returns (bool);\n}\n" + }, + "src/common/libs/ECDSAExtendedLib.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"./StringsLib.sol\";\n\n\n/**\n * @title ECDSA extended library\n */\nlibrary ECDSAExtendedLib {\n using StringsLib for uint;\n\n function toEthereumSignedMessageHash(\n bytes memory message\n )\n internal\n pure\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n\",\n message.length.toString(),\n abi.encodePacked(message)\n ));\n }\n}\n" + }, + "src/common/account/Account.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../access/Controlled.sol\";\nimport \"./AccountBase.sol\";\n\n\n/**\n * @title Account\n *\n * @author Stanisław Głogowski \n */\ncontract Account is Controlled, AccountBase {\n address public implementation;\n\n /**\n * @dev Public constructor\n * @param registry_ account registry address\n * @param implementation_ account implementation address\n */\n constructor(\n address registry_,\n address implementation_\n )\n public\n Controlled()\n {\n registry = registry_;\n implementation = implementation_;\n }\n\n // external functions\n\n /**\n * @notice Payable receive\n */\n receive()\n external\n payable\n {\n //\n }\n\n /**\n * @notice Fallback\n */\n // solhint-disable-next-line payable-fallback\n fallback()\n external\n {\n if (msg.data.length != 0) {\n address implementation_ = implementation;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let calldedatasize := calldatasize()\n\n calldatacopy(0, 0, calldedatasize)\n\n let result := delegatecall(gas(), implementation_, 0, calldedatasize, 0, 0)\n let returneddatasize := returndatasize()\n\n returndatacopy(0, 0, returneddatasize)\n\n switch result\n case 0 { revert(0, returneddatasize) }\n default { return(0, returneddatasize) }\n }\n }\n }\n\n /**\n * @notice Sets implementation\n * @param implementation_ implementation address\n */\n function setImplementation(\n address implementation_\n )\n external\n onlyController\n {\n implementation = implementation_;\n }\n\n /**\n * @notice Executes transaction\n * @param to to address\n * @param value value\n * @param data data\n * @return transaction result\n */\n function executeTransaction(\n address to,\n uint256 value,\n bytes calldata data\n )\n external\n onlyController\n returns (bytes memory)\n {\n bytes memory result;\n bool succeeded;\n\n // solhint-disable-next-line avoid-call-value, avoid-low-level-calls\n (succeeded, result) = payable(to).call{value: value}(data);\n\n require(\n succeeded,\n \"Account: transaction reverted\"\n );\n\n return result;\n }\n}\n" + }, + "src/common/account/AccountBase.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title Account base\n *\n * @author Stanisław Głogowski \n */\ncontract AccountBase {\n address public registry;\n}\n" + }, + "src/common/libs/StringsLib.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title Strings library\n *\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/utils/Strings.sol#L12\n */\nlibrary StringsLib {\n function toString(\n uint256 value\n )\n internal\n pure\n returns (string memory)\n {\n if (value == 0) {\n return \"0\";\n }\n\n uint256 temp = value;\n uint256 digits;\n\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n\n bytes memory buffer = new bytes(digits);\n uint256 index = digits - 1;\n temp = value;\n\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n\n return string(buffer);\n }\n}\n" + }, + "src/common/libs/BytesLib.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title Bytes library\n *\n * @author Stanisław Głogowski \n */\nlibrary BytesLib {\n /**\n * @notice Converts bytes to address\n * @param data data\n * @return address\n */\n function toAddress(\n bytes memory data\n )\n internal\n pure\n returns (address)\n {\n address result;\n\n require(\n data.length == 20,\n \"BytesLib: invalid data length\"\n );\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := div(mload(add(data, 0x20)), 0x1000000000000000000000000)\n }\n\n return result;\n }\n}\n" + }, + "src/tokens/WrappedWeiToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../common/lifecycle/Initializable.sol\";\nimport \"../common/token/ERC20Token.sol\";\nimport \"../gateway/GatewayRecipient.sol\";\n\n\n/**\n * @title Wrapped wei token\n *\n * @notice One to one wei consumable ERC20 token\n *\n * @dev After the transfer to consumer's account is done, the token will be automatically burned and withdrawn.\n *\n * Use `startConsuming` to become a consumer.\n *\n * @author Stanisław Głogowski \n */\ncontract WrappedWeiToken is Initializable, ERC20Token, GatewayRecipient {\n mapping(address => bool) private consumers;\n\n // events\n\n /**\n * @dev Emitted when the new consumer is added\n * @param consumer consumer address\n */\n event ConsumerAdded(\n address consumer\n );\n\n /**\n * @dev Emitted when the existing consumer is removed\n * @param consumer consumer address\n */\n event ConsumerRemoved(\n address consumer\n );\n\n /**\n * @dev Public constructor\n */\n constructor()\n public\n Initializable()\n {\n name = \"Wrapped Wei\";\n symbol = \"WWEI\";\n }\n\n /**\n * @notice Receive fallback\n */\n receive()\n external\n payable\n {\n _mint(_getSender(), msg.value);\n }\n\n // external functions\n\n /**\n * @notice Initializes `WrappedWeiToken` contract\n * @param consumers_ array of consumers addresses\n * @param gateway_ `Gateway` contract address\n */\n function initialize(\n address[] calldata consumers_,\n address gateway_\n )\n external\n onlyInitializer\n {\n if (consumers_.length != 0) {\n uint consumersLen = consumers_.length;\n for (uint i = 0; i < consumersLen; i++) {\n _addConsumer(consumers_[i]);\n }\n }\n\n _initializeGatewayRecipient(gateway_);\n }\n\n /**\n * @notice Starts consuming\n * @dev Add caller as a consumer\n */\n function startConsuming()\n external\n {\n _addConsumer(_getSender());\n }\n\n /**\n * @notice Stops consuming\n * @dev Remove caller from consumers\n */\n function stopConsuming()\n external\n {\n address consumer = _getSender();\n\n require(\n consumers[consumer],\n \"WrappedWeiToken: consumer doesn't exist\"\n );\n\n consumers[consumer] = false;\n\n emit ConsumerRemoved(consumer);\n }\n\n /**\n * @notice Deposits `msg.value` to address\n * @param to to address\n */\n function depositTo(\n address to\n )\n external\n payable\n {\n _mint(to, msg.value);\n }\n\n /**\n * @notice Withdraws\n * @param value value to withdraw\n */\n function withdraw(\n uint256 value\n )\n external\n {\n _withdraw(_getSender(), _getSender(), value);\n }\n\n /**\n * @notice Withdraws to address\n * @param to to address\n * @param value value to withdraw\n */\n function withdrawTo(\n address to,\n uint256 value\n )\n external\n {\n _withdraw(_getSender(), to, value);\n }\n\n /**\n * @notice Withdraws all\n */\n function withdrawAll()\n external\n {\n address sender = _getSender();\n\n _withdraw(sender, sender, balances[sender]);\n }\n\n /**\n * @notice Withdraws all to address\n * @param to to address\n */\n function withdrawAllTo(\n address to\n )\n external\n {\n address sender = _getSender();\n\n _withdraw(sender, to, balances[sender]);\n }\n\n // external functions (views)\n\n /**\n * @notice Checks if consumer exists\n * @param consumer consumer address\n * @return true if consumer exists\n */\n function isConsumer(\n address consumer\n )\n external\n view\n returns (bool)\n {\n return consumers[consumer];\n }\n\n // internal functions\n\n function _transfer(\n address from,\n address to,\n uint256 value\n )\n override\n internal\n {\n if (consumers[to]) {\n _withdraw(from, to, value);\n } else {\n super._transfer(from, to, value);\n }\n }\n\n // internal functions (views)\n\n function _getSender()\n override\n internal\n view\n returns (address)\n {\n return _getContextAccount();\n }\n\n // private functions\n\n function _addConsumer(\n address consumer\n )\n private\n {\n require(\n !consumers[consumer],\n \"WrappedWeiToken: consumer already exists\"\n );\n\n consumers[consumer] = true;\n\n emit ConsumerAdded(consumer);\n }\n\n function _withdraw(\n address from,\n address to,\n uint256 value\n )\n private\n {\n _burn(from, value);\n\n require(\n // solhint-disable-next-line check-send-result\n payable(to).send(value),\n \"WrappedWeiToken: transaction reverted\"\n );\n }\n}\n" + }, + "src/gateway/Gateway.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../common/libs/ECDSALib.sol\";\nimport \"../common/libs/SafeMathLib.sol\";\nimport \"../common/lifecycle/Initializable.sol\";\nimport \"../common/signature/SignatureValidator.sol\";\nimport \"../external/ExternalAccountRegistry.sol\";\nimport \"../personal/PersonalAccountRegistry.sol\";\n\n\n/**\n * @title Gateway\n *\n * @notice GSN replacement\n *\n * @author Stanisław Głogowski \n */\ncontract Gateway is Initializable, SignatureValidator {\n using ECDSALib for bytes32;\n using SafeMathLib for uint256;\n\n struct DelegatedBatch {\n address account;\n uint256 nonce;\n address[] to;\n bytes[] data;\n }\n\n struct DelegatedBatchWithGasPrice {\n address account;\n uint256 nonce;\n address[] to;\n bytes[] data;\n uint256 gasPrice;\n }\n\n bytes32 private constant HASH_PREFIX_DELEGATED_BATCH = keccak256(\n \"DelegatedBatch(address account,uint256 nonce,address[] to,bytes[] data)\"\n );\n\n bytes32 private constant HASH_PREFIX_DELEGATED_BATCH_WITH_GAS_PRICE = keccak256(\n \"DelegatedBatchWithGasPrice(address account,uint256 nonce,address[] to,bytes[] data,uint256 gasPrice)\"\n );\n\n ExternalAccountRegistry public externalAccountRegistry;\n PersonalAccountRegistry public personalAccountRegistry;\n\n mapping(address => uint256) private accountNonce;\n\n // events\n\n /**\n * @dev Emitted when the single batch is delegated\n * @param sender sender address\n * @param batch batch\n * @param succeeded if succeeded\n */\n event BatchDelegated(\n address sender,\n bytes batch,\n bool succeeded\n );\n\n /**\n * @dev Public constructor\n */\n constructor() public Initializable() SignatureValidator() {}\n\n // external functions\n\n /**\n * @notice Initializes `Gateway` contract\n * @param externalAccountRegistry_ `ExternalAccountRegistry` contract address\n * @param personalAccountRegistry_ `PersonalAccountRegistry` contract address\n */\n function initialize(\n ExternalAccountRegistry externalAccountRegistry_,\n PersonalAccountRegistry personalAccountRegistry_\n )\n external\n onlyInitializer\n {\n externalAccountRegistry = externalAccountRegistry_;\n personalAccountRegistry = personalAccountRegistry_;\n }\n\n // public functions\n\n /**\n * @notice Sends batch\n * @dev `GatewayRecipient` context api:\n * `_getContextAccount` will return `msg.sender`\n * `_getContextSender` will return `msg.sender`\n *\n * @param to array of batch recipients contracts\n * @param data array of batch data\n */\n function sendBatch(\n address[] memory to,\n bytes[] memory data\n )\n public\n {\n _sendBatch(\n msg.sender,\n msg.sender,\n to,\n data\n );\n }\n\n /**\n * @notice Sends batch from the account\n * @dev `GatewayRecipient` context api:\n * `_getContextAccount` will return `account` arg\n * `_getContextSender` will return `msg.sender`\n *\n * @param account account address\n * @param to array of batch recipients contracts\n * @param data array of batch data\n */\n function sendBatchFromAccount(\n address account,\n address[] memory to,\n bytes[] memory data\n )\n public\n {\n _sendBatch(\n account,\n msg.sender,\n to,\n data\n );\n }\n\n /**\n * @notice Delegates batch from the account\n * @dev Use `hashDelegatedBatch` to create sender message payload.\n *\n * `GatewayRecipient` context api:\n * `_getContextAccount` will return `account` arg\n * `_getContextSender` will return recovered address from `senderSignature` arg\n *\n * @param account account address\n * @param nonce next account nonce\n * @param to array of batch recipients contracts\n * @param data array of batch data\n * @param senderSignature sender signature\n */\n function delegateBatch(\n address account,\n uint256 nonce,\n address[] memory to,\n bytes[] memory data,\n bytes memory senderSignature\n )\n public\n {\n require(\n nonce > accountNonce[account],\n \"Gateway: nonce is lower than current account nonce\"\n );\n\n address sender = _hashDelegatedBatch(\n account,\n nonce,\n to,\n data\n ).recoverAddress(senderSignature);\n\n accountNonce[account] = nonce;\n\n _sendBatch(\n account,\n sender,\n to,\n data\n );\n }\n\n /**\n * @notice Delegates batch from the account (with gas price)\n *\n * @dev Use `hashDelegatedBatchWithGasPrice` to create sender message payload (tx.gasprice as gasPrice)\n *\n * `GatewayRecipient` context api:\n * `_getContextAccount` will return `account` arg\n * `_getContextSender` will return recovered address from `senderSignature` arg\n *\n * @param account account address\n * @param nonce next account nonce\n * @param to array of batch recipients contracts\n * @param data array of batch data\n * @param senderSignature sender signature\n */\n function delegateBatchWithGasPrice(\n address account,\n uint256 nonce,\n address[] memory to,\n bytes[] memory data,\n bytes memory senderSignature\n )\n public\n {\n require(\n nonce > accountNonce[account],\n \"Gateway: nonce is lower than current account nonce\"\n );\n\n address sender = _hashDelegatedBatchWithGasPrice(\n account,\n nonce,\n to,\n data,\n tx.gasprice\n ).recoverAddress(senderSignature);\n\n accountNonce[account] = nonce;\n\n _sendBatch(\n account,\n sender,\n to,\n data\n );\n }\n\n /**\n * @notice Delegates multiple batches\n * @dev It will revert when all batches fail\n * @param batches array of batches\n * @param revertOnFailure reverts on any error\n */\n function delegateBatches(\n bytes[] memory batches,\n bool revertOnFailure\n )\n public\n {\n require(\n batches.length > 0,\n \"Gateway: cannot delegate empty batches\"\n );\n\n bool anySucceeded;\n\n for (uint256 i = 0; i < batches.length; i++) {\n // solhint-disable-next-line avoid-low-level-calls\n (bool succeeded,) = address(this).call(batches[i]);\n\n if (revertOnFailure) {\n require(\n succeeded,\n \"Gateway: batch reverted\"\n );\n } else if (succeeded && !anySucceeded) {\n anySucceeded = true;\n }\n\n emit BatchDelegated(\n msg.sender,\n batches[i],\n succeeded\n );\n }\n\n if (!anySucceeded) {\n revert(\"Gateway: all batches reverted\");\n }\n }\n\n // public functions (views)\n\n /**\n * @notice Hashes `DelegatedBatch` message payload\n * @param delegatedBatch struct\n * @return hash\n */\n function hashDelegatedBatch(\n DelegatedBatch memory delegatedBatch\n )\n public\n view\n returns (bytes32)\n {\n return _hashDelegatedBatch(\n delegatedBatch.account,\n delegatedBatch.nonce,\n delegatedBatch.to,\n delegatedBatch.data\n );\n }\n\n /**\n * @notice Hashes `DelegatedBatchWithGasPrice` message payload\n * @param delegatedBatch struct\n * @return hash\n */\n function hashDelegatedBatchWithGasPrice(\n DelegatedBatchWithGasPrice memory delegatedBatch\n )\n public\n view\n returns (bytes32)\n {\n return _hashDelegatedBatchWithGasPrice(\n delegatedBatch.account,\n delegatedBatch.nonce,\n delegatedBatch.to,\n delegatedBatch.data,\n delegatedBatch.gasPrice\n );\n }\n\n // external functions (views)\n\n /**\n * @notice Gets next account nonce\n * @param account account address\n * @return next nonce\n */\n function getAccountNextNonce(\n address account\n )\n external\n view\n returns (uint256)\n {\n return accountNonce[account].add(1);\n }\n\n // private functions\n\n function _sendBatch(\n address account,\n address sender,\n address[] memory to,\n bytes[] memory data\n )\n private\n {\n require(\n account != address(0),\n \"Gateway: cannot send from 0x0 account\"\n );\n require(\n to.length > 0,\n \"Gateway: cannot send empty batch\"\n );\n require(\n data.length == to.length,\n \"Gateway: invalid batch\"\n );\n\n if (account != sender) {\n require(\n personalAccountRegistry.verifyAccountOwner(account, sender) ||\n externalAccountRegistry.verifyAccountOwner(account, sender),\n \"Gateway: sender is not the account owner\"\n );\n }\n\n bool succeeded;\n\n for (uint256 i = 0; i < data.length; i++) {\n require(\n to[i] != address(0),\n \"Gateway: cannot send to 0x0\"\n );\n\n // solhint-disable-next-line avoid-low-level-calls\n (succeeded,) = to[i].call(abi.encodePacked(data[i], account, sender));\n\n require(\n succeeded,\n \"Gateway: batch transaction reverted\"\n );\n }\n }\n\n // private functions (views)\n\n function _hashDelegatedBatch(\n address account,\n uint256 nonce,\n address[] memory to,\n bytes[] memory data\n )\n private\n view\n returns (bytes32)\n {\n return _hashMessagePayload(HASH_PREFIX_DELEGATED_BATCH, abi.encodePacked(\n account,\n nonce,\n to,\n _concatBytes(data)\n ));\n }\n\n function _hashDelegatedBatchWithGasPrice(\n address account,\n uint256 nonce,\n address[] memory to,\n bytes[] memory data,\n uint256 gasPrice\n )\n private\n view\n returns (bytes32)\n {\n return _hashMessagePayload(HASH_PREFIX_DELEGATED_BATCH_WITH_GAS_PRICE, abi.encodePacked(\n account,\n nonce,\n to,\n _concatBytes(data),\n gasPrice\n ));\n }\n\n// private functions (pure)\n\n function _concatBytes(bytes[] memory data)\n private\n pure\n returns (bytes memory)\n {\n bytes memory result;\n uint dataLen = data.length;\n\n for (uint i = 0 ; i < dataLen ; i++) {\n result = abi.encodePacked(result, data[i]);\n }\n\n return result;\n }\n}\n" + }, + "src/ens/ENSController.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../common/access/Guarded.sol\";\nimport \"../common/lifecycle/Initializable.sol\";\nimport \"../common/signature/SignatureValidator.sol\";\nimport \"../gateway/GatewayRecipient.sol\";\nimport \"./resolvers/ENSAddressResolver.sol\";\nimport \"./resolvers/ENSNameResolver.sol\";\nimport \"./resolvers/ENSPubKeyResolver.sol\";\nimport \"./resolvers/ENSTextResolver.sol\";\nimport \"./ENSRegistry.sol\";\n\n\n/**\n * @title ENS controller\n *\n * @notice ENS subnode registrar\n *\n * @dev The process of adding root node consists of 3 steps:\n * 1. `submitNode` - should be called from ENS node owner,\n * 2. Change ENS node owner in ENS registry to ENS controller,\n * 3. `verifyNode` - should be called from previous ENS node owner,\n *\n * To register sub node, `msg.sender` need to send valid signature from one of guardian key.\n * Once registration is complete `msg.sender` becoming both node owner and `addr` record value.\n *\n * After registration sub node cannot be replaced.\n *\n * @author Stanisław Głogowski \n */\ncontract ENSController is Guarded, Initializable, SignatureValidator, GatewayRecipient, ENSAddressResolver, ENSNameResolver, ENSPubKeyResolver, ENSTextResolver {\n struct SubNodeRegistration {\n address account;\n bytes32 node;\n bytes32 label;\n }\n\n bytes4 private constant INTERFACE_META_ID = bytes4(keccak256(abi.encodePacked(\"supportsInterface(bytes4)\")));\n\n bytes32 private constant HASH_PREFIX_SUB_NODE_REGISTRATION = keccak256(\n \"SubNodeRegistration(address account,bytes32 node,bytes32 label)\"\n );\n\n ENSRegistry public registry;\n\n mapping(bytes32 => address) public nodeOwners;\n\n // events\n\n /**\n * @dev Emitted when new node is submitted\n * @param node node name hash\n * @param owner owner address\n */\n event NodeSubmitted(\n bytes32 node,\n address owner\n );\n\n /**\n * @dev Emitted when the existing owner is verified\n * @param node node name hash\n */\n event NodeVerified(\n bytes32 node\n );\n\n /**\n * @dev Emitted when new node is released\n * @param node node name hash\n * @param owner owner address\n */\n event NodeReleased(\n bytes32 node,\n address owner\n );\n\n /**\n * @dev Emitted when ENS registry address is changed\n * @param registry registry address\n */\n event RegistryChanged(\n address registry\n );\n\n /**\n * @dev Public constructor\n */\n constructor() public Guarded() Initializable() SignatureValidator() {}\n\n // external functions\n\n /**\n * @notice Initializes `ENSController` contract\n * @param registry_ ENS registry address\n * @param gateway_ gateway address\n */\n function initialize(\n ENSRegistry registry_,\n address[] calldata guardians_,\n address gateway_\n )\n external\n onlyInitializer\n {\n require(\n address(registry_) != address(0),\n \"ENSController: cannot set 0x0 registry\"\n );\n\n registry = registry_;\n\n // Guarded\n _initializeGuarded(guardians_);\n\n // GatewayRecipient\n _initializeGatewayRecipient(gateway_);\n }\n\n /**\n * @notice Sets registry\n * @param registry_ registry address\n */\n function setRegistry(\n ENSRegistry registry_\n )\n external\n onlyGuardian\n {\n require(\n address(registry_) != address(0),\n \"ENSController: cannot set 0x0 registry\"\n );\n\n require(\n registry_ != registry,\n \"ENSController: registry already set\"\n );\n\n registry = registry_;\n\n emit RegistryChanged(\n address(registry)\n );\n }\n\n /**\n * @notice Submits node\n * @dev Should be called from the current ENS node owner\n * @param node node name hash\n */\n function submitNode(\n bytes32 node\n )\n external\n {\n address owner = _getContextAccount();\n\n require(\n _addr(node) == address(0),\n \"ENSController: node already exists\"\n );\n\n require(\n nodeOwners[node] == address(0),\n \"ENSController: node already submitted\"\n );\n\n require(\n registry.owner(node) == owner,\n \"ENSController: invalid ens node owner\"\n );\n\n nodeOwners[node] = owner;\n\n emit NodeSubmitted(node, owner);\n }\n\n /**\n * @notice Verifies node\n * @dev Should be called from the previous ENS node owner\n * @param node node name hash\n */\n function verifyNode(\n bytes32 node\n )\n external\n {\n address owner = _getContextAccount();\n\n require(\n _addr(node) == address(0),\n \"ENSController: node already exists\"\n );\n\n require(\n nodeOwners[node] == owner,\n \"ENSController: invalid node owner\"\n );\n\n require(\n registry.owner(node) == address(this),\n \"ENSController: invalid ens node owner\"\n );\n\n _setAddr(node, address(this));\n\n registry.setResolver(node, address(this));\n\n emit NodeVerified(node);\n }\n\n /**\n * @notice Releases node\n * @dev Should be called from the previous ENS node owner\n * @param node node name hash\n */\n function releaseNode(\n bytes32 node\n )\n external\n {\n address owner = _getContextAccount();\n\n require(\n _addr(node) == address(this),\n \"ENSController: node doesn't exist\"\n );\n\n require(\n nodeOwners[node] == owner,\n \"ENSController: invalid node owner\"\n );\n\n registry.setOwner(node, owner);\n\n delete nodeOwners[node];\n\n emit NodeReleased(node, owner);\n }\n\n /**\n * @notice Sync address\n * @param node node name hash\n */\n function syncAddr(\n bytes32 node\n )\n external\n {\n address account = _getContextAccount();\n\n require(\n account == registry.owner(node),\n \"ENSController: caller is not the node owner\"\n );\n\n require(\n registry.resolver(node) == address(this),\n \"ENSController: invalid node resolver\"\n );\n\n require(\n _addr(node) == address(0),\n \"ENSController: node already in sync\"\n );\n\n _setAddr(node, account);\n }\n\n /**\n * @notice Registers sub node\n * @param node node name hash\n * @param label label hash\n * @param guardianSignature guardian signature\n */\n function registerSubNode(\n bytes32 node,\n bytes32 label,\n bytes calldata guardianSignature\n )\n external\n {\n address account = _getContextAccount();\n\n bytes32 messageHash = _hashSubNodeRegistration(\n account,\n node,\n label\n );\n\n require(\n _verifyGuardianSignature(messageHash, guardianSignature),\n \"ENSController: invalid guardian signature\"\n );\n\n bytes32 subNode = keccak256(\n abi.encodePacked(\n node,\n label\n )\n );\n\n require(\n _addr(node) == address(this),\n \"ENSController: invalid node\"\n );\n\n require(\n _addr(subNode) == address(0),\n \"ENSController: label already taken\"\n );\n\n registry.setSubnodeRecord(node, label, address(this), address(this), 0);\n registry.setOwner(subNode, account);\n\n _setAddr(subNode, account);\n }\n\n // external functions (pure)\n function supportsInterface(\n bytes4 interfaceID\n )\n external\n pure\n returns(bool)\n {\n return interfaceID == INTERFACE_META_ID ||\n interfaceID == INTERFACE_ADDR_ID ||\n interfaceID == INTERFACE_ADDRESS_ID ||\n interfaceID == INTERFACE_NAME_ID ||\n interfaceID == INTERFACE_PUB_KEY_ID ||\n interfaceID == INTERFACE_TEXT_ID;\n }\n\n // public functions (views)\n\n /**\n * @notice Hashes `SubNodeRegistration` message payload\n * @param subNodeRegistration struct\n * @return hash\n */\n function hashSubNodeRegistration(\n SubNodeRegistration memory subNodeRegistration\n )\n public\n view\n returns (bytes32)\n {\n return _hashSubNodeRegistration(\n subNodeRegistration.account,\n subNodeRegistration.node,\n subNodeRegistration.label\n );\n }\n\n // internal functions (views)\n\n function _isNodeOwner(\n bytes32 node\n )\n internal\n override\n view\n returns (bool)\n {\n return registry.owner(node) == _getContextAccount();\n }\n\n // private functions (views)\n\n function _hashSubNodeRegistration(\n address account,\n bytes32 node,\n bytes32 label\n )\n private\n view\n returns (bytes32)\n {\n return _hashMessagePayload(HASH_PREFIX_SUB_NODE_REGISTRATION, abi.encodePacked(\n account,\n node,\n label\n ));\n }\n}\n" + }, + "src/ens/resolvers/ENSAddressResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"./ENSAbstractResolver.sol\";\n\n\n/**\n * @title ENS abstract address resolver\n *\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/AddrResolver.sol\n */\nabstract contract ENSAddressResolver is ENSAbstractResolver {\n bytes4 internal constant INTERFACE_ADDR_ID = bytes4(keccak256(abi.encodePacked(\"addr(bytes32)\")));\n bytes4 internal constant INTERFACE_ADDRESS_ID = bytes4(keccak256(abi.encodePacked(\"addr(bytes32,uint)\")));\n\n uint internal constant COIN_TYPE_ETH = 60;\n\n mapping(bytes32 => mapping(uint => bytes)) internal resolverAddresses;\n\n // events\n\n event AddrChanged(\n bytes32 indexed node,\n address addr\n );\n\n event AddressChanged(\n bytes32 indexed node,\n uint coinType,\n bytes newAddress\n );\n\n // external functions\n\n function setAddr(\n bytes32 node,\n address addr_\n )\n external\n onlyNodeOwner(node)\n {\n _setAddr(node, addr_);\n }\n\n function setAddr(\n bytes32 node,\n uint coinType,\n bytes memory addr_\n )\n external\n onlyNodeOwner(node)\n {\n _setAddr(node, coinType, addr_);\n }\n\n // external functions (views)\n\n function addr(\n bytes32 node\n )\n external\n view\n returns (address)\n {\n return _addr(node);\n }\n\n function addr(\n bytes32 node,\n uint coinType\n )\n external\n view\n returns (bytes memory)\n {\n return resolverAddresses[node][coinType];\n }\n\n // internal functions\n\n function _setAddr(\n bytes32 node,\n address addr_\n )\n internal\n {\n _setAddr(node, COIN_TYPE_ETH, _addressToBytes(addr_));\n }\n\n function _setAddr(\n bytes32 node,\n uint coinType,\n bytes memory addr_\n )\n internal\n {\n emit AddressChanged(node, coinType, addr_);\n\n if(coinType == COIN_TYPE_ETH) {\n emit AddrChanged(node, _bytesToAddress(addr_));\n }\n\n resolverAddresses[node][coinType] = addr_;\n }\n\n // internal functions (views)\n\n function _addr(\n bytes32 node\n )\n internal\n view\n returns (address)\n {\n address result;\n\n bytes memory addr_ = resolverAddresses[node][COIN_TYPE_ETH];\n\n if (addr_.length > 0) {\n result = _bytesToAddress(addr_);\n }\n\n return result;\n }\n\n // private function (pure)\n\n function _bytesToAddress(\n bytes memory data\n )\n private\n pure\n returns(address payable)\n {\n address payable result;\n\n require(data.length == 20);\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := div(mload(add(data, 32)), exp(256, 12))\n }\n\n return result;\n }\n\n function _addressToBytes(\n address addr_\n )\n private\n pure\n returns(bytes memory)\n {\n bytes memory result = new bytes(20);\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(add(result, 32), mul(addr_, exp(256, 12)))\n }\n\n return result;\n }\n}\n" + }, + "src/ens/resolvers/ENSNameResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"./ENSAbstractResolver.sol\";\n\n\n/**\n * @title ENS abstract name resolver\n *\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/NameResolver.sol\n */\nabstract contract ENSNameResolver is ENSAbstractResolver {\n bytes4 internal constant INTERFACE_NAME_ID = bytes4(keccak256(abi.encodePacked(\"name(bytes32)\")));\n\n mapping(bytes32 => string) internal resolverNames;\n\n // events\n\n event NameChanged(\n bytes32 indexed node,\n string name\n );\n\n // external functions\n\n function setName(\n bytes32 node,\n string calldata name\n )\n external\n onlyNodeOwner(node)\n {\n resolverNames[node] = name;\n\n emit NameChanged(node, name);\n }\n\n // external functions (views)\n\n function name(\n bytes32 node\n )\n external\n view\n returns (string memory)\n {\n return resolverNames[node];\n }\n}\n" + }, + "src/ens/resolvers/ENSPubKeyResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"./ENSAbstractResolver.sol\";\n\n\n/**\n * @title ENS abstract pub key resolver\n *\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/PubkeyResolver.sol\n */\nabstract contract ENSPubKeyResolver is ENSAbstractResolver {\n bytes4 internal constant INTERFACE_PUB_KEY_ID = bytes4(keccak256(abi.encodePacked(\"pubkey(bytes32)\")));\n\n struct PubKey {\n bytes32 x;\n bytes32 y;\n }\n\n mapping(bytes32 => PubKey) internal resolverPubKeys;\n\n // events\n\n event PubkeyChanged(\n bytes32 indexed node,\n bytes32 x,\n bytes32 y\n );\n\n // external functions (views)\n\n function setPubkey(\n bytes32 node,\n bytes32 x,\n bytes32 y\n )\n external\n onlyNodeOwner(node)\n {\n resolverPubKeys[node] = PubKey(x, y);\n\n emit PubkeyChanged(node, x, y);\n }\n\n // external functions (views)\n\n function pubkey(\n bytes32 node\n )\n external\n view\n returns (bytes32 x, bytes32 y)\n {\n return (resolverPubKeys[node].x, resolverPubKeys[node].y);\n }\n}\n" + }, + "src/ens/resolvers/ENSTextResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"./ENSAbstractResolver.sol\";\n\n\n/**\n * @title ENS abstract text resolver\n *\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/profiles/TextResolver.sol\n */\nabstract contract ENSTextResolver is ENSAbstractResolver {\n bytes4 internal constant INTERFACE_TEXT_ID = bytes4(keccak256(abi.encodePacked(\"text(bytes32,string)\")));\n\n mapping(bytes32 => mapping(string => string)) internal resolverTexts;\n\n // events\n\n event TextChanged(\n bytes32 indexed node,\n string indexed indexedKey,\n string key\n );\n\n // external functions (views)\n\n function setText(\n bytes32 node,\n string calldata key,\n string calldata value\n )\n external\n onlyNodeOwner(node)\n {\n resolverTexts[node][key] = value;\n\n emit TextChanged(node, key, key);\n }\n\n // external functions (views)\n\n function text(\n bytes32 node,\n string calldata key\n )\n external\n view\n returns (string memory)\n {\n return resolverTexts[node][key];\n }\n}\n" + }, + "src/ens/ENSRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title ENS registry\n *\n * @dev Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ENSRegistry.sol\n */\ncontract ENSRegistry {\n struct Record {\n address owner;\n address resolver;\n uint64 ttl;\n }\n\n mapping (bytes32 => Record) private records;\n mapping (address => mapping(address => bool)) private operators;\n\n // events\n\n event NewOwner(\n bytes32 indexed node,\n bytes32 indexed label,\n address owner\n );\n\n event Transfer(\n bytes32 indexed node,\n address owner\n );\n\n event NewResolver(\n bytes32 indexed node,\n address resolver\n );\n\n event NewTTL(\n bytes32 indexed node,\n uint64 ttl\n );\n\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n // modifiers\n\n modifier authorised(\n bytes32 node\n )\n {\n address owner = records[node].owner;\n\n require(\n owner == msg.sender || operators[owner][msg.sender],\n \"ENSRegistry: reverted by authorised modifier\"\n );\n\n _;\n }\n\n /**\n * @dev Public constructor\n */\n constructor()\n public\n {\n // solhint-disable-next-line avoid-tx-origin\n records[0x0].owner = tx.origin;\n }\n\n // external functions\n\n function setRecord(\n bytes32 node,\n address owner_,\n address resolver_,\n uint64 ttl_\n )\n external\n {\n setOwner(node, owner_);\n\n _setResolverAndTTL(node, resolver_, ttl_);\n }\n\n function setTTL(\n bytes32 node,\n uint64 ttl_\n )\n external\n authorised(node)\n {\n records[node].ttl = ttl_;\n\n emit NewTTL(node, ttl_);\n }\n\n function setSubnodeRecord(\n bytes32 node,\n bytes32 label,\n address owner_,\n address resolver_,\n uint64 ttl_\n )\n external\n {\n bytes32 subNode = setSubnodeOwner(node, label, owner_);\n\n _setResolverAndTTL(subNode, resolver_, ttl_);\n }\n\n function setApprovalForAll(\n address operator,\n bool approved\n )\n external\n {\n operators[msg.sender][operator] = approved;\n\n emit ApprovalForAll(\n msg.sender,\n operator,\n approved\n );\n }\n\n // external functions (views)\n\n function owner(\n bytes32 node\n )\n external\n view\n returns (address)\n {\n address addr = records[node].owner;\n\n if (addr == address(this)) {\n return address(0x0);\n }\n\n return addr;\n }\n\n function resolver(\n bytes32 node\n )\n external\n view\n returns (address)\n {\n return records[node].resolver;\n }\n\n function ttl(\n bytes32 node\n )\n external\n view\n returns (uint64)\n {\n return records[node].ttl;\n }\n\n function recordExists(\n bytes32 node\n )\n external\n view\n returns (bool)\n {\n return records[node].owner != address(0x0);\n }\n\n function isApprovedForAll(\n address owner_,\n address operator\n )\n external\n view\n returns (bool)\n {\n return operators[owner_][operator];\n }\n\n // public functions\n\n function setOwner(\n bytes32 node,\n address owner_\n )\n public\n authorised(node)\n {\n records[node].owner = owner_;\n\n emit Transfer(node, owner_);\n }\n\n function setResolver(\n bytes32 node,\n address resolver_\n )\n public\n authorised(node)\n {\n records[node].resolver = resolver_;\n\n emit NewResolver(node, resolver_);\n }\n\n function setSubnodeOwner(\n bytes32 node,\n bytes32 label,\n address owner_\n )\n public\n authorised(node)\n returns(bytes32)\n {\n bytes32 subNode = keccak256(abi.encodePacked(node, label));\n\n records[subNode].owner = owner_;\n\n emit NewOwner(node, label, owner_);\n\n return subNode;\n }\n\n // private functions\n\n function _setResolverAndTTL(\n bytes32 node,\n address resolver_,\n uint64 ttl_\n )\n private\n {\n if (resolver_ != records[node].resolver) {\n records[node].resolver = resolver_;\n\n emit NewResolver(node, resolver_);\n }\n\n if (ttl_ != records[node].ttl) {\n records[node].ttl = ttl_;\n\n emit NewTTL(node, ttl_);\n }\n }\n}\n" + }, + "src/ens/resolvers/ENSAbstractResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title ENS abstract resolver\n *\n * @dev Base on https://github.com/ensdomains/resolvers/blob/f7d62ab04bfe1692a4344f6f1d31ff81315a98c3/contracts/ResolverBase.sol\n */\nabstract contract ENSAbstractResolver {\n // modifiers\n\n modifier onlyNodeOwner(bytes32 node)\n {\n require(\n _isNodeOwner(node),\n \"ENSAbstractResolver: reverted by onlyNodeOwner modifier\"\n );\n\n _;\n }\n\n // internal functions (views)\n\n function _isNodeOwner(\n bytes32 node\n )\n internal\n virtual\n view\n returns (bool);\n}\n" + }, + "src/ens/ENSReverseRegistrar.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../common/libs/AddressLib.sol\";\nimport \"../common/lifecycle/Initializable.sol\";\nimport \"./resolvers/ENSNameResolver.sol\";\nimport \"./ENSRegistry.sol\";\n\n/**\n * @title ENS reverse registrar\n *\n * @dev Base on https://github.com/ensdomains/ens/blob/ff0f41747c05f1598973b0fe7ad0d9e09565dfcd/contracts/ReverseRegistrar.sol\n */\ncontract ENSReverseRegistrar is Initializable {\n using AddressLib for address;\n\n // namehash('addr.reverse')\n bytes32 public constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;\n\n ENSRegistry public registry;\n ENSNameResolver public resolver;\n\n /**\n * @dev Public constructor\n */\n constructor() public Initializable() {}\n\n // external functions\n\n /**\n * @notice Initializes `ENSReverseRegistrar` contract\n * @param registry_ ENS registry address\n * @param resolver_ ENS name resolver address\n */\n function initialize(\n ENSRegistry registry_,\n ENSNameResolver resolver_\n )\n external\n onlyInitializer\n {\n registry = registry_;\n resolver = resolver_;\n }\n\n // external functions\n\n function claim(\n address owner\n )\n public\n returns (bytes32)\n {\n return _claimWithResolver(owner, address(0));\n }\n\n function claimWithResolver(\n address owner,\n address resolver_\n )\n public\n returns (bytes32)\n {\n return _claimWithResolver(owner, resolver_);\n }\n\n function setName(\n string memory name\n )\n public\n returns (bytes32)\n {\n bytes32 node = _claimWithResolver(address(this), address(resolver));\n\n resolver.setName(node, name);\n\n return node;\n }\n\n // external functions (pure)\n\n function node(\n address addr_\n )\n external\n pure\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(ADDR_REVERSE_NODE, addr_.toSha3Hash()));\n }\n\n // private functions\n\n function _claimWithResolver(\n address owner,\n address resolver_\n )\n private\n returns (bytes32)\n {\n bytes32 label = address(msg.sender).toSha3Hash();\n bytes32 node_ = keccak256(abi.encodePacked(ADDR_REVERSE_NODE, label));\n address currentOwner = registry.owner(node_);\n\n if (resolver_ != address(0x0) && resolver_ != registry.resolver(node_)) {\n if (currentOwner != address(this)) {\n registry.setSubnodeOwner(ADDR_REVERSE_NODE, label, address(this));\n currentOwner = address(this);\n }\n\n registry.setResolver(node_, resolver_);\n }\n\n // Update the owner if required\n if (currentOwner != owner) {\n registry.setSubnodeOwner(ADDR_REVERSE_NODE, label, owner);\n }\n\n return node_;\n }\n}\n" + }, + "src/common/libs/AddressLib.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title Address library\n */\nlibrary AddressLib {\n /**\n * @notice Converts address into sha3 hash\n * @param self address\n * @return sha3 hash\n */\n function toSha3Hash(\n address self\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 result;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let lookup := 0x3031323334353637383961626364656600000000000000000000000000000000\n\n for { let i := 40 } gt(i, 0) { } {\n i := sub(i, 1)\n mstore8(i, byte(and(self, 0xf), lookup))\n self := div(self, 0x10)\n i := sub(i, 1)\n mstore8(i, byte(and(self, 0xf), lookup))\n self := div(self, 0x10)\n }\n\n result := keccak256(0, 40)\n }\n\n return result;\n }\n}\n" + }, + "src/ens/ENSHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../common/lifecycle/Initializable.sol\";\nimport \"./resolvers/ENSAddressResolver.sol\";\nimport \"./resolvers/ENSNameResolver.sol\";\nimport \"./ENSRegistry.sol\";\n\n/**\n * @title ENS helper\n *\n * @author Stanisław Głogowski \n */\ncontract ENSHelper is Initializable {\n ENSRegistry public registry;\n\n /**\n * @dev Public constructor\n */\n constructor() public Initializable() {}\n\n // external functions\n\n /**\n * @notice Initializes `ENSLookupHelper` contract\n * @param registry_ ENS registry address\n */\n function initialize(\n ENSRegistry registry_\n )\n external\n onlyInitializer\n {\n registry = registry_;\n }\n\n // external functions (views)\n\n /**\n * @notice Gets nodes addresses\n * @param nodes array of nodes\n * @return nodes addresses\n */\n function getAddresses(\n bytes32[] memory nodes\n )\n external\n view\n returns (address[] memory)\n {\n uint nodesLen = nodes.length;\n address[] memory result = new address[](nodesLen);\n\n for (uint i = 0; i < nodesLen; i++) {\n result[i] = _getAddress(nodes[i]);\n }\n\n return result;\n }\n\n /**\n * @notice Gets nodes names\n * @param nodes array of nodes\n * @return nodes names\n */\n function getNames(\n bytes32[] memory nodes\n )\n external\n view\n returns (string[] memory)\n {\n uint nodesLen = nodes.length;\n string[] memory result = new string[](nodesLen);\n\n for (uint i = 0; i < nodesLen; i++) {\n result[i] = _getName(nodes[i]);\n }\n\n return result;\n }\n\n // private functions (views)\n\n function _getAddress(\n bytes32 node\n )\n private\n view\n returns (address)\n {\n address result;\n address resolver = registry.resolver(node);\n\n if (resolver != address(0)) {\n try ENSAddressResolver(resolver).addr(node) returns (address addr) {\n result = addr;\n } catch {\n //\n }\n }\n\n return result;\n }\n\n function _getName(\n bytes32 node\n )\n private\n view\n returns (string memory)\n {\n string memory result;\n address resolver = registry.resolver(node);\n\n if (resolver != address(0)) {\n try ENSNameResolver(resolver).name(node) returns (string memory name) {\n result = name;\n } catch {\n //\n }\n }\n\n return result;\n }\n}\n" + }, + "src/common/access/mocks/GuardedMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../Guarded.sol\";\n\n\n/**\n * @title Guarded mock\n *\n * @dev Used in `Guarded` contract tests\n *\n * @author Stanisław Głogowski \n */\ncontract GuardedMock is Guarded {\n /**\n * @dev Public constructor\n * @param guardians_ array of guardians addresses\n */\n constructor(\n address[] memory guardians_\n )\n public\n {\n _initializeGuarded(guardians_);\n }\n}\n" + }, + "src/common/account/mocks/AccountRegistryMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../../libs/ECDSALib.sol\";\nimport \"../../libs/ECDSAExtendedLib.sol\";\nimport \"../AccountRegistry.sol\";\n\n\n/**\n * @title Account registry mock\n *\n * @author Stanisław Głogowski \n */\ncontract AccountRegistryMock is AccountRegistry {\n using ECDSALib for bytes32;\n using ECDSAExtendedLib for bytes;\n\n mapping(address => mapping(address => bool)) private mockedAccountsOwners;\n\n // external functions\n\n function mockAccountOwners(\n address account,\n address[] memory owners\n )\n external\n {\n uint ownersLen = owners.length;\n for (uint i = 0; i < ownersLen; i++) {\n mockedAccountsOwners[account][owners[i]] = true;\n }\n }\n\n // external functions (views)\n\n function isValidAccountSignature(\n address account,\n bytes32 messageHash,\n bytes calldata signature\n )\n override\n external\n view\n returns (bool)\n {\n address recovered = messageHash.recoverAddress(signature);\n\n return mockedAccountsOwners[account][recovered];\n }\n\n function isValidAccountSignature(\n address account,\n bytes calldata message,\n bytes calldata signature\n )\n override\n external\n view\n returns (bool)\n {\n address recovered = message.toEthereumSignedMessageHash().recoverAddress(signature);\n\n return mockedAccountsOwners[account][recovered];\n }\n}\n" + }, + "src/common/account/mocks/AccountControllerMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../AccountController.sol\";\n\n\n/**\n * @title Account controller mock\n *\n * @author Stanisław Głogowski \n */\ncontract AccountControllerMock is AccountController {\n /**\n * @dev Public constructor\n * @param accountRegistry_ account registry address\n * @param accountImplementation_ account implementation address\n */\n constructor(\n address accountRegistry_,\n address accountImplementation_\n )\n public\n AccountController()\n {\n _initializeAccountController(accountRegistry_, accountImplementation_);\n }\n\n // external functions\n\n /**\n * @notice Sets account registry\n * @param accountRegistry_ account registry address\n */\n function setAccountRegistry(\n address accountRegistry_\n )\n external\n {\n _setAccountRegistry(accountRegistry_, true);\n }\n\n /**\n * @notice Sets account implementation\n * @param accountImplementation_ account implementation address\n */\n function setAccountImplementation(\n address accountImplementation_\n )\n external\n {\n _setAccountImplementation(accountImplementation_, true);\n }\n\n /**\n * @notice Deploys account\n * @param salt CREATE2 salt\n */\n function deployAccount(\n bytes32 salt\n )\n external\n {\n _deployAccount(salt, true);\n }\n\n /**\n * @notice Upgrades account\n * @param account account address\n */\n function upgradeAccount(\n address account\n )\n external\n {\n _upgradeAccount(account, true);\n }\n\n /**\n * @notice Executes transaction from the account\n * @param account account address\n * @param to to address\n * @param value value\n * @param data data\n */\n function executeAccountTransaction(\n address account,\n address to,\n uint256 value,\n bytes memory data\n )\n external\n {\n _executeAccountTransaction(account, to, value, data, true);\n }\n\n // external functions (views)\n\n /**\n * @notice Computes account CREATE2 address\n * @param salt CREATE2 salt\n * @return account address\n */\n function computeAccountAddress(\n bytes32 salt\n )\n external\n view\n returns (address)\n {\n return _computeAccountAddress(salt);\n }\n}\n" + }, + "src/common/account/AccountImplementationV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../lifecycle/Initializable.sol\";\nimport \"./AccountBase.sol\";\nimport \"./AccountRegistry.sol\";\n\n\n/**\n * @title Account implementation (version 1)\n *\n * @author Stanisław Głogowski \n */\ncontract AccountImplementationV1 is Initializable, AccountBase {\n bytes32 constant private ERC777_TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(abi.encodePacked(\"ERC777TokensRecipient\"));\n bytes32 constant private ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked(\"ERC1820_ACCEPT_MAGIC\"));\n\n bytes4 constant private ERC1271_VALID_MESSAGE_HASH_SIGNATURE = bytes4(keccak256(abi.encodePacked(\"isValidSignature(bytes32,bytes)\")));\n bytes4 constant private ERC1271_VALID_MESSAGE_SIGNATURE = bytes4(keccak256(abi.encodePacked(\"isValidSignature(bytes,bytes)\")));\n bytes4 constant private ERC1271_INVALID_SIGNATURE = 0xffffffff;\n\n /**\n * @dev Internal constructor\n */\n constructor() internal Initializable() {}\n\n // external functions\n\n /**\n * @notice Initializes `AccountImplementation` contract\n * @param registry_ registry address\n */\n function initialize(\n address registry_\n )\n external\n onlyInitializer\n {\n registry = registry_;\n }\n\n // external functions (views)\n\n // ERC1820\n\n function canImplementInterfaceForAddress(\n bytes32 interfaceHash,\n address addr\n )\n external\n view\n returns(bytes32)\n {\n bytes32 result;\n\n if (interfaceHash == ERC777_TOKENS_RECIPIENT_INTERFACE_HASH && addr == address(this)) {\n result = ERC1820_ACCEPT_MAGIC;\n }\n\n return result;\n }\n\n // ERC1271\n\n function isValidSignature(\n bytes32 messageHash,\n bytes calldata signature\n )\n external\n view\n returns (bytes4)\n {\n return AccountRegistry(registry).isValidAccountSignature(address(this), messageHash, signature)\n ? ERC1271_VALID_MESSAGE_HASH_SIGNATURE\n : ERC1271_INVALID_SIGNATURE;\n }\n\n function isValidSignature(\n bytes calldata message,\n bytes calldata signature\n )\n external\n view\n returns (bytes4)\n {\n return AccountRegistry(registry).isValidAccountSignature(address(this), message, signature)\n ? ERC1271_VALID_MESSAGE_SIGNATURE\n : ERC1271_INVALID_SIGNATURE;\n }\n\n // external functions (pure)\n\n // ERC721\n\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n )\n external\n pure\n returns (bytes4)\n {\n return this.onERC721Received.selector;\n }\n\n // ERC1155\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n pure\n returns (bytes4)\n {\n return this.onERC1155Received.selector;\n }\n\n // ERC777\n\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n )\n external\n pure\n {}\n}\n" + }, + "src/personal/PersonalAccountImplementationV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../common/account/AccountImplementationV1.sol\";\n\n\n/**\n * @title Personal account implementation (version 1)\n *\n * @author Stanisław Głogowski \n */\ncontract PersonalAccountImplementationV1 is AccountImplementationV1 {\n\n /**\n * @dev Public constructor\n */\n constructor() public AccountImplementationV1() {}\n}\n" + }, + "src/common/account/mocks/AccountImplementationV1Mock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../AccountImplementationV1.sol\";\n\n\n/**\n * @title Account implementation mock (version 1)\n *\n * @author Stanisław Głogowski \n */\ncontract AccountImplementationV1Mock is AccountImplementationV1 {\n /**\n * @dev Public constructor\n * @param registry_ account registry address\n */\n constructor(\n address registry_\n )\n public\n AccountImplementationV1()\n {\n registry = registry_;\n }\n}\n" + }, + "src/common/helpers/BalancesHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../token/ERC20Token.sol\";\nimport \"../libs/SafeMathLib.sol\";\n\n\n/**\n * @title Balances helper\n *\n * @author Jegor Sidorenko \n * @author Stanisław Głogowski \n */\ncontract BalancesHelper {\n using SafeMathLib for uint256;\n\n // external functions\n\n /**\n * @notice Checks the token balances of accounts for multiple tokens.\n * @dev Pass 0x0 as a \"token\" address to get ETH balance.\n *\n * Possible error throws:\n * - extremely large arrays for account and or tokens (gas cost too high)\n *\n * @param accounts array of accounts addresses\n * @param tokens array of tokens addresses\n * @return a one-dimensional that's user.length * tokens.length long. The\n * array is ordered by all of the 0th accounts token balances, then the 1th\n * user, and so on.\n */\n function getBalances(\n address[] calldata accounts,\n address[] calldata tokens\n )\n external\n view\n returns (uint[] memory)\n {\n uint[] memory result = new uint[](accounts.length.mul(tokens.length));\n\n for (uint i = 0; i < accounts.length; i++) {\n for (uint j = 0; j < tokens.length; j++) {\n uint index = j.add(tokens.length.mul(i));\n\n if (tokens[j] != address(0x0)) {\n result[index] = _getBalance(accounts[i], tokens[j]);\n } else {\n result[index] = accounts[i].balance;\n }\n }\n }\n\n return result;\n }\n\n // private functions\n\n function _getBalance(\n address account,\n address token\n )\n private\n view\n returns (uint256)\n {\n uint256 result = 0;\n uint256 tokenCode;\n\n /// @dev check if token is actually a contract\n // solhint-disable-next-line no-inline-assembly\n assembly { tokenCode := extcodesize(token) } // contract code size\n\n if (tokenCode > 0) {\n /// @dev is it a contract and does it implement balanceOf\n // solhint-disable-next-line avoid-low-level-calls\n (bool methodExists,) = token.staticcall(abi.encodeWithSelector(\n ERC20Token(token).balanceOf.selector,\n account\n ));\n\n if (methodExists) {\n result = ERC20Token(token).balanceOf(account);\n }\n }\n\n return result;\n }\n}\n" + }, + "src/gateway/mocks/GatewayRecipientMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../GatewayRecipient.sol\";\n\n\n/**\n * @title Gateway recipient mock\n *\n * @dev Used in `GatewayRecipient` contract tests\n *\n * @author Stanisław Głogowski \n */\ncontract GatewayRecipientMock is GatewayRecipient {\n // events\n\n event Context(\n address account,\n address sender,\n bytes data\n );\n\n /**\n * @dev Public constructor\n * @param gateway_ `Gateway` contract address\n */\n constructor(\n address gateway_\n )\n public\n {\n _initializeGatewayRecipient(gateway_);\n }\n\n function emitContext()\n external\n {\n emit Context(\n _getContextAccount(),\n _getContextSender(),\n _getContextData()\n );\n }\n}\n" + } + }, + "settings": { + "evmVersion": "istanbul", + "metadata": { + "bytecodeHash": "none", + "useLiteralContent": true + }, + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/solcInputs/82f81c73c615e1d8d0ff013db621d6da.json b/deployments/neonDevnet/solcInputs/82f81c73c615e1d8d0ff013db621d6da.json new file mode 100644 index 00000000..ebdde869 --- /dev/null +++ b/deployments/neonDevnet/solcInputs/82f81c73c615e1d8d0ff013db621d6da.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "src/bridges/facets/StargateFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.4;\n\nimport {IStargateRouter} from \"../interfaces/IStargateRouter.sol\";\nimport {IStargateReceiver} from \"../interfaces/IStargateReceiver.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {ReentrancyGuard} from \"../../common/helpers/DiamondReentrancyGuard.sol\";\nimport {CannotBridgeToSameNetwork, InvalidAmount, InvalidConfig} from \"../errors/GenericErrors.sol\";\nimport {SenderNotStargateRouter, NoMsgValueForCrossChainMessage, StargateRouterAddressZero, InvalidSourcePoolId, InvalidDestinationPoolId} from \"../errors/StargateErrors.sol\";\nimport {LibDiamond} from \"../libs/LibDiamond.sol\";\n\n/// @title StargateFacet\n/// @author Luke Wickens \n/// @notice Stargate/LayerZero intergration for bridging tokens\n\ncontract StargateFacet is IStargateReceiver, ReentrancyGuard {\n using SafeERC20 for IERC20;\n\n //////////////////////////////////////////////////////////////\n /////////////////////////// Events ///////////////////////////\n //////////////////////////////////////////////////////////////\n event SGInitialized(address stargate, uint16 chainId);\n event SGTransferStarted(\n string bridgeUsed,\n address fromToken,\n address toToken,\n address from,\n address to,\n uint256 amount,\n uint16 chainIdTo\n );\n event SGReceivedOnDestination(address token, uint256 amount);\n event SGUpdatedRouter(address newAddress);\n event SGUpdatedSlippageTolerance(uint256 newSlippage);\n event SGAddedPool(uint16 chainId, address token, uint16 poolId);\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Storage ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"io.etherspot.facets.stargate\");\n struct Storage {\n address stargateRouter;\n uint16 chainId;\n uint256 dstGas;\n uint256 slippage;\n mapping(uint16 => mapping(address => uint16)) poolIds;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Structs ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n struct StargateData {\n uint256 qty;\n address fromToken;\n address toToken;\n uint16 dstChainId;\n address to;\n address destStargateComposed;\n }\n\n /// @notice initializes state variables for the Stargate facet\n /// @param _stargateRouter - address of the Stargate router contract\n /// @param _chainId - current chain id\n function sgInitialize(address _stargateRouter, uint16 _chainId) external {\n if (_stargateRouter == address(0)) revert InvalidConfig();\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.stargateRouter = address(_stargateRouter);\n s.chainId = _chainId;\n s.slippage = 50; // equates to 0.5%\n // Adding pre-existing pools => USDC: 1, USDT: 2, BUSD: 5\n sgAddPool(1, 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, 1);\n sgAddPool(1, 0xdAC17F958D2ee523a2206206994597C13D831ec7, 2);\n sgAddPool(2, 0x55d398326f99059fF775485246999027B3197955, 2);\n sgAddPool(2, 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56, 5);\n sgAddPool(6, 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E, 1);\n sgAddPool(6, 0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7, 2);\n sgAddPool(9, 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174, 1);\n sgAddPool(9, 0xc2132D05D31c914a87C6611C10748AEb04B58e8F, 2);\n sgAddPool(10, 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8, 1);\n sgAddPool(10, 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9, 2);\n sgAddPool(11, 0x7F5c764cBc14f9669B88837ca1490cCa17c31607, 1);\n sgAddPool(12, 0x04068DA6C83AFCFA0e13ba15A6696662335D5B75, 1);\n emit SGInitialized(_stargateRouter, _chainId);\n }\n\n /// @notice initializes state variables for the stargate facet\n /// @param _sgData - struct containing information required to execute bridge\n function sgBridgeTokens(StargateData memory _sgData)\n external\n payable\n nonReentrant\n {\n // if (msg.value <= 0) revert NoMsgValueForCrossChainMessage();\n if (_sgData.qty <= 0) revert InvalidAmount();\n if (\n _sgData.fromToken == address(0) ||\n _sgData.toToken == address(0) ||\n _sgData.to == address(0) ||\n _sgData.destStargateComposed == address(0)\n ) revert InvalidConfig();\n\n // access storage\n Storage storage s = getStorage();\n\n // check pool ids are valid\n uint16 srcPoolId = sgRetrievePoolId(s.chainId, _sgData.fromToken);\n if (srcPoolId == 0) revert InvalidSourcePoolId();\n uint16 dstPoolId = sgRetrievePoolId(\n _sgData.dstChainId,\n _sgData.toToken\n );\n\n // calculate cross chain fees\n uint256 fees = sgCalculateFees(\n _sgData.dstChainId,\n _sgData.to,\n s.stargateRouter\n );\n\n // calculate slippage\n uint256 minAmountOut = sgMinAmountOut(_sgData.qty);\n\n // encode sgReceive implemented\n bytes memory destination = abi.encodePacked(\n _sgData.destStargateComposed\n );\n\n // encode payload data to send to destination contract, which it will handle with sgReceive()\n bytes memory payload = abi.encode(_sgData.to);\n\n // this contract calls stargate swap()\n IERC20(_sgData.fromToken).safeTransferFrom(\n msg.sender,\n address(this),\n _sgData.qty\n );\n\n IERC20(_sgData.fromToken).safeApprove(\n address(s.stargateRouter),\n _sgData.qty\n );\n\n // Stargate's Router.swap() function sends the tokens to the destination chain.\n IStargateRouter(s.stargateRouter).swap{value: fees}(\n _sgData.dstChainId, // the destination chain id\n srcPoolId, // the source Stargate poolId\n dstPoolId, // the destination Stargate poolId\n payable(msg.sender), // refund adddress. if msg.sender pays too much gas, return extra eth\n _sgData.qty, // total tokens to send to destination chain\n minAmountOut, // min amount allowed out\n IStargateRouter.lzTxObj(200000, 0, \"0x\"), // default lzTxObj\n destination, // destination address, the sgReceive() implementer\n payload // bytes payload\n );\n\n emit SGTransferStarted(\n \"stargate\",\n _sgData.fromToken,\n _sgData.toToken,\n msg.sender,\n _sgData.to,\n _sgData.qty,\n _sgData.dstChainId\n );\n }\n\n /// @notice required to receive tokens on destination chain\n /// @param _chainId The remote chainId sending the tokens\n /// @param _srcAddress The remote Bridge address\n /// @param _nonce The message ordering nonce\n /// @param _token The token contract on the local chain\n /// @param amountLD The qty of local _token contract tokens\n /// @param _payload The bytes containing the toAddress\n function sgReceive(\n uint16 _chainId,\n bytes memory _srcAddress,\n uint256 _nonce,\n address _token,\n uint256 amountLD,\n bytes memory _payload\n ) external override {\n Storage storage s = getStorage();\n if (msg.sender != address(s.stargateRouter))\n revert SenderNotStargateRouter();\n\n address _toAddr = abi.decode(_payload, (address));\n IERC20(_token).transfer(_toAddr, amountLD);\n emit SGReceivedOnDestination(_token, amountLD);\n }\n\n /// @notice Calculates cross chain fee\n /// @param _destChain Destination chain id\n /// @param _receiver Receiver on destination chain\n /// @param _router Address of stargate router\n function sgCalculateFees(\n uint16 _destChain,\n address _receiver,\n address _router\n ) public view returns (uint256) {\n (uint256 nativeFee, ) = IStargateRouter(_router).quoteLayerZeroFee(\n _destChain, // destination chain id\n 1, // 1 = swap\n abi.encodePacked(_receiver), // receiver on destination chain\n \"0x\", // payload, using abi.encode()\n IStargateRouter.lzTxObj(200000, 0, \"0x\")\n );\n return nativeFee;\n }\n\n /// @notice Calculates the minimum amount out using slippage tolerance\n /// @param _amount Transfer amount\n function sgMinAmountOut(uint256 _amount) public view returns (uint256) {\n Storage storage s = getStorage();\n // equates to 0.5% slippage\n return (_amount * (10000 - s.slippage)) / (10000);\n }\n\n /// @notice Updates stargate router address for deployed chain\n /// @param _newAddress Address of the new router\n function sgUpdateRouter(address _newAddress) external {\n LibDiamond.enforceIsContractOwner();\n if (_newAddress == address(0)) revert StargateRouterAddressZero();\n Storage storage s = getStorage();\n s.stargateRouter = address(_newAddress);\n emit SGUpdatedRouter(_newAddress);\n }\n\n /// @notice Updates slippage tolerance amount\n /// @param _newSlippage New slippage amount\n function sgUpdateSlippageTolerance(uint256 _newSlippage) external {\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.slippage = _newSlippage;\n emit SGUpdatedSlippageTolerance(_newSlippage);\n }\n\n /// @notice Withdraws tokens on contract\n /// @param _token Address of token\n /// @param _user Address of receiver of tokens\n /// @param _amount Amount to withdraw\n function sgWithdraw(\n address _token,\n address _user,\n uint256 _amount\n ) external payable nonReentrant {\n LibDiamond.enforceIsContractOwner();\n IERC20(_token).safeApprove(address(this), _amount);\n IERC20(_token).safeTransferFrom(address(this), _user, _amount);\n }\n\n /// @notice Adds a new pool for a specific token and chain\n /// @param _chainId Chain id of new pool (NOT actual chain id - check stargate pool ids docs)\n /// @param _token Address of token\n /// @param _poolId Pool id (check stargate pool ids docs)\n function sgAddPool(\n uint16 _chainId,\n address _token,\n uint16 _poolId\n ) public {\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.poolIds[_chainId][_token] = _poolId;\n emit SGAddedPool(_chainId, _token, _poolId);\n }\n\n /// @notice Checks for a valid token pool on specific chain\n /// @param _chainId Chain id of new pool (NOT actual chain id - check stargate pool ids docs)\n /// @param _token Address of token\n /// @param _poolId Pool id (check stargate pool ids docs)\n function sgCheckPoolId(\n uint16 _chainId,\n address _token,\n uint16 _poolId\n ) external view returns (bool) {\n Storage storage s = getStorage();\n return s.poolIds[_chainId][_token] == _poolId ? true : false;\n }\n\n /// @notice Retrieves pool id for a token on a specified chain\n /// @param _chainId Chain id of new pool (NOT actual chain id - check stargate pool ids docs)\n /// @param _token Address of token\n function sgRetrievePoolId(uint16 _chainId, address _token)\n public\n view\n returns (uint16)\n {\n Storage storage s = getStorage();\n return s.poolIds[_chainId][_token];\n }\n\n receive() external payable {}\n\n //////////////////////////////////////////////////////////////\n ////////////////////// Private Functions /////////////////////\n //////////////////////////////////////////////////////////////\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/bridges/interfaces/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier:MIT\n\npragma solidity 0.8.4;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function addLiquidity(\n uint256 _poolId,\n uint256 _amountLD,\n address _to\n ) external;\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n\n function redeemRemote(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLP,\n uint256 _minAmountLD,\n bytes calldata _to,\n lzTxObj memory _lzTxParams\n ) external payable;\n\n function instantRedeemLocal(\n uint16 _srcPoolId,\n uint256 _amountLP,\n address _to\n ) external returns (uint256);\n\n function redeemLocal(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLP,\n bytes calldata _to,\n lzTxObj memory _lzTxParams\n ) external payable;\n\n function sendCredits(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress\n ) external payable;\n\n function quoteLayerZeroFee(\n uint16 _dstChainId,\n uint8 _functionType,\n bytes calldata _toAddress,\n bytes calldata _transferAndCallPayload,\n lzTxObj memory _lzTxParams\n ) external view returns (uint256, uint256);\n}\n" + }, + "src/bridges/interfaces/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.4;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "src/common/helpers/DiamondReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.4;\n\n/// @title Reentrancy Guard\n/// @notice Abstract contract to provide protection against reentrancy\nabstract contract ReentrancyGuard {\n //////////////////////////////////////////////////////////////\n ////////////////////////// Storage ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n bytes32 private constant NAMESPACE =\n keccak256(\"io.etherspot.helpers.reentrancyguard\");\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Structs ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n struct ReentrancyStorage {\n uint256 status;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Errors ////////////////////////////\n //////////////////////////////////////////////////////////////\n\n error ReentrancyError();\n\n //////////////////////////////////////////////////////////////\n ///////////////////////// Constants //////////////////////////\n //////////////////////////////////////////////////////////////\n\n uint256 private constant _NOT_ENTERED = 0;\n uint256 private constant _ENTERED = 1;\n\n //////////////////////////////////////////////////////////////\n ///////////////////////// Modifiers ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n modifier nonReentrant() {\n ReentrancyStorage storage s = reentrancyStorage();\n if (s.status == _ENTERED) revert ReentrancyError();\n s.status = _ENTERED;\n _;\n s.status = _NOT_ENTERED;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////// Private Functions /////////////////////\n //////////////////////////////////////////////////////////////\n\n /// @dev fetch local storage\n function reentrancyStorage()\n private\n pure\n returns (ReentrancyStorage storage data)\n {\n bytes32 position = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n data.slot := position\n }\n }\n}\n" + }, + "src/bridges/errors/GenericErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\nerror InvalidAmount();\nerror TokenAddressIsZero();\nerror CannotBridgeToSameNetwork();\nerror ZeroPostSwapBalance();\nerror InvalidBridgeConfigLength();\nerror NoSwapDataProvided();\nerror NativeValueWithERC();\nerror ContractCallNotAllowed();\nerror NullAddrIsNotAValidSpender();\nerror NullAddrIsNotAnERC20Token();\nerror NoTransferToNullAddress();\nerror NativeAssetTransferFailed();\nerror InvalidContract();\nerror InvalidConfig();\n" + }, + "src/bridges/errors/StargateErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\nerror SenderNotStargateRouter();\nerror NoMsgValueForCrossChainMessage();\nerror StargateRouterAddressZero();\nerror InvalidSourcePoolId();\nerror InvalidDestinationPoolId();\n" + }, + "src/bridges/libs/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport { IDiamondCut } from \"../interfaces/IDiamondCut.sol\";\n\nlibrary LibDiamond {\n bytes32 internal constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, \"LibDiamond: Must be contract owner\");\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress != _facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, \"LibDiamondCut: New facet has no code\");\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n require(_calldata.length == 0, \"LibDiamondCut: _init is address(0) but_calldata is not empty\");\n } else {\n require(_calldata.length > 0, \"LibDiamondCut: _calldata is empty but _init is not address(0)\");\n if (_init != address(this)) {\n enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");\n }\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "src/bridges/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "src/bridges/libs/LibAsset.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\n// solhint-disable-next-line\npragma solidity 0.8.4;\nimport {NullAddrIsNotAnERC20Token, NullAddrIsNotAValidSpender, NoTransferToNullAddress, InvalidAmount, NativeValueWithERC, NativeAssetTransferFailed} from \"../errors/GenericErrors.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title LibAsset\n/// @author Connext \n/// @notice This library contains helpers for dealing with onchain transfers\n/// of assets, including accounting for the native asset `assetId`\n/// conventions and any noncompliant ERC20 transfers\nlibrary LibAsset {\n uint256 private constant MAX_INT = type(uint256).max;\n\n address internal constant NULL_ADDRESS =\n 0x0000000000000000000000000000000000000000; //address(0)\n\n /// @dev All native assets use the empty address for their asset id\n /// by convention\n\n address internal constant NATIVE_ASSETID = NULL_ADDRESS; //address(0)\n\n /// @notice Gets the balance of the inheriting contract for the given asset\n /// @param assetId The asset identifier to get the balance of\n /// @return Balance held by contracts using this library\n function getOwnBalance(address assetId) internal view returns (uint256) {\n return\n assetId == NATIVE_ASSETID\n ? address(this).balance\n : IERC20(assetId).balanceOf(address(this));\n }\n\n /// @notice Transfers ether from the inheriting contract to a given\n /// recipient\n /// @param recipient Address to send ether to\n /// @param amount Amount to send to given recipient\n function transferNativeAsset(address payable recipient, uint256 amount)\n private\n {\n if (recipient == NULL_ADDRESS) revert NoTransferToNullAddress();\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = recipient.call{value: amount}(\"\");\n if (!success) revert NativeAssetTransferFailed();\n }\n\n /// @notice Gives MAX approval for another address to spend tokens\n /// @param assetId Token address to transfer\n /// @param spender Address to give spend approval to\n /// @param amount Amount to approve for spending\n function maxApproveERC20(\n IERC20 assetId,\n address spender,\n uint256 amount\n ) internal {\n if (address(assetId) == NATIVE_ASSETID) return;\n if (spender == NULL_ADDRESS) revert NullAddrIsNotAValidSpender();\n uint256 allowance = assetId.allowance(address(this), spender);\n if (allowance < amount)\n SafeERC20.safeApprove(IERC20(assetId), spender, MAX_INT);\n }\n\n /// @notice Transfers tokens from the inheriting contract to a given\n /// recipient\n /// @param assetId Token address to transfer\n /// @param recipient Address to send token to\n /// @param amount Amount to send to given recipient\n function transferERC20(\n address assetId,\n address recipient,\n uint256 amount\n ) private {\n if (isNativeAsset(assetId)) revert NullAddrIsNotAnERC20Token();\n SafeERC20.safeTransfer(IERC20(assetId), recipient, amount);\n }\n\n /// @notice Transfers tokens from a sender to a given recipient\n /// @param assetId Token address to transfer\n /// @param from Address of sender/owner\n /// @param to Address of recipient/spender\n /// @param amount Amount to transfer from owner to spender\n function transferFromERC20(\n address assetId,\n address from,\n address to,\n uint256 amount\n ) internal {\n if (assetId == NATIVE_ASSETID) revert NullAddrIsNotAnERC20Token();\n if (to == NULL_ADDRESS) revert NoTransferToNullAddress();\n SafeERC20.safeTransferFrom(IERC20(assetId), from, to, amount);\n }\n\n /// @notice Deposits an asset into the contract and performs checks to avoid NativeValueWithERC\n /// @param tokenId Token to deposit\n /// @param amount Amount to deposit\n /// @param isNative Wether the token is native or ERC20\n function depositAsset(\n address tokenId,\n uint256 amount,\n bool isNative\n ) internal {\n if (amount == 0) revert InvalidAmount();\n if (isNative) {\n if (msg.value != amount) revert InvalidAmount();\n } else {\n if (msg.value != 0) revert NativeValueWithERC();\n uint256 _fromTokenBalance = LibAsset.getOwnBalance(tokenId);\n LibAsset.transferFromERC20(\n tokenId,\n msg.sender,\n address(this),\n amount\n );\n if (LibAsset.getOwnBalance(tokenId) - _fromTokenBalance != amount)\n revert InvalidAmount();\n }\n }\n\n /// @notice Overload for depositAsset(address tokenId, uint256 amount, bool isNative)\n /// @param tokenId Token to deposit\n /// @param amount Amount to deposit\n function depositAsset(address tokenId, uint256 amount) internal {\n return depositAsset(tokenId, amount, tokenId == NATIVE_ASSETID);\n }\n\n /// @notice Determines whether the given assetId is the native asset\n /// @param assetId The asset identifier to evaluate\n /// @return Boolean indicating if the asset is the native asset\n function isNativeAsset(address assetId) internal pure returns (bool) {\n return assetId == NATIVE_ASSETID;\n }\n\n /// @notice Wrapper function to transfer a given asset (native or erc20) to\n /// some recipient. Should handle all non-compliant return value\n /// tokens as well by using the SafeERC20 contract by open zeppelin.\n /// @param assetId Asset id for transfer (address(0) for native asset,\n /// token address for erc20s)\n /// @param recipient Address to send asset to\n /// @param amount Amount to send to given recipient\n function transferAsset(\n address assetId,\n address payable recipient,\n uint256 amount\n ) internal {\n (assetId == NATIVE_ASSETID)\n ? transferNativeAsset(recipient, amount)\n : transferERC20(assetId, recipient, amount);\n }\n\n /// @dev Checks whether the given address is a contract and contains code\n function isContract(address _contractAddr) internal view returns (bool) {\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n size := extcodesize(_contractAddr)\n }\n return size > 0;\n }\n}\n" + }, + "src/common/helpers/BalancesHelperV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\n/// @title BalancesHelperV2\n/// @author Luke Wickens \n/// @notice Used to get account balances of ERC20 tokens and Wrapped Super Tokens\n\nimport {ISuperfluidToken} from \"@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluidToken.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\ncontract BalancesHelperV2 {\n using Address for address;\n\n /// @notice Custom errors to handle address(0)\n error AccountZeroAddress(address account, address token);\n error TokenZeroAddress(address account, address token);\n\n constructor() {}\n\n /// @notice Returns balances of accounts for multiple ERC20 tokens.\n /// @dev Error thrown if: account or token address is address(0),\n /// large arrays of accounts/tokens are passed in could cause gas block limit issue\n /// @param accounts = Array of accounts addresses\n /// @param tokens = Array of tokens addresses\n /// @return One-dimensional that's accounts.length * tokens.length long. The\n /// array is ordered by all of accounts[0] token balances, then accounts[1] etc.\n\n function getBalances(address[] calldata accounts, address[] calldata tokens)\n external\n view\n returns (uint256[] memory)\n {\n uint256[] memory result = new uint256[](\n accounts.length * tokens.length\n );\n\n for (uint256 i; i < accounts.length; i++) {\n for (uint256 j; j < tokens.length; j++) {\n uint256 index = j + (tokens.length * i);\n result[index] = _getBalance(accounts[i], tokens[j]);\n }\n }\n return result;\n }\n\n /// @notice Returns balances of accounts for multiple Wrapped Super Tokens.\n /// @dev Error thrown if: account or token address is address(0),\n /// large arrays of accounts/tokens are passed in could cause gas block limit issue\n /// @param accounts = Array of accounts addresses\n /// @param tokens = Array of tokens addresses\n /// @return One-dimensional that's accounts.length * tokens.length long. The\n /// array is ordered by all of accounts[0] token balances, then accounts[1] etc.\n\n function getSuperfluidWrappedTokenBalances(\n address[] calldata accounts,\n address[] calldata tokens\n ) external view returns (int256[] memory) {\n int256[] memory result = new int256[](accounts.length * tokens.length);\n\n for (uint256 i; i < accounts.length; i++) {\n for (uint256 j; j < tokens.length; j++) {\n uint256 index = j + (tokens.length * i);\n result[index] = _getSuperfluidWrappedTokenBalance(\n accounts[i],\n tokens[j]\n );\n }\n }\n return result;\n }\n\n /// Private fuctions\n\n /// @notice Returns balance of account for an ERC20 token.\n /// @dev Error thrown if: account or token address is address(0)\n /// @param account = account address\n /// @param token = tokens address\n /// @return balance of account as uint256.\n\n function _getBalance(address account, address token)\n private\n view\n returns (uint256)\n {\n if (account == address(0)) revert AccountZeroAddress(account, token);\n if (token == address(0)) revert TokenZeroAddress(account, token);\n\n bytes memory returnedData = token.functionStaticCall(\n abi.encodeWithSelector(IERC20(token).balanceOf.selector, account)\n );\n\n return abi.decode(returnedData, (uint256));\n }\n\n /// @notice Returns real balance of a user, taking into consideration all agreements of account\n /// @dev Error thrown if: account or token address is address(0)\n /// @param account = account address\n /// @param token = tokens address\n /// @return available balance of account as int256.\n\n function _getSuperfluidWrappedTokenBalance(address account, address token)\n private\n view\n returns (int256)\n {\n if (account == address(0)) revert AccountZeroAddress(account, token);\n if (token == address(0)) revert TokenZeroAddress(account, token);\n\n bytes memory returnedData = token.functionStaticCall(\n abi.encodeWithSelector(\n ISuperfluidToken(token).realtimeBalanceOfNow.selector,\n account\n )\n );\n\n (int256 availableBalance, , , ) = abi.decode(\n returnedData,\n (int256, uint256, uint256, uint256)\n );\n return availableBalance;\n }\n}\n" + }, + "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluidToken.sol": { + "content": "// SPDX-License-Identifier: AGPLv3\npragma solidity >= 0.8.0;\n\nimport { ISuperAgreement } from \"./ISuperAgreement.sol\";\n\n\n/**\n * @title Superfluid token interface\n * @author Superfluid\n */\ninterface ISuperfluidToken {\n\n /**************************************************************************\n * Basic information\n *************************************************************************/\n\n /**\n * @dev Get superfluid host contract address\n */\n function getHost() external view returns(address host);\n\n /**\n * @dev Encoded liquidation type data mainly used for handling stack to deep errors\n *\n * Note:\n * - version: 1\n * - liquidationType key:\n * - 0 = reward account receives reward (PIC period)\n * - 1 = liquidator account receives reward (Pleb period)\n * - 2 = liquidator account receives reward (Pirate period/bailout)\n */\n struct LiquidationTypeData {\n uint256 version;\n uint8 liquidationType;\n }\n\n /**************************************************************************\n * Real-time balance functions\n *************************************************************************/\n\n /**\n * @dev Calculate the real balance of a user, taking in consideration all agreements of the account\n * @param account for the query\n * @param timestamp Time of balance\n * @return availableBalance Real-time balance\n * @return deposit Account deposit\n * @return owedDeposit Account owed Deposit\n */\n function realtimeBalanceOf(\n address account,\n uint256 timestamp\n )\n external view\n returns (\n int256 availableBalance,\n uint256 deposit,\n uint256 owedDeposit);\n\n /**\n * @notice Calculate the realtime balance given the current host.getNow() value\n * @dev realtimeBalanceOf with timestamp equals to block timestamp\n * @param account for the query\n * @return availableBalance Real-time balance\n * @return deposit Account deposit\n * @return owedDeposit Account owed Deposit\n */\n function realtimeBalanceOfNow(\n address account\n )\n external view\n returns (\n int256 availableBalance,\n uint256 deposit,\n uint256 owedDeposit,\n uint256 timestamp);\n\n /**\n * @notice Check if account is critical\n * @dev A critical account is when availableBalance < 0\n * @param account The account to check\n * @param timestamp The time we'd like to check if the account is critical (should use future)\n * @return isCritical Whether the account is critical\n */\n function isAccountCritical(\n address account,\n uint256 timestamp\n )\n external view\n returns(bool isCritical);\n\n /**\n * @notice Check if account is critical now (current host.getNow())\n * @dev A critical account is when availableBalance < 0\n * @param account The account to check\n * @return isCritical Whether the account is critical\n */\n function isAccountCriticalNow(\n address account\n )\n external view\n returns(bool isCritical);\n\n /**\n * @notice Check if account is solvent\n * @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance\n * @param account The account to check\n * @param timestamp The time we'd like to check if the account is solvent (should use future)\n * @return isSolvent\n */\n function isAccountSolvent(\n address account,\n uint256 timestamp\n )\n external view\n returns(bool isSolvent);\n\n /**\n * @notice Check if account is solvent now\n * @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance\n * @param account The account to check\n * @return isSolvent\n */\n function isAccountSolventNow(\n address account\n )\n external view\n returns(bool isSolvent);\n\n /**\n * @notice Get a list of agreements that is active for the account\n * @dev An active agreement is one that has state for the account\n * @param account Account to query\n * @return activeAgreements List of accounts that have non-zero states for the account\n */\n function getAccountActiveAgreements(address account)\n external view\n returns(ISuperAgreement[] memory activeAgreements);\n\n\n /**************************************************************************\n * Super Agreement hosting functions\n *************************************************************************/\n\n /**\n * @dev Create a new agreement\n * @param id Agreement ID\n * @param data Agreement data\n */\n function createAgreement(\n bytes32 id,\n bytes32[] calldata data\n )\n external;\n /**\n * @dev Agreement created event\n * @param agreementClass Contract address of the agreement\n * @param id Agreement ID\n * @param data Agreement data\n */\n event AgreementCreated(\n address indexed agreementClass,\n bytes32 id,\n bytes32[] data\n );\n\n /**\n * @dev Get data of the agreement\n * @param agreementClass Contract address of the agreement\n * @param id Agreement ID\n * @return data Data of the agreement\n */\n function getAgreementData(\n address agreementClass,\n bytes32 id,\n uint dataLength\n )\n external view\n returns(bytes32[] memory data);\n\n /**\n * @dev Create a new agreement\n * @param id Agreement ID\n * @param data Agreement data\n */\n function updateAgreementData(\n bytes32 id,\n bytes32[] calldata data\n )\n external;\n /**\n * @dev Agreement updated event\n * @param agreementClass Contract address of the agreement\n * @param id Agreement ID\n * @param data Agreement data\n */\n event AgreementUpdated(\n address indexed agreementClass,\n bytes32 id,\n bytes32[] data\n );\n\n /**\n * @dev Close the agreement\n * @param id Agreement ID\n */\n function terminateAgreement(\n bytes32 id,\n uint dataLength\n )\n external;\n /**\n * @dev Agreement terminated event\n * @param agreementClass Contract address of the agreement\n * @param id Agreement ID\n */\n event AgreementTerminated(\n address indexed agreementClass,\n bytes32 id\n );\n\n /**\n * @dev Update agreement state slot\n * @param account Account to be updated\n *\n * NOTE\n * - To clear the storage out, provide zero-ed array of intended length\n */\n function updateAgreementStateSlot(\n address account,\n uint256 slotId,\n bytes32[] calldata slotData\n )\n external;\n /**\n * @dev Agreement account state updated event\n * @param agreementClass Contract address of the agreement\n * @param account Account updated\n * @param slotId slot id of the agreement state\n */\n event AgreementStateUpdated(\n address indexed agreementClass,\n address indexed account,\n uint256 slotId\n );\n\n /**\n * @dev Get data of the slot of the state of an agreement\n * @param agreementClass Contract address of the agreement\n * @param account Account to query\n * @param slotId slot id of the state\n * @param dataLength length of the state data\n */\n function getAgreementStateSlot(\n address agreementClass,\n address account,\n uint256 slotId,\n uint dataLength\n )\n external view\n returns (bytes32[] memory slotData);\n\n /**\n * @notice Settle balance from an account by the agreement\n * @dev The agreement needs to make sure that the balance delta is balanced afterwards\n * @param account Account to query.\n * @param delta Amount of balance delta to be settled\n *\n * Modifiers:\n * - onlyAgreement\n */\n function settleBalance(\n address account,\n int256 delta\n )\n external;\n\n /**\n * @dev Make liquidation payouts (v2)\n * @param id Agreement ID\n * @param liquidationTypeData Data regarding the version of the liquidation schema and the type\n * @param liquidatorAccount Address of the executor of the liquidation\n * @param useDefaultRewardAccount Whether or not the default reward account receives the rewardAmount\n * @param targetAccount Account of the stream sender\n * @param rewardAmount The amount the reward recepient account will receive\n * @param targetAccountBalanceDelta The amount the sender account balance should change by\n *\n * - If a bailout is required (bailoutAmount > 0)\n * - the actual reward (single deposit) goes to the executor,\n * - while the reward account becomes the bailout account\n * - total bailout include: bailout amount + reward amount\n * - the targetAccount will be bailed out\n * - If a bailout is not required\n * - the targetAccount will pay the rewardAmount\n * - the liquidator (reward account in PIC period) will receive the rewardAmount\n *\n * Modifiers:\n * - onlyAgreement\n */\n function makeLiquidationPayoutsV2\n (\n bytes32 id,\n bytes memory liquidationTypeData,\n address liquidatorAccount,\n bool useDefaultRewardAccount,\n address targetAccount,\n uint256 rewardAmount,\n int256 targetAccountBalanceDelta\n ) external;\n /**\n * @dev Agreement liquidation event v2 (including agent account)\n * @param agreementClass Contract address of the agreement\n * @param id Agreement ID\n * @param liquidatorAccount Address of the executor of the liquidation\n * @param targetAccount Account of the stream sender\n * @param rewardAccount Account that collects the reward or bails out insolvent accounts\n * @param rewardAmount The amount the reward recipient account balance should change by\n * @param targetAccountBalanceDelta The amount the sender account balance should change by\n * @param liquidationTypeData The encoded liquidation type data including the version (how to decode)\n *\n * NOTE:\n * Reward account rule:\n * - if the agreement is liquidated during the PIC period\n * - the rewardAccount will get the rewardAmount (remaining deposit), regardless of the liquidatorAccount\n * - the targetAccount will pay for the rewardAmount\n * - if the agreement is liquidated after the PIC period AND the targetAccount is solvent\n * - the liquidatorAccount will get the rewardAmount (remaining deposit)\n * - the targetAccount will pay for the rewardAmount\n * - if the targetAccount is insolvent\n * - the liquidatorAccount will get the rewardAmount (single deposit)\n * - the rewardAccount will pay for both the rewardAmount and bailoutAmount\n * - the targetAccount will receive the bailoutAmount\n */\n event AgreementLiquidatedV2(\n address indexed agreementClass,\n bytes32 id,\n address indexed liquidatorAccount,\n address indexed targetAccount,\n address rewardAccount,\n uint256 rewardAmount,\n int256 targetAccountBalanceDelta,\n bytes liquidationTypeData\n );\n\n /**************************************************************************\n * Function modifiers for access control and parameter validations\n *\n * While they cannot be explicitly stated in function definitions, they are\n * listed in function definition comments instead for clarity.\n *\n * NOTE: solidity-coverage not supporting it\n *************************************************************************/\n\n /// @dev The msg.sender must be host contract\n //modifier onlyHost() virtual;\n\n /// @dev The msg.sender must be a listed agreement.\n //modifier onlyAgreement() virtual;\n\n /**************************************************************************\n * DEPRECATED\n *************************************************************************/\n\n /**\n * @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedBy)\n * @param agreementClass Contract address of the agreement\n * @param id Agreement ID\n * @param penaltyAccount Account of the agreement to be penalized\n * @param rewardAccount Account that collect the reward\n * @param rewardAmount Amount of liquidation reward\n *\n * NOTE:\n *\n * [DEPRECATED] Use AgreementLiquidatedV2 instead\n */\n event AgreementLiquidated(\n address indexed agreementClass,\n bytes32 id,\n address indexed penaltyAccount,\n address indexed rewardAccount,\n uint256 rewardAmount\n );\n\n /**\n * @dev System bailout occurred (DEPRECATED BY AgreementLiquidatedBy)\n * @param bailoutAccount Account that bailout the penalty account\n * @param bailoutAmount Amount of account bailout\n *\n * NOTE:\n *\n * [DEPRECATED] Use AgreementLiquidatedV2 instead\n */\n event Bailout(\n address indexed bailoutAccount,\n uint256 bailoutAmount\n );\n\n /**\n * @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedV2)\n * @param liquidatorAccount Account of the agent that performed the liquidation.\n * @param agreementClass Contract address of the agreement\n * @param id Agreement ID\n * @param penaltyAccount Account of the agreement to be penalized\n * @param bondAccount Account that collect the reward or bailout accounts\n * @param rewardAmount Amount of liquidation reward\n * @param bailoutAmount Amount of liquidation bailouot\n *\n * NOTE:\n * Reward account rule:\n * - if bailout is equal to 0, then\n * - the bondAccount will get the rewardAmount,\n * - the penaltyAccount will pay for the rewardAmount.\n * - if bailout is larger than 0, then\n * - the liquidatorAccount will get the rewardAmouont,\n * - the bondAccount will pay for both the rewardAmount and bailoutAmount,\n * - the penaltyAccount will pay for the rewardAmount while get the bailoutAmount.\n */\n event AgreementLiquidatedBy(\n address liquidatorAccount,\n address indexed agreementClass,\n bytes32 id,\n address indexed penaltyAccount,\n address indexed bondAccount,\n uint256 rewardAmount,\n uint256 bailoutAmount\n );\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\n" + }, + "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperAgreement.sol": { + "content": "// SPDX-License-Identifier: AGPLv3\npragma solidity >= 0.8.0;\n\nimport { ISuperfluidToken } from \"./ISuperfluidToken.sol\";\n\n/**\n * @title Super agreement interface\n * @author Superfluid\n */\ninterface ISuperAgreement {\n\n /**\n * @dev Get the type of the agreement class\n */\n function agreementType() external view returns (bytes32);\n\n /**\n * @dev Calculate the real-time balance for the account of this agreement class\n * @param account Account the state belongs to\n * @param time Time used for the calculation\n * @return dynamicBalance Dynamic balance portion of real-time balance of this agreement\n * @return deposit Account deposit amount of this agreement\n * @return owedDeposit Account owed deposit amount of this agreement\n */\n function realtimeBalanceOf(\n ISuperfluidToken token,\n address account,\n uint256 time\n )\n external\n view\n returns (\n int256 dynamicBalance,\n uint256 deposit,\n uint256 owedDeposit\n );\n\n}\n" + }, + "src/bridges/facets/HopFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.4;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { IHopBridge } from \"../interfaces/IHopBridge.sol\";\nimport { LibAsset } from \"../libs/LibAsset.sol\";\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\nimport { ReentrancyGuard } from \"../../common/helpers/DiamondReentrancyGuard.sol\";\nimport {\n InvalidAmount,\n InvalidBridgeConfigLength,\n CannotBridgeToSameNetwork,\n NativeValueWithERC,\n InvalidConfig\n} from \"../errors/GenericErrors.sol\";\n\n/**\n * @title Hop Protocol Integration\n *\n * @notice Contract which provides bridging functionality through Hop Protocol\n *\n */\ncontract HopFacet is ReentrancyGuard {\n // storage\n\n bytes32 internal constant NAMESPACE = keccak256(\"io.etherspot.facets.hop\");\n struct Storage {\n uint256 chainLayerId;\n }\n\n // types\n\n struct HopData {\n address bridge;\n address ammWrapper;\n address asset;\n address recipient;\n uint256 chainId;\n uint256 amount;\n uint256 bonderFee;\n uint256 amountOutMin;\n uint256 deadline;\n uint256 destinationAmountOutMin;\n uint256 destinationDeadline;\n }\n\n // events\n\n /**\n * @dev Emitted when facet initializes\n * @param chainId current chain id\n * @param chainLayerId current chain layer id\n */\n event HopInitialized(\n uint256 chainId,\n uint256 chainLayerId\n );\n\n /**\n * @dev Emitted on token swap\n * @param _destination destination chain id\n * @param _bridge address of the bridge on chain _destination,\n * @param _ammWrapper address of the amm wrapper,\n * @param _recipient recipient\n * @param _asset address of the asset\n * @param _amount amount of assets\n * @param _bonderFee fee\n * @param _amountOutMin The minimum amount received after attempting to\n * swap in the destination\n * @param _deadline The deadline for swapping in the destination AMM market.\n * 0 if no * swap is intended.\n * @param _destinationAmountOutMin The minimum amount of tokens to receive after bridging\n * @param _destinationDeadline The time the transaction must be completed\n */\n event HopTokenSwap(\n uint256 indexed _destination,\n address _bridge,\n address _ammWrapper,\n address indexed _recipient,\n address indexed _asset,\n uint256 _amount,\n uint256 _bonderFee,\n uint256 _amountOutMin,\n uint256 _deadline,\n uint256 _destinationAmountOutMin,\n uint256 _destinationDeadline\n );\n\n\n\n // external functions\n\n /**\n * @notice Initializes local variables for the Connext facet\n */\n function initHop(uint256 _chainLayerId) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n s.chainLayerId = _chainLayerId;\n\n emit HopInitialized(\n getChainID(),\n _chainLayerId\n );\n }\n\n /**\n * @notice Bridges tokens via Hop Protocol\n * @param _hopData data specific to Hop Protocol\n */\n function hopTokenTransfer(\n HopData calldata _hopData\n ) external payable nonReentrant {\n LibAsset.depositAsset(_hopData.asset, _hopData.amount);\n\n address bridge;\n if (getLayerId() == 1) {\n bridge = _hopData.bridge;\n } else {\n bridge = _hopData.ammWrapper;\n }\n\n if (getChainID() == _hopData.chainId)\n revert CannotBridgeToSameNetwork();\n\n // Give Hop approval to bridge tokens\n LibAsset.maxApproveERC20(\n IERC20(_hopData.asset),\n bridge,\n _hopData.amount\n );\n\n uint256 value = LibAsset.isNativeAsset(_hopData.asset)\n ? _hopData.amount\n : 0;\n\n if (getLayerId() == 1) {\n // Ethereum L1\n IHopBridge(bridge).sendToL2{value: value}(\n _hopData.chainId,\n _hopData.recipient,\n _hopData.amount,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline,\n address(0),\n 0\n );\n } else {\n // L2\n IHopBridge(bridge).swapAndSend{value: value}(\n _hopData.chainId,\n _hopData.recipient,\n _hopData.amount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n }\n emit HopTokenSwap(\n _hopData.chainId,\n _hopData.bridge,\n _hopData.ammWrapper,\n _hopData.recipient,\n _hopData.asset,\n _hopData.amount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n }\n\n /// private Methods ///\n\n /**\n * @dev returns local storage\n */\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n\n /**\n * @dev returns current chain layer number\n * @return uint256 layer number\n */\n function getLayerId() private view returns (uint256) {\n return getStorage().chainLayerId;\n }\n\n /**\n * @dev fetch chain id\n */\n function getChainID() private view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n}\n" + }, + "src/bridges/interfaces/IHopBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.4;\n\ninterface IHopBridge {\n function sendToL2(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 amountOutMin,\n uint256 deadline,\n address relayer,\n uint256 relayerFee\n ) external payable;\n\n function swapAndSend(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 deadline,\n uint256 destinationAmountOutMin,\n uint256 destinationDeadline\n ) external payable;\n}\n" + } + }, + "settings": { + "evmVersion": "istanbul", + "metadata": { + "bytecodeHash": "none", + "useLiteralContent": true + }, + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/solcInputs/8d42885a5f19da22f710ffc8b637c191.json b/deployments/neonDevnet/solcInputs/8d42885a5f19da22f710ffc8b637c191.json new file mode 100644 index 00000000..edfd6042 --- /dev/null +++ b/deployments/neonDevnet/solcInputs/8d42885a5f19da22f710ffc8b637c191.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "src/bridges/facets/StargateFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.4;\n\nimport {IStargateRouter} from \"../interfaces/IStargateRouter.sol\";\nimport {IStargateReceiver} from \"../interfaces/IStargateReceiver.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {ReentrancyGuard} from \"../../common/helpers/DiamondReentrancyGuard.sol\";\nimport {CannotBridgeToSameNetwork, InvalidAmount, InvalidConfig} from \"../errors/GenericErrors.sol\";\nimport {SenderNotStargateRouter, NoMsgValueForCrossChainMessage, StargateRouterAddressZero, InvalidSourcePoolId, InvalidDestinationPoolId} from \"../errors/StargateErrors.sol\";\nimport {LibDiamond} from \"../libs/LibDiamond.sol\";\n\n/// @title StargateFacet\n/// @author Luke Wickens \n/// @notice Stargate/LayerZero intergration for bridging tokens\n\ncontract StargateFacet is IStargateReceiver, ReentrancyGuard {\n using SafeERC20 for IERC20;\n\n //////////////////////////////////////////////////////////////\n /////////////////////////// Events ///////////////////////////\n //////////////////////////////////////////////////////////////\n event SGInitialized(address stargate, uint16 chainId);\n event SGTransferStarted(\n string bridgeUsed,\n address fromToken,\n address toToken,\n address from,\n address to,\n uint256 amount,\n uint16 chainIdTo\n );\n event SGReceivedOnDestination(address token, uint256 amount);\n event SGUpdatedRouter(address newAddress);\n event SGUpdatedSlippageTolerance(uint256 newSlippage);\n event SGAddedPool(uint16 chainId, address token, uint16 poolId);\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Storage ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"io.etherspot.facets.stargate\");\n struct Storage {\n address stargateRouter;\n uint16 chainId;\n uint256 dstGas;\n uint256 slippage;\n mapping(uint16 => mapping(address => uint16)) poolIds;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Structs ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n struct StargateData {\n uint256 qty;\n address fromToken;\n address toToken;\n uint16 dstChainId;\n address to;\n address destStargateComposed;\n }\n\n /// @notice initializes state variables for the Stargate facet\n /// @param _stargateRouter - address of the Stargate router contract\n /// @param _chainId - current chain id\n function sgInitialize(address _stargateRouter, uint16 _chainId) external {\n if (_stargateRouter == address(0)) revert InvalidConfig();\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.stargateRouter = address(_stargateRouter);\n s.chainId = _chainId;\n s.slippage = 50; // equates to 0.5%\n // Adding pre-existing pools => USDC: 1, USDT: 2, BUSD: 5\n sgAddPool(1, 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, 1);\n sgAddPool(1, 0xdAC17F958D2ee523a2206206994597C13D831ec7, 2);\n sgAddPool(2, 0x55d398326f99059fF775485246999027B3197955, 2);\n sgAddPool(2, 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56, 5);\n sgAddPool(6, 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E, 1);\n sgAddPool(6, 0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7, 2);\n sgAddPool(9, 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174, 1);\n sgAddPool(9, 0xc2132D05D31c914a87C6611C10748AEb04B58e8F, 2);\n sgAddPool(10, 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8, 1);\n sgAddPool(10, 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9, 2);\n sgAddPool(11, 0x7F5c764cBc14f9669B88837ca1490cCa17c31607, 1);\n sgAddPool(12, 0x04068DA6C83AFCFA0e13ba15A6696662335D5B75, 1);\n emit SGInitialized(_stargateRouter, _chainId);\n }\n\n /// @notice initializes state variables for the stargate facet\n /// @param _sgData - struct containing information required to execute bridge\n function sgBridgeTokens(StargateData memory _sgData)\n external\n payable\n nonReentrant\n {\n // if (msg.value <= 0) revert NoMsgValueForCrossChainMessage();\n if (_sgData.qty <= 0) revert InvalidAmount();\n if (\n _sgData.fromToken == address(0) ||\n _sgData.toToken == address(0) ||\n _sgData.to == address(0) ||\n _sgData.destStargateComposed == address(0)\n ) revert InvalidConfig();\n\n // access storage\n Storage storage s = getStorage();\n\n // check pool ids are valid\n uint16 srcPoolId = sgRetrievePoolId(s.chainId, _sgData.fromToken);\n if (srcPoolId == 0) revert InvalidSourcePoolId();\n uint16 dstPoolId = sgRetrievePoolId(\n _sgData.dstChainId,\n _sgData.toToken\n );\n\n // calculate cross chain fees\n uint256 fees = sgCalculateFees(\n _sgData.dstChainId,\n _sgData.to,\n s.stargateRouter\n );\n\n // calculate slippage\n uint256 minAmountOut = sgMinAmountOut(_sgData.qty);\n\n // encode sgReceive implemented\n bytes memory destination = abi.encodePacked(\n _sgData.destStargateComposed\n );\n\n // encode payload data to send to destination contract, which it will handle with sgReceive()\n bytes memory payload = abi.encode(_sgData.to);\n\n // this contract calls stargate swap()\n IERC20(_sgData.fromToken).safeTransferFrom(\n msg.sender,\n address(this),\n _sgData.qty\n );\n\n IERC20(_sgData.fromToken).safeApprove(\n address(s.stargateRouter),\n _sgData.qty\n );\n\n // Stargate's Router.swap() function sends the tokens to the destination chain.\n IStargateRouter(s.stargateRouter).swap{value: fees}(\n _sgData.dstChainId, // the destination chain id\n srcPoolId, // the source Stargate poolId\n dstPoolId, // the destination Stargate poolId\n payable(msg.sender), // refund adddress. if msg.sender pays too much gas, return extra eth\n _sgData.qty, // total tokens to send to destination chain\n minAmountOut, // min amount allowed out\n IStargateRouter.lzTxObj(200000, 0, \"0x\"), // default lzTxObj\n destination, // destination address, the sgReceive() implementer\n payload // bytes payload\n );\n\n emit SGTransferStarted(\n \"stargate\",\n _sgData.fromToken,\n _sgData.toToken,\n msg.sender,\n _sgData.to,\n _sgData.qty,\n _sgData.dstChainId\n );\n }\n\n /// @notice required to receive tokens on destination chain\n /// @param _chainId The remote chainId sending the tokens\n /// @param _srcAddress The remote Bridge address\n /// @param _nonce The message ordering nonce\n /// @param _token The token contract on the local chain\n /// @param amountLD The qty of local _token contract tokens\n /// @param _payload The bytes containing the toAddress\n function sgReceive(\n uint16 _chainId,\n bytes memory _srcAddress,\n uint256 _nonce,\n address _token,\n uint256 amountLD,\n bytes memory _payload\n ) external override {\n Storage storage s = getStorage();\n if (msg.sender != address(s.stargateRouter))\n revert SenderNotStargateRouter();\n\n address _toAddr = abi.decode(_payload, (address));\n IERC20(_token).transfer(_toAddr, amountLD);\n emit SGReceivedOnDestination(_token, amountLD);\n }\n\n /// @notice Calculates cross chain fee\n /// @param _destChain Destination chain id\n /// @param _receiver Receiver on destination chain\n /// @param _router Address of stargate router\n function sgCalculateFees(\n uint16 _destChain,\n address _receiver,\n address _router\n ) public view returns (uint256) {\n (uint256 nativeFee, ) = IStargateRouter(_router).quoteLayerZeroFee(\n _destChain, // destination chain id\n 1, // 1 = swap\n abi.encodePacked(_receiver), // receiver on destination chain\n \"0x\", // payload, using abi.encode()\n IStargateRouter.lzTxObj(200000, 0, \"0x\")\n );\n return nativeFee;\n }\n\n /// @notice Calculates the minimum amount out using slippage tolerance\n /// @param _amount Transfer amount\n function sgMinAmountOut(uint256 _amount) public view returns (uint256) {\n Storage storage s = getStorage();\n // equates to 0.5% slippage\n return (_amount * (10000 - s.slippage)) / (10000);\n }\n\n /// @notice Updates stargate router address for deployed chain\n /// @param _newAddress Address of the new router\n function sgUpdateRouter(address _newAddress) external {\n LibDiamond.enforceIsContractOwner();\n if (_newAddress == address(0)) revert StargateRouterAddressZero();\n Storage storage s = getStorage();\n s.stargateRouter = address(_newAddress);\n emit SGUpdatedRouter(_newAddress);\n }\n\n /// @notice Updates slippage tolerance amount\n /// @param _newSlippage New slippage amount\n function sgUpdateSlippageTolerance(uint256 _newSlippage) external {\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.slippage = _newSlippage;\n emit SGUpdatedSlippageTolerance(_newSlippage);\n }\n\n /// @notice Adds a new pool for a specific token and chain\n /// @param _chainId Chain id of new pool (NOT actual chain id - check stargate pool ids docs)\n /// @param _token Address of token\n /// @param _poolId Pool id (check stargate pool ids docs)\n function sgAddPool(\n uint16 _chainId,\n address _token,\n uint16 _poolId\n ) public {\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.poolIds[_chainId][_token] = _poolId;\n emit SGAddedPool(_chainId, _token, _poolId);\n }\n\n /// @notice Checks for a valid token pool on specific chain\n /// @param _chainId Chain id of new pool (NOT actual chain id - check stargate pool ids docs)\n /// @param _token Address of token\n /// @param _poolId Pool id (check stargate pool ids docs)\n function sgCheckPoolId(\n uint16 _chainId,\n address _token,\n uint16 _poolId\n ) external view returns (bool) {\n Storage storage s = getStorage();\n return s.poolIds[_chainId][_token] == _poolId ? true : false;\n }\n\n /// @notice Retrieves pool id for a token on a specified chain\n /// @param _chainId Chain id of new pool (NOT actual chain id - check stargate pool ids docs)\n /// @param _token Address of token\n function sgRetrievePoolId(uint16 _chainId, address _token)\n public\n view\n returns (uint16)\n {\n Storage storage s = getStorage();\n return s.poolIds[_chainId][_token];\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////// Private Functions /////////////////////\n //////////////////////////////////////////////////////////////\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/bridges/interfaces/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier:MIT\n\npragma solidity 0.8.4;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function addLiquidity(\n uint256 _poolId,\n uint256 _amountLD,\n address _to\n ) external;\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n\n function redeemRemote(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLP,\n uint256 _minAmountLD,\n bytes calldata _to,\n lzTxObj memory _lzTxParams\n ) external payable;\n\n function instantRedeemLocal(\n uint16 _srcPoolId,\n uint256 _amountLP,\n address _to\n ) external returns (uint256);\n\n function redeemLocal(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLP,\n bytes calldata _to,\n lzTxObj memory _lzTxParams\n ) external payable;\n\n function sendCredits(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress\n ) external payable;\n\n function quoteLayerZeroFee(\n uint16 _dstChainId,\n uint8 _functionType,\n bytes calldata _toAddress,\n bytes calldata _transferAndCallPayload,\n lzTxObj memory _lzTxParams\n ) external view returns (uint256, uint256);\n}\n" + }, + "src/bridges/interfaces/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.4;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "src/common/helpers/DiamondReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.4;\n\n/// @title Reentrancy Guard\n/// @notice Abstract contract to provide protection against reentrancy\nabstract contract ReentrancyGuard {\n //////////////////////////////////////////////////////////////\n ////////////////////////// Storage ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n bytes32 private constant NAMESPACE =\n keccak256(\"io.etherspot.helpers.reentrancyguard\");\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Structs ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n struct ReentrancyStorage {\n uint256 status;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Errors ////////////////////////////\n //////////////////////////////////////////////////////////////\n\n error ReentrancyError();\n\n //////////////////////////////////////////////////////////////\n ///////////////////////// Constants //////////////////////////\n //////////////////////////////////////////////////////////////\n\n uint256 private constant _NOT_ENTERED = 0;\n uint256 private constant _ENTERED = 1;\n\n //////////////////////////////////////////////////////////////\n ///////////////////////// Modifiers ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n modifier nonReentrant() {\n ReentrancyStorage storage s = reentrancyStorage();\n if (s.status == _ENTERED) revert ReentrancyError();\n s.status = _ENTERED;\n _;\n s.status = _NOT_ENTERED;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////// Private Functions /////////////////////\n //////////////////////////////////////////////////////////////\n\n /// @dev fetch local storage\n function reentrancyStorage()\n private\n pure\n returns (ReentrancyStorage storage data)\n {\n bytes32 position = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n data.slot := position\n }\n }\n}\n" + }, + "src/bridges/errors/GenericErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\nerror InvalidAmount();\nerror TokenAddressIsZero();\nerror CannotBridgeToSameNetwork();\nerror ZeroPostSwapBalance();\nerror InvalidBridgeConfigLength();\nerror NoSwapDataProvided();\nerror NativeValueWithERC();\nerror ContractCallNotAllowed();\nerror NullAddrIsNotAValidSpender();\nerror NullAddrIsNotAnERC20Token();\nerror NoTransferToNullAddress();\nerror NativeAssetTransferFailed();\nerror InvalidContract();\nerror InvalidConfig();\nerror ZeroAddressProvided();\n" + }, + "src/bridges/errors/StargateErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\nerror SenderNotStargateRouter();\nerror NoMsgValueForCrossChainMessage();\nerror StargateRouterAddressZero();\nerror InvalidSourcePoolId();\nerror InvalidDestinationPoolId();\n" + }, + "src/bridges/libs/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\nlibrary LibDiamond {\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\n keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(\n msg.sender == diamondStorage().contractOwner,\n \"LibDiamond: Must be contract owner\"\n );\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n require(\n _functionSelectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n require(\n _functionSelectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n require(\n _functionSelectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress)\n internal\n {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata)\n internal\n {\n if (_init == address(0)) {\n require(\n _calldata.length == 0,\n \"LibDiamondCut: _init is address(0) but_calldata is not empty\"\n );\n } else {\n require(\n _calldata.length > 0,\n \"LibDiamondCut: _calldata is empty but _init is not address(0)\"\n );\n if (_init != address(this)) {\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n }\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "src/bridges/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "src/bridges/libs/LibAsset.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\n// solhint-disable-next-line\npragma solidity 0.8.4;\nimport {NullAddrIsNotAnERC20Token, NullAddrIsNotAValidSpender, NoTransferToNullAddress, InvalidAmount, NativeValueWithERC, NativeAssetTransferFailed} from \"../errors/GenericErrors.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title LibAsset\n/// @author Connext \n/// @notice This library contains helpers for dealing with onchain transfers\n/// of assets, including accounting for the native asset `assetId`\n/// conventions and any noncompliant ERC20 transfers\nlibrary LibAsset {\n uint256 private constant MAX_INT = type(uint256).max;\n\n address internal constant NULL_ADDRESS =\n 0x0000000000000000000000000000000000000000; //address(0)\n\n /// @dev All native assets use the empty address for their asset id\n /// by convention\n\n address internal constant NATIVE_ASSETID = NULL_ADDRESS; //address(0)\n\n /// @notice Gets the balance of the inheriting contract for the given asset\n /// @param assetId The asset identifier to get the balance of\n /// @return Balance held by contracts using this library\n function getOwnBalance(address assetId) internal view returns (uint256) {\n return\n assetId == NATIVE_ASSETID\n ? address(this).balance\n : IERC20(assetId).balanceOf(address(this));\n }\n\n /// @notice Transfers ether from the inheriting contract to a given\n /// recipient\n /// @param recipient Address to send ether to\n /// @param amount Amount to send to given recipient\n function transferNativeAsset(address payable recipient, uint256 amount)\n private\n {\n if (recipient == NULL_ADDRESS) revert NoTransferToNullAddress();\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = recipient.call{value: amount}(\"\");\n if (!success) revert NativeAssetTransferFailed();\n }\n\n /// @notice Gives MAX approval for another address to spend tokens\n /// @param assetId Token address to transfer\n /// @param spender Address to give spend approval to\n /// @param amount Amount to approve for spending\n function maxApproveERC20(\n IERC20 assetId,\n address spender,\n uint256 amount\n ) internal {\n if (address(assetId) == NATIVE_ASSETID) return;\n if (spender == NULL_ADDRESS) revert NullAddrIsNotAValidSpender();\n uint256 allowance = assetId.allowance(address(this), spender);\n if (allowance < amount)\n SafeERC20.safeApprove(IERC20(assetId), spender, MAX_INT);\n }\n\n /// @notice Transfers tokens from the inheriting contract to a given\n /// recipient\n /// @param assetId Token address to transfer\n /// @param recipient Address to send token to\n /// @param amount Amount to send to given recipient\n function transferERC20(\n address assetId,\n address recipient,\n uint256 amount\n ) private {\n if (isNativeAsset(assetId)) revert NullAddrIsNotAnERC20Token();\n SafeERC20.safeTransfer(IERC20(assetId), recipient, amount);\n }\n\n /// @notice Transfers tokens from a sender to a given recipient\n /// @param assetId Token address to transfer\n /// @param from Address of sender/owner\n /// @param to Address of recipient/spender\n /// @param amount Amount to transfer from owner to spender\n function transferFromERC20(\n address assetId,\n address from,\n address to,\n uint256 amount\n ) internal {\n if (assetId == NATIVE_ASSETID) revert NullAddrIsNotAnERC20Token();\n if (to == NULL_ADDRESS) revert NoTransferToNullAddress();\n SafeERC20.safeTransferFrom(IERC20(assetId), from, to, amount);\n }\n\n /// @notice Deposits an asset into the contract and performs checks to avoid NativeValueWithERC\n /// @param tokenId Token to deposit\n /// @param amount Amount to deposit\n /// @param isNative Wether the token is native or ERC20\n function depositAsset(\n address tokenId,\n uint256 amount,\n bool isNative\n ) internal {\n if (amount == 0) revert InvalidAmount();\n if (isNative) {\n if (msg.value != amount) revert InvalidAmount();\n } else {\n if (msg.value != 0) revert NativeValueWithERC();\n uint256 _fromTokenBalance = LibAsset.getOwnBalance(tokenId);\n LibAsset.transferFromERC20(\n tokenId,\n msg.sender,\n address(this),\n amount\n );\n if (LibAsset.getOwnBalance(tokenId) - _fromTokenBalance != amount)\n revert InvalidAmount();\n }\n }\n\n /// @notice Overload for depositAsset(address tokenId, uint256 amount, bool isNative)\n /// @param tokenId Token to deposit\n /// @param amount Amount to deposit\n function depositAsset(address tokenId, uint256 amount) internal {\n return depositAsset(tokenId, amount, tokenId == NATIVE_ASSETID);\n }\n\n /// @notice Determines whether the given assetId is the native asset\n /// @param assetId The asset identifier to evaluate\n /// @return Boolean indicating if the asset is the native asset\n function isNativeAsset(address assetId) internal pure returns (bool) {\n return assetId == NATIVE_ASSETID;\n }\n\n /// @notice Wrapper function to transfer a given asset (native or erc20) to\n /// some recipient. Should handle all non-compliant return value\n /// tokens as well by using the SafeERC20 contract by open zeppelin.\n /// @param assetId Asset id for transfer (address(0) for native asset,\n /// token address for erc20s)\n /// @param recipient Address to send asset to\n /// @param amount Amount to send to given recipient\n function transferAsset(\n address assetId,\n address payable recipient,\n uint256 amount\n ) internal {\n (assetId == NATIVE_ASSETID)\n ? transferNativeAsset(recipient, amount)\n : transferERC20(assetId, recipient, amount);\n }\n\n /// @dev Checks whether the given address is a contract and contains code\n function isContract(address _contractAddr) internal view returns (bool) {\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n size := extcodesize(_contractAddr)\n }\n return size > 0;\n }\n}\n" + }, + "src/bridges/facets/CBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\n/// @title CBridgeFacet\n/// @author Luke Wickens \n/// @notice cBridge intergration for bridging tokens\n\nimport {ICBridge} from \"../interfaces/ICBridge.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {ReentrancyGuard} from \"../../common/helpers/DiamondReentrancyGuard.sol\";\nimport {CannotBridgeToSameNetwork, InvalidAmount, InvalidConfig, TokenAddressIsZero, ZeroAddressProvided} from \"../errors/GenericErrors.sol\";\nimport {CBSlippageTooLow} from \"../errors/CBridgeErrors.sol\";\nimport {LibDiamond} from \"../libs/LibDiamond.sol\";\n\ncontract CBridgeFacet is ReentrancyGuard {\n using SafeERC20 for IERC20;\n //////////////////////////////////////////////////////////////\n /////////////////////////// Events ///////////////////////////\n //////////////////////////////////////////////////////////////\n event CBInitialized(address cBridge, uint256 chainId);\n event CBTransferStarted(\n string bridgeUsed,\n address token,\n address from,\n address to,\n uint256 qty,\n uint256 chainIdTo\n );\n event CBUpdatedBridge(address newAddress);\n event CBUpdatedSlippageTolerance(uint256 newSlippage);\n //////////////////////////////////////////////////////////////\n ////////////////////////// Storage ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"io.etherspot.facets.cbridge\");\n struct Storage {\n address cbBridge;\n uint256 cbChainId;\n uint32 cbSlippage;\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////////// Structs ///////////////////////////\n //////////////////////////////////////////////////////////////\n\n struct CBridgeData {\n uint64 dstChainId;\n uint64 nonce;\n uint256 qty;\n address to;\n address token;\n }\n\n /// @notice initializes state variables for the cBridge facet\n /// @param _cbBridge address of the CBridge router contract\n function cbInitialize(address _cbBridge) external {\n LibDiamond.enforceIsContractOwner();\n if (_cbBridge == address(0)) revert ZeroAddressProvided();\n Storage storage s = getStorage();\n s.cbBridge = _cbBridge;\n s.cbChainId = block.chainid;\n s.cbSlippage = 10000; // equates to 1% - has to be > 0.5% (slippage * 1M)\n emit CBInitialized(_cbBridge, block.chainid);\n }\n\n /// @notice initiates token bridging\n /// @param _cbData: provides necessary data for cBridge transfer\n\n function cbBridgeTokens(CBridgeData calldata _cbData)\n external\n payable\n nonReentrant\n {\n if (block.chainid == _cbData.dstChainId)\n revert CannotBridgeToSameNetwork();\n if (_cbData.to == address(0)) revert ZeroAddressProvided();\n if (_cbData.qty <= 0) revert InvalidAmount();\n if (_cbData.token == address(0)) revert TokenAddressIsZero();\n\n Storage storage s = getStorage();\n address bridge = s.cbBridge;\n\n // this contract calls stargate swap()\n IERC20(_cbData.token).safeTransferFrom(\n msg.sender,\n address(this),\n _cbData.qty\n );\n IERC20(_cbData.token).safeApprove(address(bridge), _cbData.qty);\n\n ICBridge(bridge).send(\n _cbData.to,\n _cbData.token,\n _cbData.qty,\n _cbData.dstChainId,\n _cbData.nonce,\n s.cbSlippage\n );\n\n emit CBTransferStarted(\n \"cbridge\",\n _cbData.token,\n msg.sender,\n _cbData.to,\n _cbData.qty,\n _cbData.dstChainId\n );\n }\n\n function cbUpdateSlippageTolerance(uint32 _newSlippage) external {\n // should be > 0.5% (5000)\n if (_newSlippage <= 5000) revert CBSlippageTooLow();\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.cbSlippage = _newSlippage;\n emit CBUpdatedSlippageTolerance(_newSlippage);\n }\n\n function cbUpdateBridge(address _newAddress) external {\n LibDiamond.enforceIsContractOwner();\n if (_newAddress == address(0)) revert ZeroAddressProvided();\n Storage storage s = getStorage();\n s.cbBridge = _newAddress;\n emit CBUpdatedBridge(_newAddress);\n }\n\n //////////////////////////////////////////////////////////////\n ////////////////////// Private Functions /////////////////////\n //////////////////////////////////////////////////////////////\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/bridges/interfaces/ICBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\ninterface ICBridge {\n function send(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChinId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external;\n\n function sendNative(\n address _receiver,\n uint256 _amount,\n uint64 _dstChinId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external payable;\n\n function relay(\n bytes calldata _relayRequest,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external;\n}\n" + }, + "src/bridges/errors/CBridgeErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.4;\n\nerror CBSlippageTooLow();\n" + }, + "src/bridges/facets/HopFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.4;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { IHopBridge } from \"../interfaces/IHopBridge.sol\";\nimport { LibAsset } from \"../libs/LibAsset.sol\";\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\nimport { ReentrancyGuard } from \"../../common/helpers/DiamondReentrancyGuard.sol\";\nimport {\n InvalidAmount,\n InvalidBridgeConfigLength,\n CannotBridgeToSameNetwork,\n NativeValueWithERC,\n InvalidConfig\n} from \"../errors/GenericErrors.sol\";\n\n/**\n * @title Hop Protocol Integration\n *\n * @notice Contract which provides bridging functionality through Hop Protocol\n *\n */\ncontract HopFacet is ReentrancyGuard {\n // storage\n\n bytes32 internal constant NAMESPACE = keccak256(\"io.etherspot.facets.hop\");\n struct Storage {\n uint256 chainLayerId;\n }\n\n // types\n\n struct HopData {\n address bridge;\n address ammWrapper;\n address asset;\n address recipient;\n uint256 chainId;\n uint256 amount;\n uint256 bonderFee;\n uint256 amountOutMin;\n uint256 deadline;\n uint256 destinationAmountOutMin;\n uint256 destinationDeadline;\n }\n\n // events\n\n /**\n * @dev Emitted when facet initializes\n * @param chainId current chain id\n * @param chainLayerId current chain layer id\n */\n event HopInitialized(\n uint256 chainId,\n uint256 chainLayerId\n );\n\n /**\n * @dev Emitted on token swap\n * @param _destination destination chain id\n * @param _bridge address of the bridge on chain _destination,\n * @param _ammWrapper address of the amm wrapper,\n * @param _recipient recipient\n * @param _asset address of the asset\n * @param _amount amount of assets\n * @param _bonderFee fee\n * @param _amountOutMin The minimum amount received after attempting to\n * swap in the destination\n * @param _deadline The deadline for swapping in the destination AMM market.\n * 0 if no * swap is intended.\n * @param _destinationAmountOutMin The minimum amount of tokens to receive after bridging\n * @param _destinationDeadline The time the transaction must be completed\n */\n event HopTokenSwap(\n uint256 indexed _destination,\n address _bridge,\n address _ammWrapper,\n address indexed _recipient,\n address indexed _asset,\n uint256 _amount,\n uint256 _bonderFee,\n uint256 _amountOutMin,\n uint256 _deadline,\n uint256 _destinationAmountOutMin,\n uint256 _destinationDeadline\n );\n\n\n\n // external functions\n\n /**\n * @notice Initializes local variables for the Connext facet\n */\n function initHop(uint256 _chainLayerId) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n s.chainLayerId = _chainLayerId;\n\n emit HopInitialized(\n getChainID(),\n _chainLayerId\n );\n }\n\n /**\n * @notice Bridges tokens via Hop Protocol\n * @param _hopData data specific to Hop Protocol\n */\n function hopTokenTransfer(\n HopData calldata _hopData\n ) external payable nonReentrant {\n LibAsset.depositAsset(_hopData.asset, _hopData.amount);\n\n address bridge;\n if (getLayerId() == 1) {\n bridge = _hopData.bridge;\n } else {\n bridge = _hopData.ammWrapper;\n }\n\n if (getChainID() == _hopData.chainId)\n revert CannotBridgeToSameNetwork();\n\n // Give Hop approval to bridge tokens\n LibAsset.maxApproveERC20(\n IERC20(_hopData.asset),\n bridge,\n _hopData.amount\n );\n\n uint256 value = LibAsset.isNativeAsset(_hopData.asset)\n ? _hopData.amount\n : 0;\n\n if (getLayerId() == 1) {\n // Ethereum L1\n IHopBridge(bridge).sendToL2{value: value}(\n _hopData.chainId,\n _hopData.recipient,\n _hopData.amount,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline,\n address(0),\n 0\n );\n } else {\n // L2\n IHopBridge(bridge).swapAndSend{value: value}(\n _hopData.chainId,\n _hopData.recipient,\n _hopData.amount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n }\n emit HopTokenSwap(\n _hopData.chainId,\n _hopData.bridge,\n _hopData.ammWrapper,\n _hopData.recipient,\n _hopData.asset,\n _hopData.amount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n }\n\n /// private Methods ///\n\n /**\n * @dev returns local storage\n */\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n\n /**\n * @dev returns current chain layer number\n * @return uint256 layer number\n */\n function getLayerId() private view returns (uint256) {\n return getStorage().chainLayerId;\n }\n\n /**\n * @dev fetch chain id\n */\n function getChainID() private view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n}\n" + }, + "src/bridges/interfaces/IHopBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.4;\n\ninterface IHopBridge {\n function sendToL2(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 amountOutMin,\n uint256 deadline,\n address relayer,\n uint256 relayerFee\n ) external payable;\n\n function swapAndSend(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 deadline,\n uint256 destinationAmountOutMin,\n uint256 destinationDeadline\n ) external payable;\n}\n" + } + }, + "settings": { + "evmVersion": "istanbul", + "metadata": { + "bytecodeHash": "none", + "useLiteralContent": true + }, + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + } + } +} \ No newline at end of file diff --git a/deployments/neonDevnet/solcInputs/ae94371f40f594d6ee02698e497ed59a.json b/deployments/neonDevnet/solcInputs/ae94371f40f594d6ee02698e497ed59a.json new file mode 100644 index 00000000..5b95b205 --- /dev/null +++ b/deployments/neonDevnet/solcInputs/ae94371f40f594d6ee02698e497ed59a.json @@ -0,0 +1,229 @@ +{ + "language": "Solidity", + "sources": { + "src/bridges/Diamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport {LibDiamond} from \"./libs/LibDiamond.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\ncontract Diamond {\n constructor(address _contractOwner, address _diamondCutFacet) payable {\n LibDiamond.setContractOwner(_contractOwner);\n\n // Add the diamondCut external function from the diamondCutFacet\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n\n // get diamond storage\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ds.slot := position\n }\n\n // get facet from function selector\n address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;\n require(facet != address(0), \"Diamond: Function does not exist\");\n\n // Execute external function from facet using delegatecall and return any value.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n // Able to receive ether\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n}\n" + }, + "src/bridges/libs/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\nlibrary LibDiamond {\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\n keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(\n msg.sender == diamondStorage().contractOwner,\n \"LibDiamond: Must be contract owner\"\n );\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n require(\n _functionSelectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n require(\n _functionSelectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n require(\n _functionSelectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress)\n internal\n {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata)\n internal\n {\n if (_init == address(0)) {\n require(\n _calldata.length == 0,\n \"LibDiamondCut: _init is address(0) but_calldata is not empty\"\n );\n } else {\n require(\n _calldata.length > 0,\n \"LibDiamondCut: _calldata is empty but _init is not address(0)\"\n );\n if (_init != address(this)) {\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n }\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "src/bridges/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "src/bridges/facets/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport { IDiamondCut } from \"../interfaces/IDiamondCut.sol\";\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\n\ncontract DiamondCutFacet is IDiamondCut {\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n}\n" + }, + "src/bridges/facets/ConnextFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IConnextHandler } from \"@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnextHandler.sol\";\nimport { CallParams, XCallArgs } from \"@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\n\n/**\n * @title Connext Amarok Integration\n *\n * @notice Contract which provides bridging functionality through Connext\n *\n */\ncontract ConnextFacet {\n // storage\n \n bytes32 internal constant NAMESPACE = keccak256(\"io.etherspot.facets.connext\");\n struct Storage {\n address connext;\n uint32 domainId;\n }\n\n // events\n\n /**\n * @dev Emitted when facet initializes\n * @param _connext connext handler address\n */\n event ConnextInitialized(address _connext);\n\n /**\n * @dev Emitted on erc20 token swap\n * @param _destination destination domain\n * @param _recipient recipient\n * @param _asset address of the asset\n * @param _amount amount of assets\n * @param _relayerFee fee\n * @param _transferId transfer ID of created crosschain transfer\n */\n event ConnextTokenSwap(\n uint32 indexed _destination,\n address indexed _recipient,\n address indexed _asset,\n uint256 _amount,\n uint256 _relayerFee,\n bytes32 _transferId\n );\n\n /**\n * @dev Emitted on native asset swap\n * @param _destination destination domain\n * @param _recipient recipient\n * @param _amount amount of assets\n * @param _relayerFee fee\n * @param _transferId transfer ID of created crosschain transfer\n */\n event ConnextNativeSwap(\n uint32 indexed _destination,\n address indexed _recipient,\n uint256 _amount,\n uint256 _relayerFee,\n bytes32 _transferId\n );\n\n /**\n * @dev Emitted on connext crosschain call\n * @param _destination destination domain\n * @param _recipient recipient of a call\n * @param _asset asset being sent / traded\n * @param _amount amount of asset\n * @param _callData call data\n * @param _relayerFee fee\n * @param _transferId transfer ID of created crosschain transfer\n */\n event ConnextXCall(\n uint32 indexed _destination,\n address indexed _recipient,\n address _asset,\n uint256 _amount,\n bytes _callData,\n uint256 _relayerFee,\n bytes32 _transferId\n );\n\n // init\n\n /**\n * @notice Initializes local variables for the Connext facet\n * @param _connext connext handler address\n */\n function initConnext(address _connext, uint32 _domainId) external {\n LibDiamond.enforceIsContractOwner();\n require(\n _connext != address(0),\n \"Connext: invalid address\"\n );\n Storage storage s = getStorage();\n s.connext = _connext;\n s.domainId = _domainId;\n emit ConnextInitialized(_connext);\n }\n\n /**\n * @notice Transfer ERC20 tokens\n * @param _asset - The asset the caller sent with the transfer\n * @param _to - The address you are sending funds (and potentially data) to\n * @param _destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called)\n * @param _amount - The amount of transferring asset the tx called xcall with\n * @param _relayerFee - The amount of relayer fee the tx called xcall with\n */\n function connextTokenTransfer(\n address _asset,\n address _to,\n uint32 _destinationDomain,\n uint256 _amount,\n uint256 _relayerFee\n ) external payable {\n bytes32 transferId = xcall(\n _to,\n \"\",\n getDomainId(),\n _destinationDomain,\n _asset,\n _amount,\n _relayerFee,\n msg.sender,\n address(0),\n 0,\n false\n );\n emit ConnextTokenSwap(\n _destinationDomain,\n _to,\n _asset,\n _amount,\n _relayerFee,\n transferId\n );\n }\n\n /**\n * @notice Transfer native asset\n * @param _to - The address you are sending funds (and potentially data) to\n * @param _destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called)\n * @param _relayerFee - The amount of relayer fee the tx called xcall with\n */\n function connextNativeAssetTransfer(\n address _to,\n uint32 _destinationDomain,\n uint256 _relayerFee\n ) external payable {\n bytes32 transferId = xcall(\n _to,\n \"\",\n getDomainId(),\n _destinationDomain,\n address(0),\n msg.value,\n _relayerFee,\n msg.sender,\n address(0),\n 0,\n false\n );\n emit ConnextNativeSwap(\n _destinationDomain,\n _to,\n msg.value,\n _relayerFee,\n transferId\n );\n }\n\n /**\n * @notice Crosschain function call\n * @param _to - The address you are sending funds (and potentially data) to\n * @param _callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty\n * @param _destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called)\n * @param _asset - The asset the caller sent with the transfer\n * @param _amount - The amount of transferring asset the tx called xcall with\n * @param _relayerFee - The amount of relayer fee the tx called xcall with\n * @param _recovery - The address to send funds to if your `Executor.execute call` fails\n * @param _callback - The address on the origin domain of the callback contract\n * @param _callbackFee - The relayer fee to execute the callback\n */\n function connextCall(\n address _to,\n bytes memory _callData,\n uint32 _destinationDomain,\n address _asset,\n uint256 _amount,\n uint256 _relayerFee,\n address _recovery,\n address _callback,\n uint256 _callbackFee\n ) external payable {\n bytes32 transferId = xcall(\n _to,\n _callData,\n getDomainId(),\n _destinationDomain,\n _asset,\n _amount,\n _relayerFee,\n _recovery,\n _callback,\n _callbackFee,\n false\n );\n emit ConnextXCall(\n _destinationDomain,\n _to,\n _asset,\n _amount,\n _callData,\n _relayerFee,\n transferId\n );\n }\n\n\n /**\n * @notice Wrapper over connext.call\n * @param _to - The address you are sending funds (and potentially data) to\n * @param _callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty\n * @param _originDomain - The originating domain (i.e. where `xcall` is called)\n * @param _destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called)\n * @param _asset - The asset the caller sent with the transfer\n * @param _amount - The amount of transferring asset the tx called xcall with\n * @param _relayerFee - The amount of relayer fee the tx called xcall with\n * @param _recovery - The address to send funds to if your `Executor.execute call` fails\n * @param _callback - The address on the origin domain of the callback contract\n * @param _callbackFee - The relayer fee to execute the callback\n * @param _forceSlow - If true, will take slow liquidity path even if it is not a permissioned call\n */\n function xcall(\n address _to,\n bytes memory _callData,\n uint32 _originDomain,\n uint32 _destinationDomain,\n address _asset,\n uint256 _amount,\n uint256 _relayerFee,\n address _recovery,\n address _callback,\n uint256 _callbackFee,\n bool _forceSlow\n ) internal returns (bytes32 transferId) {\n depositAssetAndFees(_asset, _amount, _relayerFee, _callbackFee);\n if (_asset != address(0)) {\n IERC20(_asset).approve(getConnext(), _amount);\n }\n IConnextHandler connext = IConnextHandler(getConnext());\n CallParams memory callParams = CallParams({\n to: _to,\n callData: _callData,\n originDomain: _originDomain,\n destinationDomain: _destinationDomain,\n recovery: _recovery,\n callback: _callback,\n callbackFee: _callbackFee,\n forceSlow: _forceSlow,\n receiveLocal: false,\n relayerFee: _relayerFee,\n slippageTol: 9995, // .05% slippage\n agent: _to\n });\n XCallArgs memory xcallArgs = XCallArgs({\n params: callParams,\n transactingAssetId: _asset,\n amount: _amount\n });\n transferId = connext.xcall{value: msg.value}(xcallArgs);\n }\n\n /**\n * @dev handles asset deposit\n * @param _asset asset address, 0 for native asset\n * @param _amount amount of asset\n */\n function depositAssetAndFees(\n address _asset,\n uint256 _amount,\n uint256 _relayerFee,\n uint256 _callbackFee\n )\n private\n {\n if (_asset == address(0)) {\n require(msg.value == _amount + _relayerFee + _callbackFee, \"Connext: Invalid value\");\n } else {\n require(msg.value == _relayerFee + _callbackFee, \"Connext: Invalid value\");\n uint256 _tokenBalanceBefore = IERC20(_asset).balanceOf(address(this));\n IERC20(_asset).transferFrom(msg.sender, address(this), _amount);\n uint256 _tokenBalanceAfter = IERC20(_asset).balanceOf(address(this));\n require(_tokenBalanceAfter - _tokenBalanceBefore == _amount, \"Connext: Invalid value\");\n }\n }\n\n\n /**\n * @dev returns connext handler\n * @return IConnextHandler connext handler\n */\n function getConnext() private view returns (address) {\n Storage storage s = getStorage();\n return s.connext;\n }\n\n /**\n * @dev returns chain id\n * @return uint32 chain id\n */\n function getDomainId() private view returns (uint32) {\n Storage storage s = getStorage();\n return s.domainId;\n }\n\n /**\n * @dev fetch local storage\n */\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnextHandler.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {XAppConnectionManager} from \"../../../nomad-core/contracts/XAppConnectionManager.sol\";\n\nimport {RelayerFeeRouter} from \"../../relayer-fee/RelayerFeeRouter.sol\";\nimport {PromiseRouter} from \"../../promise/PromiseRouter.sol\";\n\nimport {ConnextMessage} from \"../libraries/ConnextMessage.sol\";\nimport {XCallArgs, ExecuteArgs, CallParams} from \"../libraries/LibConnextStorage.sol\";\nimport {SwapUtils} from \"../libraries/SwapUtils.sol\";\n\nimport {IStableSwap} from \"./IStableSwap.sol\";\nimport {ITokenRegistry} from \"./ITokenRegistry.sol\";\nimport {IWrapped} from \"./IWrapped.sol\";\nimport {IExecutor} from \"./IExecutor.sol\";\nimport {ISponsorVault} from \"./ISponsorVault.sol\";\n\nimport {IDiamondCut} from \"./IDiamondCut.sol\";\n\ninterface IConnextHandler {\n // AssetFacet\n function canonicalToAdopted(bytes32 _canonicalId) external view returns (address);\n\n function adoptedToCanonical(address _adopted) external view returns (ConnextMessage.TokenId memory);\n\n function approvedAssets(bytes32 _asset) external view returns (bool);\n\n function adoptedToLocalPools(bytes32 _adopted) external view returns (IStableSwap);\n\n function setupAsset(\n ConnextMessage.TokenId calldata _canonical,\n address _adoptedAssetId,\n address _stableSwapPool\n ) external;\n\n function addStableSwapPool(ConnextMessage.TokenId calldata _canonical, address _stableSwapPool) external;\n\n function removeAssetId(bytes32 _canonicalId, address _adoptedAssetId) external;\n\n // BaseConnextFacet\n function isRouterOwnershipRenounced() external view returns (bool);\n\n function isAssetOwnershipRenounced() external view returns (bool);\n\n function VERSION() external view returns (uint8);\n\n // BridgeFacet\n function relayerFees(bytes32 _transferId) external view returns (uint256);\n\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\n\n function reconciledTransfers(bytes32 _transferId) external view returns (bool);\n\n function tokenRegistry() external view returns (ITokenRegistry);\n\n function domain() external view returns (uint256);\n\n function executor() external view returns (IExecutor);\n\n function nonce() external view returns (uint256);\n\n function wrapper() external view returns (IWrapped);\n\n function sponsorVault() external view returns (ISponsorVault);\n\n function promiseRouter() external view returns (PromiseRouter);\n\n function relayerFeeRouer() external view returns (RelayerFeeRouter);\n\n function setTokenRegistry(address _tokenRegistry) external;\n\n function setRelayerFeeRouter(address _relayerFeeRouter) external;\n\n function setPromiseRouter(address payable _promiseRouter) external;\n\n function setExecutor(address _executor) external;\n\n function setWrapper(address _wrapper) external;\n\n function setSponsorVault(address _sponsorVault) external;\n\n function xcall(XCallArgs calldata _args) external payable returns (bytes32);\n\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external;\n\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\n\n function bumpTransfer(bytes32 _transferId) external payable;\n\n function forceReceiveLocal(\n CallParams calldata _params,\n uint256 _amount,\n uint256 _nonce,\n bytes32 _canonicalId,\n uint32 _canonicalDomain,\n address _originSender\n ) external payable;\n\n // NomadFacet\n function xAppConnectionManager() external view returns (XAppConnectionManager);\n\n function remotes(uint32 _domain) external view returns (bytes32);\n\n function setXAppConnectionManager(address _xAppConnectionManager) external;\n\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n // ProposedOwnableFacet\n function routerOwnershipRenounced() external view returns (bool);\n\n function assetOwnershipRenounced() external view returns (bool);\n\n function proposedOwnableOwner() external view returns (address);\n\n function proposed() external view returns (address);\n\n function proposedTimestamp() external view returns (uint256);\n\n function routerOwnershipTimestamp() external view returns (uint256);\n\n function assetOwnershipTimestamp() external view returns (uint256);\n\n function delay() external view returns (uint256);\n\n function proposeRouterOwnershipRenunciation() external;\n\n function renounceRouterOwnership() external;\n\n function proposeAssetOwnershipRenunciation() external;\n\n function renounceAssetOwnership() external;\n\n function renounced() external view returns (bool);\n\n function proposeNewOwner(address newlyProposed) external;\n\n function renounceOwnership() external;\n\n function acceptProposedOwner() external;\n\n function pause() external;\n\n function unpause() external;\n\n // RelayerFacet\n function transferRelayer(bytes32 _transferId) external view returns (address);\n\n function approvedRelayers(address _relayer) external view returns (bool);\n\n function relayerFeeRouter() external view returns (RelayerFeeRouter);\n\n function addRelayer(address _relayer) external;\n\n function removeRelayer(address _relayer) external;\n\n function initiateClaim(\n uint32 _domain,\n address _recipient,\n bytes32[] calldata _transferIds\n ) external;\n\n function claim(address _recipient, bytes32[] calldata _transferIds) external;\n\n // RoutersFacet\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\n\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\n\n function getRouterApproval(address _router) external view returns (bool);\n\n function getRouterRecipient(address _router) external view returns (address);\n\n function getRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\n\n function maxRoutersPerTransfer() external view returns (uint256);\n\n function setLiquidityFeeNumerator(uint256 _numerator) external;\n\n function routerBalances(address _router, address _asset) external view returns (uint256);\n\n function setRouterRecipient(address router, address recipient) external;\n\n function proposeRouterOwner(address router, address proposed) external;\n\n function acceptProposedRouterOwner(address router) external;\n\n function setupRouter(\n address router,\n address owner,\n address recipient\n ) external;\n\n function removeRouter(address router) external;\n\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\n\n function addRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address _router\n ) external payable;\n\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\n\n function removeRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address payable _to,\n address _router\n ) external;\n\n function removeRouterLiquidity(\n uint256 _amount,\n address _local,\n address payable _to\n ) external;\n\n // PortalFacet\n function getRouterApprovalForPortal(address _router) external view returns (bool);\n\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\n\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\n\n function aavePool() external view returns (address);\n\n function aavePortalFee() external view returns (uint256);\n\n function approveRouterForPortal(address _router) external;\n\n function unapproveRouterForPortal(address _router) external;\n\n function setAavePool(address _aavePool) external;\n\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\n\n function repayAavePortal(\n address _asset,\n uint256 _backingAmount,\n uint256 _feeAmount,\n uint256 _maxIn,\n bytes32 _transferId\n ) external;\n\n function repayAavePortalFor(\n address _router,\n address _adopted,\n uint256 _backingAmount,\n uint256 _feeAmount,\n bytes32 _transferId\n ) external;\n\n // StableSwapFacet\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\n\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\n\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\n\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\n\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\n\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\n\n function calculateSwap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapTokenAmount(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n bool deposit\n ) external view returns (uint256);\n\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) external view returns (uint256);\n\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\n\n function swap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n bytes32 canonicalId,\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n bytes32 canonicalId,\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function addSwapLiquidity(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidity(\n bytes32 canonicalId,\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidityImbalance(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function initializeSwap(\n bytes32 _canonicalId,\n IERC20[] memory _pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 _a,\n uint256 _fee,\n uint256 _adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\n\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\n\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\n\n function rampA(\n bytes32 canonicalId,\n uint256 futureA,\n uint256 futureTime\n ) external;\n\n function stopRampA(bytes32 canonicalId) external;\n\n // DiamondCutFacet\n function diamondCut(\n IDiamondCut.FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n function proposeDiamondCut(\n IDiamondCut.FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n function rescindDiamondCut(\n IDiamondCut.FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {XAppConnectionManager} from \"../../../nomad-core/contracts/XAppConnectionManager.sol\";\n\nimport {RelayerFeeRouter} from \"../../relayer-fee/RelayerFeeRouter.sol\";\nimport {PromiseRouter} from \"../../promise/PromiseRouter.sol\";\n\nimport {ITokenRegistry} from \"../interfaces/ITokenRegistry.sol\";\nimport {IWrapped} from \"../interfaces/IWrapped.sol\";\nimport {IExecutor} from \"../interfaces/IExecutor.sol\";\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\nimport {ISponsorVault} from \"../interfaces/ISponsorVault.sol\";\n\nimport {ConnextMessage} from \"./ConnextMessage.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n// ============= Structs =============\n\n/**\n * @notice These are the call parameters that will remain constant between the\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\n * @property to - The account that receives funds, in the event of a crosschain call,\n * will receive funds if the call fails.\n * @param to - The address you are sending funds (and potentially data) to\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\n * @param agent - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n * @param recovery - The address to send funds to if your `Executor.execute call` fails\n * @param callback - The address on the origin domain of the callback contract\n * @param callbackFee - The relayer fee to execute the callback\n * @param forceSlow - If true, will take slow liquidity path even if it is not a permissioned call\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\n * @param relayerFee - The amount of relayer fee the tx called xcall with\n * @param slippageTol - Max bps of original due to slippage (i.e. would be 9995 to tolerate .05% slippage)\n */\nstruct CallParams {\n address to;\n bytes callData;\n uint32 originDomain;\n uint32 destinationDomain;\n address agent;\n address recovery;\n bool forceSlow;\n bool receiveLocal;\n address callback;\n uint256 callbackFee;\n uint256 relayerFee;\n uint256 slippageTol;\n}\n\n/**\n * @notice The arguments you supply to the `xcall` function called by user on origin domain\n * @param params - The CallParams. These are consistent across sending and receiving chains\n * @param transactingAssetId - The asset the caller sent with the transfer. Can be the adopted, canonical,\n * or the representational asset\n * @param amount - The amount of transferring asset the tx called xcall with\n */\nstruct XCallArgs {\n CallParams params;\n address transactingAssetId; // Could be adopted, local, or wrapped\n uint256 amount;\n}\n\n/**\n * @notice\n * @param params - The CallParams. These are consistent across sending and receiving chains\n * @param local - The local asset for the transfer, will be swapped to the adopted asset if\n * appropriate\n * @param routers - The routers who you are sending the funds on behalf of\n * @param amount - The amount of liquidity the router provided or the bridge forwarded, depending on\n * if fast liquidity was used\n * @param nonce - The nonce used to generate transfer id\n * @param originSender - The msg.sender of the xcall on origin domain\n */\nstruct ExecuteArgs {\n CallParams params;\n address local; // local representation of canonical token\n address[] routers;\n bytes[] routerSignatures;\n uint256 amount;\n uint256 nonce;\n address originSender;\n}\n\n/**\n * @notice Contains RouterFacet related state\n * @param approvedRouters - Mapping of whitelisted router addresses\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\n * (if configured) or the router itself\n * @param routerOwners - Mapping of router owners\n * If set, can update the routerRecipient\n * @param proposedRouterOwners - Mapping of proposed router owners\n * Must wait timeout to set the\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\n * When accepting a proposed owner, must wait for delay to elapse\n */\nstruct RouterPermissionsManagerInfo {\n mapping(address => bool) approvedRouters;\n mapping(address => bool) approvedForPortalRouters;\n mapping(address => address) routerRecipients;\n mapping(address => address) routerOwners;\n mapping(address => address) proposedRouterOwners;\n mapping(address => uint256) proposedRouterTimestamp;\n}\n\nstruct AppStorage {\n bool initialized;\n //\n // ConnextHandler\n //\n // 0\n uint256 LIQUIDITY_FEE_NUMERATOR;\n // 1\n uint256 LIQUIDITY_FEE_DENOMINATOR;\n // The local nomad relayer fee router\n // 2\n RelayerFeeRouter relayerFeeRouter;\n // The local nomad promise callback router\n // 3\n PromiseRouter promiseRouter;\n // /**\n // * @notice The address of the wrapper for the native asset on this domain\n // * @dev Needed because the nomad only handles ERC20 assets\n // */\n // 4\n IWrapped wrapper;\n // /**\n // * @notice Nonce for the contract, used to keep unique transfer ids.\n // * @dev Assigned at first interaction (xcall on origin domain);\n // */\n // 5\n uint256 nonce;\n // /**\n // * @notice The external contract that will execute crosschain calldata\n // */\n // 6\n IExecutor executor;\n // /**\n // * @notice The domain this contract exists on\n // * @dev Must match the nomad domain, which is distinct from the \"chainId\"\n // */\n // 7\n uint32 domain;\n // /**\n // * @notice The local nomad token registry\n // */\n // 8\n ITokenRegistry tokenRegistry;\n // /**\n // * @notice Mapping holding the AMMs for swapping in and out of local assets\n // * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\n // */\n // 9\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\n // /**\n // * @notice Mapping of whitelisted assets on same domain as contract\n // * @dev Mapping is keyed on the canonical token identifier matching what is stored in the token\n // * registry\n // */\n // 10\n mapping(bytes32 => bool) approvedAssets;\n // /**\n // * @notice Mapping of canonical to adopted assets on this domain\n // * @dev If the adopted asset is the native asset, the keyed address will\n // * be the wrapped asset address\n // */\n // 11\n mapping(address => ConnextMessage.TokenId) adoptedToCanonical;\n // /**\n // * @notice Mapping of adopted to canonical on this domain\n // * @dev If the adopted asset is the native asset, the stored address will be the\n // * wrapped asset address\n // */\n // 12\n mapping(bytes32 => address) canonicalToAdopted;\n // /**\n // * @notice Mapping to determine if transfer is reconciled\n // */\n // 13\n mapping(bytes32 => bool) reconciledTransfers;\n // /**\n // * @notice Mapping holding router address that provided fast liquidity\n // */\n // 14\n mapping(bytes32 => address[]) routedTransfers;\n // /**\n // * @notice Mapping of router to available balance of an asset\n // * @dev Routers should always store liquidity that they can expect to receive via the bridge on\n // * this domain (the nomad local asset)\n // */\n // 15\n mapping(address => mapping(address => uint256)) routerBalances;\n // /**\n // * @notice Mapping of approved relayers\n // * @dev Send relayer fee if msg.sender is approvedRelayer. otherwise revert()\n // */\n // 16\n mapping(address => bool) approvedRelayers;\n // /**\n // * @notice Stores the relayer fee for a transfer. Updated on origin domain when a user calls xcall or bump\n // * @dev This will track all of the relayer fees assigned to a transfer by id, including any bumps made by the relayer\n // */\n // 17\n mapping(bytes32 => uint256) relayerFees;\n // /**\n // * @notice Stores the relayer of a transfer. Updated on the destination domain when a relayer calls execute\n // * for transfer\n // * @dev When relayer claims, must check that the msg.sender has forwarded transfer\n // */\n // 18\n mapping(bytes32 => address) transferRelayer;\n // /**\n // * @notice The max amount of routers a payment can be routed through\n // */\n // 19\n uint256 maxRoutersPerTransfer;\n // /**\n // * @notice The Vault used for sponsoring fees\n // */\n // 20\n ISponsorVault sponsorVault;\n //\n // Router\n //\n // 21\n mapping(uint32 => bytes32) remotes;\n //\n // XAppConnectionClient\n //\n // 22\n XAppConnectionManager xAppConnectionManager;\n //\n // ProposedOwnable\n //\n // 23\n address _proposed;\n // 24\n uint256 _proposedOwnershipTimestamp;\n // 25\n bool _routerOwnershipRenounced;\n // 26\n uint256 _routerOwnershipTimestamp;\n // 27\n bool _assetOwnershipRenounced;\n // 28\n uint256 _assetOwnershipTimestamp;\n //\n // RouterFacet\n //\n // 29\n RouterPermissionsManagerInfo routerPermissionInfo;\n //\n // ReentrancyGuard\n //\n // 30\n uint256 _status;\n //\n // StableSwap\n //\n /**\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\n * Struct storing data responsible for automatic market maker functionalities. In order to\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol\n */\n // 31\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\n /**\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\n */\n // 32\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\n /**\n * @notice Stores whether or not bribing, AMMs, have been paused\n */\n // 33\n bool _paused;\n //\n // AavePortals\n //\n /**\n * @notice Address of Aave Pool contract\n */\n address aavePool;\n /**\n * @notice Fee percentage numerator for using Portal liquidity\n * @dev Assumes the same basis points as the liquidity fee\n */\n uint256 aavePortalFeeNumerator;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals\n */\n mapping(bytes32 => uint256) portalDebt;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals\n */\n mapping(bytes32 => uint256) portalFeeDebt;\n //\n // BridgeFacet (cont.) TODO: can we move this\n //\n /**\n * @notice Stores whether a transfer has had `receiveLocal` overrides forced\n */\n // 34\n mapping(bytes32 => bool) receiveLocalOverrides;\n}\n\nlibrary LibConnextStorage {\n function connextStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/contracts/XAppConnectionManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ Internal Imports ============\nimport {Home} from \"./Home.sol\";\nimport {Replica} from \"./Replica.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\n// ============ External Imports ============\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title XAppConnectionManager\n * @author Illusory Systems Inc.\n * @notice Manages a registry of local Replica contracts\n * for remote Home domains. Accepts Watcher signatures\n * to un-enroll Replicas attached to fraudulent remote Homes\n */\ncontract XAppConnectionManager is Ownable {\n // ============ Public Storage ============\n\n // Home contract\n Home public home;\n // local Replica address => remote Home domain\n mapping(address => uint32) public replicaToDomain;\n // remote Home domain => local Replica address\n mapping(uint32 => address) public domainToReplica;\n // watcher address => replica remote domain => has/doesn't have permission\n mapping(address => mapping(uint32 => bool)) private watcherPermissions;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new Replica is enrolled / added\n * @param domain the remote domain of the Home contract for the Replica\n * @param replica the address of the Replica\n */\n event ReplicaEnrolled(uint32 indexed domain, address replica);\n\n /**\n * @notice Emitted when a new Replica is un-enrolled / removed\n * @param domain the remote domain of the Home contract for the Replica\n * @param replica the address of the Replica\n */\n event ReplicaUnenrolled(uint32 indexed domain, address replica);\n\n /**\n * @notice Emitted when Watcher permissions are changed\n * @param domain the remote domain of the Home contract for the Replica\n * @param watcher the address of the Watcher\n * @param access TRUE if the Watcher was given permissions, FALSE if permissions were removed\n */\n event WatcherPermissionSet(uint32 indexed domain, address watcher, bool access);\n\n // ============ Modifiers ============\n\n modifier onlyReplica() {\n require(isReplica(msg.sender), \"!replica\");\n _;\n }\n\n // ============ Constructor ============\n\n // solhint-disable-next-line no-empty-blocks\n constructor() Ownable() {}\n\n // ============ External Functions ============\n\n /**\n * @notice Un-Enroll a replica contract\n * in the case that fraud was detected on the Home\n * @dev in the future, if fraud occurs on the Home contract,\n * the Watcher will submit their signature directly to the Home\n * and it can be relayed to all remote chains to un-enroll the Replicas\n * @param _domain the remote domain of the Home contract for the Replica\n * @param _updater the address of the Updater for the Home contract (also stored on Replica)\n * @param _signature signature of watcher on (domain, replica address, updater address)\n */\n function unenrollReplica(\n uint32 _domain,\n bytes32 _updater,\n bytes memory _signature\n ) external {\n // ensure that the replica is currently set\n address _replica = domainToReplica[_domain];\n require(_replica != address(0), \"!replica exists\");\n // ensure that the signature is on the proper updater\n require(Replica(_replica).updater() == TypeCasts.bytes32ToAddress(_updater), \"!current updater\");\n // get the watcher address from the signature\n // and ensure that the watcher has permission to un-enroll this replica\n address _watcher = _recoverWatcherFromSig(_domain, TypeCasts.addressToBytes32(_replica), _updater, _signature);\n require(watcherPermissions[_watcher][_domain], \"!valid watcher\");\n // remove the replica from mappings\n _unenrollReplica(_replica);\n }\n\n /**\n * @notice Set the address of the local Home contract\n * @param _home the address of the local Home contract\n */\n function setHome(address _home) external onlyOwner {\n home = Home(_home);\n }\n\n /**\n * @notice Allow Owner to enroll Replica contract\n * @param _replica the address of the Replica\n * @param _domain the remote domain of the Home contract for the Replica\n */\n function ownerEnrollReplica(address _replica, uint32 _domain) external onlyOwner {\n // un-enroll any existing replica\n _unenrollReplica(_replica);\n // add replica and domain to two-way mapping\n replicaToDomain[_replica] = _domain;\n domainToReplica[_domain] = _replica;\n emit ReplicaEnrolled(_domain, _replica);\n }\n\n /**\n * @notice Allow Owner to un-enroll Replica contract\n * @param _replica the address of the Replica\n */\n function ownerUnenrollReplica(address _replica) external onlyOwner {\n _unenrollReplica(_replica);\n }\n\n /**\n * @notice Allow Owner to set Watcher permissions for a Replica\n * @param _watcher the address of the Watcher\n * @param _domain the remote domain of the Home contract for the Replica\n * @param _access TRUE to give the Watcher permissions, FALSE to remove permissions\n */\n function setWatcherPermission(\n address _watcher,\n uint32 _domain,\n bool _access\n ) external onlyOwner {\n watcherPermissions[_watcher][_domain] = _access;\n emit WatcherPermissionSet(_domain, _watcher, _access);\n }\n\n /**\n * @notice Query local domain from Home\n * @return local domain\n */\n function localDomain() external view returns (uint32) {\n return home.localDomain();\n }\n\n /**\n * @notice Get access permissions for the watcher on the domain\n * @param _watcher the address of the watcher\n * @param _domain the domain to check for watcher permissions\n * @return TRUE iff _watcher has permission to un-enroll replicas on _domain\n */\n function watcherPermission(address _watcher, uint32 _domain) external view returns (bool) {\n return watcherPermissions[_watcher][_domain];\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check whether _replica is enrolled\n * @param _replica the replica to check for enrollment\n * @return TRUE iff _replica is enrolled\n */\n function isReplica(address _replica) public view returns (bool) {\n return replicaToDomain[_replica] != 0;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Remove the replica from the two-way mappings\n * @param _replica replica to un-enroll\n */\n function _unenrollReplica(address _replica) internal {\n uint32 _currentDomain = replicaToDomain[_replica];\n domainToReplica[_currentDomain] = address(0);\n replicaToDomain[_replica] = 0;\n emit ReplicaUnenrolled(_currentDomain, _replica);\n }\n\n /**\n * @notice Get the Watcher address from the provided signature\n * @return address of watcher that signed\n */\n function _recoverWatcherFromSig(\n uint32 _domain,\n bytes32 _replica,\n bytes32 _updater,\n bytes memory _signature\n ) internal view returns (address) {\n bytes32 _homeDomainHash = Replica(TypeCasts.bytes32ToAddress(_replica)).homeDomainHash();\n bytes32 _digest = keccak256(abi.encodePacked(_homeDomainHash, _domain, _updater));\n _digest = ECDSA.toEthSignedMessageHash(_digest);\n return ECDSA.recover(_digest, _signature);\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/relayer-fee/RelayerFeeRouter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\nimport {Home} from \"../../nomad-core/contracts/Home.sol\";\nimport {TypedMemView} from \"../../nomad-core/libs/TypedMemView.sol\";\n\nimport {IConnextHandler} from \"../connext/interfaces/IConnextHandler.sol\";\n\nimport {Router} from \"../shared/Router.sol\";\nimport {XAppConnectionClient} from \"../shared/XAppConnectionClient.sol\";\nimport {Version} from \"../shared/Version.sol\";\n\nimport {RelayerFeeMessage} from \"./libraries/RelayerFeeMessage.sol\";\n\n/**\n * @title RelayerFeeRouter\n */\ncontract RelayerFeeRouter is Version, Router {\n // ============ Libraries ============\n\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n using RelayerFeeMessage for bytes29;\n\n // ========== Custom Errors ===========\n\n error RelayerFeeRouter__onlyConnext_notConnext();\n error RelayerFeeRouter__send_claimEmpty();\n error RelayerFeeRouter__send_recipientEmpty();\n\n // ============ Public Storage ============\n\n IConnextHandler public connext;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[49] private __GAP;\n\n // ======== Events =========\n\n /**\n * @notice Emitted when a fees claim has been initialized in this domain\n * @param domain The domain where to claim the fees\n * @param recipient The address of the relayer\n * @param transferIds A group of transaction ids to claim for fee bumps\n * @param remote Remote RelayerFeeRouter address\n * @param message The message sent to the destination domain\n */\n event Send(uint32 domain, address recipient, bytes32[] transferIds, bytes32 remote, bytes message);\n\n /**\n * @notice Emitted when the a fees claim message has arrived to this domain\n * @param originAndNonce Domain where the transfer originated and the unique identifier\n * for the message from origin to destination, combined in a single field ((origin << 32) & nonce)\n * @param origin Domain where the transfer originated\n * @param recipient The address of the relayer\n * @param transferIds A group of transaction ids to claim for fee bumps\n */\n event Receive(uint64 indexed originAndNonce, uint32 indexed origin, address indexed recipient, bytes32[] transferIds);\n\n /**\n * @notice Emitted when a new Connext address is set\n * @param connext The new connext address\n */\n event SetConnext(address indexed connext);\n\n // ============ Modifiers ============\n\n /**\n * @notice Restricts the caller to the local bridge router\n */\n modifier onlyConnext() {\n if (msg.sender != address(connext)) revert RelayerFeeRouter__onlyConnext_notConnext();\n _;\n }\n\n // ======== Initializer ========\n\n function initialize(address _xAppConnectionManager) public initializer {\n __XAppConnectionClient_initialize(_xAppConnectionManager);\n }\n\n /**\n * @notice Sets the Connext.\n * @dev Connext and relayer fee router store references to each other\n * @param _connext The address of the Connext implementation\n */\n function setConnext(address _connext) external onlyOwner {\n connext = IConnextHandler(_connext);\n emit SetConnext(_connext);\n }\n\n // ======== External: Send Claim =========\n\n /**\n * @notice Sends a request to claim the fees in the originated domain\n * @param _domain The domain where to claim the fees\n * @param _recipient The address of the relayer\n * @param _transferIds A group of transfer ids to claim for fee bumps\n */\n function send(\n uint32 _domain,\n address _recipient,\n bytes32[] calldata _transferIds\n ) external onlyConnext {\n if (_transferIds.length == 0) revert RelayerFeeRouter__send_claimEmpty();\n if (_recipient == address(0)) revert RelayerFeeRouter__send_recipientEmpty();\n\n // get remote RelayerFeeRouter address; revert if not found\n bytes32 remote = _mustHaveRemote(_domain);\n\n bytes memory message = RelayerFeeMessage.formatClaimFees(_recipient, _transferIds);\n\n xAppConnectionManager.home().dispatch(_domain, remote, message);\n\n // emit Send event\n emit Send(_domain, _recipient, _transferIds, remote, message);\n }\n\n // ======== External: Handle =========\n\n /**\n * @notice Handles an incoming message\n * @param _origin The origin domain\n * @param _nonce The unique identifier for the message from origin to destination\n * @param _sender The sender address\n * @param _message The message\n */\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external override onlyReplica onlyRemoteRouter(_origin, _sender) {\n // parse recipient and transferIds from message\n bytes29 _msg = _message.ref(0).mustBeClaimFees();\n\n address recipient = _msg.recipient();\n bytes32[] memory transferIds = _msg.transferIds();\n\n connext.claim(recipient, transferIds);\n\n // emit Receive event\n emit Receive(_originAndNonce(_origin, _nonce), _origin, recipient, transferIds);\n }\n\n /**\n * @dev explicit override for compiler inheritance\n * @dev explicit override for compiler inheritance\n * @return domain of chain on which the contract is deployed\n */\n function _localDomain() internal view override(XAppConnectionClient) returns (uint32) {\n return XAppConnectionClient._localDomain();\n }\n\n /**\n * @notice Internal utility function that combines\n * `_origin` and `_nonce`.\n * @dev Both origin and nonce should be less than 2^32 - 1\n * @param _origin Domain of chain where the transfer originated\n * @param _nonce The unique identifier for the message from origin to destination\n * @return uint64 (`_origin` << 32) | `_nonce`\n */\n function _originAndNonce(uint32 _origin, uint32 _nonce) internal pure returns (uint64) {\n return (uint64(_origin) << 32) | _nonce;\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/promise/PromiseRouter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\nimport {Home} from \"../../nomad-core/contracts/Home.sol\";\nimport {TypedMemView} from \"../../nomad-core/libs/TypedMemView.sol\";\n\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {ReentrancyGuardUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\n\nimport {IConnextHandler} from \"../connext/interfaces/IConnextHandler.sol\";\nimport {IBridgeToken} from \"../connext/interfaces/IBridgeToken.sol\";\n\nimport {Router} from \"../shared/Router.sol\";\nimport {XAppConnectionClient} from \"../shared/XAppConnectionClient.sol\";\nimport {Version} from \"../shared/Version.sol\";\n\nimport {ICallback} from \"./interfaces/ICallback.sol\";\nimport {PromiseMessage} from \"./libraries/PromiseMessage.sol\";\n\n/**\n * @title PromiseRouter\n */\ncontract PromiseRouter is Version, Router, ReentrancyGuardUpgradeable {\n // ============ Libraries ============\n\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n using PromiseMessage for bytes29;\n\n // ========== Custom Errors ===========\n\n error PromiseRouter__onlyConnext_notConnext();\n error PromiseRouter__send_returndataEmpty();\n error PromiseRouter__send_callbackEmpty();\n error PromiseRouter__process_invalidTransferId();\n error PromiseRouter__process_invalidMessage();\n error PromiseRouter__process_notApprovedRelayer();\n error PromiseRouter__process_insufficientCallbackFee();\n error PromiseRouter__process_notContractCallback();\n error PromiseRouter__bumpCallbackFee_valueIsZero();\n error PromiseRouter__bumpCallbackFee_messageUnavailable();\n error PromiseRouter__initCallbackFee_valueIsZero();\n\n // ============ Public Storage ============\n\n IConnextHandler public connext;\n\n /**\n * @notice Mapping of transferId to promise callback messages\n * @dev While handling the message, it will parse transferId from incomming message and store the message in the mapping\n */\n mapping(bytes32 => bytes32) public messageHashes;\n\n /**\n * @notice Mapping of transferId to callback fee\n * @dev This will track all the callback fees for each transferId.\n * Can add while xcall or bumping callback fee\n */\n mapping(bytes32 => uint256) public callbackFees;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[49] private __GAP;\n\n // ======== Events =========\n\n /**\n * @notice Emitted when a promise callback has been sent from this domain\n * @param domain The domain where to execute the callback\n * @param remote Remote PromiseRouter address\n * @param transferId The transferId\n * @param callbackAddress The address of the callback\n * @param success The return success from the execution on the destination domain\n * @param data The returnData from the execution on the destination domain\n * @param message The message sent to the destination domain\n */\n event Send(\n uint32 domain,\n bytes32 remote,\n bytes32 transferId,\n address callbackAddress,\n bool success,\n bytes data,\n bytes message\n );\n\n /**\n * @notice Emitted when a promise callback message has arrived to this domain\n * @param originAndNonce Domain where the transfer originated and the unique identifier\n * for the message from origin to destination, combined in a single field ((origin << 32) & nonce)\n * @param origin Domain where the transfer originated\n * @param transferId The transferId\n * @param callbackAddress The address of the callback\n * @param success The return success from the execution on the destination domain\n * @param data The returnData from the execution on the destination domain\n * @param message The message sent to the destination domain\n */\n event Receive(\n uint64 indexed originAndNonce,\n uint32 indexed origin,\n bytes32 transferId,\n address callbackAddress,\n bool success,\n bytes data,\n bytes message\n );\n\n /**\n * @notice Emitted when transaction fee for callback added\n * @param transferId The transferId\n * @param addedFee The fee amount that added newly\n * @param totalFee The total fee amount, can be bumped by multiple times\n * @param caller The transaction caller\n */\n event CallbackFeeAdded(bytes32 indexed transferId, uint256 addedFee, uint256 totalFee, address caller);\n\n /**\n * @notice Emitted when callback function executed\n * @param transferId The transferId\n * @param relayer The address of the relayer which executed the callback\n */\n event CallbackExecuted(bytes32 indexed transferId, address relayer);\n\n /**\n * @notice Emitted when a new Connext address is set\n * @param connext The new connext address\n */\n event SetConnext(address indexed connext);\n\n // ============ Modifiers ============\n\n /**\n * @notice Restricts the caller to the local bridge router\n */\n modifier onlyConnext() {\n if (msg.sender != address(connext)) revert PromiseRouter__onlyConnext_notConnext();\n _;\n }\n\n // ======== Initializer ========\n\n function initialize(address _xAppConnectionManager) public initializer {\n __XAppConnectionClient_initialize(_xAppConnectionManager);\n }\n\n /**\n * @notice Sets the Connext.\n * @dev Connext and relayer fee router store references to each other\n * @param _connext The address of the Connext implementation\n */\n function setConnext(address _connext) external onlyOwner {\n connext = IConnextHandler(_connext);\n emit SetConnext(_connext);\n }\n\n // ======== External: Send PromiseCallback =========\n\n /**\n * @notice Sends a request to execute callback in the originated domain\n * @param _domain The domain where to execute callback\n * @param _transferId The transferId\n * @param _callbackAddress A callback address to be called when promise callback is received\n * @param _returnSuccess The returnSuccess from the execution\n * @param _returnData The returnData from the execution\n */\n function send(\n uint32 _domain,\n bytes32 _transferId,\n address _callbackAddress,\n bool _returnSuccess,\n bytes calldata _returnData\n ) external onlyConnext {\n if (_returnData.length == 0) revert PromiseRouter__send_returndataEmpty();\n if (_callbackAddress == address(0)) revert PromiseRouter__send_callbackEmpty();\n\n // get remote PromiseRouter address; revert if not found\n bytes32 remote = _mustHaveRemote(_domain);\n\n bytes memory message = PromiseMessage.formatPromiseCallback(\n _transferId,\n _callbackAddress,\n _returnSuccess,\n _returnData\n );\n\n xAppConnectionManager.home().dispatch(_domain, remote, message);\n\n // emit Send event\n emit Send(_domain, remote, _transferId, _callbackAddress, _returnSuccess, _returnData, message);\n }\n\n // ======== External: Handle =========\n\n /**\n * @notice Handles an incoming message\n * @param _origin The origin domain\n * @param _nonce The unique identifier for the message from origin to destination\n * @param _sender The sender address\n * @param _message The message\n */\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external override onlyReplica onlyRemoteRouter(_origin, _sender) {\n // parse transferId, callbackAddress, callData from message\n bytes29 _msg = _message.ref(0).mustBePromiseCallback();\n\n bytes32 transferId = _msg.transferId();\n address callbackAddress = _msg.callbackAddress();\n bool success = _msg.returnSuccess();\n bytes memory data = _msg.returnData();\n\n // store Promise message\n messageHashes[transferId] = _msg.keccak();\n\n // emit Receive event\n emit Receive(_originAndNonce(_origin, _nonce), _origin, transferId, callbackAddress, success, data, _message);\n }\n\n /**\n * @notice Process stored callback function\n * @param transferId The transferId to process\n */\n function process(bytes32 transferId, bytes calldata _message) public nonReentrant {\n // parse out the return data and callback address from message\n bytes32 messageHash = messageHashes[transferId];\n if (messageHash == bytes32(0)) revert PromiseRouter__process_invalidTransferId();\n\n bytes29 _msg = _message.ref(0).mustBePromiseCallback();\n if (messageHash != _msg.keccak()) revert PromiseRouter__process_invalidMessage();\n\n // enforce relayer is whitelisted by calling local connext contract\n if (!connext.approvedRelayers(msg.sender)) revert PromiseRouter__process_notApprovedRelayer();\n\n address callbackAddress = _msg.callbackAddress();\n\n if (!AddressUpgradeable.isContract(callbackAddress)) revert PromiseRouter__process_notContractCallback();\n\n uint256 callbackFee = callbackFees[transferId];\n\n // remove message\n delete messageHashes[transferId];\n\n // remove callback fees\n callbackFees[transferId] = 0;\n\n // execute callback\n ICallback(callbackAddress).callback(transferId, _msg.returnSuccess(), _msg.returnData());\n\n emit CallbackExecuted(transferId, msg.sender);\n\n // Should transfer the stored relayer fee to the msg.sender\n if (callbackFee != 0) {\n AddressUpgradeable.sendValue(payable(msg.sender), callbackFee);\n }\n }\n\n /**\n * @notice This function will be called on the origin domain to init the callback fee while xcall\n * @param _transferId - The unique identifier of the crosschain transaction\n */\n function initCallbackFee(bytes32 _transferId) external payable onlyConnext {\n if (msg.value == 0) revert PromiseRouter__initCallbackFee_valueIsZero();\n\n callbackFees[_transferId] += msg.value;\n\n emit CallbackFeeAdded(_transferId, msg.value, callbackFees[_transferId], msg.sender);\n }\n\n /**\n * @notice This function will be called on the origin domain to increase the callback fee\n * @param _transferId - The unique identifier of the crosschain transaction\n */\n function bumpCallbackFee(bytes32 _transferId) external payable {\n if (msg.value == 0) revert PromiseRouter__bumpCallbackFee_valueIsZero();\n\n // use the presence of the message to evaluate if the fee should be bumped.\n // this is to check that the user is not bumping a transferId that does not exist, or they\n // are not bumping the fees of a transfer that has already been processed.\n // the other options are to (a) track process status in a separate mapping (3 mappings updated)\n // on process) or (b) use the callbackFees mapping and require the callback fees are nonzero\n // on xcall (preventing 0-fee callbacks)\n if (messageHashes[_transferId] == bytes32(0)) revert PromiseRouter__bumpCallbackFee_messageUnavailable();\n\n callbackFees[_transferId] += msg.value;\n\n emit CallbackFeeAdded(_transferId, msg.value, callbackFees[_transferId], msg.sender);\n }\n\n /**\n * @dev explicit override for compiler inheritance\n * @return domain of chain on which the contract is deployed\n */\n function _localDomain() internal view override(XAppConnectionClient) returns (uint32) {\n return XAppConnectionClient._localDomain();\n }\n\n /**\n * @notice Internal utility function that combines\n * `_origin` and `_nonce`.\n * @dev Both origin and nonce should be less than 2^32 - 1\n * @param _origin Domain of chain where the transfer originated\n * @param _nonce The unique identifier for the message from origin to destination\n * @return uint64 (`_origin` << 32) | `_nonce`\n */\n function _originAndNonce(uint32 _origin, uint32 _nonce) internal pure returns (uint64) {\n return (uint64(_origin) << 32) | _nonce;\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/libraries/ConnextMessage.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {TypedMemView} from \"../../../nomad-core/libs/TypedMemView.sol\";\n\nlibrary ConnextMessage {\n // ============ Libraries ============\n\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n // ============ Enums ============\n\n // WARNING: do NOT re-write the numbers / order\n // of message types in an upgrade;\n // will cause in-flight messages to be mis-interpreted\n enum Types {\n Invalid, // 0\n TokenId, // 1\n Message, // 2\n Transfer // 3\n }\n\n // ============ Structs ============\n\n // Tokens are identified by a TokenId:\n // domain - 4 byte chain ID of the chain from which the token originates\n // id - 32 byte identifier of the token address on the origin chain, in that chain's address format\n struct TokenId {\n uint32 domain;\n bytes32 id;\n }\n\n // ============ Constants ============\n\n uint256 private constant TOKEN_ID_LEN = 36; // 4 bytes domain + 32 bytes id\n uint256 private constant IDENTIFIER_LEN = 1;\n uint256 private constant TRANSFER_LEN = 129;\n // 1 byte identifier + 32 bytes recipient + 32 bytes amount + 32 bytes detailsHash + 32 bytes external hash\n\n // ============ Modifiers ============\n\n /**\n * @notice Asserts a message is of type `_t`\n * @param _view The message\n * @param _t The expected type\n */\n modifier typeAssert(bytes29 _view, Types _t) {\n _view.assertType(uint40(_t));\n _;\n }\n\n // ============ Internal Functions: Validation ============\n\n /**\n * @notice Checks that Action is valid type\n * @param _action The action\n * @return TRUE if action is valid\n */\n function isValidAction(bytes29 _action) internal pure returns (bool) {\n return isTransfer(_action);\n }\n\n /**\n * @notice Checks that the message is of the specified type\n * @param _type the type to check for\n * @param _action The message\n * @return True if the message is of the specified type\n */\n function isType(bytes29 _action, Types _type) internal pure returns (bool) {\n return actionType(_action) == uint8(_type) && messageType(_action) == _type;\n }\n\n /**\n * @notice Checks that the message is of type Transfer\n * @param _action The message\n * @return True if the message is of type Transfer\n */\n function isTransfer(bytes29 _action) internal pure returns (bool) {\n return isType(_action, Types.Transfer);\n }\n\n /**\n * @notice Checks that view is a valid message length\n * @param _view The bytes string\n * @return TRUE if message is valid\n */\n function isValidMessageLength(bytes29 _view) internal pure returns (bool) {\n uint256 _len = _view.len();\n return _len == TOKEN_ID_LEN + TRANSFER_LEN;\n }\n\n /**\n * @notice Asserts that the message is of type Message\n * @param _view The message\n * @return The message\n */\n function mustBeMessage(bytes29 _view) internal pure returns (bytes29) {\n return tryAsMessage(_view).assertValid();\n }\n\n // ============ Internal Functions: Formatting ============\n\n /**\n * @notice Formats an action message\n * @param _tokenId The token ID\n * @param _action The action\n * @return The formatted message\n */\n function formatMessage(bytes29 _tokenId, bytes29 _action)\n internal\n view\n typeAssert(_tokenId, Types.TokenId)\n returns (bytes memory)\n {\n require(isValidAction(_action), \"!action\");\n bytes29[] memory _views = new bytes29[](2);\n _views[0] = _tokenId;\n _views[1] = _action;\n return TypedMemView.join(_views);\n }\n\n /**\n * @notice Formats Transfer\n * @param _to The recipient address as bytes32\n * @param _amnt The transfer amount\n * @param _detailsHash The token details hash\n * @param _transferId Unique identifier for transfer\n * @return\n */\n function formatTransfer(\n bytes32 _to,\n uint256 _amnt,\n bytes32 _detailsHash,\n bytes32 _transferId\n ) internal pure returns (bytes29) {\n return\n abi.encodePacked(Types.Transfer, _to, _amnt, _detailsHash, _transferId).ref(0).castTo(uint40(Types.Transfer));\n }\n\n /**\n * @notice Serializes a Token ID struct\n * @param _tokenId The token id struct\n * @return The formatted Token ID\n */\n function formatTokenId(TokenId memory _tokenId) internal pure returns (bytes29) {\n return formatTokenId(_tokenId.domain, _tokenId.id);\n }\n\n /**\n * @notice Creates a serialized Token ID from components\n * @param _domain The domain\n * @param _id The ID\n * @return The formatted Token ID\n */\n function formatTokenId(uint32 _domain, bytes32 _id) internal pure returns (bytes29) {\n return abi.encodePacked(_domain, _id).ref(0).castTo(uint40(Types.TokenId));\n }\n\n /**\n * @notice Formats the keccak256 hash of the token details\n * Token Details Format:\n * length of name cast to bytes - 32 bytes\n * name - x bytes (variable)\n * length of symbol cast to bytes - 32 bytes\n * symbol - x bytes (variable)\n * decimals - 1 byte\n * @param _name The name\n * @param _symbol The symbol\n * @param _decimals The decimals\n * @return The Details message\n */\n function formatDetailsHash(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(bytes(_name).length, _name, bytes(_symbol).length, _symbol, _decimals));\n }\n\n /**\n * @notice Converts to a Message\n * @param _message The message\n * @return The newly typed message\n */\n function tryAsMessage(bytes29 _message) internal pure returns (bytes29) {\n if (isValidMessageLength(_message)) {\n return _message.castTo(uint40(Types.Message));\n }\n return TypedMemView.nullView();\n }\n\n // ============ Internal Functions: Parsing msg ============\n\n /**\n * @notice Returns the type of the message\n * @param _view The message\n * @return The type of the message\n */\n function messageType(bytes29 _view) internal pure returns (Types) {\n return Types(uint8(_view.typeOf()));\n }\n\n /**\n * @notice Retrieves the token ID from a Message\n * @param _message The message\n * @return The ID\n */\n function tokenId(bytes29 _message) internal pure typeAssert(_message, Types.Message) returns (bytes29) {\n return _message.slice(0, TOKEN_ID_LEN, uint40(Types.TokenId));\n }\n\n /**\n * @notice Retrieves the action data from a Message\n * @param _message The message\n * @return The action\n */\n function action(bytes29 _message) internal pure typeAssert(_message, Types.Message) returns (bytes29) {\n uint256 _actionLen = _message.len() - TOKEN_ID_LEN;\n uint40 _type = uint40(msgType(_message));\n return _message.slice(TOKEN_ID_LEN, _actionLen, _type);\n }\n\n // ============ Internal Functions: Parsing tokenId ============\n\n /**\n * @notice Retrieves the domain from a TokenID\n * @param _tokenId The message\n * @return The domain\n */\n function domain(bytes29 _tokenId) internal pure typeAssert(_tokenId, Types.TokenId) returns (uint32) {\n return uint32(_tokenId.indexUint(0, 4));\n }\n\n /**\n * @notice Retrieves the ID from a TokenID\n * @param _tokenId The message\n * @return The ID\n */\n function id(bytes29 _tokenId) internal pure typeAssert(_tokenId, Types.TokenId) returns (bytes32) {\n // before = 4 bytes domain\n return _tokenId.index(4, 32);\n }\n\n /**\n * @notice Retrieves the EVM ID\n * @param _tokenId The message\n * @return The EVM ID\n */\n function evmId(bytes29 _tokenId) internal pure typeAssert(_tokenId, Types.TokenId) returns (address) {\n // before = 4 bytes domain + 12 bytes empty to trim for address\n return _tokenId.indexAddress(16);\n }\n\n // ============ Internal Functions: Parsing action ============\n\n /**\n * @notice Retrieves the action identifier from message\n * @param _message The action\n * @return The message type\n */\n function msgType(bytes29 _message) internal pure returns (uint8) {\n return uint8(_message.indexUint(TOKEN_ID_LEN, 1));\n }\n\n /**\n * @notice Retrieves the identifier from action\n * @param _action The action\n * @return The action type\n */\n function actionType(bytes29 _action) internal pure returns (uint8) {\n return uint8(_action.indexUint(0, 1));\n }\n\n /**\n * @notice Retrieves the recipient from a Transfer\n * @param _transferAction The message\n * @return The recipient address as bytes32\n */\n function recipient(bytes29 _transferAction) internal pure returns (bytes32) {\n // before = 1 byte identifier\n return _transferAction.index(1, 32);\n }\n\n /**\n * @notice Retrieves the EVM Recipient from a Transfer\n * @param _transferAction The message\n * @return The EVM Recipient\n */\n function evmRecipient(bytes29 _transferAction) internal pure returns (address) {\n // before = 1 byte identifier + 12 bytes empty to trim for address = 13 bytes\n return _transferAction.indexAddress(13);\n }\n\n /**\n * @notice Retrieves the amount from a Transfer\n * @param _transferAction The message\n * @return The amount\n */\n function amnt(bytes29 _transferAction) internal pure returns (uint256) {\n // before = 1 byte identifier + 32 bytes ID = 33 bytes\n return _transferAction.indexUint(33, 32);\n }\n\n /**\n * @notice Retrieves the unique identifier from a Transfer\n * @param _transferAction The message\n * @return The amount\n */\n function transferId(bytes29 _transferAction) internal pure returns (bytes32) {\n // before = 1 byte identifier + 32 bytes ID + 32 bytes amount + 32 bytes detailsHash = 97 bytes\n return _transferAction.index(97, 32);\n }\n\n /**\n * @notice Retrieves the detailsHash from a Transfer\n * @param _transferAction The message\n * @return The detailsHash\n */\n function detailsHash(bytes29 _transferAction) internal pure returns (bytes32) {\n // before = 1 byte identifier + 32 bytes ID + 32 bytes amount = 65 bytes\n return _transferAction.index(65, 32);\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport {SafeERC20, IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {LPToken} from \"../helpers/LPToken.sol\";\nimport {AmplificationUtils} from \"./AmplificationUtils.sol\";\nimport {MathUtils} from \"./MathUtils.sol\";\n\n/**\n * @title SwapUtils library\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\n * Admin functions should be protected within contracts using this library.\n */\nlibrary SwapUtils {\n using SafeERC20 for IERC20;\n using SafeMath for uint256;\n using MathUtils for uint256;\n\n /*** EVENTS ***/\n\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\n event AddLiquidity(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(uint256 newAdminFee);\n event NewSwapFee(uint256 newSwapFee);\n\n struct Swap {\n // variables around the ramp management of A,\n // the amplification coefficient * n * (n - 1)\n // see https://www.curve.fi/stableswap-paper.pdf for details\n uint256 initialA;\n uint256 futureA;\n uint256 initialATime;\n uint256 futureATime;\n // fee calculation\n uint256 swapFee;\n uint256 adminFee;\n LPToken lpToken;\n // contract references for all tokens being pooled\n IERC20[] pooledTokens;\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\n uint256[] tokenPrecisionMultipliers;\n // the pool balance of each token, in the token's precision\n // the contract's actual token balance might differ\n uint256[] balances;\n // the admin fee balance of each token, in the token's precision\n uint256[] adminFees;\n }\n\n // Struct storing variables used in calculations in the\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\n struct CalculateWithdrawOneTokenDYInfo {\n uint256 d0;\n uint256 d1;\n uint256 newY;\n uint256 feePerToken;\n uint256 preciseA;\n }\n\n // Struct storing variables used in calculations in the\n // {add,remove}Liquidity functions to avoid stack too deep errors\n struct ManageLiquidityInfo {\n uint256 d0;\n uint256 d1;\n uint256 d2;\n uint256 preciseA;\n LPToken lpToken;\n uint256 totalSupply;\n uint256[] balances;\n uint256[] multipliers;\n }\n\n // the precision all pools tokens will be converted to\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\n\n // the denominator used to calculate admin and LP fees. For example, an\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\n uint256 internal constant FEE_DENOMINATOR = 1e10;\n\n // Max swap fee is 1% or 100bps of each swap\n uint256 internal constant MAX_SWAP_FEE = 1e8;\n\n // Max adminFee is 100% of the swapFee\n // adminFee does not add additional fee on top of swapFee\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\n // users but only on the earnings of LPs\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\n\n // Constant value used as max loop limit\n uint256 internal constant MAX_LOOP_LIMIT = 256;\n\n /*** VIEW & PURE FUNCTIONS ***/\n\n function _getAPrecise(Swap storage self) private view returns (uint256) {\n return AmplificationUtils._getAPrecise(self);\n }\n\n /**\n * @notice Calculate the dy, the amount of selected token that user receives and\n * the fee of withdrawing in one token\n * @param tokenAmount the amount to withdraw in the pool's precision\n * @param tokenIndex which token will be withdrawn\n * @param self Swap struct to read from\n * @return the amount of token user will receive\n */\n function calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) internal view returns (uint256) {\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\n self,\n tokenAmount,\n tokenIndex,\n self.lpToken.totalSupply()\n );\n return availableTokenAmount;\n }\n\n function _calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 totalSupply\n ) private view returns (uint256, uint256) {\n uint256 dy;\n uint256 newY;\n uint256 currentY;\n\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\n\n // dy_0 (without fees)\n // dy, dy_0 - dy\n\n uint256 dySwapFee = currentY.sub(newY).div(self.tokenPrecisionMultipliers[tokenIndex]).sub(dy);\n\n return (dy, dySwapFee);\n }\n\n /**\n * @notice Calculate the dy of withdrawing in one token\n * @param self Swap struct to read from\n * @param tokenIndex which token will be withdrawn\n * @param tokenAmount the amount to withdraw in the pools precision\n * @return the d and the new y after withdrawing one token\n */\n function calculateWithdrawOneTokenDY(\n Swap storage self,\n uint8 tokenIndex,\n uint256 tokenAmount,\n uint256 totalSupply\n )\n internal\n view\n returns (\n uint256,\n uint256,\n uint256\n )\n {\n // Get the current D, then solve the stableswap invariant\n // y_i for D - tokenAmount\n uint256[] memory xp = _xp(self);\n\n require(tokenIndex < xp.length, \"index out of range\");\n\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\n v.preciseA = _getAPrecise(self);\n v.d0 = getD(xp, v.preciseA);\n v.d1 = v.d0.sub(tokenAmount.mul(v.d0).div(totalSupply));\n\n require(tokenAmount <= xp[tokenIndex], \"exceeds available\");\n\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\n\n uint256[] memory xpReduced = new uint256[](xp.length);\n\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\n for (uint256 i; i < xp.length; ) {\n uint256 xpi = xp[i];\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\n xpReduced[i] = xpi.sub(\n ((i == tokenIndex) ? xpi.mul(v.d1).div(v.d0).sub(v.newY) : xpi.sub(xpi.mul(v.d1).div(v.d0)))\n .mul(v.feePerToken)\n .div(FEE_DENOMINATOR)\n );\n\n unchecked {\n ++i;\n }\n }\n\n uint256 dy = xpReduced[tokenIndex].sub(getYD(v.preciseA, tokenIndex, xpReduced, v.d1));\n dy = dy.sub(1).div(self.tokenPrecisionMultipliers[tokenIndex]);\n\n return (dy, v.newY, xp[tokenIndex]);\n }\n\n /**\n * @notice Calculate the price of a token in the pool with given\n * precision-adjusted balances and a particular D.\n *\n * @dev This is accomplished via solving the invariant iteratively.\n * See the StableSwap paper and Curve.fi implementation for further details.\n *\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\n * x_1**2 + b*x_1 = c\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\n *\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\n * @param tokenIndex Index of token we are calculating for.\n * @param xp a precision-adjusted set of pool balances. Array should be\n * the same cardinality as the pool.\n * @param d the stableswap invariant\n * @return the price of the token, in the same precision as in xp\n */\n function getYD(\n uint256 a,\n uint8 tokenIndex,\n uint256[] memory xp,\n uint256 d\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndex < numTokens, \"Token not found\");\n\n uint256 c = d;\n uint256 s;\n uint256 nA = a.mul(numTokens);\n\n for (uint256 i; i < numTokens; ) {\n if (i != tokenIndex) {\n s = s.add(xp[i]);\n c = c.mul(d).div(xp[i].mul(numTokens));\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n }\n\n unchecked {\n ++i;\n }\n }\n c = c.mul(d).mul(AmplificationUtils.A_PRECISION).div(nA.mul(numTokens));\n\n uint256 b = s.add(d.mul(AmplificationUtils.A_PRECISION).div(nA));\n uint256 yPrev;\n uint256 y = d;\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = y.mul(y).add(c).div(y.mul(2).add(b).sub(d));\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\n * as the pool.\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\n * See the StableSwap paper for details\n * @return the invariant, at the precision of the pool\n */\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n uint256 s;\n for (uint256 i; i < numTokens; ) {\n s = s.add(xp[i]);\n\n unchecked {\n ++i;\n }\n }\n if (s == 0) {\n return 0;\n }\n\n uint256 prevD;\n uint256 d = s;\n uint256 nA = a.mul(numTokens);\n\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n uint256 dP = d;\n for (uint256 j; j < numTokens; ) {\n dP = dP.mul(d).div(xp[j].mul(numTokens));\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // dP = dP * D * D * D * ... overflow!\n\n unchecked {\n ++j;\n }\n }\n prevD = d;\n d = nA.mul(s).div(AmplificationUtils.A_PRECISION).add(dP.mul(numTokens)).mul(d).div(\n nA.sub(AmplificationUtils.A_PRECISION).mul(d).div(AmplificationUtils.A_PRECISION).add(numTokens.add(1).mul(dP))\n );\n if (d.within1(prevD)) {\n return d;\n }\n\n unchecked {\n ++i;\n }\n }\n\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\n // function which does not rely on D.\n revert(\"D does not converge\");\n }\n\n /**\n * @notice Given a set of balances and precision multipliers, return the\n * precision-adjusted balances.\n *\n * @param balances an array of token balances, in their native precisions.\n * These should generally correspond with pooled tokens.\n *\n * @param precisionMultipliers an array of multipliers, corresponding to\n * the amounts in the balances array. When multiplied together they\n * should yield amounts at the pool's precision.\n *\n * @return an array of amounts \"scaled\" to the pool's precision\n */\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\n internal\n pure\n returns (uint256[] memory)\n {\n uint256 numTokens = balances.length;\n require(numTokens == precisionMultipliers.length, \"mismatch multipliers\");\n uint256[] memory xp = new uint256[](numTokens);\n for (uint256 i; i < numTokens; ) {\n xp[i] = balances[i].mul(precisionMultipliers[i]);\n\n unchecked {\n ++i;\n }\n }\n return xp;\n }\n\n /**\n * @notice Return the precision-adjusted balances of all tokens in the pool\n * @param self Swap struct to read from\n * @return the pool balances \"scaled\" to the pool's precision, allowing\n * them to be more easily compared.\n */\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\n return _xp(self.balances, self.tokenPrecisionMultipliers);\n }\n\n /**\n * @notice Get the virtual price, to help calculate profit\n * @param self Swap struct to read from\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\n */\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\n uint256 d = getD(_xp(self), _getAPrecise(self));\n LPToken lpToken = self.lpToken;\n uint256 supply = lpToken.totalSupply();\n if (supply != 0) {\n return d.mul(10**uint256(POOL_PRECISION_DECIMALS)).div(supply);\n }\n return 0;\n }\n\n /**\n * @notice Calculate the new balances of the tokens given the indexes of the token\n * that is swapped from (FROM) and the token that is swapped to (TO).\n * This function is used as a helper function to calculate how much TO token\n * the user should receive on swap.\n *\n * @param preciseA precise form of amplification coefficient\n * @param tokenIndexFrom index of FROM token\n * @param tokenIndexTo index of TO token\n * @param x the new total amount of FROM token\n * @param xp balances of the tokens in the pool\n * @return the amount of TO token that should remain in the pool\n */\n function getY(\n uint256 preciseA,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 x,\n uint256[] memory xp\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \"token not found\");\n\n uint256 d = getD(xp, preciseA);\n uint256 c = d;\n uint256 s;\n uint256 nA = numTokens.mul(preciseA);\n\n uint256 _x;\n for (uint256 i; i < numTokens; ) {\n if (i == tokenIndexFrom) {\n _x = x;\n } else if (i != tokenIndexTo) {\n _x = xp[i];\n } else {\n unchecked {\n ++i;\n }\n continue;\n }\n s = s.add(_x);\n c = c.mul(d).div(_x.mul(numTokens));\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n\n unchecked {\n ++i;\n }\n }\n c = c.mul(d).mul(AmplificationUtils.A_PRECISION).div(nA.mul(numTokens));\n uint256 b = s.add(d.mul(AmplificationUtils.A_PRECISION).div(nA));\n uint256 yPrev;\n uint256 y = d;\n\n // iterative approximation\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = y.mul(y).add(c).div(y.mul(2).add(b).sub(d));\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get\n */\n function calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) internal view returns (uint256 dy) {\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy.\n * @return dx the number of tokens the user have to transfer + fee\n */\n function calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) internal view returns (uint256 dx) {\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get\n * @return dyFee the associated fee\n */\n function _calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256[] memory balances\n ) internal view returns (uint256 dy, uint256 dyFee) {\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n uint256 x = dx.mul(multipliers[tokenIndexFrom]).add(xp[tokenIndexFrom]);\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\n dy = xp[tokenIndexTo].sub(y).sub(1);\n dyFee = dy.mul(self.swapFee).div(FEE_DENOMINATOR);\n dy = dy.sub(dyFee).div(multipliers[tokenIndexTo]);\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dx the number of tokens the user have to deposit\n * @return dxFee the associated fee\n */\n function _calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256[] memory balances\n ) internal view returns (uint256 dx, uint256 dxFee) {\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n\n uint256 a = _getAPrecise(self);\n uint256 d0 = getD(xp, a);\n\n xp[tokenIndexTo] = xp[tokenIndexTo].sub(dy.mul(multipliers[tokenIndexTo]));\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\n dx = x.sub(xp[tokenIndexFrom]).add(1);\n dxFee = dx.mul(self.swapFee).div(FEE_DENOMINATOR);\n dx = dx.add(dxFee).div(multipliers[tokenIndexFrom]);\n }\n\n /**\n * @notice A simple method to calculate amount of each underlying\n * tokens that is returned upon burning given amount of\n * LP tokens\n *\n * @param amount the amount of LP tokens that would to be burned on\n * withdrawal\n * @return array of amounts of tokens user will receive\n */\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\n }\n\n function _calculateRemoveLiquidity(\n uint256[] memory balances,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (uint256[] memory) {\n require(amount <= totalSupply, \"exceed total supply\");\n\n uint256 numBalances = balances.length;\n uint256[] memory amounts = new uint256[](numBalances);\n\n for (uint256 i; i < numBalances; ) {\n amounts[i] = balances[i].mul(amount).div(totalSupply);\n\n unchecked {\n ++i;\n }\n }\n return amounts;\n }\n\n /**\n * @notice A simple method to calculate prices from deposits or\n * withdrawals, excluding fees but including slippage. This is\n * helpful as an input into the various \"min\" parameters on calls\n * to fight front-running\n *\n * @dev This shouldn't be used outside frontends for user estimates.\n *\n * @param self Swap struct to read from\n * @param amounts an array of token amounts to deposit or withdrawal,\n * corresponding to pooledTokens. The amount should be in each\n * pooled token's native precision. If a token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @param deposit whether this is a deposit or a withdrawal\n * @return if deposit was true, total amount of lp token that will be minted and if\n * deposit was false, total amount of lp token that will be burned\n */\n function calculateTokenAmount(\n Swap storage self,\n uint256[] calldata amounts,\n bool deposit\n ) internal view returns (uint256) {\n uint256 a = _getAPrecise(self);\n uint256[] memory balances = self.balances;\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n\n uint256 numBalances = balances.length;\n uint256 d0 = getD(_xp(balances, multipliers), a);\n for (uint256 i; i < numBalances; ) {\n if (deposit) {\n balances[i] = balances[i].add(amounts[i]);\n } else {\n balances[i] = balances[i].sub(amounts[i], \"withdraw >available\");\n }\n\n unchecked {\n ++i;\n }\n }\n uint256 d1 = getD(_xp(balances, multipliers), a);\n uint256 totalSupply = self.lpToken.totalSupply();\n\n if (deposit) {\n return d1.sub(d0).mul(totalSupply).div(d0);\n } else {\n return d0.sub(d1).mul(totalSupply).div(d0);\n }\n }\n\n /**\n * @notice return accumulated amount of admin fees of the token with given index\n * @param self Swap struct to read from\n * @param index Index of the pooled token\n * @return admin balance in the token's precision\n */\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\n require(index < self.pooledTokens.length, \"index out of range\");\n return self.adminFees[index];\n }\n\n /**\n * @notice internal helper function to calculate fee per token multiplier used in\n * swap fee calculations\n * @param swapFee swap fee for the tokens\n * @param numTokens number of tokens pooled\n */\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\n return swapFee.mul(numTokens).div(numTokens.sub(1).mul(4));\n }\n\n /*** STATE MODIFYING FUNCTIONS ***/\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"swap more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n dx = tokenFrom.balanceOf(address(this)).sub(beforeBalance);\n }\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = dyFee.mul(self.adminFee).div(FEE_DENOMINATOR).div(\n self.tokenPrecisionMultipliers[tokenIndexTo]\n );\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom].add(dx);\n self.balances[tokenIndexTo] = balances[tokenIndexTo].sub(dy).sub(dyAdminFee);\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo].add(dyAdminFee);\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dy the amount of tokens the user wants to buy\n * @param maxDx the max amount the user would like to send.\n * @return amount of token user have to transfer on swap\n */\n function swapOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \">pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = dxFee.mul(self.adminFee).div(FEE_DENOMINATOR).div(\n self.tokenPrecisionMultipliers[tokenIndexFrom]\n );\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom].add(dx).sub(dxAdminFee);\n self.balances[tokenIndexTo] = balances[tokenIndexTo].sub(dy);\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom].add(dxAdminFee);\n }\n\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)).sub(beforeBalance), \"not support fee token\");\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice swap two tokens in the pool internally\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swapInternal(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"more than you own\");\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = dyFee.mul(self.adminFee).div(FEE_DENOMINATOR).div(\n self.tokenPrecisionMultipliers[tokenIndexTo]\n );\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom].add(dx);\n self.balances[tokenIndexTo] = balances[tokenIndexTo].sub(dy).sub(dyAdminFee);\n\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo].add(dyAdminFee);\n }\n\n emit TokenSwap(msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice Should get exact amount out of AMM for asset put in\n */\n function swapInternalOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \"more than pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = dxFee.mul(self.adminFee).div(FEE_DENOMINATOR).div(\n self.tokenPrecisionMultipliers[tokenIndexFrom]\n );\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom].add(dx).sub(dxAdminFee);\n self.balances[tokenIndexTo] = balances[tokenIndexTo].sub(dy);\n\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom].add(dxAdminFee);\n }\n\n emit TokenSwap(msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice Add liquidity to the pool\n * @param self Swap struct to read from and write to\n * @param amounts the amounts of each token to add, in their native precision\n * @param minToMint the minimum LP tokens adding this amount of liquidity\n * should mint, otherwise revert. Handy for front-running mitigation\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\n * @return amount of LP token user received\n */\n function addLiquidity(\n Swap storage self,\n uint256[] memory amounts,\n uint256 minToMint\n ) internal returns (uint256) {\n IERC20[] memory pooledTokens = self.pooledTokens;\n uint256 numTokens = pooledTokens.length;\n require(amounts.length == numTokens, \"mismatch pooled tokens\");\n\n // current state\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n if (v.totalSupply != 0) {\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n }\n\n uint256[] memory newBalances = new uint256[](numTokens);\n\n for (uint256 i; i < numTokens; ) {\n require(v.totalSupply != 0 || amounts[i] != 0, \"!supply all tokens\");\n\n // Transfer tokens first to see if a fee was charged on transfer\n if (amounts[i] != 0) {\n uint256 beforeBalance = pooledTokens[i].balanceOf(address(this));\n pooledTokens[i].safeTransferFrom(msg.sender, address(this), amounts[i]);\n\n // Update the amounts[] with actual transfer amount\n amounts[i] = pooledTokens[i].balanceOf(address(this)).sub(beforeBalance);\n }\n\n newBalances[i] = v.balances[i].add(amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n // invariant after change\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n require(v.d1 > v.d0, \"D should increase\");\n\n // updated to reflect fees and calculate the user's LP tokens\n v.d2 = v.d1;\n uint256[] memory fees = new uint256[](numTokens);\n\n if (v.totalSupply != 0) {\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n for (uint256 i; i < numTokens; ) {\n uint256 idealBalance = v.d1.mul(v.balances[i]).div(v.d0);\n fees[i] = feePerToken.mul(idealBalance.difference(newBalances[i])).div(FEE_DENOMINATOR);\n uint256 adminFee = fees[i].mul(self.adminFee).div(FEE_DENOMINATOR);\n self.balances[i] = newBalances[i].sub(adminFee);\n self.adminFees[i] = self.adminFees[i].add(adminFee);\n newBalances[i] = newBalances[i].sub(fees[i]);\n\n unchecked {\n ++i;\n }\n }\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n } else {\n // the initial depositor doesn't pay fees\n self.balances = newBalances;\n }\n\n uint256 toMint;\n if (v.totalSupply == 0) {\n toMint = v.d1;\n } else {\n toMint = v.d2.sub(v.d0).mul(v.totalSupply).div(v.d0);\n }\n\n require(toMint >= minToMint, \"mint < min\");\n\n // mint the user's LP tokens\n v.lpToken.mint(msg.sender, toMint);\n\n emit AddLiquidity(msg.sender, amounts, fees, v.d1, v.totalSupply.add(toMint));\n\n return toMint;\n }\n\n /**\n * @notice Burn LP tokens to remove liquidity from the pool.\n * @dev Liquidity can always be removed, even when the pool is paused.\n * @param self Swap struct to read from and write to\n * @param amount the amount of LP tokens to burn\n * @param minAmounts the minimum amounts of each token in the pool\n * acceptable for this burn. Useful as a front-running mitigation\n * @return amounts of tokens the user received\n */\n function removeLiquidity(\n Swap storage self,\n uint256 amount,\n uint256[] calldata minAmounts\n ) internal returns (uint256[] memory) {\n LPToken lpToken = self.lpToken;\n IERC20[] memory pooledTokens = self.pooledTokens;\n require(amount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = pooledTokens.length;\n require(minAmounts.length == numTokens, \"mismatch poolTokens\");\n\n uint256[] memory balances = self.balances;\n uint256 totalSupply = lpToken.totalSupply();\n\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\n\n uint256 numAmounts = amounts.length;\n for (uint256 i; i < numAmounts; ) {\n require(amounts[i] >= minAmounts[i], \"amounts[i] < minAmounts[i]\");\n self.balances[i] = balances[i].sub(amounts[i]);\n pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n lpToken.burnFrom(msg.sender, amount);\n\n emit RemoveLiquidity(msg.sender, amounts, totalSupply.sub(amount));\n\n return amounts;\n }\n\n /**\n * @notice Remove liquidity from the pool all in one token.\n * @param self Swap struct to read from and write to\n * @param tokenAmount the amount of the lp tokens to burn\n * @param tokenIndex the index of the token you want to receive\n * @param minAmount the minimum amount to withdraw, otherwise revert\n * @return amount chosen token that user received\n */\n function removeLiquidityOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount\n ) internal returns (uint256) {\n LPToken lpToken = self.lpToken;\n IERC20[] memory pooledTokens = self.pooledTokens;\n\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = pooledTokens.length;\n require(tokenIndex < numTokens, \"not found\");\n\n uint256 totalSupply = lpToken.totalSupply();\n\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\n\n require(dy >= minAmount, \"dy < minAmount\");\n\n uint256 adminFee = dyFee.mul(self.adminFee).div(FEE_DENOMINATOR);\n self.balances[tokenIndex] = self.balances[tokenIndex].sub(dy.add(adminFee));\n if (adminFee != 0) {\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex].add(adminFee);\n }\n lpToken.burnFrom(msg.sender, tokenAmount);\n pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\n\n emit RemoveLiquidityOne(msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\n\n return dy;\n }\n\n /**\n * @notice Remove liquidity from the pool, weighted differently than the\n * pool's current balances.\n *\n * @param self Swap struct to read from and write to\n * @param amounts how much of each token to withdraw\n * @param maxBurnAmount the max LP token provider is willing to pay to\n * remove liquidity. Useful as a front-running mitigation.\n * @return actual amount of LP tokens burned in the withdrawal\n */\n function removeLiquidityImbalance(\n Swap storage self,\n uint256[] memory amounts,\n uint256 maxBurnAmount\n ) internal returns (uint256) {\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n\n IERC20[] memory pooledTokens = self.pooledTokens;\n\n uint256 numTokens = pooledTokens.length;\n uint256 numAmounts = amounts.length;\n require(numAmounts == numTokens, \"mismatch pool tokens\");\n\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \">LP.balanceOf\");\n\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n uint256[] memory fees = new uint256[](numTokens);\n {\n uint256[] memory balances1 = new uint256[](numTokens);\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n for (uint256 i; i < numTokens; ) {\n balances1[i] = v.balances[i].sub(amounts[i], \"withdraw more than available\");\n\n unchecked {\n ++i;\n }\n }\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\n\n for (uint256 i; i < numTokens; ) {\n {\n uint256 idealBalance = v.d1.mul(v.balances[i]).div(v.d0);\n uint256 difference = idealBalance.difference(balances1[i]);\n fees[i] = feePerToken.mul(difference).div(FEE_DENOMINATOR);\n }\n uint256 adminFee = fees[i].mul(self.adminFee).div(FEE_DENOMINATOR);\n self.balances[i] = balances1[i].sub(adminFee);\n self.adminFees[i] = self.adminFees[i].add(adminFee);\n balances1[i] = balances1[i].sub(fees[i]);\n\n unchecked {\n ++i;\n }\n }\n\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\n }\n uint256 tokenAmount = v.d0.sub(v.d2).mul(v.totalSupply).div(v.d0);\n require(tokenAmount != 0, \"!zero amount\");\n tokenAmount = tokenAmount.add(1);\n\n require(tokenAmount <= maxBurnAmount, \"tokenAmount > maxBurnAmount\");\n\n v.lpToken.burnFrom(msg.sender, tokenAmount);\n\n for (uint256 i; i < numTokens; ) {\n pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n emit RemoveLiquidityImbalance(msg.sender, amounts, fees, v.d1, v.totalSupply.sub(tokenAmount));\n\n return tokenAmount;\n }\n\n /**\n * @notice withdraw all admin fees to a given address\n * @param self Swap struct to withdraw fees from\n * @param to Address to send the fees to\n */\n function withdrawAdminFees(Swap storage self, address to) internal {\n IERC20[] memory pooledTokens = self.pooledTokens;\n for (uint256 i; i < pooledTokens.length; ) {\n IERC20 token = pooledTokens[i];\n uint256 balance = self.adminFees[i];\n if (balance != 0) {\n self.adminFees[i] = 0;\n token.safeTransfer(to, balance);\n }\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Sets the admin fee\n * @dev adminFee cannot be higher than 100% of the swap fee\n * @param self Swap struct to update\n * @param newAdminFee new admin fee to be applied on future transactions\n */\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\n require(newAdminFee <= MAX_ADMIN_FEE, \"too high\");\n self.adminFee = newAdminFee;\n\n emit NewAdminFee(newAdminFee);\n }\n\n /**\n * @notice update the swap fee\n * @dev fee cannot be higher than 1% of each swap\n * @param self Swap struct to update\n * @param newSwapFee new swap fee to be applied on future transactions\n */\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\n require(newSwapFee <= MAX_SWAP_FEE, \"too high\");\n self.swapFee = newSwapFee;\n\n emit NewSwapFee(newSwapFee);\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IStableSwap {\n /*** EVENTS ***/\n\n // events replicated from SwapUtils to make the ABI easier for dumb\n // clients\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\n event AddLiquidity(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(uint256 newAdminFee);\n event NewSwapFee(uint256 newSwapFee);\n event NewWithdrawFee(uint256 newWithdrawFee);\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n function swapExact(\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut\n ) external payable returns (uint256);\n\n function swapExactOut(\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn\n ) external payable returns (uint256);\n\n function getA() external view returns (uint256);\n\n function getToken(uint8 index) external view returns (IERC20);\n\n function getTokenIndex(address tokenAddress) external view returns (uint8);\n\n function getTokenBalance(uint8 index) external view returns (uint256);\n\n function getVirtualPrice() external view returns (uint256);\n\n // min return calculation functions\n function calculateSwap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapOut(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) external view returns (uint256);\n\n function calculateSwapFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountIn\n ) external view returns (uint256);\n\n function calculateSwapOutFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountOut\n ) external view returns (uint256);\n\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\n\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\n external\n view\n returns (uint256 availableTokenAmount);\n\n // state modifying functions\n function initialize(\n IERC20[] memory pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 a,\n uint256 fee,\n uint256 adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function swap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function addLiquidity(\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidity(\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeLiquidityOneToken(\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidityImbalance(\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/interfaces/ITokenRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ITokenRegistry {\n function isLocalOrigin(address _token) external view returns (bool);\n\n function ensureLocalToken(uint32 _domain, bytes32 _id) external returns (address _local);\n\n function mustHaveLocalToken(uint32 _domain, bytes32 _id) external view returns (IERC20);\n\n function getLocalAddress(uint32 _domain, bytes32 _id) external view returns (address _local);\n\n function getTokenId(address _token) external view returns (uint32, bytes32);\n\n function enrollCustom(\n uint32 _domain,\n bytes32 _id,\n address _custom\n ) external;\n\n function oldReprToCurrentRepr(address _oldRepr) external view returns (address _currentRepr);\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/interfaces/IWrapped.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface IWrapped {\n function deposit() external payable;\n\n function withdraw(uint256 amount) external;\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/interfaces/IExecutor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface IExecutor {\n /**\n * @param _transferId Unique identifier of transaction id that necessitated\n * calldata execution\n * @param _amount The amount to approve or send with the call\n * @param _to The address to execute the calldata on\n * @param _assetId The assetId of the funds to approve to the contract or\n * send along with the call\n * @param _properties The origin properties\n * @param _callData The data to execute\n */\n struct ExecutorArgs {\n bytes32 transferId;\n uint256 amount;\n address to;\n address recovery;\n address assetId;\n bytes properties;\n bytes callData;\n }\n\n event Executed(\n bytes32 indexed transferId,\n address indexed to,\n address indexed recovery,\n address assetId,\n uint256 amount,\n bytes _properties,\n bytes callData,\n bytes returnData,\n bool success\n );\n\n function getConnext() external returns (address);\n\n function originSender() external returns (address);\n\n function origin() external returns (uint32);\n\n function amount() external returns (uint256);\n\n function execute(ExecutorArgs calldata _args) external payable returns (bool success, bytes memory returnData);\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/interfaces/ISponsorVault.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface ISponsorVault {\n // Should be callable by the Connext contract only. Should:\n // - call `addLiquidityFor` to send the calculated fee to the router\n // - return the amount of liquidity router was reimbursed\n function reimburseLiquidityFees(\n address token,\n uint256 amount,\n address receiver\n ) external returns (uint256);\n\n // Should be callable by the Connext contract only. Should:\n // - take in an amount of relayer fee specified on origin chain\n // - convert that amount to destination domain gas\n // - send the user the destination domain gas\n function reimburseRelayerFees(\n uint32 originDomain,\n address payable receiver,\n uint256 amount\n ) external;\n\n // Should allow anyone to send funds to the vault for sponsoring fees\n function deposit(address _token, uint256 _amount) external payable;\n\n // Should allow the owner of the vault to withdraw funds put in to a given\n // address\n function withdraw(\n address token,\n address receiver,\n uint256 amount\n ) external;\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/contracts/Home.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ Internal Imports ============\nimport {Version0} from \"./Version0.sol\";\nimport {NomadBase} from \"./NomadBase.sol\";\nimport {QueueLib} from \"../libs/Queue.sol\";\nimport {MerkleLib} from \"../libs/Merkle.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {MerkleTreeManager} from \"./Merkle.sol\";\nimport {QueueManager} from \"./Queue.sol\";\nimport {IUpdaterManager} from \"../interfaces/IUpdaterManager.sol\";\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, QueueManager, MerkleTreeManager, NomadBase {\n // ============ Libraries ============\n\n using QueueLib for QueueLib.Queue;\n using MerkleLib for MerkleLib.Tree;\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain => next available nonce for the domain\n mapping(uint32 => uint32) public nonces;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination << 32) & nonce)\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\n * @param committedRoot the latest notarized root submitted in the last signed Update\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes32 committedRoot,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper update is submitted,\n * which sets the contract to FAILED state\n * @param oldRoot Old root of the improper update\n * @param newRoot New root of the improper update\n * @param signature Signature on `oldRoot` and `newRoot\n */\n event ImproperUpdate(bytes32 oldRoot, bytes32 newRoot, bytes signature);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) NomadBase(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n __QueueManager_initialize();\n _setUpdaterManager(_updaterManager);\n __NomadBase_initialize(updaterManager.updater());\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n // ============ External: Updater & UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding & slashing, and rules for Updater selection & rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message it to the destination domain & recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n bytes memory _messageBody\n ) external notFailed {\n require(_messageBody.length <= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n // get the next nonce for the destination domain, then increment it\n uint32 _nonce = nonces[_destinationDomain];\n nonces[_destinationDomain] = _nonce + 1;\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(\n localDomain,\n bytes32(uint256(uint160(msg.sender))),\n _nonce,\n _destinationDomain,\n _recipientAddress,\n _messageBody\n );\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n tree.insert(_messageHash);\n // enqueue the new Merkle root after inserting the message\n queue.enqueue(root());\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(_messageHash, count() - 1, _destinationAndNonce(_destinationDomain, _nonce), committedRoot, _message);\n }\n\n /**\n * @notice Submit a signature from the Updater \"notarizing\" a root,\n * which updates the Home contract's `committedRoot`,\n * and publishes the signature which will be relayed to Replica contracts\n * @dev emits Update event\n * @dev If _newRoot is not contained in the queue,\n * the Update is a fraudulent Improper Update, so\n * the Updater is slashed & Home is set to FAILED state\n * @param _committedRoot Current updated merkle root which the update is building off of\n * @param _newRoot New merkle root to update the contract state to\n * @param _signature Updater signature on `_committedRoot` and `_newRoot`\n */\n function update(\n bytes32 _committedRoot,\n bytes32 _newRoot,\n bytes memory _signature\n ) external notFailed {\n // check that the update is not fraudulent;\n // if fraud is detected, Updater is slashed & Home is set to FAILED state\n if (improperUpdate(_committedRoot, _newRoot, _signature)) return;\n // clear all of the intermediate roots contained in this update from the queue\n while (true) {\n bytes32 _next = queue.dequeue();\n if (_next == _newRoot) break;\n }\n // update the Home state with the latest signed root & emit event\n committedRoot = _newRoot;\n emit Update(localDomain, _committedRoot, _newRoot, _signature);\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If queue is empty, null bytes returned for both\n * (No update is necessary because no messages have been dispatched since the last update)\n * @return _committedRoot Latest root signed by the Updater\n * @return _new Latest enqueued Merkle root\n */\n function suggestUpdate() external view returns (bytes32 _committedRoot, bytes32 _new) {\n if (queue.length() != 0) {\n _committedRoot = committedRoot;\n _new = queue.lastItem();\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Hash of Home domain concatenated with \"NOMAD\"\n */\n function homeDomainHash() public view override returns (bytes32) {\n return _homeDomainHash(localDomain);\n }\n\n /**\n * @notice Check if an Update is an Improper Update;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Update is an update building off of the Home's `committedRoot`\n * for which the `_newRoot` does not currently exist in the Home's queue.\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Update will only be accepted as valid by the Replica\n * If an Improper Update is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Update is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Update.\n *\n * An Improper Update submitted to the Replica is only valid\n * while the `_oldRoot` is still equal to the `committedRoot` on Home;\n * if the `committedRoot` on Home has already been updated with a valid Update,\n * then the Updater should be slashed with a Double Update.\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _oldRoot Old merkle tree root (should equal home's committedRoot)\n * @param _newRoot New merkle tree root\n * @param _signature Updater signature on `_oldRoot` and `_newRoot`\n * @return TRUE if update was an Improper Update (implying Updater was slashed)\n */\n function improperUpdate(\n bytes32 _oldRoot,\n bytes32 _newRoot,\n bytes memory _signature\n ) public notFailed returns (bool) {\n require(_isUpdaterSignature(_oldRoot, _newRoot, _signature), \"!updater sig\");\n require(_oldRoot == committedRoot, \"not a current update\");\n // if the _newRoot is not currently contained in the queue,\n // slash the Updater and set the contract to FAILED state\n if (!queue.contains(_newRoot)) {\n _fail();\n emit ImproperUpdate(_oldRoot, _newRoot, _signature);\n return true;\n }\n // if the _newRoot is contained in the queue,\n // this is not an improper update\n return false;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal override {\n // set contract to FAILED\n _setFailed();\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` << 32) & `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce) internal pure returns (uint64) {\n return (uint64(_destination) << 32) | _nonce;\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/contracts/Replica.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ Internal Imports ============\nimport {Version0} from \"./Version0.sol\";\nimport {NomadBase} from \"./NomadBase.sol\";\nimport {MerkleLib} from \"../libs/Merkle.sol\";\nimport {Message} from \"../libs/Message.sol\";\n// ============ External Imports ============\n// import {TypedMemView} from \"@summa-tx/memview-sol/contracts/TypedMemView.sol\";\nimport {TypedMemView} from \"../libs/TypedMemView.sol\";\n\n/**\n * @title Replica\n * @author Illusory Systems Inc.\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract Replica is Version0, NomadBase {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n using Message for bytes29;\n\n // ============ Enums ============\n\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // ============ Immutables ============\n\n // Minimum gas for message processing\n uint256 public immutable PROCESS_GAS;\n // Reserved gas (to ensure tx completes in case message processing runs out)\n uint256 public immutable RESERVE_GAS;\n\n // ============ Public Storage ============\n\n // Domain of home chain\n uint32 public remoteDomain;\n // Number of seconds to wait before root becomes confirmable\n uint256 public optimisticSeconds;\n // re-entrancy guard\n uint8 private entered;\n // Mapping of roots to allowable confirmation times\n mapping(bytes32 => uint256) public confirmAt;\n // Mapping of message leaves to MessageStatus\n mapping(bytes32 => MessageStatus) public messages;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash Hash of message that failed to process\n * @param success TRUE if the call was executed successfully, FALSE if the call reverted\n * @param returnData the return data from the external call\n */\n event Process(bytes32 indexed messageHash, bool indexed success, bytes indexed returnData);\n\n /**\n * @notice Emitted when the value for optimisticTimeout is set\n * @param timeout The new value for optimistic timeout\n */\n event SetOptimisticTimeout(uint256 timeout);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt);\n\n // ============ Constructor ============\n\n // solhint-disable-next-line no-empty-blocks\n constructor(\n uint32 _localDomain,\n uint256 _processGas,\n uint256 _reserveGas\n ) NomadBase(_localDomain) {\n require(_processGas >= 850_000, \"!process gas\");\n require(_reserveGas >= 15_000, \"!reserve gas\");\n PROCESS_GAS = _processGas;\n RESERVE_GAS = _reserveGas;\n }\n\n // ============ Initializer ============\n\n function initialize(\n uint32 _remoteDomain,\n address _updater,\n bytes32 _committedRoot,\n uint256 _optimisticSeconds\n ) public initializer {\n __NomadBase_initialize(_updater);\n // set storage variables\n entered = 1;\n remoteDomain = _remoteDomain;\n committedRoot = _committedRoot;\n confirmAt[_committedRoot] = 1;\n optimisticSeconds = _optimisticSeconds;\n emit SetOptimisticTimeout(_optimisticSeconds);\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed update's new root,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _oldRoot Old merkle root\n * @param _newRoot New merkle root\n * @param _signature Updater's signature on `_oldRoot` and `_newRoot`\n */\n function update(\n bytes32 _oldRoot,\n bytes32 _newRoot,\n bytes memory _signature\n ) external notFailed {\n // ensure that update is building off the last submitted root\n require(_oldRoot == committedRoot, \"not current update\");\n // validate updater signature\n require(_isUpdaterSignature(_oldRoot, _newRoot, _signature), \"!updater sig\");\n // Hook for future use\n _beforeUpdate();\n // set the new root's confirmation timer\n confirmAt[_newRoot] = block.timestamp + optimisticSeconds;\n // update committedRoot\n committedRoot = _newRoot;\n emit Update(remoteDomain, _oldRoot, _newRoot, _signature);\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to NomadBase.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(keccak256(_message), _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if not enough gas is provided for the dispatch transaction.\n * @param _message Formatted message\n * @return _success TRUE iff dispatch transaction succeeded\n */\n function process(bytes memory _message) public returns (bool _success) {\n bytes29 _m = _message.ref(0);\n // ensure message was meant for this domain\n require(_m.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n require(messages[_messageHash] == MessageStatus.Proven, \"!proven\");\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n // update message status as processed\n messages[_messageHash] = MessageStatus.Processed;\n // A call running out of gas TYPICALLY errors the whole tx. We want to\n // a) ensure the call has a sufficient amount of gas to make a\n // meaningful state change.\n // b) ensure that if the subcall runs out of gas, that the tx as a whole\n // does not revert (i.e. we still mark the message processed)\n // To do this, we require that we have enough gas to process\n // and still return. We then delegate only the minimum processing gas.\n require(gasleft() >= PROCESS_GAS + RESERVE_GAS, \"!gas\");\n // get the message recipient\n address _recipient = _m.recipientAddress();\n // set up for assembly call\n uint256 _toCopy;\n uint256 _maxCopy = 256;\n uint256 _gas = PROCESS_GAS;\n // allocate memory for returndata\n bytes memory _returnData = new bytes(_maxCopy);\n bytes memory _calldata = abi.encodeWithSignature(\n \"handle(uint32,uint32,bytes32,bytes)\",\n _m.origin(),\n _m.nonce(),\n _m.sender(),\n _m.body().clone()\n );\n // dispatch message to recipient\n // by assembly calling \"handle\" function\n // we call via assembly to avoid memcopying a very large returndata\n // returned by a malicious contract\n assembly {\n _success := call(\n _gas, // gas\n _recipient, // recipient\n 0, // ether value\n add(_calldata, 0x20), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n // limit our copy to 256 bytes\n _toCopy := returndatasize()\n if gt(_toCopy, _maxCopy) {\n _toCopy := _maxCopy\n }\n // Store the length of the copied bytes\n mstore(_returnData, _toCopy)\n // copy the bytes from returndata[0:_toCopy]\n returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n }\n // emit process results\n emit Process(_messageHash, _success, _returnData);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set optimistic timeout period for new roots\n * @dev Only callable by owner (Governance)\n * @param _optimisticSeconds New optimistic timeout period\n */\n function setOptimisticTimeout(uint256 _optimisticSeconds) external onlyOwner {\n optimisticSeconds = _optimisticSeconds;\n emit SetOptimisticTimeout(_optimisticSeconds);\n }\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(bytes32 _root, uint256 _confirmAt) external onlyOwner {\n uint256 _previousConfirmAt = confirmAt[_root];\n confirmAt[_root] = _confirmAt;\n emit SetConfirmation(_root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted & timeout has expired\n */\n function acceptableRoot(bytes32 _root) public view returns (bool) {\n uint256 _time = confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp >= _time;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _leaf Leaf of message to prove\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n bytes32 _leaf,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n // ensure that message has not been proven or processed\n require(messages[_leaf] == MessageStatus.None, \"!MessageStatus.None\");\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, change status to Proven\n if (acceptableRoot(_calculatedRoot)) {\n messages[_leaf] = MessageStatus.Proven;\n return true;\n }\n return false;\n }\n\n /**\n * @notice Hash of Home domain concatenated with \"NOMAD\"\n */\n function homeDomainHash() public view override returns (bytes32) {\n return _homeDomainHash(remoteDomain);\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Moves the contract into failed state\n * @dev Called when a Double Update is submitted\n */\n function _fail() internal override {\n _setFailed();\n }\n\n /// @notice Hook for potential future use\n // solhint-disable-next-line no-empty-blocks\n function _beforeUpdate() internal {}\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/libs/TypeCasts.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// import \"@summa-tx/memview-sol/contracts/TypedMemView.sol\";\nimport \"./TypedMemView.sol\";\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen < 32 && _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/contracts/Version0.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n/**\n * @title Version0\n * @notice Version getter for contracts\n **/\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/contracts/NomadBase.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ Internal Imports ============\nimport {Message} from \"../libs/Message.sol\";\n// ============ External Imports ============\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title NomadBase\n * @author Illusory Systems Inc.\n * @notice Shared utilities between Home and Replica.\n */\nabstract contract NomadBase is Initializable, OwnableUpgradeable {\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n // Current state of contract\n States public state;\n // The latest root that has been signed by the Updater\n bytes32 public committedRoot;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param oldRoot Old merkle root\n * @param newRoot New merkle root\n * @param signature Updater's signature on `oldRoot` and `newRoot`\n */\n event Update(uint32 indexed homeDomain, bytes32 indexed oldRoot, bytes32 indexed newRoot, bytes signature);\n\n /**\n * @notice Emitted when proof of a double update is submitted,\n * which sets the contract to FAILED state\n * @param oldRoot Old root shared between two conflicting updates\n * @param newRoot Array containing two conflicting new roots\n * @param signature Signature on `oldRoot` and `newRoot`[0]\n * @param signature2 Signature on `oldRoot` and `newRoot`[1]\n */\n event DoubleUpdate(bytes32 oldRoot, bytes32[2] newRoot, bytes signature, bytes signature2);\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __NomadBase_initialize(address _updater) internal initializer {\n __Ownable_init();\n _setUpdater(_updater);\n state = States.Active;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Checks that signatures on two sets of\n * roots are valid and that the new roots conflict with each other. If both\n * cases hold true, the contract is failed and a `DoubleUpdate` event is\n * emitted.\n * @dev When `fail()` is called on Home, updater is slashed.\n * @param _oldRoot Old root shared between two conflicting updates\n * @param _newRoot Array containing two conflicting new roots\n * @param _signature Signature on `_oldRoot` and `_newRoot`[0]\n * @param _signature2 Signature on `_oldRoot` and `_newRoot`[1]\n */\n function doubleUpdate(\n bytes32 _oldRoot,\n bytes32[2] calldata _newRoot,\n bytes calldata _signature,\n bytes calldata _signature2\n ) external notFailed {\n if (\n NomadBase._isUpdaterSignature(_oldRoot, _newRoot[0], _signature) &&\n NomadBase._isUpdaterSignature(_oldRoot, _newRoot[1], _signature2) &&\n _newRoot[0] != _newRoot[1]\n ) {\n _fail();\n emit DoubleUpdate(_oldRoot, _newRoot, _signature, _signature2);\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Hash of Home domain concatenated with \"NOMAD\"\n */\n function homeDomainHash() public view virtual returns (bytes32);\n\n // ============ Internal Functions ============\n\n /**\n * @notice Hash of Home domain concatenated with \"NOMAD\"\n * @param _homeDomain the Home domain to hash\n */\n function _homeDomainHash(uint32 _homeDomain) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(_homeDomain, \"NOMAD\"));\n }\n\n /**\n * @notice Set contract state to FAILED\n * @dev Called when a valid fraud proof is submitted\n */\n function _setFailed() internal {\n state = States.Failed;\n }\n\n /**\n * @notice Moves the contract into failed state\n * @dev Called when fraud is proven\n * (Double Update is submitted on Home or Replica,\n * or Improper Update is submitted on Home)\n */\n function _fail() internal virtual;\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @notice Checks that signature was signed by Updater\n * @param _oldRoot Old merkle root\n * @param _newRoot New merkle root\n * @param _signature Signature on `_oldRoot` and `_newRoot`\n * @return TRUE iff signature is valid signed by updater\n **/\n function _isUpdaterSignature(\n bytes32 _oldRoot,\n bytes32 _newRoot,\n bytes memory _signature\n ) internal view returns (bool) {\n bytes32 _digest = keccak256(abi.encodePacked(homeDomainHash(), _oldRoot, _newRoot));\n _digest = ECDSA.toEthSignedMessageHash(_digest);\n return (ECDSA.recover(_digest, _signature) == updater);\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/libs/Queue.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n/**\n * @title QueueLib\n * @author Illusory Systems Inc.\n * @notice Library containing queue struct and operations for queue used by\n * Home and Replica.\n **/\nlibrary QueueLib {\n /**\n * @notice Queue struct\n * @dev Internally keeps track of the `first` and `last` elements through\n * indices and a mapping of indices to enqueued elements.\n **/\n struct Queue {\n uint128 first;\n uint128 last;\n mapping(uint256 => bytes32) queue;\n }\n\n /**\n * @notice Initializes the queue\n * @dev Empty state denoted by _q.first > q._last. Queue initialized\n * with _q.first = 1 and _q.last = 0.\n **/\n function initialize(Queue storage _q) internal {\n if (_q.first == 0) {\n _q.first = 1;\n }\n }\n\n /**\n * @notice Enqueues a single new element\n * @param _item New element to be enqueued\n * @return _last Index of newly enqueued element\n **/\n function enqueue(Queue storage _q, bytes32 _item) internal returns (uint128 _last) {\n _last = _q.last + 1;\n _q.last = _last;\n if (_item != bytes32(0)) {\n // saves gas if we're queueing 0\n _q.queue[_last] = _item;\n }\n }\n\n /**\n * @notice Dequeues element at front of queue\n * @dev Removes dequeued element from storage\n * @return _item Dequeued element\n **/\n function dequeue(Queue storage _q) internal returns (bytes32 _item) {\n uint128 _last = _q.last;\n uint128 _first = _q.first;\n require(_length(_last, _first) != 0, \"Empty\");\n _item = _q.queue[_first];\n if (_item != bytes32(0)) {\n // saves gas if we're dequeuing 0\n delete _q.queue[_first];\n }\n _q.first = _first + 1;\n }\n\n /**\n * @notice Batch enqueues several elements\n * @param _items Array of elements to be enqueued\n * @return _last Index of last enqueued element\n **/\n function enqueue(Queue storage _q, bytes32[] memory _items) internal returns (uint128 _last) {\n _last = _q.last;\n for (uint256 i = 0; i < _items.length; i += 1) {\n _last += 1;\n bytes32 _item = _items[i];\n if (_item != bytes32(0)) {\n _q.queue[_last] = _item;\n }\n }\n _q.last = _last;\n }\n\n /**\n * @notice Batch dequeues `_number` elements\n * @dev Reverts if `_number` > queue length\n * @param _number Number of elements to dequeue\n * @return Array of dequeued elements\n **/\n function dequeue(Queue storage _q, uint256 _number) internal returns (bytes32[] memory) {\n uint128 _last = _q.last;\n uint128 _first = _q.first;\n // Cannot underflow unless state is corrupted\n require(_length(_last, _first) >= _number, \"Insufficient\");\n\n bytes32[] memory _items = new bytes32[](_number);\n\n for (uint256 i = 0; i < _number; i++) {\n _items[i] = _q.queue[_first];\n delete _q.queue[_first];\n _first++;\n }\n _q.first = _first;\n return _items;\n }\n\n /**\n * @notice Returns true if `_item` is in the queue and false if otherwise\n * @dev Linearly scans from _q.first to _q.last looking for `_item`\n * @param _item Item being searched for in queue\n * @return True if `_item` currently exists in queue, false if otherwise\n **/\n function contains(Queue storage _q, bytes32 _item) internal view returns (bool) {\n for (uint256 i = _q.first; i <= _q.last; i++) {\n if (_q.queue[i] == _item) {\n return true;\n }\n }\n return false;\n }\n\n /// @notice Returns last item in queue\n /// @dev Returns bytes32(0) if queue empty\n function lastItem(Queue storage _q) internal view returns (bytes32) {\n return _q.queue[_q.last];\n }\n\n /// @notice Returns element at front of queue without removing element\n /// @dev Reverts if queue is empty\n function peek(Queue storage _q) internal view returns (bytes32 _item) {\n require(!isEmpty(_q), \"Empty\");\n _item = _q.queue[_q.first];\n }\n\n /// @notice Returns true if queue is empty and false if otherwise\n function isEmpty(Queue storage _q) internal view returns (bool) {\n return _q.last < _q.first;\n }\n\n /// @notice Returns number of elements in queue\n function length(Queue storage _q) internal view returns (uint256) {\n uint128 _last = _q.last;\n uint128 _first = _q.first;\n // Cannot underflow unless state is corrupted\n return _length(_last, _first);\n }\n\n /// @notice Returns number of elements between `_last` and `_first` (used internally)\n function _length(uint128 _last, uint128 _first) internal pure returns (uint256) {\n return uint256(_last + 1 - _first);\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/libs/Merkle.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// work based on eth2 deposit contract, which is used under CC0-1.0\n\n/**\n * @title MerkleLib\n * @author Illusory Systems Inc.\n * @notice An incremental merkle tree modeled on the eth2 deposit contract.\n **/\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n require(_tree.count < MAX_LEAVES, \"merkle tree full\");\n\n _tree.count += 1;\n uint256 size = _tree.count;\n for (uint256 i = 0; i < TREE_DEPTH; i++) {\n if ((size & 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size /= 2;\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i < TREE_DEPTH; i++) {\n uint256 _ithBit = (_index >> i) & 0x01;\n bytes32 _next = _tree.branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i < TREE_DEPTH; i++) {\n uint256 _ithBit = (_index >> i) & 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 = hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 = hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 = hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 = hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 = hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 = hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 = hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 = hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 = hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 = hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 = hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 = hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 = hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 = hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 = hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 = hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 = hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 = hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 = hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 = hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 = hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 = hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 = hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 = hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 = hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 = hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 = hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 = hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 = hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 = hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 = hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 = hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/libs/Message.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// import \"@summa-tx/memview-sol/contracts/TypedMemView.sol\";\n\nimport \"./TypedMemView.sol\";\n\nimport {TypeCasts} from \"./TypeCasts.sol\";\n\n/**\n * @title Message Library\n * @author Illusory Systems Inc.\n * @notice Library for formatted messages used by Home and Replica.\n **/\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n // Number of bytes in formatted message before `body` field\n uint256 internal constant PREFIX_LENGTH = 76;\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _originDomain Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce\n * @param _destinationDomain Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_originDomain, _sender, _nonce, _destinationDomain, _recipient, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n bytes memory _body\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_origin, _sender, _nonce, _destination, _recipient, _body));\n }\n\n /// @notice Returns message's origin field\n function origin(bytes29 _message) internal pure returns (uint32) {\n return uint32(_message.indexUint(0, 4));\n }\n\n /// @notice Returns message's sender field\n function sender(bytes29 _message) internal pure returns (bytes32) {\n return _message.index(4, 32);\n }\n\n /// @notice Returns message's nonce field\n function nonce(bytes29 _message) internal pure returns (uint32) {\n return uint32(_message.indexUint(36, 4));\n }\n\n /// @notice Returns message's destination field\n function destination(bytes29 _message) internal pure returns (uint32) {\n return uint32(_message.indexUint(40, 4));\n }\n\n /// @notice Returns message's recipient field as bytes32\n function recipient(bytes29 _message) internal pure returns (bytes32) {\n return _message.index(44, 32);\n }\n\n /// @notice Returns message's recipient field as an address\n function recipientAddress(bytes29 _message) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_message));\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure returns (bytes29) {\n return _message.slice(PREFIX_LENGTH, _message.len() - PREFIX_LENGTH, 0);\n }\n\n function leaf(bytes29 _message) internal view returns (bytes32) {\n return\n messageHash(\n origin(_message),\n sender(_message),\n nonce(_message),\n destination(_message),\n recipient(_message),\n TypedMemView.clone(body(_message))\n );\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/contracts/Merkle.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ Internal Imports ============\nimport {MerkleLib} from \"../libs/Merkle.sol\";\n\n/**\n * @title MerkleTreeManager\n * @author Illusory Systems Inc.\n * @notice Contains a Merkle tree instance and\n * exposes view functions for the tree.\n */\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[49] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/contracts/Queue.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ Internal Imports ============\nimport {QueueLib} from \"../libs/Queue.sol\";\n// ============ External Imports ============\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title QueueManager\n * @author Illusory Systems Inc.\n * @notice Contains a queue instance and\n * exposes view functions for the queue.\n **/\ncontract QueueManager is Initializable {\n // ============ Libraries ============\n\n using QueueLib for QueueLib.Queue;\n QueueLib.Queue internal queue;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[49] private __GAP;\n\n // ============ Initializer ============\n\n function __QueueManager_initialize() internal initializer {\n queue.initialize();\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Returns number of elements in queue\n */\n function queueLength() external view returns (uint256) {\n return queue.length();\n }\n\n /**\n * @notice Returns TRUE iff `_item` is in the queue\n */\n function queueContains(bytes32 _item) external view returns (bool) {\n return queue.contains(_item);\n }\n\n /**\n * @notice Returns last item enqueued to the queue\n */\n function queueEnd() external view returns (bytes32) {\n return queue.lastItem();\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/interfaces/IUpdaterManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 && !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/libs/TypedMemView.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.11;\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b >> 4); // top 4 bits\n encoded <<= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i > 15; ) {\n uint8 _byte = uint8(_b >> (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first <<= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i < 255; ) {\n uint8 _byte = uint8(_b >> (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second <<= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v >> 8) & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);\n // swap 2-byte long pairs\n v =\n ((v >> 16) & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);\n // swap 4-byte long pairs\n v =\n ((v >> 32) & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);\n // swap 8-byte long pairs\n v =\n ((v >> 64) & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);\n // swap 16-byte long pairs\n v = (v >> 128) | (v << 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(sub(_len, 1), 0x8000000000000000000000000000000000000000000000000000000000000000)\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\"Type assertion failed. Got 0x\", uint80(g), \". Expected 0x\", uint80(e))\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) >> (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len > end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes > len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes <= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have >= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) >> ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have >= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (loc(left) == loc(right) && len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) && keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location) private view returns (bytes29 unsafeView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i < memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/shared/Router.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ Internal Imports ============\nimport {XAppConnectionClient} from \"./XAppConnectionClient.sol\";\n// ============ External Imports ============\nimport {IMessageRecipient} from \"../../nomad-core/interfaces/IMessageRecipient.sol\";\n\nabstract contract Router is XAppConnectionClient, IMessageRecipient {\n // ============ Mutable Storage ============\n\n mapping(uint32 => bytes32) public remotes;\n\n // ============ Upgrade Gap ============\n\n uint256[49] private __GAP; // gap for upgrade safety\n\n // ============ Modifiers ============\n\n /**\n * @notice Only accept messages from a remote Router contract\n * @param _origin The domain the message is coming from\n * @param _router The address the message is coming from\n */\n modifier onlyRemoteRouter(uint32 _origin, bytes32 _router) {\n require(_isRemoteRouter(_origin, _router), \"!remote router\");\n _;\n }\n\n // ============ External functions ============\n\n /**\n * @notice Register the address of a Router contract for the same xApp on a remote chain\n * @param _domain The domain of the remote xApp Router\n * @param _router The address of the remote xApp Router\n */\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external onlyOwner {\n remotes[_domain] = _router;\n }\n\n // ============ Virtual functions ============\n\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external virtual override;\n\n // ============ Internal functions ============\n /**\n * @notice Return true if the given domain / router is the address of a remote xApp Router\n * @param _domain The domain of the potential remote xApp Router\n * @param _router The address of the potential remote xApp Router\n */\n function _isRemoteRouter(uint32 _domain, bytes32 _router) internal view returns (bool) {\n return remotes[_domain] == _router;\n }\n\n /**\n * @notice Assert that the given domain has a xApp Router registered and return its address\n * @param _domain The domain of the chain for which to get the xApp Router\n * @return _remote The address of the remote xApp Router on _domain\n */\n function _mustHaveRemote(uint32 _domain) internal view returns (bytes32 _remote) {\n _remote = remotes[_domain];\n require(_remote != bytes32(0), \"!remote\");\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/shared/XAppConnectionClient.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ External Imports ============\nimport {Home} from \"../../nomad-core/contracts/Home.sol\";\nimport {XAppConnectionManager} from \"../../nomad-core/contracts/XAppConnectionManager.sol\";\n\nimport {ProposedOwnableUpgradeable} from \"./ProposedOwnable.sol\";\n\nabstract contract XAppConnectionClient is ProposedOwnableUpgradeable {\n // ============ Mutable Storage ============\n\n XAppConnectionManager public xAppConnectionManager;\n\n // ============ Upgrade Gap ============\n\n uint256[49] private __GAP; // gap for upgrade safety\n\n // ============ Modifiers ============\n\n /**\n * @notice Only accept messages from an Nomad Replica contract\n */\n modifier onlyReplica() {\n require(_isReplica(msg.sender), \"!replica\");\n _;\n }\n\n // ======== Initializer =========\n\n function __XAppConnectionClient_initialize(address _xAppConnectionManager) internal initializer {\n xAppConnectionManager = XAppConnectionManager(_xAppConnectionManager);\n __ProposedOwnable_init();\n }\n\n // ============ External functions ============\n\n /**\n * @notice Modify the contract the xApp uses to validate Replica contracts\n * @param _xAppConnectionManager The address of the xAppConnectionManager contract\n */\n function setXAppConnectionManager(address _xAppConnectionManager) external onlyOwner {\n xAppConnectionManager = XAppConnectionManager(_xAppConnectionManager);\n }\n\n // ============ Internal functions ============\n\n /**\n * @notice Get the local Home contract from the xAppConnectionManager\n * @return The local Home contract\n */\n function _home() internal view returns (Home) {\n return xAppConnectionManager.home();\n }\n\n /**\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\n * @return True if _potentialReplica is an enrolled Replica\n */\n function _isReplica(address _potentialReplica) internal view returns (bool) {\n return xAppConnectionManager.isReplica(_potentialReplica);\n }\n\n /**\n * @notice Get the local domain from the xAppConnectionManager\n * @return The local domain\n */\n function _localDomain() internal view virtual returns (uint32) {\n return xAppConnectionManager.localDomain();\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/shared/Version.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\n/**\n * @title Version\n * @notice Version getter for contracts\n **/\ncontract Version {\n uint8 public constant VERSION = 0;\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/relayer-fee/libraries/RelayerFeeMessage.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\n// ============ External Imports ============\nimport {TypedMemView} from \"../../../nomad-core/libs/TypedMemView.sol\";\n\nlibrary RelayerFeeMessage {\n // ============ Libraries ============\n\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n // ============ Enums ============\n\n // WARNING: do NOT re-write the numbers / order\n // of message types in an upgrade;\n // will cause in-flight messages to be mis-interpreted\n enum Types {\n Invalid, // 0\n ClaimFees // 1\n }\n\n // ============ Constants ============\n\n // before: 1 byte identifier + 20 bytes recipient + 32 bytes length + 32 bytes 1 transfer id = 85 bytes\n uint256 private constant MIN_CLAIM_LEN = 85;\n // before: 1 byte identifier + 20 bytes recipient = 21 bytes\n uint256 private constant LENGTH_ID_START = 21;\n uint8 private constant LENGTH_ID_LEN = 32;\n // before: 1 byte identifier\n uint256 private constant RECIPIENT_START = 1;\n // before: 1 byte identifier + 20 bytes recipient + 32 bytes length = 53 bytes\n uint256 private constant TRANSFER_IDS_START = 53;\n uint8 private constant TRANSFER_ID_LEN = 32;\n\n // ============ Modifiers ============\n\n /**\n * @notice Asserts a message is of type `_t`\n * @param _view The message\n * @param _t The expected type\n */\n modifier typeAssert(bytes29 _view, Types _t) {\n _view.assertType(uint40(_t));\n _;\n }\n\n // ============ Formatters ============\n\n /**\n * @notice Formats an claim fees message\n * @param _recipient The address of the relayer\n * @param _transferIds A group of transfers ids to claim for fee bumps\n * @return The formatted message\n */\n function formatClaimFees(address _recipient, bytes32[] calldata _transferIds) internal pure returns (bytes memory) {\n return abi.encodePacked(uint8(Types.ClaimFees), _recipient, _transferIds.length, _transferIds);\n }\n\n // ============ Getters ============\n\n /**\n * @notice Parse the recipient address of the fees\n * @param _view The message\n * @return The recipient address\n */\n function recipient(bytes29 _view) internal pure typeAssert(_view, Types.ClaimFees) returns (address) {\n // before = 1 byte identifier\n return _view.indexAddress(1);\n }\n\n /**\n * @notice Parse The group of transfers ids to claim for fee bumps\n * @param _view The message\n * @return The group of transfers ids to claim for fee bumps\n */\n function transferIds(bytes29 _view) internal pure typeAssert(_view, Types.ClaimFees) returns (bytes32[] memory) {\n uint256 length = _view.indexUint(LENGTH_ID_START, LENGTH_ID_LEN);\n\n bytes32[] memory ids = new bytes32[](length);\n for (uint256 i; i < length; ) {\n ids[i] = _view.index(TRANSFER_IDS_START + i * TRANSFER_ID_LEN, TRANSFER_ID_LEN);\n\n unchecked {\n ++i;\n }\n }\n return ids;\n }\n\n /**\n * @notice Checks that view is a valid message length\n * @param _view The bytes string\n * @return TRUE if message is valid\n */\n function isValidClaimFeesLength(bytes29 _view) internal pure returns (bool) {\n uint256 _len = _view.len();\n // at least 1 transfer id where the excess is multiplier of transfer id length\n return _len >= MIN_CLAIM_LEN && (_len - TRANSFER_IDS_START) % TRANSFER_ID_LEN == 0;\n }\n\n /**\n * @notice Converts to a ClaimFees\n * @param _view The message\n * @return The newly typed message\n */\n function tryAsClaimFees(bytes29 _view) internal pure returns (bytes29) {\n if (isValidClaimFeesLength(_view)) {\n return _view.castTo(uint40(Types.ClaimFees));\n }\n return TypedMemView.nullView();\n }\n\n /**\n * @notice Asserts that the message is of type ClaimFees\n * @param _view The message\n * @return The message\n */\n function mustBeClaimFees(bytes29 _view) internal pure returns (bytes29) {\n return tryAsClaimFees(_view).assertValid();\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/interfaces/IBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\ninterface IBridgeToken {\n function initialize() external;\n\n function name() external returns (string memory);\n\n function balanceOf(address _account) external view returns (uint256);\n\n function symbol() external view returns (string memory);\n\n function decimals() external view returns (uint8);\n\n function detailsHash() external view returns (bytes32);\n\n function burn(address _from, uint256 _amnt) external;\n\n function mint(address _to, uint256 _amnt) external;\n\n function setDetailsHash(bytes32 _detailsHash) external;\n\n function setDetails(\n string calldata _name,\n string calldata _symbol,\n uint8 _decimals\n ) external;\n\n // inherited from ownable\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/promise/interfaces/ICallback.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface ICallback {\n function callback(\n bytes32 transferId,\n bool success,\n bytes memory data\n ) external;\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/promise/libraries/PromiseMessage.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\n// ============ External Imports ============\nimport {TypedMemView} from \"../../../nomad-core/libs/TypedMemView.sol\";\n\nlibrary PromiseMessage {\n // ============ Libraries ============\n\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n // ============ Enums ============\n\n // WARNING: do NOT re-write the numbers / order\n // of message types in an upgrade;\n // will cause in-flight messages to be mis-interpreted\n enum Types {\n Invalid, // 0\n PromiseCallback // 1\n }\n\n // ============ Constants ============\n uint256 private constant IDENTIFIER_LEN = 1;\n // 1 byte identifier + 32 bytes transferId + 20 bytes callback + 1 byte success + 32 bytes length + x bytes data\n // before: 1 byte identifier + 32 bytes transferId + 20 bytes callback + 1 byte success= 54 bytes\n uint256 private constant LENGTH_RETURNDATA_START = 54;\n uint8 private constant LENGTH_RETURNDATA_LEN = 32;\n\n // before: 1 byte identifier + 32 bytes transferId + 20 bytes callback + 1 byte success + 32 bytes length = 86 bytes\n uint256 private constant RETURNDATA_START = 86;\n\n // ============ Modifiers ============\n\n /**\n * @notice Asserts a message is of type `_t`\n * @param _view The message\n * @param _t The expected type\n */\n modifier typeAssert(bytes29 _view, Types _t) {\n _view.assertType(uint40(_t));\n _;\n }\n\n // ============ Formatters ============\n\n /**\n * @notice Formats an promise callback message\n * @param _transferId The address of the relayer\n * @param _callbackAddress The callback address on destination domain\n * @param _returnSuccess The success of the call\n * @param _returnData The return data of the call\n * @return The formatted message\n */\n function formatPromiseCallback(\n bytes32 _transferId,\n address _callbackAddress,\n bool _returnSuccess,\n bytes calldata _returnData\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n uint8(Types.PromiseCallback),\n _transferId,\n _callbackAddress,\n uint8(_returnSuccess ? 1 : 0),\n _returnData.length,\n _returnData\n );\n }\n\n // ============ Getters ============\n\n /**\n * @notice Parse the transferId from the message\n * @param _view The message\n * @return The transferId\n */\n function transferId(bytes29 _view) internal pure typeAssert(_view, Types.PromiseCallback) returns (bytes32) {\n // before = 1 byte identifier\n return _view.index(1, 32);\n }\n\n /**\n * @notice Parse the callback address from the message\n * @param _view The message\n * @return The callback address\n */\n function callbackAddress(bytes29 _view) internal pure typeAssert(_view, Types.PromiseCallback) returns (address) {\n // before = 1 byte identifier + 32 bytes transferId\n return _view.indexAddress(33);\n }\n\n /**\n * @notice Parse the result of execution on the destination domain\n * @param _view The message\n * @return The call result\n */\n function returnSuccess(bytes29 _view) internal pure typeAssert(_view, Types.PromiseCallback) returns (bool) {\n // before: 1 byte identifier + 32 bytes transferId + 20 bytes callback = 53 bytes\n return _view.indexUint(53, 1) == 1;\n }\n\n /**\n * @notice Parse the returnData length from the message\n * @param _view The message\n * @return The returnData length\n */\n function lengthOfReturnData(bytes29 _view) internal pure returns (uint256) {\n return _view.indexUint(LENGTH_RETURNDATA_START, LENGTH_RETURNDATA_LEN);\n }\n\n /**\n * @notice Parse returnData from the message\n * @param _view The message\n * @return data\n */\n function returnData(bytes29 _view)\n internal\n view\n typeAssert(_view, Types.PromiseCallback)\n returns (bytes memory data)\n {\n uint256 length = lengthOfReturnData(_view);\n\n data = _view.slice(RETURNDATA_START, length, 0).clone();\n }\n\n /**\n * @notice Checks that view is a valid message length\n * @param _view The bytes string\n * @return TRUE if message is valid\n */\n function isValidPromiseCallbackLength(bytes29 _view) internal pure returns (bool) {\n uint256 _len = _view.len();\n if (_len <= LENGTH_RETURNDATA_START) {\n return false;\n }\n uint256 _length = lengthOfReturnData(_view);\n // before = 1 byte identifier + 32 bytes transferId + 20 bytes callback address + 1 byte success + 32 bytes length + x bytes data\n // allow zero-length return data\n return _length >= 0 && (RETURNDATA_START + _length) == _len;\n }\n\n /**\n * @notice Converts to a Promise callback message\n * @param _view The message\n * @return The newly typed message\n */\n function tryAsPromiseCallback(bytes29 _view) internal pure returns (bytes29) {\n if (isValidPromiseCallbackLength(_view)) {\n return _view.castTo(uint40(Types.PromiseCallback));\n }\n return TypedMemView.nullView();\n }\n\n /**\n * @notice Asserts that the message is of type PromiseCallback\n * @param _view The message\n * @return The message\n */\n function mustBePromiseCallback(bytes29 _view) internal pure returns (bytes29) {\n return tryAsPromiseCallback(_view).assertValid();\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/nomad-core/interfaces/IMessageRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external;\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/shared/ProposedOwnable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport {IProposedOwnable} from \"./interfaces/IProposedOwnable.sol\";\n\n/**\n * @title ProposedOwnable\n * @notice Contract module which provides a basic access control mechanism,\n * where there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed via a two step process:\n * 1. Call `proposeOwner`\n * 2. Wait out the delay period\n * 3. Call `acceptOwner`\n *\n * @dev This module is used through inheritance. It will make available the\n * modifier `onlyOwner`, which can be applied to your functions to restrict\n * their use to the owner.\n *\n * @dev The majority of this code was taken from the openzeppelin Ownable\n * contract\n *\n */\nabstract contract ProposedOwnable is IProposedOwnable {\n // ========== Custom Errors ===========\n\n error ProposedOwnable__onlyOwner_notOwner();\n error ProposedOwnable__onlyProposed_notProposedOwner();\n error ProposedOwnable__proposeNewOwner_invalidProposal();\n error ProposedOwnable__proposeNewOwner_noOwnershipChange();\n error ProposedOwnable__renounceOwnership_noProposal();\n error ProposedOwnable__renounceOwnership_delayNotElapsed();\n error ProposedOwnable__renounceOwnership_invalidProposal();\n error ProposedOwnable__acceptProposedOwner_delayNotElapsed();\n\n // ============ Properties ============\n\n address private _owner;\n\n address private _proposed;\n uint256 private _proposedOwnershipTimestamp;\n\n uint256 private constant _delay = 7 days;\n\n // ======== Getters =========\n\n /**\n * @notice Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @notice Returns the address of the proposed owner.\n */\n function proposed() public view virtual returns (address) {\n return _proposed;\n }\n\n /**\n * @notice Returns the address of the proposed owner.\n */\n function proposedTimestamp() public view virtual returns (uint256) {\n return _proposedOwnershipTimestamp;\n }\n\n /**\n * @notice Returns the delay period before a new owner can be accepted.\n */\n function delay() public view virtual returns (uint256) {\n return _delay;\n }\n\n /**\n * @notice Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n if (_owner != msg.sender) revert ProposedOwnable__onlyOwner_notOwner();\n _;\n }\n\n /**\n * @notice Throws if called by any account other than the proposed owner.\n */\n modifier onlyProposed() {\n if (_proposed != msg.sender) revert ProposedOwnable__onlyProposed_notProposedOwner();\n _;\n }\n\n /**\n * @notice Indicates if the ownership has been renounced() by\n * checking if current owner is address(0)\n */\n function renounced() public view returns (bool) {\n return _owner == address(0);\n }\n\n // ======== External =========\n\n /**\n * @notice Sets the timestamp for an owner to be proposed, and sets the\n * newly proposed owner as step 1 in a 2-step process\n */\n function proposeNewOwner(address newlyProposed) public virtual onlyOwner {\n // Contract as source of truth\n if (_proposed == newlyProposed && newlyProposed != address(0))\n revert ProposedOwnable__proposeNewOwner_invalidProposal();\n\n // Sanity check: reasonable proposal\n if (_owner == newlyProposed) revert ProposedOwnable__proposeNewOwner_noOwnershipChange();\n\n _setProposed(newlyProposed);\n }\n\n /**\n * @notice Renounces ownership of the contract after a delay\n */\n function renounceOwnership() public virtual onlyOwner {\n // Ensure there has been a proposal cycle started\n if (_proposedOwnershipTimestamp == 0) revert ProposedOwnable__renounceOwnership_noProposal();\n\n // Ensure delay has elapsed\n if ((block.timestamp - _proposedOwnershipTimestamp) <= _delay)\n revert ProposedOwnable__renounceOwnership_delayNotElapsed();\n\n // Require proposed is set to 0\n if (_proposed != address(0)) revert ProposedOwnable__renounceOwnership_invalidProposal();\n\n // Emit event, set new owner, reset timestamp\n _setOwner(_proposed);\n }\n\n /**\n * @notice Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function acceptProposedOwner() public virtual onlyProposed {\n // NOTE: no need to check if _owner == _proposed, because the _proposed\n // is 0-d out and this check is implicitly enforced by modifier\n\n // NOTE: no need to check if _proposedOwnershipTimestamp > 0 because\n // the only time this would happen is if the _proposed was never\n // set (will fail from modifier) or if the owner == _proposed (checked\n // above)\n\n // Ensure delay has elapsed\n if ((block.timestamp - _proposedOwnershipTimestamp) <= _delay)\n revert ProposedOwnable__acceptProposedOwner_delayNotElapsed();\n\n // Emit event, set new owner, reset timestamp\n _setOwner(_proposed);\n }\n\n // ======== Internal =========\n\n function _setOwner(address newOwner) internal {\n address oldOwner = _owner;\n _owner = newOwner;\n _proposedOwnershipTimestamp = 0;\n _proposed = address(0);\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n function _setProposed(address newlyProposed) private {\n _proposedOwnershipTimestamp = block.timestamp;\n _proposed = newlyProposed;\n emit OwnershipProposed(newlyProposed);\n }\n}\n\nabstract contract ProposedOwnableUpgradeable is Initializable, ProposedOwnable {\n /**\n * @dev Initializes the contract setting the deployer as the initial\n */\n function __ProposedOwnable_init() internal onlyInitializing {\n __ProposedOwnable_init_unchained();\n }\n\n function __ProposedOwnable_init_unchained() internal onlyInitializing {\n _setOwner(msg.sender);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __GAP;\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/shared/interfaces/IProposedOwnable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IProposedOwnable\n * @notice Defines a minimal interface for ownership with a two step proposal and acceptance\n * process\n */\ninterface IProposedOwnable {\n /**\n * @dev This emits when change in ownership of a contract is proposed.\n */\n event OwnershipProposed(address indexed proposedOwner);\n\n /**\n * @dev This emits when ownership of a contract changes.\n */\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @notice Get the address of the owner\n * @return owner_ The address of the owner.\n */\n function owner() external view returns (address owner_);\n\n /**\n * @notice Get the address of the proposed owner\n * @return proposed_ The address of the proposed.\n */\n function proposed() external view returns (address proposed_);\n\n /**\n * @notice Set the address of the proposed owner of the contract\n * @param newlyProposed The proposed new owner of the contract\n */\n function proposeNewOwner(address newlyProposed) external;\n\n /**\n * @notice Set the address of the proposed owner of the contract\n */\n function acceptProposedOwner() external;\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {ERC20BurnableUpgradeable, ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title Liquidity Provider Token\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\n * It is used to represent user's shares when providing liquidity to swap contracts.\n * @dev Only Swap contracts should initialize and own LPToken contracts.\n */\ncontract LPToken is ERC20BurnableUpgradeable, OwnableUpgradeable {\n // ============ Upgrade Gap ============\n\n uint256[49] private __GAP; // gap for upgrade safety\n\n // ============ Storage ============\n\n /**\n * @notice Used to enforce proper token dilution\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\n * See audit recommendations here:\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\n * and uniswap v2 implementation here:\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\n */\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\n\n // ============ Initializer ============\n\n /**\n * @notice Initializes this LPToken contract with the given name and symbol\n * @dev The caller of this function will become the owner. A Swap contract should call this\n * in its initializer function.\n * @param name name of this token\n * @param symbol symbol of this token\n */\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\n __Context_init_unchained();\n __ERC20_init_unchained(name, symbol);\n __Ownable_init_unchained();\n return true;\n }\n\n // ============ External functions ============\n\n /**\n * @notice Mints the given amount of LPToken to the recipient.\n * @dev only owner can call this mint function\n * @param recipient address of account to receive the tokens\n * @param amount amount of tokens to mint\n */\n function mint(address recipient, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot mint 0\");\n if (totalSupply() == 0) {\n // NOTE: using the _mint function directly will error because it is going\n // to the 0 address. fix by using the address(1) here instead\n _mint(address(1), MINIMUM_LIQUIDITY);\n }\n _mint(recipient, amount);\n }\n\n // ============ Internal functions ============\n\n /**\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\n * This assumes the owner is set to a Swap contract's address.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20Upgradeable) {\n super._beforeTokenTransfer(from, to, amount);\n require(to != address(this), \"LPToken: cannot send to itself\");\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n/**\n * @title AmplificationUtils library\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\n * This library assumes the struct is fully validated.\n */\nlibrary AmplificationUtils {\n using SafeMath for uint256;\n\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n // Constant values used in ramping A calculations\n uint256 public constant A_PRECISION = 100;\n uint256 public constant MAX_A = 10**6;\n uint256 private constant MAX_A_CHANGE = 2;\n uint256 private constant MIN_RAMP_TIME = 14 days;\n\n /**\n * @notice Return A, the amplification coefficient * n * (n - 1)\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter\n */\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self).div(A_PRECISION);\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self);\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n uint256 t1 = self.futureATime; // time when ramp is finished\n uint256 a1 = self.futureA; // final A value when ramp is finished\n\n if (block.timestamp < t1) {\n uint256 t0 = self.initialATime; // time when ramp is started\n uint256 a0 = self.initialA; // initial A value when ramp is started\n if (a1 > a0) {\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\n return a0.add(a1.sub(a0).mul(block.timestamp.sub(t0)).div(t1.sub(t0)));\n } else {\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\n return a0.sub(a0.sub(a1).mul(block.timestamp.sub(t0)).div(t1.sub(t0)));\n }\n } else {\n return a1;\n }\n }\n\n /**\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\n * Checks if the change is too rapid, and commits the new A value only when it falls under\n * the limit range.\n * @param self Swap struct to update\n * @param futureA_ the new A to ramp towards\n * @param futureTime_ timestamp when the new A should be reached\n */\n function rampA(\n SwapUtils.Swap storage self,\n uint256 futureA_,\n uint256 futureTime_\n ) internal {\n require(block.timestamp >= self.initialATime.add(1 days), \"Wait 1 day before starting ramp\");\n require(futureTime_ >= block.timestamp.add(MIN_RAMP_TIME), \"Insufficient ramp time\");\n require(futureA_ != 0 && futureA_ < MAX_A, \"futureA_ must be > 0 and < MAX_A\");\n\n uint256 initialAPrecise = _getAPrecise(self);\n uint256 futureAPrecise = futureA_.mul(A_PRECISION);\n\n if (futureAPrecise < initialAPrecise) {\n require(futureAPrecise.mul(MAX_A_CHANGE) >= initialAPrecise, \"futureA_ is too small\");\n } else {\n require(futureAPrecise <= initialAPrecise.mul(MAX_A_CHANGE), \"futureA_ is too large\");\n }\n\n self.initialA = initialAPrecise;\n self.futureA = futureAPrecise;\n self.initialATime = block.timestamp;\n self.futureATime = futureTime_;\n\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\n }\n\n /**\n * @notice Stops ramping A immediately. Once this function is called, rampA()\n * cannot be called for another 24 hours\n * @param self Swap struct to update\n */\n function stopRampA(SwapUtils.Swap storage self) internal {\n require(self.futureATime > block.timestamp, \"Ramp is already stopped\");\n\n uint256 currentA = _getAPrecise(self);\n self.initialA = currentA;\n self.futureA = currentA;\n self.initialATime = block.timestamp;\n self.futureATime = block.timestamp;\n\n emit StopRampA(currentA, block.timestamp);\n }\n}\n" + }, + "@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\n/**\n * @title MathUtils library\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\n * differences between two uint256.\n */\nlibrary MathUtils {\n /**\n * @notice Compares a and b and returns true if the difference between a and b\n * is less than 1 or equal to each other.\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return True if the difference between a and b is less than 1 or equal,\n * otherwise return false\n */\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\n return (difference(a, b) <= 1);\n }\n\n /**\n * @notice Calculates absolute difference between a and b\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return Difference between a and b\n */\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a > b) {\n return a - b;\n }\n return b - a;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "src/bridges/facets/OwnershipFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\nimport { IERC173 } from \"../interfaces/IERC173.sol\";\n\ncontract OwnershipFacet is IERC173 {\n function transferOwnership(address _newOwner) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.setContractOwner(_newOwner);\n }\n\n function owner() external view override returns (address owner_) {\n owner_ = LibDiamond.contractOwner();\n }\n}" + }, + "src/bridges/interfaces/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "src/bridges/facets/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\nimport { IDiamondLoupe } from \"../interfaces/IDiamondLoupe.sol\";\nimport { IERC165 } from \"../interfaces/IERC165.sol\";\n\ncontract DiamondLoupeFacet is IDiamondLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools.\n //\n // struct Facet {\n // address facetAddress;\n // bytes4[] functionSelectors;\n // }\n\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets() external view override returns (Facet[] memory facets_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i = 0; i < numFacets; i++) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\n }\n }\n\n /// @notice Gets all the function selectors provided by a facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(address _facet)\n external\n view\n override\n returns (bytes4[] memory facetFunctionSelectors_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = ds.facetAddresses;\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\n }\n\n // This implements ERC-165.\n function supportsInterface(bytes4 _interfaceId) external view override returns (bool) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n return ds.supportedInterfaces[_interfaceId];\n }\n}\n" + }, + "src/bridges/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" + }, + "src/bridges/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}" + } + }, + "settings": { + "evmVersion": "istanbul", + "metadata": { + "bytecodeHash": "none", + "useLiteralContent": true + }, + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + } + } +} \ No newline at end of file diff --git a/extensions/constants.ts b/extensions/constants.ts index d5bfd28c..95bfeb14 100644 --- a/extensions/constants.ts +++ b/extensions/constants.ts @@ -26,6 +26,8 @@ export enum NetworkNames { FuseSparknet = "fuseSparknet", Celo = "celo", CeloTest = "celoTest", + Neon = "neon", + NeonDevnet = "neonDevnet", ArbitrumNova = "arbitrumNova", ArbitrumNitro = "arbitrumNitro", Etherspot = "etherspot", @@ -187,16 +189,6 @@ export const NETWORK_CONFIGS: { defaultProviderUrl: "https://alfajores-forno.celo-testnet.org", defaultGasPrice: 1, }, - [NetworkNames.Fuse]: { - chainId: 122, - defaultProviderUrl: "https://rpc.fuse.io", - defaultGasPrice: 1, - }, - [NetworkNames.FuseSparknet]: { - chainId: 123, - defaultProviderUrl: "https://rpc.fusespark.io", - defaultGasPrice: 1, - }, [NetworkNames.ArbitrumNova]: { chainId: 42170, defaultProviderUrl: "https://nova.arbitrum.io/rpc", @@ -209,14 +201,25 @@ export const NETWORK_CONFIGS: { }, [NetworkNames.Fuse]: { chainId: 122, - defaultProviderUrl: 'https://rpc.fuse.io', + defaultProviderUrl: "https://rpc.fuse.io", defaultGasPrice: 1, }, [NetworkNames.FuseSparknet]: { chainId: 123, - defaultProviderUrl : 'https://rpc.fusespark.io', + defaultProviderUrl: "https://rpc.fusespark.io", defaultGasPrice: 1, }, + [NetworkNames.Neon]: { + chainId: 245022934, + defaultProviderUrl: "https://proxy.mainnet.neonlabs.org/solana", + explorer: "https://neonscan.org/", + defaultGasPrice: 1, + }, + [NetworkNames.NeonDevnet]: { + chainId: 245022926, + defaultProviderUrl: "https://proxy.devnet.neonlabs.org/solana", + defaultGasPrice: 0, + }, [NetworkNames.Etherspot]: { chainId: 4386, defaultProviderUrl: "https://qa-etherspot-testnet.pillarproject.io", diff --git a/package-lock.json b/package-lock.json index 883081cb..91aabe38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@etherspot/contracts", - "version": "1.9.3", + "version": "1.9.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@etherspot/contracts", - "version": "1.9.3", + "version": "1.9.4", "license": "MIT", "devDependencies": { "@connext/nxtp-contracts": "0.2.0-beta.20", @@ -1405,6 +1405,826 @@ "@ethersproject/transactions": "^5.6.2" } }, + "node_modules/@ethersproject/hardware-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hardware-wallets/-/hardware-wallets-5.7.0.tgz", + "integrity": "sha512-DjMMXIisRc8xFvEoLoYz1w7JDOYmaz/a0X9sp7Zu668RR8U1zCAyj5ow25HLRW+TCzEC5XiFetTXqS5kXonFCQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ledgerhq/hw-app-eth": "5.27.2", + "@ledgerhq/hw-transport": "5.26.0", + "@ledgerhq/hw-transport-u2f": "5.26.0", + "ethers": "^5.7.0" + }, + "optionalDependencies": { + "@ledgerhq/hw-transport-node-hid": "5.26.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true, + "peer": true + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true, + "peer": true + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, "node_modules/@ethersproject/hash": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.1.tgz", @@ -1929,6 +2749,227 @@ "node": ">= 10.14.2" } }, + "node_modules/@ledgerhq/cryptoassets": { + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-5.53.0.tgz", + "integrity": "sha512-M3ibc3LRuHid5UtL7FI3IC6nMEppvly98QHFoSa7lJU0HDzQxY6zHec/SPM4uuJUC8sXoGVAiRJDkgny54damw==", + "dev": true, + "peer": true, + "dependencies": { + "invariant": "2" + } + }, + "node_modules/@ledgerhq/devices": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-5.51.1.tgz", + "integrity": "sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA==", + "dev": true, + "peer": true, + "dependencies": { + "@ledgerhq/errors": "^5.50.0", + "@ledgerhq/logs": "^5.50.0", + "rxjs": "6", + "semver": "^7.3.5" + } + }, + "node_modules/@ledgerhq/errors": { + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-5.50.0.tgz", + "integrity": "sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow==", + "dev": true, + "peer": true + }, + "node_modules/@ledgerhq/hw-app-eth": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-5.27.2.tgz", + "integrity": "sha512-llNdrE894cCN8j6yxJEUniciyLVcLmu5N0UmIJLOObztG+5rOF4bX54h4SreTWK+E10Z0CzHSeyE5Lz/tVcqqQ==", + "dev": true, + "peer": true, + "dependencies": { + "@ledgerhq/cryptoassets": "^5.27.2", + "@ledgerhq/errors": "^5.26.0", + "@ledgerhq/hw-transport": "^5.26.0", + "bignumber.js": "^9.0.1", + "rlp": "^2.2.6" + } + }, + "node_modules/@ledgerhq/hw-transport": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.26.0.tgz", + "integrity": "sha512-NFeJOJmyEfAX8uuIBTpocWHcz630sqPcXbu864Q+OCBm4EK5UOKV1h/pX7e0xgNIKY8zhJ/O4p4cIZp9tnXLHQ==", + "dev": true, + "peer": true, + "dependencies": { + "@ledgerhq/devices": "^5.26.0", + "@ledgerhq/errors": "^5.26.0", + "events": "^3.2.0" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.26.0.tgz", + "integrity": "sha512-qhaefZVZatJ6UuK8Wb6WSFNOLWc2mxcv/xgsfKi5HJCIr4bPF/ecIeN+7fRcEaycxj4XykY6Z4A7zDVulfFH4w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@ledgerhq/devices": "^5.26.0", + "@ledgerhq/errors": "^5.26.0", + "@ledgerhq/hw-transport": "^5.26.0", + "@ledgerhq/hw-transport-node-hid-noevents": "^5.26.0", + "@ledgerhq/logs": "^5.26.0", + "lodash": "^4.17.20", + "node-hid": "1.3.0", + "usb": "^1.6.3" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.51.1.tgz", + "integrity": "sha512-9wFf1L8ZQplF7XOY2sQGEeOhpmBRzrn+4X43kghZ7FBDoltrcK+s/D7S+7ffg3j2OySyP6vIIIgloXylao5Scg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@ledgerhq/devices": "^5.51.1", + "@ledgerhq/errors": "^5.50.0", + "@ledgerhq/hw-transport": "^5.51.1", + "@ledgerhq/logs": "^5.50.0", + "node-hid": "2.1.1" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/@ledgerhq/hw-transport": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz", + "integrity": "sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@ledgerhq/devices": "^5.51.1", + "@ledgerhq/errors": "^5.50.0", + "events": "^3.3.0" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/node-hid": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.1.tgz", + "integrity": "sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^3.0.2", + "prebuild-install": "^6.0.0" + }, + "bin": { + "hid-showdevices": "src/show-devices.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/prebuild-install": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.21.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/@ledgerhq/hw-transport-u2f": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-5.26.0.tgz", + "integrity": "sha512-QTxP1Rsh+WZ184LUOelYVLeaQl3++V3I2jFik+l9JZtakwEHjD0XqOT750xpYNL/vfHsy31Wlz+oicdxGzFk+w==", + "deprecated": "@ledgerhq/hw-transport-u2f is deprecated. Please use @ledgerhq/hw-transport-webusb or @ledgerhq/hw-transport-webhid. https://github.com/LedgerHQ/ledgerjs/blob/master/docs/migrate_webusb.md", + "dev": true, + "peer": true, + "dependencies": { + "@ledgerhq/errors": "^5.26.0", + "@ledgerhq/hw-transport": "^5.26.0", + "@ledgerhq/logs": "^5.26.0", + "u2f-api": "0.2.7" + } + }, + "node_modules/@ledgerhq/logs": { + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-5.50.0.tgz", + "integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA==", + "dev": true, + "peer": true + }, "node_modules/@metamask/eth-sig-util": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", @@ -2034,6 +3075,17 @@ "integrity": "sha512-h1j0af7qZfc5Q0XGUW1EZYph3paBG8YmkyJEa3BJH64tmZ0yZ4qjWSOa2IMNfI7d0h2/+mCcUCTyTwfHfSZpFg==", "dev": true }, + "node_modules/@nomiclabs/hardhat-ethers": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz", + "integrity": "sha512-RHWYwnxryWR8hzRmU4Jm/q4gzvXpetUOJ4OPlwH2YARcDB+j79+yAYCwO0lN1SUOb4++oOTJEe6AWLEc42LIvg==", + "dev": true, + "peer": true, + "peerDependencies": { + "ethers": "^5.0.0", + "hardhat": "^2.0.0" + } + }, "node_modules/@nomiclabs/hardhat-etherscan": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.7.tgz", @@ -4480,6 +5532,62 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -4877,6 +5985,45 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true, + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/blakejs": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", @@ -6063,6 +7210,14 @@ "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/constant-case": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", @@ -6593,6 +7748,14 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -6646,6 +7809,20 @@ "node": ">=4" } }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/detect-port": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", @@ -9362,6 +10539,17 @@ "safe-buffer": "^5.1.1" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/expect": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", @@ -9833,6 +11021,14 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/fs-extra": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz", @@ -10981,6 +12177,79 @@ "decamelize": "^1.2.0" } }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/get-assigned-identifiers": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", @@ -11158,6 +12427,14 @@ "node": ">=4" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -12540,6 +13817,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -13011,6 +14296,16 @@ "node": ">= 0.10" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -14133,6 +15428,19 @@ "node": ">=4" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/loupe": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", @@ -14961,6 +16269,14 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/nats": { "version": "1.4.12", "resolved": "https://registry.npmjs.org/nats/-/nats-1.4.12.tgz", @@ -15053,6 +16369,28 @@ "lower-case": "^1.1.1" } }, + "node_modules/node-abi": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", + "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "semver": "^5.4.1" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/node-addon-api": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", @@ -15118,6 +16456,27 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-hid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-1.3.0.tgz", + "integrity": "sha512-BA6G4V84kiNd1uAChub/Z/5s/xS3EHBCxotQ0nyYrUG65mXewUDHE1tWOSqA2dp3N+mV0Ffq9wo2AW9t4p/G7g==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.14.0", + "node-abi": "^2.18.0", + "prebuild-install": "^5.3.4" + }, + "bin": { + "hid-showdevices": "src/show-devices.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/node-nats-streaming": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/node-nats-streaming/-/node-nats-streaming-0.2.6.tgz", @@ -15141,6 +16500,14 @@ "node": ">=12.19" } }, + "node_modules/noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha512-6kM8CLXvuW5crTxsAtva2YLrRrDaiTIkIePWs9moLHqbFWT94WpNFjwS/5dfLfECg5i/lkmw3aoqVidxt23TEQ==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -15192,6 +16559,20 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -15844,6 +17225,78 @@ "integrity": "sha512-mMMOwSKrmyl+Y12Ri2xhH1lbzQxwwpuru9VjyJpgFIH4asSj88F2csdMwN6+M5g1Ll4rmsYghHLQJw81tgZ7LQ==", "dev": true }, + "node_modules/prebuild-install": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", + "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prebuild-install/node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prebuild-install/node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prebuild-install/node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -16135,6 +17588,34 @@ "node": ">= 0.8" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -19241,6 +20722,38 @@ "node": ">=4.5" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tar/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -20039,6 +21552,13 @@ "node": ">=8" } }, + "node_modules/u2f-api": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/u2f-api/-/u2f-api-0.2.7.tgz", + "integrity": "sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg==", + "dev": true, + "peer": true + }, "node_modules/uglify-js": { "version": "3.16.1", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.1.tgz", @@ -20192,6 +21712,30 @@ "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", "dev": true }, + "node_modules/usb": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/usb/-/usb-1.9.2.tgz", + "integrity": "sha512-dryNz030LWBPAf6gj8vyq0Iev3vPbCLHCT8dBw3gQRXRzVNsIdeuU+VjPp3ksmSPkeMAl1k+kQ14Ij0QHyeiAg==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "node-addon-api": "^4.2.0", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/usb/node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/utf-8-validate": { "version": "5.0.9", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", @@ -21450,6 +22994,17 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, "node_modules/which-typed-array": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", @@ -22853,6 +24408,506 @@ "@ethersproject/transactions": "^5.6.2" } }, + "@ethersproject/hardware-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hardware-wallets/-/hardware-wallets-5.7.0.tgz", + "integrity": "sha512-DjMMXIisRc8xFvEoLoYz1w7JDOYmaz/a0X9sp7Zu668RR8U1zCAyj5ow25HLRW+TCzEC5XiFetTXqS5kXonFCQ==", + "dev": true, + "peer": true, + "requires": { + "@ledgerhq/hw-app-eth": "5.27.2", + "@ledgerhq/hw-transport": "5.26.0", + "@ledgerhq/hw-transport-node-hid": "5.26.0", + "@ledgerhq/hw-transport-u2f": "5.26.0", + "ethers": "^5.7.0" + }, + "dependencies": { + "@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "dev": true, + "peer": true + }, + "@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true, + "peer": true + }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true, + "peer": true + }, + "ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + } + } + }, "@ethersproject/hash": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.1.tgz", @@ -23175,6 +25230,206 @@ "chalk": "^4.0.0" } }, + "@ledgerhq/cryptoassets": { + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-5.53.0.tgz", + "integrity": "sha512-M3ibc3LRuHid5UtL7FI3IC6nMEppvly98QHFoSa7lJU0HDzQxY6zHec/SPM4uuJUC8sXoGVAiRJDkgny54damw==", + "dev": true, + "peer": true, + "requires": { + "invariant": "2" + } + }, + "@ledgerhq/devices": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-5.51.1.tgz", + "integrity": "sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA==", + "dev": true, + "peer": true, + "requires": { + "@ledgerhq/errors": "^5.50.0", + "@ledgerhq/logs": "^5.50.0", + "rxjs": "6", + "semver": "^7.3.5" + } + }, + "@ledgerhq/errors": { + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-5.50.0.tgz", + "integrity": "sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow==", + "dev": true, + "peer": true + }, + "@ledgerhq/hw-app-eth": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-5.27.2.tgz", + "integrity": "sha512-llNdrE894cCN8j6yxJEUniciyLVcLmu5N0UmIJLOObztG+5rOF4bX54h4SreTWK+E10Z0CzHSeyE5Lz/tVcqqQ==", + "dev": true, + "peer": true, + "requires": { + "@ledgerhq/cryptoassets": "^5.27.2", + "@ledgerhq/errors": "^5.26.0", + "@ledgerhq/hw-transport": "^5.26.0", + "bignumber.js": "^9.0.1", + "rlp": "^2.2.6" + } + }, + "@ledgerhq/hw-transport": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.26.0.tgz", + "integrity": "sha512-NFeJOJmyEfAX8uuIBTpocWHcz630sqPcXbu864Q+OCBm4EK5UOKV1h/pX7e0xgNIKY8zhJ/O4p4cIZp9tnXLHQ==", + "dev": true, + "peer": true, + "requires": { + "@ledgerhq/devices": "^5.26.0", + "@ledgerhq/errors": "^5.26.0", + "events": "^3.2.0" + } + }, + "@ledgerhq/hw-transport-node-hid": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.26.0.tgz", + "integrity": "sha512-qhaefZVZatJ6UuK8Wb6WSFNOLWc2mxcv/xgsfKi5HJCIr4bPF/ecIeN+7fRcEaycxj4XykY6Z4A7zDVulfFH4w==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@ledgerhq/devices": "^5.26.0", + "@ledgerhq/errors": "^5.26.0", + "@ledgerhq/hw-transport": "^5.26.0", + "@ledgerhq/hw-transport-node-hid-noevents": "^5.26.0", + "@ledgerhq/logs": "^5.26.0", + "lodash": "^4.17.20", + "node-hid": "1.3.0", + "usb": "^1.6.3" + } + }, + "@ledgerhq/hw-transport-node-hid-noevents": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.51.1.tgz", + "integrity": "sha512-9wFf1L8ZQplF7XOY2sQGEeOhpmBRzrn+4X43kghZ7FBDoltrcK+s/D7S+7ffg3j2OySyP6vIIIgloXylao5Scg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@ledgerhq/devices": "^5.51.1", + "@ledgerhq/errors": "^5.50.0", + "@ledgerhq/hw-transport": "^5.51.1", + "@ledgerhq/logs": "^5.50.0", + "node-hid": "2.1.1" + }, + "dependencies": { + "@ledgerhq/hw-transport": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz", + "integrity": "sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@ledgerhq/devices": "^5.51.1", + "@ledgerhq/errors": "^5.50.0", + "events": "^3.3.0" + } + }, + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "mimic-response": "^2.0.0" + } + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "optional": true, + "peer": true + }, + "node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true, + "optional": true, + "peer": true + }, + "node-hid": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.1.tgz", + "integrity": "sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "bindings": "^1.5.0", + "node-addon-api": "^3.0.2", + "prebuild-install": "^6.0.0" + } + }, + "prebuild-install": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.21.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, + "simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + } + } + }, + "@ledgerhq/hw-transport-u2f": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-5.26.0.tgz", + "integrity": "sha512-QTxP1Rsh+WZ184LUOelYVLeaQl3++V3I2jFik+l9JZtakwEHjD0XqOT750xpYNL/vfHsy31Wlz+oicdxGzFk+w==", + "dev": true, + "peer": true, + "requires": { + "@ledgerhq/errors": "^5.26.0", + "@ledgerhq/hw-transport": "^5.26.0", + "@ledgerhq/logs": "^5.26.0", + "u2f-api": "0.2.7" + } + }, + "@ledgerhq/logs": { + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-5.50.0.tgz", + "integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA==", + "dev": true, + "peer": true + }, "@metamask/eth-sig-util": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", @@ -23258,6 +25513,14 @@ "integrity": "sha512-h1j0af7qZfc5Q0XGUW1EZYph3paBG8YmkyJEa3BJH64tmZ0yZ4qjWSOa2IMNfI7d0h2/+mCcUCTyTwfHfSZpFg==", "dev": true }, + "@nomiclabs/hardhat-ethers": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz", + "integrity": "sha512-RHWYwnxryWR8hzRmU4Jm/q4gzvXpetUOJ4OPlwH2YARcDB+j79+yAYCwO0lN1SUOb4++oOTJEe6AWLEc42LIvg==", + "dev": true, + "peer": true, + "requires": {} + }, "@nomiclabs/hardhat-etherscan": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.7.tgz", @@ -25278,6 +27541,64 @@ "picomatch": "^2.0.4" } }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true, + "optional": true, + "peer": true + }, + "are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true, + "peer": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -25592,6 +27913,33 @@ "safe-buffer": "^5.0.1" } }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + } + } + }, "blakejs": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", @@ -26594,6 +28942,14 @@ "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "optional": true, + "peer": true + }, "constant-case": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", @@ -27014,6 +29370,14 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true, + "optional": true, + "peer": true + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -27054,6 +29418,14 @@ "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", "dev": true }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true, + "peer": true + }, "detect-port": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", @@ -29102,6 +31474,14 @@ "safe-buffer": "^5.1.1" } }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "optional": true, + "peer": true + }, "expect": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", @@ -29485,6 +31865,14 @@ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "optional": true, + "peer": true + }, "fs-extra": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz", @@ -30338,6 +32726,69 @@ } } }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "optional": true, + "peer": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "get-assigned-identifiers": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", @@ -30475,6 +32926,14 @@ } } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "optional": true, + "peer": true + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -31517,6 +33976,14 @@ "has-symbols": "^1.0.2" } }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "optional": true, + "peer": true + }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -31904,6 +34371,16 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -32768,6 +35245,16 @@ } } }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "peer": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "loupe": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", @@ -33435,6 +35922,14 @@ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true, + "optional": true, + "peer": true + }, "nats": { "version": "1.4.12", "resolved": "https://registry.npmjs.org/nats/-/nats-1.4.12.tgz", @@ -33517,6 +36012,27 @@ "lower-case": "^1.1.1" } }, + "node-abi": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", + "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true, + "peer": true + } + } + }, "node-addon-api": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", @@ -33565,6 +36081,20 @@ "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", "dev": true }, + "node-hid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-1.3.0.tgz", + "integrity": "sha512-BA6G4V84kiNd1uAChub/Z/5s/xS3EHBCxotQ0nyYrUG65mXewUDHE1tWOSqA2dp3N+mV0Ffq9wo2AW9t4p/G7g==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.14.0", + "node-abi": "^2.18.0", + "prebuild-install": "^5.3.4" + } + }, "node-nats-streaming": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/node-nats-streaming/-/node-nats-streaming-0.2.6.tgz", @@ -33582,6 +36112,14 @@ "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", "dev": true }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha512-6kM8CLXvuW5crTxsAtva2YLrRrDaiTIkIePWs9moLHqbFWT94WpNFjwS/5dfLfECg5i/lkmw3aoqVidxt23TEQ==", + "dev": true, + "optional": true, + "peer": true + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -33623,6 +36161,20 @@ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -34131,6 +36683,65 @@ "integrity": "sha512-mMMOwSKrmyl+Y12Ri2xhH1lbzQxwwpuru9VjyJpgFIH4asSj88F2csdMwN6+M5g1Ll4rmsYghHLQJw81tgZ7LQ==", "dev": true }, + "prebuild-install": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", + "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "mimic-response": "^2.0.0" + } + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "optional": true, + "peer": true + }, + "simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + } + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -34355,6 +36966,30 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "optional": true, + "peer": true + } + } + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -36866,6 +39501,35 @@ } } }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, "test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", @@ -37503,6 +40167,13 @@ "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true }, + "u2f-api": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/u2f-api/-/u2f-api-0.2.7.tgz", + "integrity": "sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg==", + "dev": true, + "peer": true + }, "uglify-js": { "version": "3.16.1", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.1.tgz", @@ -37628,6 +40299,28 @@ "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", "dev": true }, + "usb": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/usb/-/usb-1.9.2.tgz", + "integrity": "sha512-dryNz030LWBPAf6gj8vyq0Iev3vPbCLHCT8dBw3gQRXRzVNsIdeuU+VjPp3ksmSPkeMAl1k+kQ14Ij0QHyeiAg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "node-addon-api": "^4.2.0", + "node-gyp-build": "^4.3.0" + }, + "dependencies": { + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true, + "optional": true, + "peer": true + } + } + }, "utf-8-validate": { "version": "5.0.9", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", @@ -38725,6 +41418,14 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, + "which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "dev": true, + "optional": true, + "peer": true + }, "which-typed-array": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", diff --git a/package.json b/package.json index 871d2e9f..a06ba314 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@etherspot/contracts", - "version": "1.9.3", + "version": "1.9.4", "description": "Etherspot Solidity contracts", "keywords": [ "ether", @@ -52,6 +52,8 @@ "deploy:celoTest": "hardhat deploy --network celoTest --tags create,setup", "deploy:fuse": "hardhat deploy --network fuse --tags create,setup", "deploy:fuseSparknet": "hardhat deploy --network fuseSparknet --tags create,setup", + "deploy:neon": "hardhat deploy --network neon --tags create,setup", + "deploy:neonDevnet": "hardhat deploy --network neonDevnet --tags create,setup", "deploy:arbitrumNova": "hardhat deploy --network arbitrumNova --tags create,setup", "deploy:arbitrumNitro": "hardhat deploy --network arbitrumNitro --tags create,setup", "deploy:etherspot": "hardhat deploy --network etherspot --tags create,setup",