From 84aca41fd4b86fa3a531c2a3606f3ce038bd07a9 Mon Sep 17 00:00:00 2001 From: SocksNFlops <91764028+SocksNFlops@users.noreply.github.com> Date: Wed, 27 May 2026 15:51:28 -0400 Subject: [PATCH 1/2] feat(briefcase): add deployers for permissioned-pool contracts --- .gitmodules | 3 + foundry.toml | 15 +- remappings.txt | 6 + script/MineWETHHookSalt.s.sol | 2 +- script/deploy/Deploy-all.s.sol | 59 ++++- script/deploy/tasks/task_template.json | 69 +++++- .../UniversalRouterDeployer.sol | 12 +- .../v2-core/UniswapV2FactoryDeployer.sol | 2 +- .../PermissionedHooksDeployer.sol | 32 +++ .../PermissionedPositionManagerDeployer.sol | 35 +++ .../PermissionsAdapterFactoryDeployer.sol | 26 +++ .../contracts/utils/introspection/IERC165.sol | 25 +++ .../solmate/src/utils/Bytes32AddressLib.sol | 14 ++ .../solmate/src/utils/CREATE3.sol | 82 +++++++ .../uniswapx/v4/base/ReactorStructs.sol | 10 +- .../v4/interfaces/IAuctionResolver.sol | 4 +- .../uniswapx/v4/interfaces/IHook.sol | 6 +- .../uniswapx/v4/interfaces/IReactor.sol | 2 +- .../interfaces/ISwapProxy.sol | 24 ++ .../universal-router/libraries/Commands.sol | 2 +- .../universal-router/libraries/Constants.sol | 3 + .../modules/uniswap/v3/BytesLib.sol | 19 +- .../types/RouterParameters.sol | 1 + .../FluidDexLite/interfaces/IFluidDexLite.sol | 113 ++++++++++ .../interfaces/IFluidDexLiteCallback.sol | 13 ++ .../interfaces/IFluidDexLiteResolver.sol | 49 +++++ .../FluidDexT1/interfaces/IDexCallback.sol | 11 + .../interfaces/IFluidDexReservesResolver.sol | 38 ++++ .../interfaces/IFluidDexResolver.sol | 34 +++ .../FluidDexT1/interfaces/IFluidDexT1.sol | 68 ++++++ .../interfaces/IPancakeSwapV3Callback.sol | 12 + .../Slipstream/interfaces/IQuoterV2.sol | 32 +++ .../interfaces/ISlipstreamFactory.sol | 13 ++ .../StableSwap/interfaces/ICurveFactory.sol | 107 +++++++++ .../StableSwap/interfaces/IMetaRegistry.sol | 20 ++ .../StableSwap/interfaces/IStableSwap.sol | 32 +++ .../interfaces/ICurveStableSwapFactoryNG.sol | 88 ++++++++ .../interfaces/ICurveStableSwapNG.sol | 45 ++++ .../TempoExchange/interfaces/ITIP20.sol | 20 ++ .../interfaces/ITempoExchange.sol | 48 ++++ .../interfaces/IUniswapV2Factory.sol | 7 + .../UniswapV2/interfaces/IUniswapV2Pair.sol | 12 + .../interfaces/IUniswapV3Factory.sol | 13 ++ .../UniswapV3/interfaces/IUniswapV3Pool.sol | 38 ++++ .../interfaces/IUniswapV3SwapCallback.sol | 12 + .../interfaces/IAggregatorHook.sol | 33 +++ .../utils/AggregatorHookMiner.sol | 71 ++++++ .../interfaces}/IWstETH.sol | 0 .../utils/HookMiner.sol | 0 .../utils/HookMinerCreate3.sol | 82 +++++++ .../v4-periphery/base/ImmutableState.sol | 25 --- .../interfaces/IAllowlistChecker.sol | 13 ++ .../interfaces/IPermissionsAdapter.sol | 87 ++++++++ .../interfaces/IPermissionsAdapterFactory.sol | 52 +++++ .../libraries/PermissionFlags.sol | 27 +++ .../interfaces/IPositionManager.sol | 7 + .../v4-periphery/interfaces/IV4Router.sol | 22 +- .../v4-periphery/libraries/Actions.sol | 17 ++ .../libraries/CalldataDecoder.sol | 20 +- .../protocols/v4-periphery/utils/BaseHook.sol | 206 ------------------ src/pkgs/v4-hooks-public | 1 + 61 files changed, 1665 insertions(+), 276 deletions(-) create mode 100644 src/briefcase/deployers/v4-hooks-public/PermissionedHooksDeployer.sol create mode 100644 src/briefcase/deployers/v4-periphery/PermissionedPositionManagerDeployer.sol create mode 100644 src/briefcase/deployers/v4-periphery/PermissionsAdapterFactoryDeployer.sol create mode 100644 src/briefcase/protocols/lib-external/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol create mode 100644 src/briefcase/protocols/lib-external/solmate/src/utils/Bytes32AddressLib.sol create mode 100644 src/briefcase/protocols/lib-external/solmate/src/utils/CREATE3.sol create mode 100644 src/briefcase/protocols/universal-router/interfaces/ISwapProxy.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLite.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLiteCallback.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLiteResolver.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IDexCallback.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexReservesResolver.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexResolver.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexT1.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/PancakeSwapV3/interfaces/IPancakeSwapV3Callback.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/Slipstream/interfaces/IQuoterV2.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/Slipstream/interfaces/ISlipstreamFactory.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/ICurveFactory.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/IMetaRegistry.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/IStableSwap.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwapNG/interfaces/ICurveStableSwapFactoryNG.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwapNG/interfaces/ICurveStableSwapNG.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/TempoExchange/interfaces/ITIP20.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/TempoExchange/interfaces/ITempoExchange.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV2/interfaces/IUniswapV2Factory.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV2/interfaces/IUniswapV2Pair.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3Factory.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3Pool.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3SwapCallback.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/interfaces/IAggregatorHook.sol create mode 100644 src/briefcase/protocols/v4-hooks-public/aggregator-hooks/utils/AggregatorHookMiner.sol rename src/briefcase/protocols/{v4-periphery/interfaces/external => v4-hooks-public/interfaces}/IWstETH.sol (100%) rename src/briefcase/protocols/{v4-periphery => v4-hooks-public}/utils/HookMiner.sol (100%) create mode 100644 src/briefcase/protocols/v4-hooks-public/utils/HookMinerCreate3.sol delete mode 100644 src/briefcase/protocols/v4-periphery/base/ImmutableState.sol create mode 100644 src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IAllowlistChecker.sol create mode 100644 src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IPermissionsAdapter.sol create mode 100644 src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IPermissionsAdapterFactory.sol create mode 100644 src/briefcase/protocols/v4-periphery/hooks/permissionedPools/libraries/PermissionFlags.sol delete mode 100644 src/briefcase/protocols/v4-periphery/utils/BaseHook.sol create mode 160000 src/pkgs/v4-hooks-public diff --git a/.gitmodules b/.gitmodules index 2e1c76fa..7bc547ea 100644 --- a/.gitmodules +++ b/.gitmodules @@ -61,3 +61,6 @@ [submodule "src/pkgs/universal-router-2_0"] path = src/pkgs/universal-router-2_0 url = https://github.com/Uniswap/universal-router +[submodule "src/pkgs/v4-hooks-public"] + path = src/pkgs/v4-hooks-public + url = https://github.com/Uniswap/v4-hooks-public diff --git a/foundry.toml b/foundry.toml index 8f8bbe7d..a244afdf 100644 --- a/foundry.toml +++ b/foundry.toml @@ -23,14 +23,16 @@ skip = [ "src/pkgs/universal-router/solmate/**", "src/pkgs/universal-router-2_0/permit2/**", "src/pkgs/universal-router-2_0/solmate/**", + "src/pkgs/v4-hooks-public/src/aggregator-hooks/**", "src/pkgs/**/*.s.sol", "*.t.sol", ] additional_compiler_profiles = [ { name = "v4", optimizer_runs = 44444444, via_ir = true, evm_version = "cancun" }, - { name = "v4-posm", optimizer_runs = 30000, via_ir = true, evm_version = "cancun" }, + { name = "v4-posm", optimizer_runs = 500, via_ir = true, evm_version = "cancun" }, { name = "v4-descriptor", optimizer_runs = 1, via_ir = true, evm_version = "cancun" }, + { name = "v4-hooks-public", optimizer_runs = 44444444, via_ir = false, evm_version = "cancun" }, { name = "v2", optimizer_runs = 999999 }, { name = "v3-core", optimizer_runs = 800, evm_version = "istanbul", via_ir = false }, { name = "v3-periphery-lowest", optimizer_runs = 1000, evm_version = "istanbul", via_ir = false }, @@ -41,7 +43,7 @@ additional_compiler_profiles = [ { name = "calibur", optimizer_runs = 10000, via_ir = true }, { name = "util-contracts", optimizer_runs = 200, via_ir = false, evm_version = "paris" }, { name = "mixed-quoter", optimizer_runs = 200, via_ir = true, evm_version = "cancun" }, - { name = "universal-router", optimizer_runs = 4444, via_ir = true, evm_version = "cancun" }, + { name = "universal-router", optimizer_runs = 1, via_ir = true, evm_version = "cancun" }, { name = "unsupported-protocol", optimizer_runs = 200, via_ir = false, evm_version = "cancun" }, ] @@ -71,11 +73,14 @@ compilation_restrictions = [ # v4 { paths = "src/pkgs/v4-core/src/PoolManager.sol", optimizer_runs = 44444444 }, { paths = "src/pkgs/v4-periphery/src/PositionDescriptor.sol", version = "=0.8.26", optimizer_runs = 1 }, - { paths = "src/pkgs/v4-periphery/src/PositionManager.sol", version = "=0.8.26", optimizer_runs = 30000 }, + { paths = "src/pkgs/v4-periphery/src/PositionManager.sol", version = "=0.8.26", optimizer_runs = 500 }, + { paths = "src/pkgs/v4-periphery/src/hooks/permissionedPools/PermissionedPositionManager.sol", version = "=0.8.26", optimizer_runs = 500 }, + { paths = "src/pkgs/v4-periphery/src/hooks/permissionedPools/PermissionsAdapterFactory.sol", version = "=0.8.26", optimizer_runs = 44444444, via_ir = true, evm_version = "cancun" }, { paths = "src/pkgs/v4-periphery/src/lens/**", version = "=0.8.26", optimizer_runs = 44444444 }, - { paths = "src/pkgs/v4-periphery/src/hooks/**", version = "=0.8.26", optimizer_runs = 44444444 }, + # v4-hooks-public (only permissioned-pools is in scope; aggregator-hooks are 0.8.29 and out of scope) + { paths = "src/pkgs/v4-hooks-public/src/permissioned-pools/**", version = "=0.8.26", optimizer_runs = 44444444, via_ir = false, evm_version = "cancun" }, # router - { paths = "src/pkgs/universal-router/contracts/UniversalRouter.sol", optimizer_runs = 4444 }, + { paths = "src/pkgs/universal-router/contracts/UniversalRouter.sol", optimizer_runs = 1 }, { paths = "src/pkgs/universal-router-2_0/contracts/UniversalRouter.sol", version = "=0.8.26", optimizer_runs = 44444444 }, { paths = "src/pkgs/swap-router-contracts/contracts/**", version = "=0.7.6", via_ir = false, optimizer_runs = 1000000 }, { paths = "src/pkgs/universal-router/contracts/deploy/UnsupportedProtocol.sol", version = "=0.8.30", optimizer_runs = 200, via_ir = false, evm_version = "cancun" }, diff --git a/remappings.txt b/remappings.txt index 931e8a96..cca3ff4d 100644 --- a/remappings.txt +++ b/remappings.txt @@ -6,6 +6,12 @@ src/pkgs/v4-periphery:solmate/src=src/pkgs/v4-periphery/lib/v4-core/lib/solmate/ src/pkgs/v4-periphery:@uniswap/v4-core=src/pkgs/v4-periphery/lib/v4-core src/pkgs/v4-periphery/src:openzeppelin-contracts=src/pkgs/v4-periphery/lib/v4-core/lib/openzeppelin-contracts src/pkgs/v4-periphery/src:@openzeppelin=src/pkgs/v4-periphery/lib/v4-core/lib/openzeppelin-contracts +src/pkgs/v4-hooks-public:solmate/src=src/pkgs/v4-hooks-public/lib/v4-periphery/lib/v4-core/lib/solmate/src +src/pkgs/v4-hooks-public:@uniswap/v4-core=src/pkgs/v4-hooks-public/lib/v4-periphery/lib/v4-core +src/pkgs/v4-hooks-public:@uniswap/v4-periphery=src/pkgs/v4-hooks-public/lib/v4-periphery +src/pkgs/v4-hooks-public/src:openzeppelin-contracts=src/pkgs/v4-hooks-public/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts +src/pkgs/v4-hooks-public/src:@openzeppelin=src/pkgs/v4-hooks-public/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts +src/pkgs/v4-hooks-public/lib/v4-periphery:@openzeppelin=src/pkgs/v4-hooks-public/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts src/pkgs/permit2:solmate=src/pkgs/permit2/lib/solmate src/pkgs/universal-router/lib/v3-periphery:@openzeppelin=lib/oz-v4.7.0 src/pkgs/universal-router/lib/v4-periphery:@openzeppelin=src/pkgs/universal-router/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts diff --git a/script/MineWETHHookSalt.s.sol b/script/MineWETHHookSalt.s.sol index 4915c697..e50aba56 100644 --- a/script/MineWETHHookSalt.s.sol +++ b/script/MineWETHHookSalt.s.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import {WETHHookDeployer} from '../src/briefcase/deployers/v4-periphery/WETHHookDeployer.sol'; import {Hooks} from '../src/briefcase/protocols/v4-core/libraries/Hooks.sol'; -import {HookMiner} from '../src/briefcase/protocols/v4-periphery/utils/HookMiner.sol'; +import {HookMiner} from '../src/briefcase/protocols/v4-hooks-public/utils/HookMiner.sol'; import {Script} from 'forge-std/Script.sol'; import {stdJson} from 'forge-std/StdJson.sol'; import {console} from 'forge-std/console.sol'; diff --git a/script/deploy/Deploy-all.s.sol b/script/deploy/Deploy-all.s.sol index 26f1bbcf..4601462d 100644 --- a/script/deploy/Deploy-all.s.sol +++ b/script/deploy/Deploy-all.s.sol @@ -42,6 +42,13 @@ import { import {PoolManagerDeployer} from '../../src/briefcase/deployers/v4-core/PoolManagerDeployer.sol'; +import {PermissionedHooksDeployer} from '../../src/briefcase/deployers/v4-hooks-public/PermissionedHooksDeployer.sol'; +import { + PermissionedPositionManagerDeployer +} from '../../src/briefcase/deployers/v4-periphery/PermissionedPositionManagerDeployer.sol'; +import { + PermissionsAdapterFactoryDeployer +} from '../../src/briefcase/deployers/v4-periphery/PermissionsAdapterFactoryDeployer.sol'; import {PositionDescriptorDeployer} from '../../src/briefcase/deployers/v4-periphery/PositionDescriptorDeployer.sol'; import {PositionManagerDeployer} from '../../src/briefcase/deployers/v4-periphery/PositionManagerDeployer.sol'; @@ -70,6 +77,8 @@ contract Deploy is Script { address nonfungiblePositionManager; address poolManager; address positionManager; + address permissionsAdapterFactory; + address permissionedPositionManager; address universalRouter; address universalRouter2_0; address calibur; @@ -250,6 +259,10 @@ contract Deploy is Script { bool deployPositionManager = config.readBoolOr('.protocols.v4.contracts.PositionManager.deploy', false); bool deployV4Quoter = config.readBoolOr('.protocols.v4.contracts.V4Quoter.deploy', false); bool deployStateView = config.readBoolOr('.protocols.v4.contracts.StateView.deploy', false); + bool deployPermissionsAdapterFactory = + config.readBoolOr('.protocols.v4.contracts.PermissionsAdapterFactory.deploy', false); + bool deployPermissionedPositionManager = + config.readBoolOr('.protocols.v4.contracts.PermissionedPositionManager.deploy', false); address positionDescriptor; @@ -312,6 +325,36 @@ contract Deploy is Script { console.log('deploying State View'); StateViewDeployer.deploy(poolManager); } + + if (deployPermissionsAdapterFactory) { + if (!deployPoolManager) { + poolManager = config.readAddress('.protocols.v4.contracts.PoolManager.address'); + } + console.log('deploying Permissions Adapter Factory'); + permissionsAdapterFactory = PermissionsAdapterFactoryDeployer.deploy(poolManager); + } + + if (deployPermissionedPositionManager) { + if (!deployPoolManager) { + poolManager = config.readAddress('.protocols.v4.contracts.PoolManager.address'); + } + if (permit2 == address(0)) { + permit2 = config.readAddress('.protocols.permit2.contracts.Permit2.address'); + } + uint256 unsubscribeGasLimit = + config.readUint('.protocols.v4.contracts.PermissionedPositionManager.params.unsubscribeGasLimit.value'); + if (!deployPositionDescriptor) { + positionDescriptor = config.readAddress('.protocols.v4.contracts.PositionDescriptor.address'); + } + if (!deployPermissionsAdapterFactory) { + permissionsAdapterFactory = + config.readAddress('.protocols.v4.contracts.PermissionsAdapterFactory.address'); + } + console.log('deploying Permissioned Position Manager'); + permissionedPositionManager = PermissionedPositionManagerDeployer.deploy( + poolManager, permit2, unsubscribeGasLimit, positionDescriptor, weth(), permissionsAdapterFactory + ); + } } function deployV4Hooks() private { @@ -319,6 +362,7 @@ contract Deploy is Script { bool deployWETHHook = config.readBoolOr('.protocols.hooks.contracts.WETHHook.deploy', false); bool deployWstETHHook = config.readBoolOr('.protocols.hooks.contracts.WstETHHook.deploy', false); bool deployWstETHRoutingHook = config.readBoolOr('.protocols.hooks.contracts.WstETHRoutingHook.deploy', false); + bool deployPermissionedHooks = config.readBoolOr('.protocols.hooks.contracts.PermissionedHooks.deploy', false); if (poolManager == address(0)) { poolManager = config.readAddress('.protocols.v4.contracts.PoolManager.address'); @@ -338,6 +382,15 @@ contract Deploy is Script { address wsteth = config.readAddress('.protocols.hooks.contracts.WstETHRoutingHook.params.wstETH.value'); WstETHRoutingHookDeployer.deploy(poolManager, wsteth, salt); } + if (deployPermissionedHooks) { + bytes32 salt = config.readBytes32('.protocols.hooks.contracts.PermissionedHooks.params.salt.value'); + if (permissionsAdapterFactory == address(0)) { + permissionsAdapterFactory = + config.readAddress('.protocols.v4.contracts.PermissionsAdapterFactory.address'); + } + console.log('deploying Permissioned Hooks'); + PermissionedHooksDeployer.deploy(poolManager, permissionsAdapterFactory, salt); + } } function deployPermit2() private { @@ -481,6 +534,9 @@ contract Deploy is Script { } address acrossSpokePool = config.readAddress('.protocols.universal-router.contracts.UniversalRouter.params.acrossSpokePool.value'); + address permissionsAdapterFactory = config.readAddress( + '.protocols.universal-router.contracts.UniversalRouter.params.permissionsAdapterFactory.value' + ); console.log('deploying Universal Router'); universalRouter = address( UniversalRouterDeployer.deploy( @@ -493,7 +549,8 @@ contract Deploy is Script { poolManager, nonfungiblePositionManager, positionManager, - acrossSpokePool + acrossSpokePool, + permissionsAdapterFactory ) ); } diff --git a/script/deploy/tasks/task_template.json b/script/deploy/tasks/task_template.json index 0b12009b..d8002b85 100644 --- a/script/deploy/tasks/task_template.json +++ b/script/deploy/tasks/task_template.json @@ -221,6 +221,49 @@ }, "dependencies": ["weth"] }, + "PermissionsAdapterFactory": { + "deploy": false, + "address": null, + "lookup": { + "latest": "PermissionsAdapterFactory" + }, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + } + } + }, + "PermissionedPositionManager": { + "deploy": false, + "address": null, + "lookup": { + "latest": "PermissionedPositionManager" + }, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "permit2": { + "name": "Permit 2 address", + "pointer": "protocols.permit2.contracts.Permit2" + }, + "unsubscribeGasLimit": { + "name": "Unsubscribe gas limit", + "type": "uint256" + }, + "positionDescriptor": { + "name": "Position Descriptor address", + "pointer": "protocols.v4.contracts.PositionDescriptor" + }, + "permissionsAdapterFactory": { + "name": "Permissions Adapter Factory", + "pointer": "protocols.v4.contracts.PermissionsAdapterFactory" + } + }, + "dependencies": ["weth"] + }, "V4Quoter": { "deploy": false, "address": null, @@ -291,6 +334,26 @@ "type": "bytes32" } } + }, + "PermissionedHooks": { + "deploy": false, + "address": null, + "lookup": { + "latest": "PermissionedHooks" + }, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "permissionsAdapterFactory": { + "name": "Permissions Adapter Factory", + "pointer": "protocols.v4.contracts.PermissionsAdapterFactory" + }, + "salt": { + "type": "bytes32" + } + } } } }, @@ -359,7 +422,7 @@ }, "universal-router": { "name": "Universal Router (Latest)", - "tag": "v2.1", + "tag": "v2.2", "deploy": false, "contracts": { "UniversalRouter": { @@ -408,6 +471,10 @@ "acrossSpokePool": { "name": "Across Spoke Pool address", "type": "address" + }, + "permissionsAdapterFactory": { + "name": "Permissions Adapter Factory", + "pointer": "protocols.v4.contracts.PermissionsAdapterFactory" } }, "dependencies": ["weth"], diff --git a/src/briefcase/deployers/universal-router/UniversalRouterDeployer.sol b/src/briefcase/deployers/universal-router/UniversalRouterDeployer.sol index 1b90f31d..45c1fd17 100644 --- a/src/briefcase/deployers/universal-router/UniversalRouterDeployer.sol +++ b/src/briefcase/deployers/universal-router/UniversalRouterDeployer.sol @@ -6,6 +6,10 @@ import {RouterParameters} from '../../protocols/universal-router/types/RouterPar import {DeployerHelper} from '../DeployerHelper.sol'; library UniversalRouterDeployer { + /// @dev v4PositionManager must be a base PositionManager, not a PermissionedPositionManager. + /// The UR's internal v4-posm call filter is a denylist that does not understand + /// permissioned-pool action selectors, so routing them through a perm posm bypasses + /// the documented mint-only boundary. function deploy( address permit2, address weth9, @@ -16,7 +20,8 @@ library UniversalRouterDeployer { address v4PoolManager, address v3NFTPositionManager, address v4PositionManager, - address acrossSpokePool + address acrossSpokePool, + address permissionsAdapterFactory ) internal returns (IUniversalRouter router) { RouterParameters memory params = RouterParameters({ permit2: permit2, @@ -26,6 +31,7 @@ library UniversalRouterDeployer { pairInitCodeHash: v2PairInitCodeHash, poolInitCodeHash: v3PoolInitCodeHash, v4PoolManager: v4PoolManager, + permissionsAdapterFactory: permissionsAdapterFactory, v3NFTPositionManager: v3NFTPositionManager, v4PositionManager: v4PositionManager, spokePool: acrossSpokePool @@ -40,11 +46,11 @@ library UniversalRouterDeployer { * @notice This initcode is generated from the following contract: * - Source Contract: src/pkgs/universal-router/contracts/UniversalRouter.sol * - solc: 0.8.26 - * - optimizer_runs: 4444 + * - optimizer_runs: 1 * - via_ir: true * - evm_version: cancun */ function initcode() internal pure returns (bytes memory) { - return hex'6102a080604052346104145761014081615c2380380380916100218285610433565b833981010312610414576040519061014082016001600160401b038111838210176104005760405261005281610456565b825261006060208201610456565b6020830190815261007360408301610456565b906040840191825261008760608401610456565b91606085019283526080840151946080810195865260a08501519360a082019485526100b560c08701610456565b9660c083019788526100c960e08801610456565b958660e08501526100f16101206100e36101008b01610456565b998a61010088015201610456565b98896101208601526040519761010689610418565b6001600160a01b03908116895298891660208901908152905194519651604051919991979082169695821695911661013d88610418565b8752602087019586525192519151905160405190936001600160a01b039384169316608082016001600160401b0381118382101761040057604052815260208101928352604081019182526060810193845260405161019d604082610433565b600f815260208101906e2ab734bb32b939b0b62937baba32b960891b8252604051916101ca604084610433565b600183526020830191601960f91b83526101e38161046a565b610120526101f084610600565b61014052519020918260e05251902080610100524660a0526040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a0815261025960c082610433565b5190206080523060c052516001600160a01b0390811661016052905161018052905181166101a05290516101c0526101e091909152905181166102005290518116610220529051811661024052905181166102605216610280526040516154ea9081610739823960805181614008015260a051816140c5015260c05181613fd9015260e051816140570152610100518161407d0152610120518161061d0152610140518161064601526101605181818161191f01528181611b020152613d230152610180518181816118fe01528181611b240152613d0201526101a0518161333f01526101c0518161339201526101e0518181816086015281816103a20152818161051d015281816124670152818161298201528181614c7101528181614ce801528181614dba01528181614f2e01526152c6015261020051818181602401528181611ec8015261202b0152610220518181816115d70152818161221901526137000152610240518181816107380152818161258e015261267a01526102605181818161042a0152612a5001526102805181818161077b01528181612da20152612ef40152f35b634e487b7160e01b5f52604160045260245ffd5b5f80fd5b604081019081106001600160401b0382111761040057604052565b601f909101601f19168101906001600160401b0382119082101761040057604052565b51906001600160a01b038216820361041457565b908151602081105f146104e4575090601f8151116104a4576020815191015160208210610495571790565b5f198260200360031b1b161790565b604460209160405192839163305a27a960e01b83528160048401528051918291826024860152018484015e5f828201840152601f01601f19168101030190fd5b6001600160401b038111610400575f54600181811c911680156105f6575b60208210146105e257601f81116105b0575b50602092601f821160011461055157928192935f92610546575b50508160011b915f199060031b1c1916175f5560ff90565b015190505f8061052e565b601f198216935f8052805f20915f5b8681106105985750836001959610610580575b505050811b015f5560ff90565b01515f1960f88460031b161c191690555f8080610573565b91926020600181928685015181550194019201610560565b5f8052601f60205f20910160051c810190601f830160051c015b8181106105d75750610514565b5f81556001016105ca565b634e487b7160e01b5f52602260045260245ffd5b90607f1690610502565b908151602081105f1461062b575090601f8151116104a4576020815191015160208210610495571790565b6001600160401b03811161040057600154600181811c9116801561072e575b60208210146105e257601f81116106fb575b50602092601f821160011461069a57928192935f9261068f575b50508160011b915f199060031b1c19161760015560ff90565b015190505f80610676565b601f1982169360015f52805f20915f5b8681106106e357508360019596106106cb575b505050811b0160015560ff90565b01515f1960f88460031b161c191690555f80806106bd565b919260206001819286850151815501940192016106aa565b60015f52601f60205f20910160051c810190601f830160051c015b818110610723575061065c565b5f8155600101610716565b90607f169061064a56fe60c08060405260043610156100ae575b50361561001a575f80fd5b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163314158061007b575b61005357005b7f38bbd576000000000000000000000000000000000000000000000000000000005f5260045ffd5b506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633141561004d565b5f3560e01c9081631a27b20114610df85750806324856bc314610d495780633593564c14610c6357806344684dc31461079f5780638021fef71461075c578063817122dc1461071957806384b0196e1461060557806391dd7346146104e2578063d04d79a21461044e578063d0c9f6cb1461040b578063d737d0c7146103c6578063dc4c90d3146103835763fa461e3314610149575f61000f565b3461027d57606060031936011261027d5760243560043560443567ffffffffffffffff811161027d57610180903690600401610e54565b5f831391821580610379575b6103515781810160408282031261027d5781359067ffffffffffffffff821161027d576101ba918301613160565b506020810135916001600160a01b03831680930361027d576101db91613278565b90601790602b8310610329578035968760601c9561020962ffffff8585013560601c9a60481c168a896132cb565b6001600160a01b033391160361030157156102f757508685105b1561023957505050610237935033916133df565b005b91935091939482602b0180602b116102e3578410610281575082821161027d578101910390600160ff1b84101561027d5761023793610278339161317e565b61344a565b5f80fd5b925050507faf28d9864a81dfdf71cab65f4e5d79a0cf9b083905fb8971425e6cb581b3f6929291925c82116102bb576102379233916133df565b7f739dbe52000000000000000000000000000000000000000000000000000000005f5260045ffd5b634e487b7160e01b5f52601160045260245ffd5b9550848710610223565b7f32b13d91000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f3b99b53d000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f316cf0eb000000000000000000000000000000000000000000000000000000005f5260045ffd5b505f85131561018c565b3461027d575f60031936011261027d5760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461027d575f60031936011261027d5760207f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c6001600160a01b0360405191168152f35b3461027d575f60031936011261027d5760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461027d575f60031936011261027d5760607fd317c76a4357223a1868125ee857a1f31cabfcec288f6cdd0ea8c52b6a71ee315c7fa42de8dec63499ed8713dc6815ea14006a1f8e80e1664c66e3beb461bb65b0da5c7f17350132762f24cc4b86e10621ea1e0b5c33483a51cca86a1b11e7ed029b6eb65c906001600160a01b036040519316835260208301526040820152f35b3461027d57602060031936011261027d5760043567ffffffffffffffff811161027d57610513903690600401610e54565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633036105dd5761054c916139c0565b908183036105b5575f5b8381106105895761058560405161056e6020826130d3565b5f8152604051918291602083526020830190610eb3565b0390f35b806105af61059a6001938789610ed8565b3560f81c6105a9838787610f17565b916141e4565b01610556565b7faaad13f7000000000000000000000000000000000000000000000000000000005f5260045ffd5b7fae18210a000000000000000000000000000000000000000000000000000000005f5260045ffd5b3461027d575f60031936011261027d576106bd6106417f0000000000000000000000000000000000000000000000000000000000000000613796565b61066a7f00000000000000000000000000000000000000000000000000000000000000006138f0565b60206106cb6040519261067d83856130d3565b5f84525f3681376040519586957f0f00000000000000000000000000000000000000000000000000000000000000875260e08588015260e0870190610eb3565b908582036040870152610eb3565b4660608501523060808501525f60a085015283810360c08501528180845192838152019301915f5b82811061070257505050500390f35b8351855286955093810193928101926001016106f3565b3461027d575f60031936011261027d5760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461027d575f60031936011261027d5760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b61010060031936011261027d5760043567ffffffffffffffff811161027d576107cc903690600401610e54565b60243567ffffffffffffffff811161027d576107ec903690600401610e82565b91604435608435801515810361027d5760c43567ffffffffffffffff811161027d5761081c903690600401610e54565b9160e435804211610c3b57908891610833896130f6565b61084060405191826130d3565b89815261084c8a6130f6565b601f196020830191013682375f5b8b8110610be25750604051915160208301929183915f5b818110610bc9575050509361097c9693604293836108a06109859b99956109769903601f1981018352826130d3565b5190209115610bb7576001600160a01b036108bf33945b8d369161312a565b60208151910120936040519360208501957f4b503a2e339bf072a489301f3eec7abaefc520266c462796ed9267bbcc6e407c8752604086015260608501528b608085015260643560a08501521660c083015260a43560e08301526101008201526101008152610930610120826130d3565b51902061093b613fcf565b90604051917f19010000000000000000000000000000000000000000000000000000000000008352600283015260228201522092369161312a565b906140eb565b90929192614125565b5f1960a43503610b20575b7fd317c76a4357223a1868125ee857a1f31cabfcec288f6cdd0ea8c52b6a71ee315d7fa42de8dec63499ed8713dc6815ea14006a1f8e80e1664c66e3beb461bb65b0da5d6064357f17350132762f24cc4b86e10621ea1e0b5c33483a51cca86a1b11e7ed029b6eb65d333014610b12576001600160a01b037f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c16610aea57610a5b93337f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085d610f32565b5f7f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085d5b5f7fd317c76a4357223a1868125ee857a1f31cabfcec288f6cdd0ea8c52b6a71ee315d5f7fa42de8dec63499ed8713dc6815ea14006a1f8e80e1664c66e3beb461bb65b0da5d5f7f17350132762f24cc4b86e10621ea1e0b5c33483a51cca86a1b11e7ed029b6eb65d005b7f6f5ffb7e000000000000000000000000000000000000000000000000000000005f5260045ffd5b610b1b93610f32565b610a7f565b6001600160a01b038116805f52600260205260405f2060a4355f5260205260ff60405f205416610b8f575f52600260205260405f2060a4355f5260205260405f2060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055610990565b7f1fb09b80000000000000000000000000000000000000000000000000000000005f5260045ffd5b6001600160a01b036108bf5f946108b7565b825184528f985060209384019390920191600101610871565b909192939450610bfd610bf6828d8d610f17565b369161312a565b60208151910120908351811015610c275760019160208260051b8601015201908b9493929161085a565b634e487b7160e01b5f52603260045260245ffd5b7f5bf6f916000000000000000000000000000000000000000000000000000000005f5260045ffd5b606060031936011261027d5760043567ffffffffffffffff811161027d57610c8f903690600401610e54565b60243567ffffffffffffffff811161027d57610caf903690600401610e82565b916044354211610c3b57333014610d40576001600160a01b037f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c16610aea57610d1b93337f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085d610f32565b5f7f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085d005b61023793610f32565b604060031936011261027d5760043567ffffffffffffffff811161027d57610d75903690600401610e54565b60243567ffffffffffffffff811161027d57610d95903690600401610e82565b91333014610d40576001600160a01b037f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c16610aea57610d1b93337f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085d610f32565b3461027d57604060031936011261027d57600435906001600160a01b03821680920361027d576020915f526002825260405f206024355f52825260ff60405f20541615158152f35b35906001600160a01b038216820361027d57565b9181601f8401121561027d5782359167ffffffffffffffff831161027d576020838186019501011161027d57565b9181601f8401121561027d5782359167ffffffffffffffff831161027d576020808501948460051b01011161027d57565b90601f19601f602080948051918291828752018686015e5f8582860101520116010190565b90821015610c27570190565b903590601e198136030182121561027d570180359067ffffffffffffffff821161027d5760200191813603831361027d57565b90821015610c2757610f2e9160051b810190610ee4565b9091565b929080820361308f579291905f915b848310610f4f575050505050565b9091929394610f5f848787610ed8565b3592610f6c858285610f17565b979092606097607f8760f81c1695600196602181105f14612ae657601081101561240157600881101561186a57806112fc5750610fae60208701359b876132a0565b95906080880135156112f5577f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c9c5b610fe889356135e0565b9d918881608052600160ff1b8314611282575b50505b604260a052602b600160ff1b82101561027d5760a0518f908a1061127c575030915b89821161027d576040916001600160a01b035f60805135956110f861108f6110a3856110658b60601c6017608051013560601c62ffffff8183109e60481c16916132cb565b16968a8614611261576401000276a49b5b878b519485938d6020860152606085019060805161318e565b91168b83015203601f1981018352826130d3565b8488519a8b98899788967f128acb080000000000000000000000000000000000000000000000000000000088521660048701528b6024870152604486015216606484015260a0608484015260a4830190610eb3565b03925af1908115611256575f905f9261121a575b61111c935015611213575061317e565b60a05190969081106111635730908060171161027d576080805160170190527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe90196610ffe565b50979396929a509794909893604090910135116111eb575b1590816111dc575b50611195575060010191909392610f41565b906111d86040519283927f2c4029e90000000000000000000000000000000000000000000000000000000084526004840152604060248401526044830190610eb3565b0390fd5b600160ff1b915016155f611183565b7f39d35496000000000000000000000000000000000000000000000000000000005f5260045ffd5b905061317e565b9150506040823d821161124e575b81611235604093836130d3565b8101031261027d5781602061111c93519101519161110c565b3d9150611228565b6040513d5f823e3d90fd5b73fffd8963efd1fc6a506488495d951d5263988d259b611076565b91611020565b601491925010610329576020602491604051928380926370a0823160e01b82523060048301523560601c5afa908115611256575f916112c4575b505f80610ffb565b90506020813d82116112ed575b816112de602093836130d3565b8101031261027d57515f6112bc565b3d91506112d1565b309c610fde565b6001819c929a97939b96999598949c145f14611419575090611323602082013592826132a0565b608083013515611412577f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c915b604061135d85356135e0565b9401357faf28d9864a81dfdf71cab65f4e5d79a0cf9b083905fb8971425e6cb581b3f6925d600160ff1b85101561027d5761139b936102788661317e565b9091901561140357506113ad9061317e565b036113db575f7faf28d9864a81dfdf71cab65f4e5d79a0cf9b083905fb8971425e6cb581b3f6925d5b61117b565b7fd4e0248e000000000000000000000000000000000000000000000000000000005f5260045ffd5b61140d915061317e565b6113ad565b3091611351565b6002810361146357506113d691604081013591507f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c61145c60208301356135e0565b91356136f4565b9394919390929060038103611633575050508135820163ffffffff60208401351683019163ffffffff83351693602080850194860101910110611626577f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c92604051926001600160a01b0360208501957f2a2d80d10000000000000000000000000000000000000000000000000000000087521660248501526060604485015260e48401928035601e198236030181121561027d5781016020813591019467ffffffffffffffff821161027d578160071b3603861361027d5781906060608489015252610104860194905f905b80821061160857505050936115bc5f969482946115ca946040896001600160a01b0361158060208e9d01610e40565b1660a4880152013560c48601527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc85840301606486015261318e565b03601f1981018352826130d3565b5190826001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1906116026131ae565b9161117b565b9091956080808261161b6001948b61321d565b019701920190611551565b633b99b53d5f526004601cfd5b9194939092509060048103611766575061165060208201356135e0565b906001600160a01b038060408301351691351680155f146116b95750479081106116915780611681575b505061117b565b61168a91613a77565b5f8061167a565b7f6a12f104000000000000000000000000000000000000000000000000000000005f5260045ffd5b91604051916370a0823160e01b8352306004840152602083602481875afa928315611256575f93611733575b50821061170b57816116fa575b50505061117b565b61170392613f20565b5f80806116f2565b7f675cae38000000000000000000000000000000000000000000000000000000005f5260045ffd5b9092506020813d821161175e575b8161174e602093836130d3565b8101031261027d5751915f6116e5565b3d9150611741565b6005810361178d57508060406113d69201359061178660208201356135e0565b903561365a565b6006810361183f57506040810135906001600160a01b036117b160208301356135e0565b913516806117cd57506117c76113d69247613ede565b90613a77565b906040516370a0823160e01b8152306004820152602081602481865afa908115611256575f9161180c575b506113d69361180691613ede565b91613f20565b90506020813d8211611837575b81611826602093836130d3565b8101031261027d57516113d66117f8565b3d9150611819565b7fd76a1e9e000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b6008819c929a97939b96999598949c145f14611ab45750611890602083013591836135a8565b90608084013515611aad577f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c915b6118c985356135e0565b928215610c27576118d9826135cc565b8360011015610c27576118fb611943916118f5602086016135cc565b90614ae9565b907f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000614b07565b948581611a93575b5050505f1982018281116102e35761197461196f6001600160a01b0392858561363d565b6135cc565b1693604051926370a0823160e01b84526001600160a01b038516928360048601526020856024818a5afa948515611256575f95611a56575b50946119bc929160209596613b35565b6024604051809581936370a0823160e01b835260048301525afa918215611256575f92611a22575b5060406119f4929301359261364d565b101561117b577f849eaf98000000000000000000000000000000000000000000000000000000005f5260045ffd5b91506020823d8211611a4e575b81611a3c602093836130d3565b8101031261027d5790519060406119e4565b3d9150611a2f565b92919450946020833d8211611a8b575b81611a73602093836130d3565b8101031261027d5791519194919390916119bc6119ac565b3d9150611a66565b611aa592611aa0856135cc565b6133df565b5f808561194b565b30916118bf565b60098103611d9a5750611ac790826135a8565b608083013515611d93577f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c915b611aff84356135e0565b917f0000000000000000000000000000000000000000000000000000000000000000937f0000000000000000000000000000000000000000000000000000000000000000955f9560028510611d6b576020820135975f1986018681116102e3579190825b611bb957505050604001358611611b91578215610c27576113d69585611b8c92611aa0856135cc565b613b35565b7f8ab0bc16000000000000000000000000000000000000000000000000000000005f5260045ffd5b90919897505f198901978989116102e357611bdb61196f611bfd9a898961363d565b611bf2611bec61196f8d8b8b61363d565b82614ae9565b8185879d939d614b07565b90604051907f0902f1ac0000000000000000000000000000000000000000000000000000000082526060826004816001600160a01b0387165afa918215611256575f905f93611d1b575b506001600160a01b036dffffffffffffffffffffffffffff8082931694169d169116145f14611d155799905b9980158015611d0d575b611ce55782611c8b91613ead565b916103e88302928084046103e814901517156102e357611caa9161364d565b6103e58102908082046103e514901517156102e357611cc891613ec0565b600181018091116102e3579880156102e3575f1901919082611b63565b7f7b9c8916000000000000000000000000000000000000000000000000000000005f5260045ffd5b508115611c7d565b90611c73565b6dffffffffffffffffffffffffffff8094506001600160a01b039250611d58839260603d8111611d64575b611d5081836130d3565b810190613aff565b50959093505050611c47565b503d611d46565b7f20db8267000000000000000000000000000000000000000000000000000000005f5260045ffd5b3091611af5565b93949193909290600a8103611e815750505063ffffffff60c08301351682019063ffffffff82351690836020808501948401019101106116265760a06115ca5f946115bc86957f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c956040519586946001600160a01b0360208701997f2b67b570000000000000000000000000000000000000000000000000000000008b52166024870152611e4c604487018261321d565b6001600160a01b03611e6060808301610e40565b1660c4870152013560e485015261010061010485015261012484019161318e565b91949390929091600b810361200c575050611ea1602082013591356135e0565b81600160ff1b8103611fdd57504791505b81611ebe57505061117b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691823b1561027d576040517fd0e30db00000000000000000000000000000000000000000000000000000000081525f8160048185885af1801561125657611fcd575b50306001600160a01b03831603611f42575b5061167a565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b03929092166004830152602482015290602090829060449082905f905af1801561125657611f9f575b8080611f3c565b611fbf9060203d8111611fc6575b611fb781836130d3565b810190613625565b505f611f98565b503d611fad565b5f611fd7916130d3565b5f611f2a565b471015611eb2577f6a12f104000000000000000000000000000000000000000000000000000000005f5260045ffd5b600c810361214357505061202081356135e0565b906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016604051916370a0823160e01b8352306004840152602083602481855afa928315611256575f9361210f575b50602001358210611691578161208e5750505061117b565b803b1561027d575f80916024604051809481937f2e1a7d4d0000000000000000000000000000000000000000000000000000000083528760048401525af18015611256576120ff575b50306001600160a01b038316036120ef575b806116f2565b6120f891613a77565b5f806120e9565b5f612109916130d3565b5f6120d7565b9092506020813d821161213b575b8161212a602093836130d3565b8101031261027d5751916020612076565b3d915061211d565b600d819c939c9b929597989b99949699145f1461232f57508a358b01988935946121756020808d019e8d0301876133d2565b11610329576001600160a01b037f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c169a935f5b86811015612201578c6001600160a01b036121cb60208f8560071b01016135cc565b16036121d9576001016121a9565b7fe7002877000000000000000000000000000000000000000000000000000000005f5260045ffd5b50989593979694929b919a5098506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690813b1561027d576040517f0d58b1db000000000000000000000000000000000000000000000000000000008152602060048201526024810184905292839160448301915f905b8082106122b55750505091815f81819503925af18015611256576122a5575b5061117b565b5f6122af916130d3565b5f61229f565b919350916080806001926001600160a01b036122d088610e40565b1681526001600160a01b036122e760208901610e40565b1660208201526001600160a01b0361230160408901610e40565b1660408201526001600160a01b0361231b60608901610e40565b166060820152019401920185939291612280565b80929b93989550600e919a97969450145f1461183f5750604051906370a0823160e01b82526001600160a01b0381351660048301526020826024816001600160a01b0384860135165afa918215611256575f926123cd575b50604001351115806113d65791506040517fa3281672000000000000000000000000000000000000000000000000000000006020820152600481526116026024826130d3565b9091506020813d82116123f9575b816123e8602093836130d3565b8101031261027d5751906040612387565b3d91506123db565b6010819c929a97939b96999598949c145f1461250f575061245a915f9160405193849283927f48c8949100000000000000000000000000000000000000000000000000000000845260206004850152602484019161318e565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1801561125657612499575061117b565b3d805f833e6124a881836130d3565b81019060208183031261027d5780519067ffffffffffffffff821161027d570181601f8201121561027d5780516124de8161310e565b926124ec60405194856130d3565b8184526020828401011161027d575f928160208094018483015e0101525f61229f565b80929495506011919350145f146125e45750907fffffffff000000000000000000000000000000000000000000000000000000008135167f7ac2ff7b0000000000000000000000000000000000000000000000000000000081036125b95750815f92918392604051928392833781018381520390826001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1906116026131ae565b7ff801e525000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b601281036128bc57507f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c917fffffffff000000000000000000000000000000000000000000000000000000008135167f0c49ccbe0000000000000000000000000000000000000000000000000000000081148015612893575b801561286a575b156125b9575060048101356001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016936040517f6352211e000000000000000000000000000000000000000000000000000000008152826004820152602081602481895afa908115611256576001600160a01b039182915f9161284c575b50169116908082149182156127c5575b8215612754575b505015612729575091815f809481946040519384928337810182815203925af1906116026131ae565b7fbb25d4c5000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b909150604051917fe985e9c500000000000000000000000000000000000000000000000000000000835260048301526024820152602081604481885afa908115611256575f916127a7575b505f80612700565b6127bf915060203d8111611fc657611fb781836130d3565b5f61279f565b91506040517f081812fc0000000000000000000000000000000000000000000000000000000081528360048201526020816024818a5afa9081156112565783916001600160a01b03915f9161281e575b501614916126f9565b61283f915060203d8111612845575b61283781836130d3565b810190613a58565b5f612815565b503d61282d565b612864915060203d81116128455761283781836130d3565b5f6126e9565b507f42966c68000000000000000000000000000000000000000000000000000000008114612665565b507ffc6f786500000000000000000000000000000000000000000000000000000000811461265e565b601381036129ad5750505f80916040516001600160a01b0360a060208301937f6276cbbe0000000000000000000000000000000000000000000000000000000085528261290882610e40565b1660248501528261291b60208301610e40565b16604485015262ffffff612931604083016131dd565b166064850152612943606082016131ed565b60020b60848501528261295860808301610e40565b1660a485015201351660c482015260c4815261297560e4826130d3565b5190826001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1906116026131ae565b6014810361183f57507fffffffff000000000000000000000000000000000000000000000000000000008235167fdd46508f0000000000000000000000000000000000000000000000000000000081036125b957508060041161027d57612a24612a1e600319830160048501613278565b90613278565b5f5b818110612a7b575050505f9182914791816040519283928337810184815203916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1906116026131ae565b612a86818385610ed8565b3560f81c8015908115612adb575b8115612ad0575b50612aa857600101612a26565b7f5d1d0f9f000000000000000000000000000000000000000000000000000000005f5260045ffd5b60039150145f612a9b565b600181149150612a94565b90989591996040829c949c999699989598105f14612c2f57506021810361183f575090612b12916139c0565b612b556040959395519460208601967f24856bc300000000000000000000000000000000000000000000000000000000885260406024880152606487019161318e565b927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc858503016044860152818452602084019160208160051b86010194845f90601e19813603015b848310612bd35750505050505050509181612bc45f9493859403601f1981018352826130d3565b519082305af1906116026131ae565b9091929394959697601f1985820301885288358281121561027d578301906020823592019167ffffffffffffffff811161027d57803603831361027d57612c1f60209283928b9561318e565b9a01980196959493019190612b9d565b949392906040810361183f575081019060208183031261027d5780359067ffffffffffffffff821161027d5701906101a08282031261027d57604051906101a0820182811067ffffffffffffffff82111761307b57604052612c9083610e40565b8252612c9e60208401610e40565b9060208301918252612cb260408501610e40565b60408401908152612cc4888601610e40565b92888501938452608085016080870135815260a086019660a0810135885260c087019460c08201358652612cfa60e08301610e40565b60e08901908152612d0e6101008401613597565b6101008a01908152612d236101208501613597565b916101208b01928352612d396101408601613597565b936101408c0194855261016086013567ffffffffffffffff811161027d5761018091612d66918801613160565b956101608d019687520135958615159081880361027d576101808d0197885251965f91600160ff1b8914612ffc575b505115612ebd575085985b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169b516001600160a01b031697516001600160a01b031698516001600160a01b03169a516001600160a01b03169c51905191516001600160a01b0316925163ffffffff16935163ffffffff16945163ffffffff169551968c3b1561027d576040519d8e9c8d9b8c9b7f7b939232000000000000000000000000000000000000000000000000000000008d5260048d015260248c015260448b015260648a0152608489015260a488015260c487015260e4860152610104850152610124840152610144830152610164820161018090526101848201612ea691610eb3565b03915a945f95f18015611256576122a5575061117b565b88516040517f095ea7b300000000000000000000000000000000000000000000000000000000602082019081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166024840181905260448085018d90528452949d949316905f908190612f3b6064866130d3565b84519082855af1612f4a6131ae565b81612fcd575b5080612fc3575b15612f65575b505050612da0565b612fb6612fbb93604051907f095ea7b300000000000000000000000000000000000000000000000000000000602083015260248201525f604482015260448152612fb06064826130d3565b82614a64565b614a64565b5f8080612f5d565b50803b1515612f57565b8051801592508215612fe2575b50505f612f50565b612ff59250602080918301019101613625565b5f80612fda565b9097501561300d5747965b5f612d95565b602460206001600160a01b038b5116604051928380926370a0823160e01b82523060048301525afa908115611256575f9161304a575b5096613007565b90506020813d8211613073575b81613064602093836130d3565b8101031261027d57515f613043565b3d9150613057565b634e487b7160e01b5f52604160045260245ffd5b7fff633a38000000000000000000000000000000000000000000000000000000005f5260045ffd5b60a0810190811067ffffffffffffffff82111761307b57604052565b90601f601f19910116810190811067ffffffffffffffff82111761307b57604052565b67ffffffffffffffff811161307b5760051b60200190565b67ffffffffffffffff811161307b57601f01601f191660200190565b9291926131368261310e565b9161314460405193846130d3565b82948184528183011161027d578281602093845f960137010152565b9080601f8301121561027d5781602061317b9335910161312a565b90565b600160ff1b81146102e3575f0390565b601f8260209493601f1993818652868601375f8582860101520116010190565b3d156131d8573d906131bf8261310e565b916131cd60405193846130d3565b82523d5f602084013e565b606090565b359062ffffff8216820361027d57565b35908160020b820361027d57565b9081602091031261027d575190565b359065ffffffffffff8216820361027d57565b65ffffffffffff613272606080936001600160a01b0361323c82610e40565b1686526001600160a01b0361325360208301610e40565b166020870152836132666040830161320a565b1660408701520161320a565b16910152565b909163ffffffff82351682019263ffffffff8435169260208086019585010191011061162657565b909163ffffffff60608301351682019263ffffffff8435169260208086019585010191011061162657565b906001600160a01b0392838216848416116133ca575b62ffffff9084604051938160208601961686521660408401521660608201526060815261330f6080826130d3565b5190206040517fff00000000000000000000000000000000000000000000000000000000000000602082019081527f000000000000000000000000000000000000000000000000000000000000000060601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602183015260358201929092527f000000000000000000000000000000000000000000000000000000000000000060558201526133c381607581016115bc565b5190201690565b9091906132e1565b919082018092116102e357565b909291906001600160a01b03841630036133ff576133fd935061365a565b565b91926001600160a01b038411613422576001600160a01b036133fd9416926136f4565b7fc4bd89a9000000000000000000000000000000000000000000000000000000005f5260045ffd5b939290602b8210610329578235938460601c92601785013560601c9380851094859760481c62ffffff169061347e926132cb565b6001600160a01b031692845f146040966001600160a01b0380956134db5f9661352e9561357c576401000276a4925b846134c78e51978f9489956020870152606086019161318e565b91168d83015203601f1981018552846130d3565b89519b8c998a9889977f128acb080000000000000000000000000000000000000000000000000000000089521660048801526024870152604486015216606484015260a0608484015260a4830190610eb3565b03925af18015611256575f925f9161354557509192565b9250506040823d604011613574575b81613561604093836130d3565b8101031261027d57602082519201519192565b3d9150613554565b73fffd8963efd1fc6a506488495d951d5263988d25926134ad565b359063ffffffff8216820361027d57565b9160608301358301916135c56020843595818601950301856133d2565b1161032957565b356001600160a01b038116810361027d5790565b6001600160a01b038116600181036136195750507f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c90565b60020361317b57503090565b9081602091031261027d5751801515810361027d5790565b9190811015610c275760051b0190565b919082039182116102e357565b9091906001600160a01b03168061367557506133fd91613a77565b600160ff1b821461368b575b916133fd92613f20565b9050604051916370a0823160e01b8352306004840152602083602481855afa8015611256575f906136c0575b90925090613681565b506020833d6020116136ec575b816136da602093836130d3565b8101031261027d576133fd92516136b7565b3d91506136cd565b91926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691823b1561027d575f6001600160a01b039384829681608496816040519b8c9a8b997f36c78516000000000000000000000000000000000000000000000000000000008b521660048a01521660248801521660448601521660648401525af180156112565761378c5750565b5f6133fd916130d3565b60ff81146137f55760ff811690601f82116137cd57604051916137ba6040846130d3565b6020808452838101919036833783525290565b7fb3512b0c000000000000000000000000000000000000000000000000000000005f5260045ffd5b506040515f80548060011c91600182169182156138e6575b6020841083146138d25783855284929081156138955750600114613838575b61317b925003826130d3565b505f80805290917f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b81831061387957505090602061317b9282010161382c565b6020919350806001915483858801015201910190918392613861565b6020925061317b9491507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682840152151560051b82010161382c565b634e487b7160e01b5f52602260045260245ffd5b92607f169261380d565b60ff81146139145760ff811690601f82116137cd57604051916137ba6040846130d3565b506040515f6001548060011c91600182169182156139b6575b6020841083146138d257838552849290811561389557506001146139575761317b925003826130d3565b5060015f90815290917fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b81831061399a57505090602061317b9282010161382c565b6020919350806001915483858801015201910190918392613982565b92607f169261392d565b604081351891606082019363ffffffff6040840135169363ffffffe0601f8601169060608201602086013518179084019260608401359463ffffffff861694641fffffffe0608082019760051b1680915f925b808410613a2b57506080925001019101101761162657565b90916020809163ffffffe0601f60808089890101359b848d18179b88010135011601019301929190613a13565b9081602091031261027d57516001600160a01b038116810361027d5790565b5f80809381935af115613a8657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c4544000000000000000000000000006044820152fd5b51906dffffffffffffffffffffffffffff8216820361027d57565b9081606091031261027d57613b1381613ae4565b916040613b2260208401613ae4565b92015163ffffffff8116810361027d5790565b9160028210613e85578115610c2757613b4d836135cc565b8260011015610c2757613b69906118f5602086979596016135cc565b50925f198101937ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8201955f90602093601f198501965b888410613bb35750505050505050505050565b613bc161196f85848661363d565b946001600160a01b03613bdb61196f60018801868861363d565b921695604051917f0902f1ac0000000000000000000000000000000000000000000000000000000083526060836004818b5afa91821561125657895f945f94613e3f575b506001600160a01b03806dffffffffffffffffffffffffffff80602496979816971693169416841494855f14613e395791935b604051938480926370a0823160e01b82528d60048301525afa918215611256575f92613e0a575b5080820392811592838015613e02575b611ce557826103e586029586046103e514911417156102e357613cac9084613ead565b916103e882029182046103e81417156102e357613cd292613ccc916133d2565b90613ec0565b9015613dfb575f90915b8b861015613df25790613cfd613d47926118f561196f60028a01888a61363d565b8193917f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000614b07565b915b9660405190613d588a836130d3565b5f82528b368b840137803b1561027d57613dc6945f8094604051978895869485937f022c0d9f000000000000000000000000000000000000000000000000000000008552600485015260248401526001600160a01b0389166044840152608060648401526084830190610eb3565b03925af191821561125657600192613de2575b50930192613ba0565b5f613dec916130d3565b5f613dd9565b5087905f613d49565b5f91613cdc565b508115613c89565b9091508981813d8311613e32575b613e2281836130d3565b8101031261027d5751905f613c79565b503d613e18565b93613c52565b6dffffffffffffffffffffffffffff955060249394506001600160a01b0386613e76829360603d8111611d6457611d5081836130d3565b50989098979650505050613c1f565b7fae52ad0c000000000000000000000000000000000000000000000000000000005f5260045ffd5b818102929181159184041417156102e357565b8115613eca570490565b634e487b7160e01b5f52601260045260245ffd5b6127108211613ef85761271091613ef491613ead565b0490565b7fdeaa01e6000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f9182604492602095604051937fa9059cbb000000000000000000000000000000000000000000000000000000008552600485015260248401525af13d15601f3d1160015f511416171615613f7157565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152fd5b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163014806140c2575b1561402a577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a081526140bc60c0826130d3565b51902090565b507f00000000000000000000000000000000000000000000000000000000000000004614614001565b815191906041830361411b576141149250602082015190606060408401519301515f1a90614bd0565b9192909190565b50505f9160029190565b60048110156141d05780614137575050565b60018103614167577ff645eedf000000000000000000000000000000000000000000000000000000005f5260045ffd5b6002810361419b57507ffce698f7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b6003146141a55750565b7fd78bce0c000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b929190600b84101561489257600784036144375761420392935061503b565b60208101906142128282615049565b5f93915080614220846135cc565b9261422d60608601614fa8565b6fffffffffffffffffffffffffffffffff811615614420575b60408601916142558388615049565b801515958692509082614415575b50506143ed575f9591949395945b8486106142f457505050505050506080016fffffffffffffffffffffffffffffffff8061429d83614fa8565b1692169182106142ab575050565b6142c56fffffffffffffffffffffffffffffffff91614fa8565b7f8b063d73000000000000000000000000000000000000000000000000000000005f521660045260245260445ffd5b86985061435461434f6fffffffffffffffffffffffffffffffff9261433161432a8a614324888f9e9c9d9e615049565b9061507f565b9687615359565b94909116936143436080880188610ee4565b929091865f03916151d3565b615432565b98614372575b50600161436789936135cc565b960194939591614271565b61439990670de0b6b3a76400006fffffffffffffffffffffffffffffffff8b169102613ec0565b6143ad876143a7868b615049565b9061363d565b358082116143bb575061435a565b877fa9b7edf7000000000000000000000000000000000000000000000000000000005f5260045260245260445260645ffd5b7f947446a5000000000000000000000000000000000000000000000000000000005f5260045ffd5b14159050855f614263565b5061443261442d85614c6a565b61518e565b614246565b6006840361452e5761444a929350614f99565b61445660c08201614fa8565b6fffffffffffffffffffffffffffffffff8116156144dd575b6144c061434f60e09261449f6fffffffffffffffffffffffffffffffff61449860a08801614fc5565b921661317e565b906144ae610100870187610ee4565b9290916144bb3689614fd2565b6151d3565b91016fffffffffffffffffffffffffffffffff8061429d83614fa8565b506144ea60a08201614fc5565b156145145760e06144c061434f61450b61442d614506866135cc565b614c6a565b9250505061446f565b60e06144c061434f61450b61442d614506602087016135cc565b600984036147455761454192935061503b565b60208101906145508282615049565b90505f9261456060608401614fa8565b9161456a846135cc565b926fffffffffffffffffffffffffffffffff811615614733575b6040850190826145948388615049565b801515958692509082614728575b50506143ed57949093929493845b61462f575050505050506080016fffffffffffffffffffffffffffffffff806145d883614fa8565b1692169182116145e6575050565b6146006fffffffffffffffffffffffffffffffff91614fa8565b7f12bacdd3000000000000000000000000000000000000000000000000000000005f521660045260245260445ffd5b8597506fffffffffffffffffffffffffffffffff61469361468961432a9361466c61465e898d9c9a9b9c615049565b96905f198d0197889161507f565b94909116938461467f6080890189610ee4565b93909215906151d3565b600f0b5f0361518e565b986146b3575b50505f196146a788926135cc565b950193929490846145b0565b6146d990670de0b6b3a76400006fffffffffffffffffffffffffffffffff8b1602613ec0565b906146e8816143a7868b615049565b35908183116146f75750614699565b7fe6518043000000000000000000000000000000000000000000000000000000005f5260045260245260445260645ffd5b14159050815f6145a2565b5061474061442d84614f27565b614584565b6008841461477c575050505b7f5cda29d7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b614787929350614f99565b61479360c08201614fa8565b6fffffffffffffffffffffffffffffffff811615614817575b6147fa61442d6147f26fffffffffffffffffffffffffffffffff60e0946147d560a08801614fc5565b6147e3610100890189610ee4565b93909216906144bb368a614fd2565b600f0b61317e565b91016fffffffffffffffffffffffffffffffff806145d883614fa8565b5061482460a08201614fc5565b156148675760e06147fa61442d6147f26fffffffffffffffffffffffffffffffff61485c61442d614857602089016135cc565b614f27565b9450505050506147ac565b60e06147fa61442d6147f26fffffffffffffffffffffffffffffffff61485c61442d614857886135cc565b92600c810361491657506148a69192614f14565b906148b081614f27565b918083116148e65750906133fd917f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c90614da8565b90507f12bacdd3000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b600f810361499957506149299192614f14565b9061493381614c6a565b918083106149695750906133fd917f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c90614cd6565b90507f8b063d73000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b600b81036149f257506149b0906133fd9293614c52565b156149e7576149e1827f0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a7085c92614d83565b91614da8565b6149e1823092614d83565b600e8103614a255750614a19614a0f614a1f926133fd9495614c52565b92829492916135e0565b92614d6f565b91614cd6565b9260108414614a3657505050614751565b6133fd929350614a4c614a5592614a1f92614c52565b929193906135e0565b91614a5f84614c6a565b613ede565b5f806001600160a01b03614a8d93169360208151910182865af1614a866131ae565b9083615451565b8051908115159182614ace575b5050614aa35750565b7f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b614ae19250602080918301019101613625565b155f80614a9a565b6001600160a01b0382166001600160a01b038216105f14610f2e5791565b916133c3906001600160a01b03947fffffffffffffffffffffffffffffffffffffffff0000000000000000000000006040519181602084019460601b16845260601b16603482015260288152614b5e6048826130d3565b5190206115bc604051938492602084019687917fffffffffffffffffffffffffffffffffffffffff000000000000000000000000605594927fff00000000000000000000000000000000000000000000000000000000000000855260601b166001840152601583015260358201520190565b91907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411614c47579160209360809260ff5f9560405194855216868401526040830152606082015282805260015afa15611256575f516001600160a01b03811615614c3d57905f905f90565b505f906001905f90565b5050505f9160039190565b90606011611626578035916040602083013592013590565b614c9581307f00000000000000000000000000000000000000000000000000000000000000006150bf565b905f8212614ca1575090565b6001600160a01b03907f4c085bf1000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b90918015614d6a576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b1561027d575f92836064926001600160a01b03948560405198899788967f0b0d9c0900000000000000000000000000000000000000000000000000000000885216600487015216602485015260448401525af180156112565761378c5750565b505050565b9081614d7f5761317b9150614c6a565b5090565b90600160ff1b8203614d995761317b915061514c565b81614d7f5761317b9150614f27565b5f918315614f0e576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691823b1561027d576001600160a01b03604051917fa584119400000000000000000000000000000000000000000000000000000000835216908160048201525f8160248183885af1801561125657614ef9575b5080614eac5750506020906004604051809581937f11da60b40000000000000000000000000000000000000000000000000000000083525af1908115614ea05750614e755750565b614e969060203d602011614e99575b614e8e81836130d3565b8101906131fb565b50565b503d614e84565b604051903d90823e3d90fd5b83948360209493614ebc936133df565b6004604051809581937f11da60b40000000000000000000000000000000000000000000000000000000083525af1908115614ea05750614e755750565b614f069194505f906130d3565b5f925f614e2d565b50505050565b9190604011611626576020823592013590565b614f5281307f00000000000000000000000000000000000000000000000000000000000000006150bf565b905f8213614f64575061317b9061317e565b6001600160a01b03907f3351b260000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b90610140116116265780350190565b356fffffffffffffffffffffffffffffffff8116810361027d5790565b35801515810361027d5790565b91908260a091031261027d57604051614fea816130b7565b6080615036818395614ffb81610e40565b855261500960208201610e40565b602086015261501a604082016131dd565b604086015261502b606082016131ed565b606086015201610e40565b910152565b9060a0116116265780350190565b903590601e198136030182121561027d570180359067ffffffffffffffff821161027d57602001918160051b3603831361027d57565b9190811015610c275760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff618136030182121561027d570190565b6001600160a01b03809381602094165f52168252602460405f2060405194859384927ff135baaa0000000000000000000000000000000000000000000000000000000084526004840152165afa908115611256575f9161511d575090565b90506020813d602011615144575b81615138602093836130d3565b8101031261027d575190565b3d915061512b565b6001600160a01b03168061515f57504790565b6020602491604051928380926370a0823160e01b82523060048301525afa908115611256575f9161511d575090565b906fffffffffffffffffffffffffffffffff82168092036151ab57565b7f93dafdf1000000000000000000000000000000000000000000000000000000005f5260045ffd5b909290831561533e576401000276a4905b60405194606086019386851067ffffffffffffffff86111761307b576001600160a01b0397886080956152b9946020986040521515998a8152888101908a82528360408201931683526040519c8d998a997ff3cd914c000000000000000000000000000000000000000000000000000000008b528281511660048c0152828d8201511660248c015262ffffff60408201511660448c0152606081015160020b60648c0152015116608489015251151560a48801525160c4870152511660e485015261012061010485015261012484019161318e565b03815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1928315611256575f9361530a575b505f130361530457600f0b90565b60801d90565b9092506020813d602011615336575b81615326602093836130d3565b8101031261027d5751915f6152f6565b3d9150615319565b73fffd8963efd1fc6a506488495d951d5263988d25906151e4565b905f6080604051615369816130b7565b8281528260208201528260408201528260608201520152615389826135cc565b6001600160a01b038216916001600160a01b0382168084105f1461542057506001600160a01b03905b1680921492602081013562ffffff811680910361027d576040820135918260020b80930361027d5760600135926001600160a01b03841680940361027d576001600160a01b039060405195615406876130b7565b865216602085015260408401526060830152608082015291565b9150506001600160a01b0382916153b2565b5f81600f0b126151ab576fffffffffffffffffffffffffffffffff1690565b9061548e575080511561546657805190602001fd5b7f1425ea42000000000000000000000000000000000000000000000000000000005f5260045ffd5b815115806154d4575b61549f575090565b6001600160a01b03907f9996b315000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b50803b1561549756fea164736f6c634300081a000a'; + return hex'6102c080604052346104605761016081615e268038038091610021828561047f565b833981010312610460576040519061016082016001600160401b0381118382101761044c57604052610052816104a2565b8252610060602082016104a2565b9160208101928352610074604083016104a2565b9260408201938452610088606084016104a2565b93606083019485526080840151926080810193845260a08501519360a082019485526100b660c087016104a2565b9660c083019788526100ca60e088016104a2565b9160e084019283526100df61010089016104a2565b96876101008601526101086101406100fa6101208c016104a2565b9a8b610120890152016104a2565b998a6101408701526040519861011d8a610464565b6001600160a01b039081168a52998a1660208a019081529051945195519751604051919a9198908216979682169695821695911661015a89610464565b8852602088019687525192519151905160405190936001600160a01b039384169316608082016001600160401b0381118382101761044c5760405281526020810192835260408101918252606081019384526040516101ba60408261047f565b600f815260208101906e2ab734bb32b939b0b62937baba32b960891b8252604051916101e760408461047f565b600183526020830191601960f91b8352610200816104b6565b6101205261020d8461064c565b61014052519020918260e05251902080610100524660a0526040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a0815261027660c08261047f565b5190206080523060c052516001600160a01b0390811661016052905161018052905181166101a05290516101c0526101e091909152610200919091529051811661022052905181166102405290518116610260529051811661028052166102a0526040516156a19081610785823960805181613cf2015260a05181613daf015260c05181613cbc015260e05181613d4101526101005181613d67015261012051816104fc01526101405181610528015261016051818181612b3701528181612cb30152613953015261018051818181612b5801528181612c92015261393201526101a05181611c7001526101c05181611c4e01526101e0518181816105ee015281816107df0152818161111c015281816116e901528181612625015281816143d701528181614430015281816145c3015281816146ce015281816151af015261534c0152610200518181816106b5015281816144ee0152614eaf0152610220518181816116a0015281816128cb0152612a0a015261024051818181610d37015281816127e801528181613095015261538201526102605181818161045e015281816110900152612423015261028051818181610756015261117b01526102a05181818161041a01528181612127015261223b0152f35b634e487b7160e01b5f52604160045260245ffd5b5f80fd5b604081019081106001600160401b0382111761044c57604052565b601f909101601f19168101906001600160401b0382119082101761044c57604052565b51906001600160a01b038216820361046057565b908151602081105f14610530575090601f8151116104f05760208151910151602082106104e1571790565b5f198260200360031b1b161790565b604460209160405192839163305a27a960e01b83528160048401528051918291826024860152018484015e5f828201840152601f01601f19168101030190fd5b6001600160401b03811161044c575f54600181811c91168015610642575b602082101461062e57601f81116105fc575b50602092601f821160011461059d57928192935f92610592575b50508160011b915f199060031b1c1916175f5560ff90565b015190505f8061057a565b601f198216935f8052805f20915f5b8681106105e457508360019596106105cc575b505050811b015f5560ff90565b01515f1960f88460031b161c191690555f80806105bf565b919260206001819286850151815501940192016105ac565b5f8052601f60205f20910160051c810190601f830160051c015b8181106106235750610560565b5f8155600101610616565b634e487b7160e01b5f52602260045260245ffd5b90607f169061054e565b908151602081105f14610677575090601f8151116104f05760208151910151602082106104e1571790565b6001600160401b03811161044c57600154600181811c9116801561077a575b602082101461062e57601f8111610747575b50602092601f82116001146106e657928192935f926106db575b50508160011b915f199060031b1c19161760015560ff90565b015190505f806106c2565b601f1982169360015f52805f20915f5b86811061072f5750836001959610610717575b505050811b0160015560ff90565b01515f1960f88460031b161c191690555f8080610709565b919260206001819286850151815501940192016106f6565b60015f52601f60205f20910160051c810190601f830160051c015b81811061076f57506106a8565b5f8155600101610762565b90607f169061069656fe60806040526004361015610022575b3615610018575f80fd5b61002061169d565b005b5f3560e01c80631a27b2011461010157806324856bc3146100fc5780633593564c146100f757806344684dc3146100f25780638021fef7146100ed578063817122dc146100e857806384b0196e146100e357806391dd7346146100de578063ab769d37146100d9578063d04d79a2146100d4578063d0c9f6cb146100cf578063d737d0c7146100ca578063dc4c90d3146100c55763fa461e330361000e5761080e565b6107ca565b610798565b610741565b6106e4565b6106a0565b6105bc565b6104e4565b610449565b610405565b61036a565b6102a9565b6101f8565b61014d565b6001600160a01b031690565b6001600160a01b0381160361012357565b5f80fd5b359061013282610112565b565b6001600160a01b03165f90815260026020526040902090565b346101235760403660031901126101235760043561016a81610112565b6024359060018060a01b03165f52600260205260405f20905f52602052602060ff60405f2054166040519015158152f35b9181601f84011215610123578235916001600160401b038311610123576020838186019501011161012357565b9181601f84011215610123578235916001600160401b038311610123576020808501948460051b01011161012357565b6040366003190112610123576004356001600160401b0381116101235761022390369060040161019b565b6024356001600160401b038111610123576102429036906004016101c8565b913330146102a0575f805160206155f58339815191525c6001600160a01b03166102915761027f93335f805160206155f58339815191525d610b4e565b5f5f805160206155f58339815191525d005b6337affdbf60e11b5f5260045ffd5b61002093610b4e565b6060366003190112610123576004356001600160401b038111610123576102d490369060040161019b565b6024356001600160401b038111610123576102f39036906004016101c8565b916044354211610339573330146102a0575f805160206155f58339815191525c6001600160a01b03166102915761027f93335f805160206155f58339815191525d610b4e565b632dfb7c8b60e11b5f5260045ffd5b8015150361012357565b6084359061013282610348565b359061013282610348565b610100366003190112610123576004356001600160401b0381116101235761039690369060040161019b565b906024356001600160401b038111610123576103b69036906004016101c8565b926044356064356103c5610352565b9060a43560c435979093906001600160401b038911610123576103ef61002099369060040161019b565b97909660e43599611236565b5f91031261012357565b34610123575f366003190112610123576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610123575f366003190112610123576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90602080835192838152019201905f5b8181106104ce5750505090565b82518452602093840193909201916001016104c1565b34610123575f366003190112610123576105766105207f00000000000000000000000000000000000000000000000000000000000000006133ce565b6105a461054c7f00000000000000000000000000000000000000000000000000000000000000006134b1565b6105846105576114a1565b91604051958695600f60f81b875260e0602088015260e087019061048d565b90858203604087015261048d565b904660608501523060808501525f60a085015283820360c08501526104b1565b0390f35b9060206105b992818152019061048d565b90565b34610123576020366003190112610123576004356001600160401b038111610123576105ec90369060040161019b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036106915761062591613569565b90818303610682575f5b838110610656576105a4604051610647602082611439565b5f8152604051918291826105a8565b8061067c6106676001938789610ad9565b3560f81c610676838787610b1c565b91613ee7565b0161062f565b63aaad13f760e01b5f5260045ffd5b63570c108560e11b5f5260045ffd5b34610123575f366003190112610123576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610123575f36600319011261012357604080516001600160a01b035f805160206156758339815191525c1681525f805160206156358339815191525c60208201525f805160206156558339815191525c91810191909152606090f35b34610123575f366003190112610123576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b6001600160a01b03909116815260200190565b34610123575f366003190112610123576040516001600160a01b035f805160206155f58339815191525c168152602090f35b34610123575f366003190112610123576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610123576060366003190112610123576024356004356044356001600160401b0381116101235761084490369060040161019b565b92905f831392831580610a61575b610a5257610899926108819161086a87850185611574565b90996001600160a01b039092169690959250611af8565b92909161088e8484613601565b999198908a8a611be4565b336001600160a01b0390911603610a43578015610a2a5790978891906001600160a01b03818116908a16105b156108dd575050505050505061002093503391611cb8565b909192939495989997506108f2866042111590565b1561099e57508651610944575b5050509461092361091661091e9361002098611d25565b939092611d3b565b6115f6565b94801561093c5761093390611682565b945b3390611dd7565b505f94610935565b61095d610967938a93610962935f1461099757506115f6565b61160b565b611642565b6109718686611660565b5180821061097f57806108ff565b631c1763d160e11b5f52610994925086611674565b5ffd5b90506115f6565b969450909192505f805160206156158339815191529796975c8711610a1b5783516109d4575b5050505061002093503391611cb8565b8661096261095d6109f7958b956109f1955f1461099757506115f6565b92611660565b51808210610a065780806109c4565b631c1763d160e11b5f52610994925085611674565b6339cedf2960e11b5f5260045ffd5b91978892906001600160a01b03898116908216106108c5565b6332b13d9160e01b5f5260045ffd5b63316cf0eb60e01b5f5260045ffd5b505f831315610852565b929190333014610abc575f805160206155f58339815191525c6001600160a01b031661029157610aaa93335f805160206155f58339815191525d610b4e565b5f5f805160206155f58339815191525d565b61013293610b4e565b634e487b7160e01b5f52603260045260245ffd5b90821015610ae5570190565b610ac5565b903590601e198136030182121561012357018035906001600160401b0382116101235760200191813603831361012357565b90821015610ae557610b339160051b810190610aea565b9091565b6040906105b993928152816020820152019061048d565b909392848103611227575f5b858110610b6957505050509050565b610b74818785610ad9565b35610b80828487610b1c565b6060929160019160f884901c607f1660218110156111ae576010811015611048576008811015610e2a5780610c495750610bca82610bc183610bfc95611b83565b9290938261270a565b92909360808301355f14610c4257610be0611ae6565b925b604081013590610bf760208201359135612888565b6131d2565b159081610c33575b50610c125750600101610b5a565b604051632c4029e960e01b8152918291610c2f9160048401610b37565b0390fd5b600160ff1b161590505f610c04565b3092610be2565b60018103610ca15750610c6382610bc183610c9595611b83565b92909360808301355f14610c9a57610c79611ae6565b925b604081013590610c9060208201359135612888565b613103565b610bfc565b3092610c7b565b60028103610cd2575050610c9590610cb7611ae6565b90604081013591610ccb6020830135612888565b9135613090565b9192909160038103610d705750505f92935090610d32610cf3849383611b58565b610d24610d01939293611ae6565b916040519485936020850197632a2d80d160e01b8952803501906024860161199f565b03601f198101835282611439565b5190827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190610d6a6117de565b91610bfc565b9092915060048103610da3575080610d8e6020610c95930135612888565b60408201356001600160a01b03169135612fc6565b60058103610dca5750806040610c9592013590610dc36020820135612888565b9035612f3b565b60068103610df15750806040610c9592013590610dea6020820135612888565b9035612ec5565b60078103610e185750806040610c9592013590610e116020820135612888565b9035612e0b565b636bb50f4f60e11b5f5260045260245ffd5b90919060088103610e8a57508181610e48610c9594610e51946126ea565b9390928261270a565b92909360808301355f14610e8357610e67611ae6565b925b604081013590610e7e60208201359135612888565b612c56565b3092610e69565b60098103610ede57508181610e48610c9594610ea5946126ea565b92909360808301355f14610ed757610ebb611ae6565b925b604081013590610ed260208201359135612888565b612b14565b3092610ebd565b909290600a8103610f2b5750505f92935081610efe610d32928594611b2d565b929091610d24610f0c611ae6565b9460405194859360208501976302b67b5760e41b895260248601611951565b909290600b8103610f505750610c959150610f4b60208201359135612888565b6129ef565b600c8103610f725750610c959150610f6d60208201359135612888565b6128ba565b600d8103610f975750610c9591610f88916126cd565b90610f91611ae6565b916127d9565b9092509050600e8103610e1857506040516370a0823160e01b81529060208280610fc5843560048301610785565b0381848401356001600160a01b03165afa918215611043575f92611010575b5060400135111580610c95576040516351940b3960e11b6020820152909250610d6a8160248101610d24565b60409192506110359060203d811161103c575b61102d8183611439565b8101906118c5565b9190610fe4565b503d611023565b6118d4565b9091906010810361105e575090610c95916125f7565b93945092909150601181036110c357505f91908161107c84936125db565b61108b6040518093819361180d565b0390827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190610d6a6117de565b601281036110e257505f9190829161107c6110dc611ae6565b826123d4565b6013810361114f5750505f809160405161111781610d24602082019463313b65df60e11b865260a08101359060248401611832565b5190827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190610d6a6117de565b60148103610e1857505f91829161116681836122f5565b47916111776040518093819361180d565b03917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190610d6a6117de565b939490939192604083101561120d57505060218103610e1857506111fe610d246111da5f948594613569565b60409593959491945194859360208501976324856bc360e01b895260248601611738565b519082305af190610d6a6117de565b9290949391604081145f14610e18575090610c95916120f5565b631fec674760e31b5f5260045ffd5b95909698929a99979197804211610339576112538c9a9b9c611a55565b5f5b8b81106113d457508686611314611324958f61132a999896610d24918f8f6112a39061131c9a60405161129081610d24602082018095611a87565b51902096156113cd5733925b36916114d7565b6020815191012097604051978896602088019a8b93909796959260e095926101008601997f4b503a2e339bf072a489301f3eec7abaefc520266c462796ed9267bbcc6e407c8752602087015260408601526060850152608084015260018060a01b031660a083015260c08201520152565b519020613392565b9236916114d7565b906133b8565b60018801611372575b61136a97505f805160206156758339815191525d5f805160206156358339815191525d5f805160206156558339815191525d610a6b565b610132611ab4565b61139661138f8961138284610134565b905f5260205260405f2090565b5460ff1690565b6113bf576113ba6113ad61136a9961138284610134565b805460ff19166001179055565b611333565b623f613760e71b5f5260045ffd5b5f9261129c565b806113e98d9f9e9d60019361129c918f610b1c565b602081519101206113fa8285611660565b52019c9a9b9c611255565b634e487b7160e01b5f52604160045260245ffd5b60a081019081106001600160401b0382111761143457604052565b611405565b601f909101601f19168101906001600160401b0382119082101761143457604052565b604051906101326101a083611439565b60405190610132606083611439565b6040519061013260a083611439565b6001600160401b0381116114345760051b60200190565b604051906114b0602083611439565b5f808352366020840137565b6001600160401b03811161143457601f01601f191660200190565b9291926114e3826114bc565b916114f16040519384611439565b829481845281830111610123578281602093845f960137010152565b9080601f83011215610123578160206105b9933591016114d7565b9291906115348161148a565b936115426040519586611439565b602085838152019160051b810192831161012357905b82821061156457505050565b8135815260209182019101611558565b6080818303126101235780356001600160401b038111610123578261159a91830161150d565b9260208201356115a981610112565b9260408301356001600160401b03811161012357830181601f82011215610123576060918160206115dc93359101611528565b92013590565b634e487b7160e01b5f52601160045260245ffd5b600160ff1b8114611606575f0390565b6115e2565b6a0c097ce7bc90715b34b9f160241b80820292918015908404909114171561160657565b8181029291811591840414171561160657565b811561164c570490565b634e487b7160e01b5f52601260045260245ffd5b8051821015610ae55760209160051b010190565b600452602452604452606490565b5f1981019190821161160657565b9190820391821161160657565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161415806116e5575b6116d657565b631c5deabb60e11b5f5260045ffd5b50337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614156116d0565b908060209392818452848401375f828201840152601f01601f1916010190565b93919061174d91604086526040860191611718565b926020818503910152808352602083019060208160051b85010193835f91601e1982360301905b848410611785575050505050505090565b90919293949596601f19828203018752873583811215610123578401602081019190356001600160401b038111610123578036038313610123576117cf6020928392600195611718565b99019701959401929190611774565b3d15611808573d906117ef826114bc565b916117fd6040519384611439565b82523d5f602084013e565b606090565b908092918237015f815290565b62ffffff81160361012357565b8060020b0361012357565b90929160a0906118b9608060c0850196803561184d81610112565b600180871b03168652602081013561186481610112565b600180871b0316602087015262ffffff60408201356118828161181a565b166040870152606081013561189681611827565b60020b606087015201356118a981610112565b6001600160a01b03166080850152565b600180831b0316910152565b90816020910312610123575190565b6040513d5f823e3d90fd5b359065ffffffffffff8216820361012357565b65ffffffffffff61194b60608093803561190b81610112565b6001600160a01b03168652602081013561192481610112565b6001600160a01b031660208701528361193f604083016118df565b166040870152016118df565b16910152565b60a06105b9959361010093600180841b0316835261197260208401826118f2565b608081013561198081610112565b600180841b031682840152013560c08201528160e08201520191611718565b6001600160a01b0390911681526060602082015290939260c08201929091853536879003601e190181121561012357860160208101949035906001600160401b038211610123578160071b360386136101235781906060808501525260e0820194905f5b818110611a3757505050604086611a236118a960206105b9999a01610127565b013560a08201526040818503910152611718565b90919560808082611a4a6001948b6118f2565b019701929101611a03565b90611a5f8261148a565b611a6c6040519182611439565b8281528092611a7d601f199161148a565b0190602036910137565b80516020909101905f5b818110611a9e5750505090565b8251845260209384019390920191600101611a91565b5f5f805160206156758339815191525d5f5f805160206156358339815191525d5f5f805160206156558339815191525d565b5f805160206155f58339815191525c90565b909163ffffffff82351682019263ffffffff84351692602080860195850101910110611b2057565b633b99b53d5f526004601cfd5b909163ffffffff60c08301351682019263ffffffff84351692602080860195850101910110611b2057565b909163ffffffff60208301351682019263ffffffff84351692602080860195850101910110611b2057565b909163ffffffff60608301351682019263ffffffff84351692602080860195850101910110611b2057565b6001600160f81b0319815260609190911b6001600160601b03191660018201526015810191909152603581019190915260550190565b6105b992611c9d92906001600160a01b0380831690841611611ca2575b604080516001600160a01b0394851660208201908152949093169083015262ffffff166060808301919091528152611c3a608082611439565b519020604051611c9581610d2460208201947f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000087611bae565b519020610106565b610106565b909190611c01565b906014820180921161160657565b909291906001600160a01b0384163003611cd6576101329350612f3b565b91926001600160a01b038411611cf957610132936001600160a01b031692613090565b63c4bd89a960e01b5f5260045ffd5b909291928360041161012357831161012357600401916003190190565b9190918260171161012357601701916016190190565b600160ff1b8110156101235790565b959493611d6660609492611d839460808a5260808a0191611718565b6001600160a01b03909216602088015286820360408801526104b1565b930152565b9190826040910312610123576020825192015190565b6001600160a01b039182168152911515602083015260408201929092529116606082015260a0608082018190526105b99291019061048d565b92919395949094611de88386613601565b6001600160a01b038084169082161098899590939092611e09929091611be4565b611e1290610106565b611e1b90610106565b94845f14604098610d245f96611e6595611e4994611ead576401000276a49e5b8d5196879560208701611d4a565b8751630251596160e31b8152998a978896879560048701611d9e565b03925af18015611043575f925f91611e7c57509192565b9050611ea191925060403d604011611ea6575b611e998183611439565b810190611d88565b919092565b503d611e8f565b73fffd8963efd1fc6a506488495d951d5263988d259e611e3b565b91939490611ed68486613601565b6001600160a01b038082169084161097889490939092611ef7929091611be4565b611f0090610106565b611f0990610106565b93835f1496611e495f94610d2486611e659560409c611ead576401000276a49e8d5196879560208701611d4a565b63ffffffff81160361012357565b359061013282611f37565b602081830312610123578035906001600160401b03821161012357016101a08183031261012357611f7f61145c565b91611f8982610127565b8352611f9760208301610127565b6020840152611fa860408301610127565b6040840152611fb960608301610127565b60608401526080820135608084015260a082013560a084015260c082013560c0840152611fe860e08301610127565b60e0840152611ffa6101008301611f45565b61010084015261200d6101208301611f45565b6101208401526120206101408301611f45565b610140840152610160820135916001600160401b0383116101235761204d6101809261205994830161150d565b6101608501520161035f565b61018082015290565b6001600160a01b039182168152918116602083015291821660408201529181166060830152608082019290925260a081019290925260c0820192909252911660e08201526105b994936101809391926120e7926120d9916120cb9063ffffffff16610100870152565b63ffffffff16610120850152565b63ffffffff16610140830152565b81610160820152019061048d565b61210191810190611f50565b6080810151905f600160ff1b831461226e575b61018082015115612224575081905b80517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316929061215a90610106565b6121676020840151610106565b6121746040850151610106565b916121826060860151610106565b9460a08101519060c081015161219b60e0830151610106565b61010083015163ffffffff16906121ba61012085015163ffffffff1690565b926101606121d061014087015163ffffffff1690565b950151958c3b1561012357604051633dc9c91960e11b81529d8e9c8d9b8c9b6121fc9b60048e01612062565b03915a945f95f18015611043576122105750565b8061221e5f61013293611439565b806103fb565b9061226983612239611c9d6040850151610106565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690613633565b612123565b915061227e610180820151151590565b1561228a574791612114565b61229d611c9d611c9d6040840151610106565b602060405180926370a0823160e01b825281806122bd3060048301610785565b03915afa908115611043575f916122d6575b5091612114565b6122ef915060203d60201161103c5761102d8183611439565b5f6122cf565b80356322b9af7160e01b6001600160e01b03198216016123b85750612321826123279361232193611d08565b90611af8565b5f5b81811061233557505050565b61236361235d612357612349848688610ad9565b356001600160f81b03191690565b60f81c90565b60ff1690565b80159081156123ad575b81156123a2575b8115612397575b5061238857600101612329565b635d1d0f9f60e01b5f5260045ffd5b60039150145f61237b565b600181149150612374565b60048114915061236d565b63f801e52560e01b5f526001600160e01b03191660045260245ffd5b80356001600160e01b031916630624e65f60e11b811480156125cb575b80156125bb575b156125a957506040516331a9108f60e11b815260049182013591810182905290916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690602083602481855afa928315611043575f93612588575b506001600160a01b03818116908416811492908315612518575b50821561249c575b50501590505b61248a5750565b63bb25d4c560e01b5f5260045260245ffd5b60405163e985e9c560e01b81526001600160a01b0394851660048201529190931660248201529160209150829060449082905afa801561104357612483915f916124e9575b505f8061247d565b61250b915060203d602011612511575b6125038183611439565b8101906129bf565b5f6124e1565b503d6124f9565b60405163020604bf60e21b81526004810187905291935090602081602481875afa908115611043575f91612559575b506001600160a01b031614915f612475565b61257b915060203d602011612581575b6125738183611439565b810190613722565b5f612547565b503d612569565b6125a291935060203d602011612581576125738183611439565b915f61245b565b63f801e52560e01b5f5260045260245ffd5b50630852cd8d60e31b81146123f8565b5063fc6f786560e01b81146123f1565b356001600160e01b03191663853d008560e01b81016125a95750565b6040516348c8949160e01b815260206004820152915f9183918291612620916024840191611718565b0381837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af180156110435761265c5750565b3d805f833e61266b8183611439565b810190602081830312610123578051906001600160401b038211610123570181601f820112156101235780516126a0816114bc565b926126ae6040519485611439565b81845260208284010111610123575f928160208094018483015e010152565b918235830191602083359481850194038560051b010111611b2057565b916060830135830191602083359481850194038560051b010111611b2057565b9160a0830135830191602083359481850194038560051b010111611b2057565b9190811015610ae55760071b0190565b356105b981610112565b60208082528101839052604001915f5b8181106127615750505090565b909192608080600192863561277581610112565b848060a01b03168152602087013561278c81610112565b848060a01b0316602082015260408701356127a681610112565b848060a01b0316604082015260608701356127c081610112565b848060a01b031660608201520194019101919091612754565b90915f5b83811061284c5750507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691823b156101235761283b925f9283604051809681958294630d58b1db60e01b845260048401612744565b03925af18015611043576122105750565b61285f61285a82868661272a565b61273a565b6001600160a01b03838116911603612879576001016127dd565b63e700287760e01b5f5260045ffd5b6001600160a01b038116600181036128ae5750505f805160206155f58339815191525c90565b6002036105b957503090565b6040516370a0823160e01b815290917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690602083806129053060048301610785565b0381855afa928315611043575f9361299e575b50821061298f578161292957505050565b803b1561012357604051632e1a7d4d60e01b815260048101839052905f908290602490829084905af180156110435761297b575b50306001600160a01b03831603612972575050565b61013291613737565b8061221e5f61298993611439565b5f61295d565b631a84bc4160e21b5f5260045ffd5b6129b891935060203d60201161103c5761102d8183611439565b915f612918565b9081602091031261012357516105b981610348565b6001600160a01b039091168152602081019190915260400190565b90600160ff1b8103612ad4575047905b81612a08575050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691823b1561012357604051630d0e30db60e41b81525f8160048185885af1801561104357612ac0575b50306001600160a01b03831603612a72575b505050565b612a96926020925f60405180968195829463a9059cbb60e01b8452600484016129d4565b03925af1801561104357612aa8575b50565b612aa59060203d602011612511576125038183611439565b8061221e5f612ace93611439565b5f612a5b565b90478211156129ff57631a84bc4160e21b5f5260045ffd5b9015610ae55790565b9060011015610ae55760200190565b9190811015610ae55760051b0190565b9290939196959460028310612c475786151580612c33575b612c245793965f94907f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000005f198601868111611606579190825b612bc2575050508811612bb3576101329785612bae92612ba961285a8787612aec565b611cb8565b6137ef565b6345585e0b60e11b5f5260045ffd5b919a9750905f198b018b811161160657612c0b8c612bf9612be7612c12948b8b612b04565b3591612bf283610112565b8a8a612b04565b3590612c0482610112565b848661412c565b919a6141c0565b9a8015611606575f1901919082612b86565b630c12651d60e31b5f5260045ffd5b505f19830183811161160657871415612b2c565b632b94ab4360e21b5f5260045ffd5b9294969095919660028510612c475781151580612df9575b612c2457612cd7612c8261285a8789612aec565b612c8f61285a888a612af5565b907f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000613bd9565b968781612de0575b505050612cfe611c9d611c9d61285a612cf788611682565b888a612b04565b91604051966370a0823160e01b885260208880612d1e8860048301610785565b0381875afa95861561104357612d62985f97612db2575b509085612d47949392602098996137ef565b60405180809681946370a0823160e01b835260048301610785565b03915afa801561104357612d7d925f91612d93575b50611690565b10612d8457565b631093d5f360e31b5f5260045ffd5b612dac915060203d60201161103c5761102d8183611439565b5f612d77565b60209750612d4794939291612dd488928a3d8c1161103c5761102d8183611439565b98509192939450612d35565b612df192612ba961285a898b612aec565b5f8087612cdf565b50612e0385611682565b821415612c6e565b670de0b6b3a76400008311612eb6576001600160a01b031680612e4d5750612e47612e39610132934761162f565b670de0b6b3a7640000900490565b90613737565b906040516370a0823160e01b815260208180612e6c3060048301610785565b0381865afa9081156110435761013294612e9192612e39925f91612e97575b5061162f565b91613bf0565b612eb0915060203d60201161103c5761102d8183611439565b5f612e8b565b6390f5ebeb60e01b5f5260045ffd5b6001600160a01b031680612ee15750612e476101329247613c5f565b6040516370a0823160e01b8152306004820152909190602081602481865afa9384156110435761013294612e91925f91612f1c575b50613c5f565b612f35915060203d60201161103c5761102d8183611439565b5f612f16565b9091906001600160a01b031680612f56575061013291613737565b600160ff1b8214612f6c575b9161013292613bf0565b6040516370a0823160e01b815230600482015292909150602083602481855afa801561104357610132935f91612fa7575b5091909250612f62565b612fc0915060203d60201161103c5761102d8183611439565b5f612f9d565b9091906001600160a01b031680612fe957504790811061298f5780612972575050565b91604051916370a0823160e01b8352602083806130093060048301610785565b0381875afa928315611043575f93613045575b508210613036578161302d57505050565b61013292613bf0565b630ceb95c760e31b5f5260045ffd5b61305f91935060203d60201161103c5761102d8183611439565b915f61301c565b6001600160a01b039182168152918116602083015291821660408201529116606082015260800190565b9290917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15610123575f80946130e860405197889687958694631b63c28b60e11b865260048601613066565b03925af18015611043576130f95750565b5f61013291611439565b9492909695939193861515806131a8575b6131995761312a61313091613154983691611528565b94613c9a565b835180156131915761314190611682565b945b61314f61091e89611d3b565b611dd7565b909190156131825750613166906115f6565b0361317357610132613c88565b636a70124760e11b5f5260045ffd5b61318c91506115f6565b613166565b505f94613143565b630e0fbd8760e21b5f5260045ffd5b506131bc6131b760178961162f565b611caa565b831415613114565b5f1981146116065760010190565b9793979590919294958715159687809861337b575b613199578998600160ff1b851461330e575b909950879391965f92808b8a61320d6114a1565b9e8f9061325793613249935b61322d613227836042111590565b98611d3b565b908815613304575061324130925b8a613cab565b929091611ec8565b9091901561099757506115f6565b966132c9575b50156132a857309961326e91611d25565b9190978892809c8795613280906131c4565b9c8d9561325794613241613249959e50509c9e509495969290919e8f90928e9a95938e613219565b5050505093509350935050106132ba57565b631ce9aa4b60e11b5f5260045ffd5b6132d6906109628861160b565b6132e1858588612b04565b358082106132ef575061325d565b632d0a7cdd60e21b5f52610994925085611674565b613241909261323b565b935097611c9d611c9d6133219289614331565b976020604051809a6370a0823160e01b825281806133423060048301610785565b03915afa8015611043578a995f9161335c575b50936131f9565b613375915060203d60201161103c5761102d8183611439565b5f613355565b5061338a6131b760178b61162f565b8a14156131e7565b60429061339d613cb9565b906040519161190160f01b8352600283015260228201522090565b6105b9916133c591613dd5565b90929192613e2d565b60ff81146133df576105b990613ea9565b506040515f80548060011c916001821680156134a7575b602084108114613493578385528492602084019190811561347a5750600114613427575b506105b992500382611439565b5f80805291507f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b84831061346357506105b99350015f61341a565b80548284015285935060209092019160010161344f565b60ff19168252506105b993151560051b0190505f61341a565b634e487b7160e01b5f52602260045260245ffd5b92607f16926133f6565b60ff81146134c2576105b990613ea9565b506040515f6001548060011c9160018216801561355f575b602084108114613493578385528492602084019190811561347a575060011461350a57506105b992500382611439565b60015f90815291507fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b84831061354857506105b99350015f61341a565b805482840152859350602090920191600101613534565b92607f16926134da565b604081351891606082019363ffffffff6040840135169363ffffffe0601f8601169060608201602086013518179084019260608401359463ffffffff861694641fffffffe0608082019760051b1680915f925b8084106135d4575060809250010191011017611b2057565b90916020809163ffffffe0601f60808089890101359b848d18179b880101350116010193019291906135bc565b90602b1161362457803591601762ffffff8460601c9460481c1692013560601c90565b633b99b53d60e01b5f5260045ffd5b91909161369a6040519261366b8461365d602082019363095ea7b360e01b855288602484016129d4565b03601f198101865285611439565b83516001600160a01b038416915f91829182855af1906136896117de565b826136f0575b50816136e957501590565b6136a357505050565b60405163095ea7b360e01b60208201526001600160a01b0390931660248401525f6044840152610132926136e4906136de8160648101610d24565b826140c1565b6140c1565b3b15919050565b80519192508115918215613708575b5050905f61368f565b61371b92506020809183010191016129bf565b5f806136ff565b9081602091031261012357516105b981610112565b5f80809381935af11561374657565b60405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606490fd5b51906001600160701b038216820361012357565b90816060910312610123576137a981613781565b9160406137b860208401613781565b9201516105b981611f37565b90926080926105b995948352602083015260018060a01b03166040820152816060820152019061048d565b9493929391909161381961380661285a8589612aec565b61381361285a868a612af5565b9061423b565b50915f19840195600119850191831515985f955b898710613841575050505050505050505050565b61384f61285a888a85612b04565b9361386161285a60018a018b86612b04565b604051630240bc6b60e21b8152909590916001600160a01b038116606084600481845afa918215611043576138df945f905f94613ba5575b506001600160a01b03948516966001600160701b039485169516871493168315613b9b579060209194965b60405180809881946370a0823160e01b835260048301610785565b03915afa978815611043578f6139078f9a978f978e9988915f91613b7d575b50039687614252565b9315613b75578c5f94965b8c821015613b675761392f61285a6139779260028501908d612b04565b847f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006142ad565b9890985b9b83613b51575b5050505f14613aea576040516370a0823160e01b81526001600160a01b0391909116949092602084806139b88a60048301610785565b0381895afa938415611043575f94613aca575b506139d46114a1565b92803b15610123575f92838993613a016040519788968795869463022c0d9f60e01b8652600486016137c4565b03925af1801561104357613ab6575b50602060405180946370a0823160e01b82528180613a318960048301610785565b03915afa90811561104357613a5f935f92613a96575b5090036a0c097ce7bc90715b34b9f160241b02611642565b613a6a88888c612b04565b35808210613a815750506001905b9601959261382d565b6365d564a560e01b5f52610994925088611674565b613aaf91925060203d811161103c5761102d8183611439565b905f613a47565b8061221e5f613ac493611439565b5f613a10565b613ae391945060203d811161103c5761102d8183611439565b925f6139cb565b5093929150613af76114a1565b93803b15610123575f92838593613b246040519889968795869463022c0d9f60e01b8652600486016137c4565b03925af191821561104357600192613b3d575b50613a78565b8061221e5f613b4b93611439565b5f613b37565b613b5b9350612b04565b3515158c8f8d90613982565b5050955087958c8c5f61397b565b8c5f96613912565b613b95915060203d811161103c5761102d8183611439565b5f6138fe565b95602091906138c4565b9050613bc991935060603d8111613bd2575b613bc18183611439565b810190613795565b5092905f613899565b503d613bb7565b90916105b993613be89161423b565b9290916142be565b5f91826044926020956040519363a9059cbb60e01b8552600485015260248401525af13d15601f3d1160015f511416171615613c2857565b60405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606490fd5b6127108211613c795761271091613c759161162f565b0490565b636f5500f360e11b5f5260045ffd5b5f5f805160206156158339815191525d565b5f805160206156158339815191525d565b90602b116101235790602b90565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161480613dac575b15613d14577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a08152613da660c082611439565b51902090565b507f00000000000000000000000000000000000000000000000000000000000000004614613ceb565b8151919060418303613e0557613dfe9250602082015190606060408401519301515f1a90614340565b9192909190565b50505f9160029190565b60041115613e1957565b634e487b7160e01b5f52602160045260245ffd5b613e3681613e0f565b80613e3f575050565b613e4881613e0f565b60018103613e5f5763f645eedf60e01b5f5260045ffd5b613e6881613e0f565b60028103613e83575063fce698f760e01b5f5260045260245ffd5b80613e8f600392613e0f565b14613e975750565b6335e2f38360e21b5f5260045260245ffd5b60ff811690601f8211613ed85760405191613ec5604084611439565b6020808452838101919036833783525290565b632cd44ac360e21b5f5260045ffd5b909190600b811015613f7b5760078103613f0e5750613f099061013292614910565b614c32565b60068103613f295750613f249061013292614724565b614b0f565b60098103613f445750613f3f9061013292614910565b614975565b9160088314613f6757505061099491505b635cda29d760e01b5f52600452602490565b610132925090613f7691614724565b6147db565b600c8103613fca5750613f8d916146b4565b90613f97816146c7565b91808311613fb357509061013291613fad611ae6565b906145ba565b6312bacdd360e01b5f52600452602482905260445ffd5b600f81036140195750613fdc916146b4565b90613fe6816143d0565b9180831061400257509061013291613ffc611ae6565b90614427565b638b063d7360e01b5f52600452602482905260445ffd5b600b810361404d575061404761403561404192610132946143b8565b938294939291936144d0565b926144eb565b916145ba565b600e810361407f575061407361406961407992610132946143b8565b9282949291612888565b926144bc565b91614427565b91601083146140945750506109949150613f55565b61013292506140a96140b292614079926143b8565b92919390612888565b916140bc846143d0565b613c5f565b5f806140e99260018060a01b03169360208151910182865af16140e26117de565b90836154c0565b8051908115159182614111575b50506140ff5750565b635274afe760e01b5f5260045260245ffd5b61412492506020809183010191016129bf565b155f806140f6565b9193929061413d614145928661423b565b9181946142be565b604051630240bc6b60e21b815290936060826004816001600160a01b0389165afa918215611043575f905f9361419b575b506001600160701b03928316939216916001600160a01b03918216911603610b335791565b90506141b791925060603d606011613bd257613bc18183611439565b5091905f614176565b9080158015614233575b61422457816141d89161162f565b916103e88302928084046103e814901517156116065781810391818311611606576103e583029283046103e514911417156116065761421691611642565b600181018091116116065790565b633dce448b60e11b5f5260045ffd5b5082156141ca565b6001600160a01b038281169082161015610b335791565b8115928380156142a5575b614224576103e58202918083046103e5149015171561160657614280908261162f565b926103e883029283046103e8141715611606578101809111611606576105b991611642565b50801561425d565b9261413d906142bb9361423b565b91565b6040516001600160601b0319606094851b8116602083019081529590941b9093166034840152602883529092909161432191906142fc604882611439565b519020614313604051948592602084019586611bae565b03601f198101845283611439565b905190206001600160a01b031690565b90601411613624573560601c90565b91906fa2a8918ca85bafe22016d0b997e4df60600160ff1b0384116143ad579160209360809260ff5f9560405194855216868401526040830152606082015282805260015afa15611043575f516001600160a01b038116156143a357905f905f90565b505f906001905f90565b5050505f9160039190565b90606011611b20578035916040602083013592013590565b6143fb81307f0000000000000000000000000000000000000000000000000000000000000000614da6565b905f8212614407575090565b634c085bf160e01b5f9081526001600160a01b0391909116600452602490fd5b908215612a6d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316803b1561012357604051630b0d9c0960e01b81526001600160a01b03938416600482015291909216602482015260448101929092525f908290606490829084905af18015611043576144a75750565b806144b35f8093611439565b80031261012357565b90816144cc576105b991506143d0565b5090565b156144e7575f805160206155f58339815191525c90565b3090565b907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168061455857505f5b6001600160a01b0316918215801561454a575b6145405750506105b990614e47565b6105b99250614e22565b50600160ff1b811415614531565b6040516312f7fd6760e11b815290602090829081806145836001600160a01b03881660048301610785565b03915afa908115611043575f9161459b575b5061451e565b6145b4915060203d602011612581576125738183611439565b5f614595565b908215612a6d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691823b1561012357604051632961046560e21b81525f81806146108560048301610785565b038183885af18015611043576146a0575b506001600160a01b03811661466f575050602090600460405180948193630476982d60e21b83525af18015611043576146575750565b612aa59060203d60201161103c5761102d8183611439565b5f936020939261467e92614ead565b600460405180948193630476982d60e21b83525af18015611043576146575750565b8061221e5f6146ae93611439565b5f614621565b9190604011611b20576020823592013590565b6146f281307f0000000000000000000000000000000000000000000000000000000000000000614da6565b905f821361470457506105b9906115f6565b63019a8d9360e51b5f9081526001600160a01b0391909116600452602490fd5b9061016011611b205780350190565b356001600160801b03811681036101235790565b356105b981610348565b91908260a09103126101235760405161476981611419565b6080808294803561477981610112565b8452602081013561478981610112565b6020850152604081013561479c8161181a565b604085015260608101356147af81611827565b60608501520135916147c083610112565b0152565b6001600160801b0390811660045216602452604490565b6147e760c08201614733565b6001600160801b038116156148d3575b61484861484361091e61483d61480f60a08701614747565b6001600160801b0390951694859061482b610120890189610aea565b929091614838368b614751565b615158565b600f0b90565b6150ac565b9160e081019261486661485a85614733565b6001600160801b031690565b6001600160801b038216949085116148b75750506101000135918261488a57505050565b6109626148969261160b565b908082106148a2575050565b63efc8d8eb60e01b5f5260045260245260445ffd5b906148c461099492614733565b6312bacdd360e01b5f526147c4565b506148e060a08201614747565b15614901576148fc6148436148f76020840161273a565b6146c7565b6147f7565b6148fc6148436148f78361273a565b9060e011611b205780350190565b903590601e198136030182121561012357018035906001600160401b03821161012357602001918160051b3603831361012357565b9190811015610ae55760051b81013590609e1981360301821215610123570190565b906020820191614985838261491e565b5f92915061499560608301614733565b9061499f8361273a565b906001600160801b03831615614afb575b60408401816149bf828761491e565b801515948592509082614af0575b5050614ae1579193825b614a06575050505050608091929350016149f361485a82614733565b6001600160801b038316116148b7575050565b849650614a3590614a67614a6061483d614a3c614a278e8c9b999a9b61491e565b5f198b019791889190614953565b998a615255565b6001600160801b039095169485614a5660808d018d610aea565b9390921590615158565b5f036150ac565b97614a85575b5050614a79869461273a565b925f19019193826149d7565b614aa9906001600160801b038916906a0c097ce7bc90715b34b9f160241b02611642565b90614abe81614ab8858a61491e565b90612b04565b3590818310614acd5750614a6d565b63e651804360e01b5f526109949350611674565b63115eb5b360e31b5f5260045ffd5b14159050815f6149cd565b9150614b09614843826146c7565b916149b0565b614b1b60c08201614733565b906001600160801b03821615614bf3575b614b74614b6f614b3e60a08401614747565b6001600160801b0390941693614b53856115f6565b90614b62610120860186610aea565b9290916148383688614751565b615327565b9060e0810191614b8661485a84614733565b6001600160801b03821693908410614bd757505061010001359182614baa57505050565b610962614bb69261160b565b90808210614bc2575050565b634713c18b60e01b5f5260045260245260445ffd5b90614be461099492614733565b638b063d7360e01b5f526147c4565b9050614c0160a08201614747565b15614c2057614c1a614843614c158361273a565b6143d0565b90614b2c565b614c1a614843614c156020840161273a565b6020810190614c41828261491e565b5f93915080614c4f8461273a565b92614c5c60608601614733565b6001600160801b03811615614d94575b6040860191614c7b838861491e565b801515958692509082614d89575b5050614ae1575f9591949395945b848610614cc75750505050505050608001614cb461485a82614733565b6001600160801b03831610614bd7575050565b869850614d17614b6f614cf2614ceb89614ce5878e9d9b9c9d61491e565b90614953565b9586615255565b6001600160801b0390941693614d0b6080880188610aea565b929091865f0391615158565b98614d35575b506001614d2a899361273a565b960194939591614c97565b614d58906001600160801b038a166a0c097ce7bc90715b34b9f160241b02611642565b614d6687614ab8868b61491e565b35808210614d745750614d1d565b63a9b7edf760e01b5f52610994925087611674565b14159050855f614c89565b50614da1614843856143d0565b614c6c565b6001600160a01b039182165f9081529282166020908152604093849020935163789add5560e11b815260048101949094529183916024918391165afa908115611043575f91614df3575090565b90506020813d602011614e1a575b81614e0e60209383611439565b81010312610123575190565b3d9150614e01565b90600160ff1b8203614e38576105b99150614e47565b816144cc576105b991506146c7565b6001600160a01b038116614e5a57504790565b6040516370a0823160e01b815230600482015290602090829060249082906001600160a01b03165afa908115611043575f91614e94575090565b6105b9915060203d60201161103c5761102d8183611439565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168061504a57505f5b6001600160a01b03811691821561503c5760405163aeb5556960e01b81526001600160a01b03919091169390602081600481885afa908115611043575f9161501d575b501561500e57614f686020614f35611ae6565b60405163f493cec360e01b81526001600160a01b039091166004820152600160f01b602482015291829081906044820190565b0381885afa908115611043575f91614fef575b5015614fe1576001600160a01b0381163003614fd45750508282614f9e9261542f565b803b1561012357604051630934f6c760e21b815260048101929092525f908290602490829084905af18015611043576122105750565b6101329493919250615374565b6282b42960e81b5f5260045ffd5b615008915060203d602011612511576125038183611439565b5f614f7b565b63888f378560e01b5f5260045ffd5b615036915060203d602011612511576125038183611439565b5f614f22565b90506101329392915061533d565b6040516312f7fd6760e11b815290602090829081806150756001600160a01b03881660048301610785565b03915afa908115611043575f9161508d575b50614edf565b6150a6915060203d602011612581576125738183611439565b5f615087565b6001600160801b03811691908290036150c157565b6393dafdf160e01b5f5260045ffd5b6001600160a01b039091169052565b81516001600160a01b03908116825260208084015182168184015260408085015162ffffff168185015260608086015160020b908501526080948501518316948401949094528451151560a084015284015160c083015291909201511660e08201526105b9929061012090816101008201520191611718565b936020919394845f14615223576151aa6401000276a4925b61518f61517b61146c565b8815158152948787870152604086016150d0565b604051633cf3645360e21b81529788948594600486016150df565b03815f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1928315611043575f93615200575b505f13901515145f146151fa57600f0b90565b60801d90565b5f91935061521c9060203d60201161103c5761102d8183611439565b92906151e7565b6151aa73fffd8963efd1fc6a506488495d951d5263988d2592615170565b356105b98161181a565b356105b981611827565b905f608060405161526581611419565b82815282602082015282604082015282606082015201526152858261273a565b906001600160a01b03808316908216101561530b57906142bb9061530260015b946152f86152b560208301615241565b6152ec6152d060606152c96040870161524b565b950161273a565b956152e36152dc61147b565b998a6150d0565b602089016150d0565b62ffffff166040870152565b60020b6060850152565b608083016150d0565b6001600160a01b03918216916142bb91166153028184146152a5565b5f81600f0b126150c1576001600160801b031690565b61013292916001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169216611cb8565b6001600160a01b03918216927f000000000000000000000000000000000000000000000000000000000000000090921691823b1561012357604051631b63c28b60e11b8152925f9284928391859183916153df91906001600160a01b038c16908b9060048601613066565b03925af180156110435761541b575b50803b1561012357604051630934f6c760e21b815260048101929092525f9082908183816024810161283b565b8061221e5f61542993611439565b5f6153ee565b9091906001600160a01b03811661545c57505f80808061545094865af11590565b6154575750565b61558b565b6040805163a9059cbb60e01b81526001600160a01b039094166004850152602484019290925291905f9060208260448582885af13d15601f3d116001855114161716928281528260208201520152156154b25750565b6001600160a01b031661551e565b906154e457508051156154d557805190602001fd5b630a12f52160e11b5f5260045ffd5b81511580615515575b6154f5575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b156154ed565b6040516390bfb86560e01b81526001600160a01b03909116600482015263a9059cbb60e01b60248201526080604482015260a03d601f01601f191690810160648301523d60848301523d5f60a484013e808201600460a482015260c4633c9fd93960e21b91015260e40190fd5b6040516390bfb86560e01b81526001600160a01b0390911660048201525f602482018190526080604483015260a03d601f01601f191690810160648401523d6084840152903d9060a484013e808201600460a482015260c4633d2cec6f60e21b91015260e40190fdfe0e87e1788ebd9ed6a7e63c70a374cd3283e41cad601d21fbe27863899ed4a708af28d9864a81dfdf71cab65f4e5d79a0cf9b083905fb8971425e6cb581b3f692a42de8dec63499ed8713dc6815ea14006a1f8e80e1664c66e3beb461bb65b0da17350132762f24cc4b86e10621ea1e0b5c33483a51cca86a1b11e7ed029b6eb6d317c76a4357223a1868125ee857a1f31cabfcec288f6cdd0ea8c52b6a71ee31a164736f6c634300081a000a'; } } diff --git a/src/briefcase/deployers/v2-core/UniswapV2FactoryDeployer.sol b/src/briefcase/deployers/v2-core/UniswapV2FactoryDeployer.sol index 66c611e2..24150c2a 100644 --- a/src/briefcase/deployers/v2-core/UniswapV2FactoryDeployer.sol +++ b/src/briefcase/deployers/v2-core/UniswapV2FactoryDeployer.sol @@ -27,6 +27,6 @@ library UniswapV2FactoryDeployer { * - evm_version: istanbul */ function initcode() internal pure returns (bytes memory) { - return hex'608060405234801561001057600080fd5b506040516136863803806136868339818101604052602081101561003357600080fd5b5051600180546001600160a01b0319166001600160a01b03909216919091179055613623806100636000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a2e74af61161005b578063a2e74af6146100fd578063c9c6539614610132578063e6a439051461016d578063f46901ed146101a857610088565b8063017e7e581461008d578063094b7415146100be5780631e3dd18b146100c6578063574f2ba3146100e3575b600080fd5b6100956101db565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6100956101f7565b610095600480360360208110156100dc57600080fd5b5035610213565b6100eb610247565b60408051918252519081900360200190f35b6101306004803603602081101561011357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661024d565b005b6100956004803603604081101561014857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661031a565b6100956004803603604081101561018357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661076d565b610130600480360360208110156101be57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166107a0565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6003818154811061022057fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60035490565b60015473ffffffffffffffffffffffffffffffffffffffff1633146102d357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156103b757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f556e697377617056323a204944454e544943414c5f4144445245535345530000604482015290519081900360640190fd5b6000808373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16106103f45783856103f7565b84845b909250905073ffffffffffffffffffffffffffffffffffffffff821661047e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f556e697377617056323a205a45524f5f41444452455353000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526002602090815260408083208585168452909152902054161561051f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f556e697377617056323a20504149525f45584953545300000000000000000000604482015290519081900360640190fd5b6060604051806020016105319061086d565b6020820181038252601f19601f82011660405250905060008383604051602001808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140192505050604051602081830303815290604052805190602001209050808251602084016000f5604080517f485cc95500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152868116602483015291519297509087169163485cc9559160448082019260009290919082900301818387803b15801561065e57600080fd5b505af1158015610672573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff84811660008181526002602081815260408084208987168086529083528185208054978d167fffffffffffffffffffffffff000000000000000000000000000000000000000098891681179091559383528185208686528352818520805488168517905560038054600181018255958190527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b90950180549097168417909655925483519283529082015281517f0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9929181900390910190a35050505092915050565b600260209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16331461082657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b612d748061087b8339019056fe60806040526001600c5534801561001557600080fd5b506040514690806052612d228239604080519182900360520182208282018252600a8352692ab734b9bbb0b8102b1960b11b6020938401528151808301835260018152603160f81b908401528151808401919091527fbfcc8ef98ffbf7b6c3fec7bf5185b566b9863e35a9d83acd49ad6824b5969738818301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101949094523060a0808601919091528151808603909101815260c09094019052825192019190912060035550600580546001600160a01b03191633179055612c1d806101056000396000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80636a627842116100f9578063ba9a7a5611610097578063d21220a711610071578063d21220a7146105da578063d505accf146105e2578063dd62ed3e14610640578063fff6cae91461067b576101b9565b8063ba9a7a5614610597578063bc25cf771461059f578063c45a0155146105d2576101b9565b80637ecebe00116100d35780637ecebe00146104d757806389afcb441461050a57806395d89b4114610556578063a9059cbb1461055e576101b9565b80636a6278421461046957806370a082311461049c5780637464fc3d146104cf576101b9565b806323b872dd116101665780633644e515116101405780633644e51514610416578063485cc9551461041e5780635909c0d5146104595780635a3d549314610461576101b9565b806323b872dd146103ad57806330adf81f146103f0578063313ce567146103f8576101b9565b8063095ea7b311610197578063095ea7b3146103155780630dfe16811461036257806318160ddd14610393576101b9565b8063022c0d9f146101be57806306fdde03146102595780630902f1ac146102d6575b600080fd5b610257600480360360808110156101d457600080fd5b81359160208101359173ffffffffffffffffffffffffffffffffffffffff604083013516919081019060808101606082013564010000000081111561021857600080fd5b82018360208201111561022a57600080fd5b8035906020019184600183028401116401000000008311171561024c57600080fd5b509092509050610683565b005b610261610d57565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561029b578181015183820152602001610283565b50505050905090810190601f1680156102c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102de610d90565b604080516dffffffffffffffffffffffffffff948516815292909316602083015263ffffffff168183015290519081900360600190f35b61034e6004803603604081101561032b57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610de5565b604080519115158252519081900360200190f35b61036a610dfc565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61039b610e18565b60408051918252519081900360200190f35b61034e600480360360608110156103c357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610e1e565b61039b610efd565b610400610f21565b6040805160ff9092168252519081900360200190f35b61039b610f26565b6102576004803603604081101561043457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610f2c565b61039b611005565b61039b61100b565b61039b6004803603602081101561047f57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611011565b61039b600480360360208110156104b257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113cb565b61039b6113dd565b61039b600480360360208110156104ed57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113e3565b61053d6004803603602081101561052057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113f5565b6040805192835260208301919091528051918290030190f35b610261611892565b61034e6004803603604081101561057457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356118cb565b61039b6118d8565b610257600480360360208110156105b557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166118de565b61036a611ad4565b61036a611af0565b610257600480360360e08110156105f857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135611b0c565b61039b6004803603604081101561065657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516611dd8565b610257611df5565b600c546001146106f457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55841515806107075750600084115b61075c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612b2f6025913960400191505060405180910390fd5b600080610767610d90565b5091509150816dffffffffffffffffffffffffffff168710801561079a5750806dffffffffffffffffffffffffffff1686105b6107ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612b786021913960400191505060405180910390fd5b600654600754600091829173ffffffffffffffffffffffffffffffffffffffff91821691908116908916821480159061085457508073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614155b6108bf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f556e697377617056323a20494e56414c49445f544f0000000000000000000000604482015290519081900360640190fd5b8a156108d0576108d0828a8d611fdb565b89156108e1576108e1818a8c611fdb565b86156109c3578873ffffffffffffffffffffffffffffffffffffffff166310d1e85c338d8d8c8c6040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156109aa57600080fd5b505af11580156109be573d6000803e3d6000fd5b505050505b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015610a2f57600080fd5b505afa158015610a43573d6000803e3d6000fd5b505050506040513d6020811015610a5957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191955073ffffffffffffffffffffffffffffffffffffffff8316916370a0823191602480820192602092909190829003018186803b158015610acb57600080fd5b505afa158015610adf573d6000803e3d6000fd5b505050506040513d6020811015610af557600080fd5b5051925060009150506dffffffffffffffffffffffffffff85168a90038311610b1f576000610b35565b89856dffffffffffffffffffffffffffff160383035b9050600089856dffffffffffffffffffffffffffff16038311610b59576000610b6f565b89856dffffffffffffffffffffffffffff160383035b90506000821180610b805750600081115b610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180612b546024913960400191505060405180910390fd5b6000610c09610beb84600363ffffffff6121e816565b610bfd876103e863ffffffff6121e816565b9063ffffffff61226e16565b90506000610c21610beb84600363ffffffff6121e816565b9050610c59620f4240610c4d6dffffffffffffffffffffffffffff8b8116908b1663ffffffff6121e816565b9063ffffffff6121e816565b610c69838363ffffffff6121e816565b1015610cd657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f556e697377617056323a204b0000000000000000000000000000000000000000604482015290519081900360640190fd5b5050610ce4848488886122e0565b60408051838152602081018390528082018d9052606081018c9052905173ffffffffffffffffffffffffffffffffffffffff8b169133917fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229181900360800190a350506001600c55505050505050505050565b6040518060400160405280600a81526020017f556e69737761702056320000000000000000000000000000000000000000000081525081565b6008546dffffffffffffffffffffffffffff808216926e0100000000000000000000000000008304909116917c0100000000000000000000000000000000000000000000000000000000900463ffffffff1690565b6000610df233848461259c565b5060015b92915050565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610ee85773ffffffffffffffffffffffffffffffffffffffff84166000908152600260209081526040808320338452909152902054610eb6908363ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff851660009081526002602090815260408083203384529091529020555b610ef384848461260b565b5060019392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60035481565b60055473ffffffffffffffffffffffffffffffffffffffff163314610fb257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560078054929093169116179055565b60095481565b600a5481565b6000600c5460011461108457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611094610d90565b50600654604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905193955091935060009273ffffffffffffffffffffffffffffffffffffffff909116916370a08231916024808301926020929190829003018186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d602081101561113857600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905192935060009273ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b1580156111b157600080fd5b505afa1580156111c5573d6000803e3d6000fd5b505050506040513d60208110156111db57600080fd5b505190506000611201836dffffffffffffffffffffffffffff871663ffffffff61226e16565b90506000611225836dffffffffffffffffffffffffffff871663ffffffff61226e16565b9050600061123387876126ec565b600054909150806112705761125c6103e8610bfd611257878763ffffffff6121e816565b612878565b985061126b60006103e86128ca565b6112cd565b6112ca6dffffffffffffffffffffffffffff8916611294868463ffffffff6121e816565b8161129b57fe5b046dffffffffffffffffffffffffffff89166112bd868563ffffffff6121e816565b816112c457fe5b0461297a565b98505b60008911611326576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612bc16028913960400191505060405180910390fd5b6113308a8a6128ca565b61133c86868a8a6122e0565b811561137e5760085461137a906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b6040805185815260208101859052815133927f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f928290030190a250506001600c5550949695505050505050565b60016020526000908152604090205481565b600b5481565b60046020526000908152604090205481565b600080600c5460011461146957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611479610d90565b50600654600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905194965092945073ffffffffffffffffffffffffffffffffffffffff9182169391169160009184916370a08231916024808301926020929190829003018186803b1580156114fb57600080fd5b505afa15801561150f573d6000803e3d6000fd5b505050506040513d602081101561152557600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b15801561159957600080fd5b505afa1580156115ad573d6000803e3d6000fd5b505050506040513d60208110156115c357600080fd5b5051306000908152600160205260408120549192506115e288886126ec565b600054909150806115f9848763ffffffff6121e816565b8161160057fe5b049a5080611614848663ffffffff6121e816565b8161161b57fe5b04995060008b11801561162e575060008a115b611683576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612b996028913960400191505060405180910390fd5b61168d3084612992565b611698878d8d611fdb565b6116a3868d8c611fdb565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8916916370a08231916024808301926020929190829003018186803b15801561170f57600080fd5b505afa158015611723573d6000803e3d6000fd5b505050506040513d602081101561173957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191965073ffffffffffffffffffffffffffffffffffffffff8816916370a0823191602480820192602092909190829003018186803b1580156117ab57600080fd5b505afa1580156117bf573d6000803e3d6000fd5b505050506040513d60208110156117d557600080fd5b505193506117e585858b8b6122e0565b811561182757600854611823906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b604080518c8152602081018c9052815173ffffffffffffffffffffffffffffffffffffffff8f169233927fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496929081900390910190a35050505050505050506001600c81905550915091565b6040518060400160405280600681526020017f554e492d5632000000000000000000000000000000000000000000000000000081525081565b6000610df233848461260b565b6103e881565b600c5460011461194f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654600754600854604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9485169490931692611a2b9285928792611a26926dffffffffffffffffffffffffffff169185916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b505afa158015611a02573d6000803e3d6000fd5b505050506040513d6020811015611a1857600080fd5b50519063ffffffff61226e16565b611fdb565b600854604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611aca9284928792611a26926e01000000000000000000000000000090046dffffffffffffffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff8616916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b50506001600c5550565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b60075473ffffffffffffffffffffffffffffffffffffffff1681565b42841015611b7b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f556e697377617056323a20455850495245440000000000000000000000000000604482015290519081900360640190fd5b60035473ffffffffffffffffffffffffffffffffffffffff80891660008181526004602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e0850182528051908301207f19010000000000000000000000000000000000000000000000000000000000006101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e2808201937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa158015611cdc573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590611d5757508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611dc257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f556e697377617056323a20494e56414c49445f5349474e415455524500000000604482015290519081900360640190fd5b611dcd89898961259c565b505050505050505050565b600260209081526000928352604080842090915290825290205481565b600c54600114611e6657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611fd49273ffffffffffffffffffffffffffffffffffffffff16916370a08231916024808301926020929190829003018186803b158015611edd57600080fd5b505afa158015611ef1573d6000803e3d6000fd5b505050506040513d6020811015611f0757600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b158015611f7a57600080fd5b505afa158015611f8e573d6000803e3d6000fd5b505050506040513d6020811015611fa457600080fd5b50516008546dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004166122e0565b6001600c55565b604080518082018252601981527f7472616e7366657228616464726573732c75696e743235362900000000000000602091820152815173ffffffffffffffffffffffffffffffffffffffff85811660248301526044808301869052845180840390910181526064909201845291810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251815160009460609489169392918291908083835b602083106120e157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016120a4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612143576040519150601f19603f3d011682016040523d82523d6000602084013e612148565b606091505b5091509150818015612176575080511580612176575080806020019051602081101561217357600080fd5b50515b6121e157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f556e697377617056323a205452414e534645525f4641494c4544000000000000604482015290519081900360640190fd5b5050505050565b60008115806122035750508082028282828161220057fe5b04145b610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b80820382811115610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b6dffffffffffffffffffffffffffff841180159061230c57506dffffffffffffffffffffffffffff8311155b61237757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f556e697377617056323a204f564552464c4f5700000000000000000000000000604482015290519081900360640190fd5b60085463ffffffff428116917c0100000000000000000000000000000000000000000000000000000000900481168203908116158015906123c757506dffffffffffffffffffffffffffff841615155b80156123e257506dffffffffffffffffffffffffffff831615155b15612492578063ffffffff16612425856123fb86612a57565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169063ffffffff612a7b16565b600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092169290920201905563ffffffff8116612465846123fb87612a57565b600a80547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216929092020190555b600880547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000166dffffffffffffffffffffffffffff888116919091177fffffffff0000000000000000000000000000ffffffffffffffffffffffffffff166e0100000000000000000000000000008883168102919091177bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff871602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260016020526040902054612641908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600160205260408082209390935590841681522054612683908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b15801561275757600080fd5b505afa15801561276b573d6000803e3d6000fd5b505050506040513d602081101561278157600080fd5b5051600b5473ffffffffffffffffffffffffffffffffffffffff821615801594509192509061286457801561285f5760006127d86112576dffffffffffffffffffffffffffff88811690881663ffffffff6121e816565b905060006127e583612878565b90508082111561285c576000612813612804848463ffffffff61226e16565b6000549063ffffffff6121e816565b905060006128388361282c86600563ffffffff6121e816565b9063ffffffff612abc16565b9050600081838161284557fe5b04905080156128585761285887826128ca565b5050505b50505b612870565b8015612870576000600b555b505092915050565b600060038211156128bb575080600160028204015b818110156128b5578091506002818285816128a457fe5b0401816128ad57fe5b04905061288d565b506128c5565b81156128c5575060015b919050565b6000546128dd908263ffffffff612abc16565b600090815573ffffffffffffffffffffffffffffffffffffffff8316815260016020526040902054612915908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000818310612989578161298b565b825b9392505050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160205260409020546129c8908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081209190915554612a02908263ffffffff61226e16565b600090815560408051838152905173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a35050565b6dffffffffffffffffffffffffffff166e0100000000000000000000000000000290565b60006dffffffffffffffffffffffffffff82167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841681612ab457fe5b049392505050565b80820182811015610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fdfe556e697377617056323a20494e53554646494349454e545f4f55545055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f494e5055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f4c4951554944495459556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4255524e4544556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4d494e544544a265627a7a72315820e6365409f1a8e7136831349254d643277a3da9a5c8ba99691d9e72cadc91ae0a64736f6c63430005100032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429a265627a7a72315820a83caa7069026b94b490745dac4e1764f1c455e5cdc69a6d0a6a888bcd6f08ee64736f6c63430005100032'; + return hex'608060405234801561001057600080fd5b506040516136863803806136868339818101604052602081101561003357600080fd5b5051600180546001600160a01b0319166001600160a01b03909216919091179055613623806100636000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a2e74af61161005b578063a2e74af6146100fd578063c9c6539614610132578063e6a439051461016d578063f46901ed146101a857610088565b8063017e7e581461008d578063094b7415146100be5780631e3dd18b146100c6578063574f2ba3146100e3575b600080fd5b6100956101db565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6100956101f7565b610095600480360360208110156100dc57600080fd5b5035610213565b6100eb610247565b60408051918252519081900360200190f35b6101306004803603602081101561011357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661024d565b005b6100956004803603604081101561014857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661031a565b6100956004803603604081101561018357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661076d565b610130600480360360208110156101be57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166107a0565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6003818154811061022057fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60035490565b60015473ffffffffffffffffffffffffffffffffffffffff1633146102d357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156103b757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f556e697377617056323a204944454e544943414c5f4144445245535345530000604482015290519081900360640190fd5b6000808373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16106103f45783856103f7565b84845b909250905073ffffffffffffffffffffffffffffffffffffffff821661047e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f556e697377617056323a205a45524f5f41444452455353000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526002602090815260408083208585168452909152902054161561051f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f556e697377617056323a20504149525f45584953545300000000000000000000604482015290519081900360640190fd5b6060604051806020016105319061086d565b6020820181038252601f19601f82011660405250905060008383604051602001808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140192505050604051602081830303815290604052805190602001209050808251602084016000f5604080517f485cc95500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152868116602483015291519297509087169163485cc9559160448082019260009290919082900301818387803b15801561065e57600080fd5b505af1158015610672573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff84811660008181526002602081815260408084208987168086529083528185208054978d167fffffffffffffffffffffffff000000000000000000000000000000000000000098891681179091559383528185208686528352818520805488168517905560038054600181018255958190527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b90950180549097168417909655925483519283529082015281517f0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9929181900390910190a35050505092915050565b600260209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16331461082657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b612d748061087b8339019056fe60806040526001600c5534801561001557600080fd5b506040514690806052612d228239604080519182900360520182208282018252600a8352692ab734b9bbb0b8102b1960b11b6020938401528151808301835260018152603160f81b908401528151808401919091527fbfcc8ef98ffbf7b6c3fec7bf5185b566b9863e35a9d83acd49ad6824b5969738818301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101949094523060a0808601919091528151808603909101815260c09094019052825192019190912060035550600580546001600160a01b03191633179055612c1d806101056000396000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80636a627842116100f9578063ba9a7a5611610097578063d21220a711610071578063d21220a7146105da578063d505accf146105e2578063dd62ed3e14610640578063fff6cae91461067b576101b9565b8063ba9a7a5614610597578063bc25cf771461059f578063c45a0155146105d2576101b9565b80637ecebe00116100d35780637ecebe00146104d757806389afcb441461050a57806395d89b4114610556578063a9059cbb1461055e576101b9565b80636a6278421461046957806370a082311461049c5780637464fc3d146104cf576101b9565b806323b872dd116101665780633644e515116101405780633644e51514610416578063485cc9551461041e5780635909c0d5146104595780635a3d549314610461576101b9565b806323b872dd146103ad57806330adf81f146103f0578063313ce567146103f8576101b9565b8063095ea7b311610197578063095ea7b3146103155780630dfe16811461036257806318160ddd14610393576101b9565b8063022c0d9f146101be57806306fdde03146102595780630902f1ac146102d6575b600080fd5b610257600480360360808110156101d457600080fd5b81359160208101359173ffffffffffffffffffffffffffffffffffffffff604083013516919081019060808101606082013564010000000081111561021857600080fd5b82018360208201111561022a57600080fd5b8035906020019184600183028401116401000000008311171561024c57600080fd5b509092509050610683565b005b610261610d57565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561029b578181015183820152602001610283565b50505050905090810190601f1680156102c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102de610d90565b604080516dffffffffffffffffffffffffffff948516815292909316602083015263ffffffff168183015290519081900360600190f35b61034e6004803603604081101561032b57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610de5565b604080519115158252519081900360200190f35b61036a610dfc565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61039b610e18565b60408051918252519081900360200190f35b61034e600480360360608110156103c357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610e1e565b61039b610efd565b610400610f21565b6040805160ff9092168252519081900360200190f35b61039b610f26565b6102576004803603604081101561043457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610f2c565b61039b611005565b61039b61100b565b61039b6004803603602081101561047f57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611011565b61039b600480360360208110156104b257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113cb565b61039b6113dd565b61039b600480360360208110156104ed57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113e3565b61053d6004803603602081101561052057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113f5565b6040805192835260208301919091528051918290030190f35b610261611892565b61034e6004803603604081101561057457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356118cb565b61039b6118d8565b610257600480360360208110156105b557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166118de565b61036a611ad4565b61036a611af0565b610257600480360360e08110156105f857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135611b0c565b61039b6004803603604081101561065657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516611dd8565b610257611df5565b600c546001146106f457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55841515806107075750600084115b61075c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612b2f6025913960400191505060405180910390fd5b600080610767610d90565b5091509150816dffffffffffffffffffffffffffff168710801561079a5750806dffffffffffffffffffffffffffff1686105b6107ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612b786021913960400191505060405180910390fd5b600654600754600091829173ffffffffffffffffffffffffffffffffffffffff91821691908116908916821480159061085457508073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614155b6108bf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f556e697377617056323a20494e56414c49445f544f0000000000000000000000604482015290519081900360640190fd5b8a156108d0576108d0828a8d611fdb565b89156108e1576108e1818a8c611fdb565b86156109c3578873ffffffffffffffffffffffffffffffffffffffff166310d1e85c338d8d8c8c6040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156109aa57600080fd5b505af11580156109be573d6000803e3d6000fd5b505050505b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015610a2f57600080fd5b505afa158015610a43573d6000803e3d6000fd5b505050506040513d6020811015610a5957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191955073ffffffffffffffffffffffffffffffffffffffff8316916370a0823191602480820192602092909190829003018186803b158015610acb57600080fd5b505afa158015610adf573d6000803e3d6000fd5b505050506040513d6020811015610af557600080fd5b5051925060009150506dffffffffffffffffffffffffffff85168a90038311610b1f576000610b35565b89856dffffffffffffffffffffffffffff160383035b9050600089856dffffffffffffffffffffffffffff16038311610b59576000610b6f565b89856dffffffffffffffffffffffffffff160383035b90506000821180610b805750600081115b610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180612b546024913960400191505060405180910390fd5b6000610c09610beb84600363ffffffff6121e816565b610bfd876103e863ffffffff6121e816565b9063ffffffff61226e16565b90506000610c21610beb84600363ffffffff6121e816565b9050610c59620f4240610c4d6dffffffffffffffffffffffffffff8b8116908b1663ffffffff6121e816565b9063ffffffff6121e816565b610c69838363ffffffff6121e816565b1015610cd657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f556e697377617056323a204b0000000000000000000000000000000000000000604482015290519081900360640190fd5b5050610ce4848488886122e0565b60408051838152602081018390528082018d9052606081018c9052905173ffffffffffffffffffffffffffffffffffffffff8b169133917fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229181900360800190a350506001600c55505050505050505050565b6040518060400160405280600a81526020017f556e69737761702056320000000000000000000000000000000000000000000081525081565b6008546dffffffffffffffffffffffffffff808216926e0100000000000000000000000000008304909116917c0100000000000000000000000000000000000000000000000000000000900463ffffffff1690565b6000610df233848461259c565b5060015b92915050565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610ee85773ffffffffffffffffffffffffffffffffffffffff84166000908152600260209081526040808320338452909152902054610eb6908363ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff851660009081526002602090815260408083203384529091529020555b610ef384848461260b565b5060019392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60035481565b60055473ffffffffffffffffffffffffffffffffffffffff163314610fb257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560078054929093169116179055565b60095481565b600a5481565b6000600c5460011461108457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611094610d90565b50600654604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905193955091935060009273ffffffffffffffffffffffffffffffffffffffff909116916370a08231916024808301926020929190829003018186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d602081101561113857600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905192935060009273ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b1580156111b157600080fd5b505afa1580156111c5573d6000803e3d6000fd5b505050506040513d60208110156111db57600080fd5b505190506000611201836dffffffffffffffffffffffffffff871663ffffffff61226e16565b90506000611225836dffffffffffffffffffffffffffff871663ffffffff61226e16565b9050600061123387876126ec565b600054909150806112705761125c6103e8610bfd611257878763ffffffff6121e816565b612878565b985061126b60006103e86128ca565b6112cd565b6112ca6dffffffffffffffffffffffffffff8916611294868463ffffffff6121e816565b8161129b57fe5b046dffffffffffffffffffffffffffff89166112bd868563ffffffff6121e816565b816112c457fe5b0461297a565b98505b60008911611326576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612bc16028913960400191505060405180910390fd5b6113308a8a6128ca565b61133c86868a8a6122e0565b811561137e5760085461137a906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b6040805185815260208101859052815133927f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f928290030190a250506001600c5550949695505050505050565b60016020526000908152604090205481565b600b5481565b60046020526000908152604090205481565b600080600c5460011461146957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611479610d90565b50600654600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905194965092945073ffffffffffffffffffffffffffffffffffffffff9182169391169160009184916370a08231916024808301926020929190829003018186803b1580156114fb57600080fd5b505afa15801561150f573d6000803e3d6000fd5b505050506040513d602081101561152557600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b15801561159957600080fd5b505afa1580156115ad573d6000803e3d6000fd5b505050506040513d60208110156115c357600080fd5b5051306000908152600160205260408120549192506115e288886126ec565b600054909150806115f9848763ffffffff6121e816565b8161160057fe5b049a5080611614848663ffffffff6121e816565b8161161b57fe5b04995060008b11801561162e575060008a115b611683576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612b996028913960400191505060405180910390fd5b61168d3084612992565b611698878d8d611fdb565b6116a3868d8c611fdb565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8916916370a08231916024808301926020929190829003018186803b15801561170f57600080fd5b505afa158015611723573d6000803e3d6000fd5b505050506040513d602081101561173957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191965073ffffffffffffffffffffffffffffffffffffffff8816916370a0823191602480820192602092909190829003018186803b1580156117ab57600080fd5b505afa1580156117bf573d6000803e3d6000fd5b505050506040513d60208110156117d557600080fd5b505193506117e585858b8b6122e0565b811561182757600854611823906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b604080518c8152602081018c9052815173ffffffffffffffffffffffffffffffffffffffff8f169233927fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496929081900390910190a35050505050505050506001600c81905550915091565b6040518060400160405280600681526020017f554e492d5632000000000000000000000000000000000000000000000000000081525081565b6000610df233848461260b565b6103e881565b600c5460011461194f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654600754600854604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9485169490931692611a2b9285928792611a26926dffffffffffffffffffffffffffff169185916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b505afa158015611a02573d6000803e3d6000fd5b505050506040513d6020811015611a1857600080fd5b50519063ffffffff61226e16565b611fdb565b600854604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611aca9284928792611a26926e01000000000000000000000000000090046dffffffffffffffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff8616916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b50506001600c5550565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b60075473ffffffffffffffffffffffffffffffffffffffff1681565b42841015611b7b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f556e697377617056323a20455850495245440000000000000000000000000000604482015290519081900360640190fd5b60035473ffffffffffffffffffffffffffffffffffffffff80891660008181526004602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e0850182528051908301207f19010000000000000000000000000000000000000000000000000000000000006101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e2808201937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa158015611cdc573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590611d5757508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611dc257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f556e697377617056323a20494e56414c49445f5349474e415455524500000000604482015290519081900360640190fd5b611dcd89898961259c565b505050505050505050565b600260209081526000928352604080842090915290825290205481565b600c54600114611e6657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611fd49273ffffffffffffffffffffffffffffffffffffffff16916370a08231916024808301926020929190829003018186803b158015611edd57600080fd5b505afa158015611ef1573d6000803e3d6000fd5b505050506040513d6020811015611f0757600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b158015611f7a57600080fd5b505afa158015611f8e573d6000803e3d6000fd5b505050506040513d6020811015611fa457600080fd5b50516008546dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004166122e0565b6001600c55565b604080518082018252601981527f7472616e7366657228616464726573732c75696e743235362900000000000000602091820152815173ffffffffffffffffffffffffffffffffffffffff85811660248301526044808301869052845180840390910181526064909201845291810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251815160009460609489169392918291908083835b602083106120e157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016120a4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612143576040519150601f19603f3d011682016040523d82523d6000602084013e612148565b606091505b5091509150818015612176575080511580612176575080806020019051602081101561217357600080fd5b50515b6121e157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f556e697377617056323a205452414e534645525f4641494c4544000000000000604482015290519081900360640190fd5b5050505050565b60008115806122035750508082028282828161220057fe5b04145b610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b80820382811115610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b6dffffffffffffffffffffffffffff841180159061230c57506dffffffffffffffffffffffffffff8311155b61237757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f556e697377617056323a204f564552464c4f5700000000000000000000000000604482015290519081900360640190fd5b60085463ffffffff428116917c0100000000000000000000000000000000000000000000000000000000900481168203908116158015906123c757506dffffffffffffffffffffffffffff841615155b80156123e257506dffffffffffffffffffffffffffff831615155b15612492578063ffffffff16612425856123fb86612a57565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169063ffffffff612a7b16565b600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092169290920201905563ffffffff8116612465846123fb87612a57565b600a80547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216929092020190555b600880547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000166dffffffffffffffffffffffffffff888116919091177fffffffff0000000000000000000000000000ffffffffffffffffffffffffffff166e0100000000000000000000000000008883168102919091177bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff871602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260016020526040902054612641908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600160205260408082209390935590841681522054612683908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b15801561275757600080fd5b505afa15801561276b573d6000803e3d6000fd5b505050506040513d602081101561278157600080fd5b5051600b5473ffffffffffffffffffffffffffffffffffffffff821615801594509192509061286457801561285f5760006127d86112576dffffffffffffffffffffffffffff88811690881663ffffffff6121e816565b905060006127e583612878565b90508082111561285c576000612813612804848463ffffffff61226e16565b6000549063ffffffff6121e816565b905060006128388361282c86600563ffffffff6121e816565b9063ffffffff612abc16565b9050600081838161284557fe5b04905080156128585761285887826128ca565b5050505b50505b612870565b8015612870576000600b555b505092915050565b600060038211156128bb575080600160028204015b818110156128b5578091506002818285816128a457fe5b0401816128ad57fe5b04905061288d565b506128c5565b81156128c5575060015b919050565b6000546128dd908263ffffffff612abc16565b600090815573ffffffffffffffffffffffffffffffffffffffff8316815260016020526040902054612915908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000818310612989578161298b565b825b9392505050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160205260409020546129c8908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081209190915554612a02908263ffffffff61226e16565b600090815560408051838152905173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a35050565b6dffffffffffffffffffffffffffff166e0100000000000000000000000000000290565b60006dffffffffffffffffffffffffffff82167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841681612ab457fe5b049392505050565b80820182811015610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fdfe556e697377617056323a20494e53554646494349454e545f4f55545055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f494e5055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f4c4951554944495459556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4255524e4544556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4d494e544544a265627a7a7231582082458131bf7952eabe55ef947cf3dde839e98cdf09064e3223dbabb61b49b1c764736f6c63430005100032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429a265627a7a723158209a2a6bd4a66cfdacd8e982b3f271382a062dc14887b960f2c0d1a47e6e170ed364736f6c63430005100032'; } } diff --git a/src/briefcase/deployers/v4-hooks-public/PermissionedHooksDeployer.sol b/src/briefcase/deployers/v4-hooks-public/PermissionedHooksDeployer.sol new file mode 100644 index 00000000..58de8661 --- /dev/null +++ b/src/briefcase/deployers/v4-hooks-public/PermissionedHooksDeployer.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import {DeployerHelper} from '../DeployerHelper.sol'; + +library PermissionedHooksDeployer { + /// @dev `salt` must be pre-mined off-chain so the resulting hook address encodes the + /// permission-flag mask (BEFORE_INITIALIZE | BEFORE_ADD_LIQUIDITY | BEFORE_SWAP). + /// Callers should assert `uint160(hook) & Hooks.ALL_HOOK_MASK == 0x2880` post-deploy. + function deploy(address poolManager, address permissionsAdapterFactory, bytes32 salt) + internal + returns (address hook) + { + bytes memory args = abi.encode(poolManager, permissionsAdapterFactory); + bytes memory initcode_ = abi.encodePacked(initcode(), args); + hook = DeployerHelper.create2(initcode_, salt); + } + + /** + * @dev autogenerated - run `./script/util/create_briefcase.sh` to generate current initcode + * + * @notice This initcode is generated from the following contract: + * - Source Contract: src/pkgs/v4-hooks-public/src/permissioned-pools/PermissionedHooks.sol + * - solc: 0.8.26 + * - optimizer_runs: 44444444 + * - via_ir: false + * - evm_version: cancun + */ + function initcode() internal pure returns (bytes memory) { + return hex'60c060405234801561000f575f80fd5b5060405161172b38038061172b83398101604081905261002e91610253565b6001600160a01b0382166080528161004530610058565b506001600160a01b031660a0525061028b565b6100d7816100d2604080516101c0810182525f60208201819052606082018190526080820181905260a0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152600180825260c082018190529181019190915290565b6100da565b50565b80511515612000831615151415806100fe5750602081015115156110008316151514155b806101155750604081015115156108008316151514155b8061012c5750606081015115156104008316151514155b806101435750608081015115156102008316151514155b8061015a575060a081015115156101008316151514155b80610170575060c0810151151560808316151514155b80610186575060e0810151151560408316151514155b8061019d5750610100810151151560208316151514155b806101b45750610120810151151560108316151514155b806101cb5750610140810151151560088316151514155b806101e25750610160810151151560048316151514155b806101f95750610180810151151560028316151514155b8061021057506101a0810151151560018316151514155b1561022657610226630732d7b560e51b8361022a565b5050565b815f526001600160a01b03811660045260245ffd5b6001600160a01b03811681146100d7575f80fd5b5f8060408385031215610264575f80fd5b825161026f8161023f565b60208401519092506102808161023f565b809150509250929050565b60805160a0516114326102f95f395f81816101f301528181610860015281816109660152610bae01525f818161031901528181610367015281816103f00152818161046f015281816104fe0152818161058d0152818161060a01528181610697015261072001526114325ff3fe608060405234801561000f575f80fd5b50600436106100da575f3560e01c8063ab769d3711610088578063c4e833ce11610063578063c4e833ce1461029b578063dc4c90d314610314578063dc98354e1461033b578063e1b4af6914610288575f80fd5b8063ab769d37146101ee578063b47b2fb11461023a578063b6a8b0fa14610288575f80fd5b80636c2bbe7e116100b85780636c2bbe7e146101905780636fe7e6eb146101db5780639f063efc14610190575f80fd5b806321d0ee70146100de578063259982e514610127578063575e24b41461013a575b5f80fd5b6100f16100ec366004610fbb565b61034e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b6100f1610135366004610fbb565b6103d7565b61014d610148366004611042565b610454565b604080517fffffffff000000000000000000000000000000000000000000000000000000009094168452602084019290925262ffffff169082015260600161011e565b6101a361019e36600461109c565b6104e4565b604080517fffffffff00000000000000000000000000000000000000000000000000000000909316835260208301919091520161011e565b6100f16101e9366004611127565b610574565b6102157f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011e565b61024d610248366004611186565b6105f0565b604080517fffffffff000000000000000000000000000000000000000000000000000000009093168352600f9190910b60208301520161011e565b6100f1610296366004611207565b61067e565b604080516101c0810182525f60208201819052606082018190526080820181905260a0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152600180825260c0820181905281830152905161011e9190611261565b6102157f000000000000000000000000000000000000000000000000000000000000000081565b6100f1610349366004611382565b610707565b5f3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146103be576040517fae18210a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103cb868686868661078a565b90505b95945050505050565b5f3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610447576040517fae18210a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103cb86868686866107bd565b5f80803373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146104c6576040517fae18210a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104d388888888886107e9565b925092509250955095509592505050565b5f803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610555576040517fae18210a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61056489898989898989610827565b9150915097509795505050505050565b5f3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146105e4576040517fae18210a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103ce8585858561078a565b5f803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610661576040517fae18210a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61066f888888888888610827565b91509150965096945050505050565b5f3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106ee576040517fae18210a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106fc87878787878761078a565b979650505050505050565b5f3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610777576040517fae18210a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61078284848461085b565b949350505050565b5f6040517f0a85dc2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f259982e5000000000000000000000000000000000000000000000000000000006103ce868683610ac6565b7f575e24b4000000000000000000000000000000000000000000000000000000005f80610817888885610ac6565b505f905080955095509592505050565b5f806040517f0a85dc2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166325efface6108a760208801886113c9565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa15801561090e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061093291906113eb565b73ffffffffffffffffffffffffffffffffffffffff16141590505f8073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166325efface8760200160208101906109b391906113c9565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa158015610a1a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a3e91906113eb565b73ffffffffffffffffffffffffffffffffffffffff161415905081158015610a64575080155b15610a9b576040517fcf43195200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b507fdc98354e0000000000000000000000000000000000000000000000000000000095945050505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663d737d0c76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b10573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3491906113eb565b9050610b4e610b4660208501856113c9565b828685610b67565b610b61610b4660408501602086016113c9565b50505050565b6040517f25efface00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301525f917f0000000000000000000000000000000000000000000000000000000000000000909116906325efface90602401602060405180830381865afa158015610bf5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c1991906113eb565b905073ffffffffffffffffffffffffffffffffffffffff8116610c3c5750610b61565b5f7fa8a1db4c000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000841601610d3557600160f01b90508573ffffffffffffffffffffffffffffffffffffffff1663aeb555696040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cd6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cfa9190611406565b610d30576040517f888f378500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610da0565b7fda667d1b000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000841601610da057507e020000000000000000000000000000000000000000000000000000000000005b6040517ff493cec300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301527fffff0000000000000000000000000000000000000000000000000000000000008316602483015287169063f493cec390604401602060405180830381865afa158015610e32573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e569190611406565b1580610eed57506040517fe73bce9500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015287169063e73bce9590602401602060405180830381865afa158015610ec7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eeb9190611406565b155b15610f24576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f4d575f80fd5b50565b5f60a08284031215610f60575f80fd5b50919050565b5f60808284031215610f60575f80fd5b5f8083601f840112610f86575f80fd5b50813567ffffffffffffffff811115610f9d575f80fd5b602083019150836020828501011115610fb4575f80fd5b9250929050565b5f805f805f6101608688031215610fd0575f80fd5b8535610fdb81610f2c565b9450610fea8760208801610f50565b9350610ff98760c08801610f66565b925061014086013567ffffffffffffffff811115611015575f80fd5b61102188828901610f76565b969995985093965092949392505050565b5f60608284031215610f60575f80fd5b5f805f805f6101408688031215611057575f80fd5b853561106281610f2c565b94506110718760208801610f50565b93506110808760c08801611032565b925061012086013567ffffffffffffffff811115611015575f80fd5b5f805f805f805f6101a0888a0312156110b3575f80fd5b87356110be81610f2c565b96506110cd8960208a01610f50565b95506110dc8960c08a01610f66565b94506101408801359350610160880135925061018088013567ffffffffffffffff811115611108575f80fd5b6111148a828b01610f76565b989b979a50959850939692959293505050565b5f805f80610100858703121561113b575f80fd5b843561114681610f2c565b93506111558660208701610f50565b925060c085013561116581610f2c565b915060e0850135600281900b811461117b575f80fd5b939692955090935050565b5f805f805f80610160878903121561119c575f80fd5b86356111a781610f2c565b95506111b68860208901610f50565b94506111c58860c08901611032565b9350610120870135925061014087013567ffffffffffffffff8111156111e9575f80fd5b6111f589828a01610f76565b979a9699509497509295939492505050565b5f805f805f80610120878903121561121d575f80fd5b863561122881610f2c565b95506112378860208901610f50565b945060c0870135935060e0870135925061010087013567ffffffffffffffff8111156111e9575f80fd5b8151151581526101c08101602083015161127f602084018215159052565b506040830151611293604084018215159052565b5060608301516112a7606084018215159052565b5060808301516112bb608084018215159052565b5060a08301516112cf60a084018215159052565b5060c08301516112e360c084018215159052565b5060e08301516112f760e084018215159052565b5061010083015161130d61010084018215159052565b5061012083015161132361012084018215159052565b5061014083015161133961014084018215159052565b5061016083015161134f61016084018215159052565b5061018083015161136561018084018215159052565b506101a083015161137b6101a084018215159052565b5092915050565b5f805f60e08486031215611394575f80fd5b833561139f81610f2c565b92506113ae8560208601610f50565b915060c08401356113be81610f2c565b809150509250925092565b5f602082840312156113d9575f80fd5b81356113e481610f2c565b9392505050565b5f602082840312156113fb575f80fd5b81516113e481610f2c565b5f60208284031215611416575f80fd5b815180151581146113e4575f80fdfea164736f6c634300081a000a'; + } +} diff --git a/src/briefcase/deployers/v4-periphery/PermissionedPositionManagerDeployer.sol b/src/briefcase/deployers/v4-periphery/PermissionedPositionManagerDeployer.sol new file mode 100644 index 00000000..aa3f941b --- /dev/null +++ b/src/briefcase/deployers/v4-periphery/PermissionedPositionManagerDeployer.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import {DeployerHelper} from '../DeployerHelper.sol'; + +library PermissionedPositionManagerDeployer { + function deploy( + address poolManager, + address permit2, + uint256 unsubscribeGasLimit, + address positionDescriptor, + address weth, + address permissionsAdapterFactory + ) internal returns (address manager) { + bytes memory args = abi.encode( + poolManager, permit2, unsubscribeGasLimit, positionDescriptor, weth, permissionsAdapterFactory + ); + bytes memory initcode_ = abi.encodePacked(initcode(), args); + manager = DeployerHelper.create2(initcode_); + } + + /** + * @dev autogenerated - run `./script/util/create_briefcase.sh` to generate current initcode + * + * @notice This initcode is generated from the following contract: + * - Source Contract: src/pkgs/v4-periphery/src/hooks/permissionedPools/PermissionedPositionManager.sol + * - solc: 0.8.26 + * - optimizer_runs: 500 + * - via_ir: true + * - evm_version: cancun + */ + function initcode() internal pure returns (bytes memory) { + return hex'6101a080604052346106055760c08161615980380380916100208285610609565b833981010312610605578051906001600160a01b0382168203610605576020810151906001600160a01b0382168203610605576040810151606082015192906001600160a01b0384168403610605576080830151926001600160a01b03841684036106055760a00151946001600160a01b0386168603610605576040516100a8604082610609565b6018815260208101907f556e697377617020763420506f736974696f6e73204e4654000000000000000082526040516100e2604082610609565b600b81526a554e492d56342d504f534d60a81b602082015281516001600160401b03811161054b576101145f5461062c565b601f81116105cb575b50806020601f821160011461056a575f9161055f575b508160011b915f199060031b1c1916175f555b8051906001600160401b03821161054b57819061016460015461062c565b601f8111610505575b50602090601f831160011461049f575f92610494575b50508160011b915f199060031b1c1916176001555b5190208060c0524660a05260405160208101917f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86683526040820152466060820152306080820152608081526101ee60a082610609565b51902060805260e0526101005261012052610140526001600855610160526101805261021a5f5461062c565b601f811161044c575b50604b5f90815580527f556e6973776170207634205065726d697373696f6e656420506f736974696f6e5f8051602061611983398151915255641cc813919560da1b7f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564556001546102939061062c565b601f8111610421575b7f554e492d56342d5045524d2d504f534d00000000000000000000000000000020600155604051615a9e908161067b823960805181611f02015260a05181611edc015260c05181611f51015260e0518181816109da01528181610b4601528181610ed9015281816114530152818161178d015281816119e801528181611aa001528181611cc201528181612527015281816125e2015281816129c70152818161314401528181613361015281816139f001528181613c1701528181613caf01528181613d2701528181613e03015281816140a1015281816142d30152818161472a015281816148d0015281816154470152818161555001526155c70152610100518181816110760152612f030152610120518181816103cd015281816108f901528181610a7301528181614b0201526155810152610140518181816110b801528181612599015281816139430152818161399f01528181613ae50152613b5501526101605181818161120a015261189f0152610180518181816116470152612ff30152f35b60015f5261044690601f0160051c5f8051602061613983398151915290810190610664565b5f61029c565b5f805261048e90601f0160051c5f80516020616119833981519152017f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e565610664565b5f610223565b015190505f80610183565b60015f9081528281209350601f198516905b8181106104ed57509084600195949392106104d5575b505050811b01600155610198565b01515f1960f88460031b161c191690555f80806104c7565b929360206001819287860151815501950193016104b1565b60015f5261053b905f80516020616139833981519152601f850160051c81019160208610610541575b601f0160051c0190610664565b5f61016d565b909150819061052e565b634e487b7160e01b5f52604160045260245ffd5b90508301515f610133565b5f8080528181209250601f198416905b8181106105b35750908360019493921061059b575b5050811b015f55610146565b8501515f1960f88460031b161c191690555f8061058f565b9192602060018192868a01518155019401920161057a565b5f80526105ff905f80516020616119833981519152601f840160051c8101916020851061054157601f0160051c0190610664565b5f61011d565b5f80fd5b601f909101601f19168101906001600160401b0382119082101761054b57604052565b90600182811c9216801561065a575b602083101461064657565b634e487b7160e01b5f52602260045260245ffd5b91607f169161063b565b81811061066f575050565b5f815560010161066456fe60806040526004361015610022575b3615610018575f80fd5b61002061258f565b005b5f3560e01c80622a3e3a146102e057806301ffc9a7146102db57806305c1ee20146102d657806306fdde03146102d1578063081812fc146102cc578063095ea7b3146102c75780630f5730f1146102c257806312261ee7146102bd57806316a24131146102b85780631efeed33146102b357806323b872dd146102ae5780632b67b570146102a95780632b9261de146102a45780633644e5151461029f578063370587491461029a5780633aea60f01461029557806342842e0e146102905780634767565f1461028b5780634aa4a4fc146102865780634afe393c14610281578063502e1a161461027c5780635a9d7a68146102775780636352211e1461027257806370a082311461026d57806375794a3c146102685780637ba03aad1461026357806386b6be7d1461025e57806389097a6a1461025957806391dd73461461025457806395d89b411461024f578063a22cb4651461024a578063ab769d3714610245578063ac9650d814610240578063ad0b27fb1461023b578063b5cdc48414610236578063b88d4fde14610231578063c87b56dd1461022c578063cd19ec6d14610227578063d737d0c714610222578063dc4c90d31461021d578063dd46508f14610218578063e985e9c514610213578063f70204051461020e5763f77de3fc0361000e57611b8f565b611b5a565b611b00565b611a0c565b6119c9565b611997565b611931565b611863565b61180b565b6117cd565b611779565b6116d4565b611628565b6115f5565b611540565b611417565b6113ed565b611369565b6112fa565b6112dd565b61125d565b61122e565b6111eb565b6111a1565b61110d565b611099565b61105f565b61103f565b610f62565b610cc9565b610ca7565b610b03565b610a20565b6109c4565b610950565b61091d565b6108da565b6107e4565b610757565b610724565b610644565b6105cb565b61054e565b61036d565b6001600160a01b038116036102f657565b5f80fd5b3590610305826102e5565b565b9181601f840112156102f65782359167ffffffffffffffff83116102f657602083818601950101116102f657565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90602061036a928181520190610335565b90565b60603660031901126102f657600435610385816102e5565b6024359067ffffffffffffffff82116102f6578136039160606003198401126102f65760443567ffffffffffffffff81116102f6576103c8903690600401610307565b6060947f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031693909290843b156102f6576001600160a01b0360405196632a2d80d160e01b88521660048701526060602487015260c4860193816004013590602219018112156102f65781016024600482013591019467ffffffffffffffff82116102f6578160071b360386136102f65760606064890152819052869460e48601949392915f5b818110610514575050506104c55f9694869488946044856104ad61049d60248b99016102fa565b6001600160a01b03166084890152565b013560a4860152848303600319016044860152611e29565b03925af190816104fa575b506104f157506104ed6104e1611e93565b60405191829182610359565b0390f35b6104ed906104e1565b806105085f61050e93610622565b806105e3565b5f6104d0565b919650919293946080808261052b6001948b611dca565b019701910191889695949392610476565b6001600160e01b03198116036102f657565b346102f65760203660031901126102f657602060043561056d8161053c565b63ffffffff60e01b166301ffc9a760e01b81149081156105ab575b811561059a575b506040519015158152f35b635b5e139f60e01b1490505f61058f565b6380ac58cd60e01b81149150610588565b908160209103126102f6573590565b60203660031901126102f6576100206004353361260a565b5f9103126102f657565b634e487b7160e01b5f52604160045260245ffd5b60a0810190811067ffffffffffffffff82111761061d57604052565b6105ed565b90601f8019910116810190811067ffffffffffffffff82111761061d57604052565b346102f6575f3660031901126102f6576040515f80548060011c906001811690811561071a575b6020831082146107065782855260208501919081156106ed575060011461069d575b6104ed846104e181860382610622565b5f8080529250907f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b8184106106d9575050016104e18261068d565b8054848401526020909301926001016106c6565b60ff191682525090151560051b0190506104e18261068d565b634e487b7160e01b5f52602260045260245ffd5b91607f169161066b565b346102f65760203660031901126102f6576004355f52600460205260206001600160a01b0360405f205416604051908152f35b346102f65760403660031901126102f657600435610774816102e5565b602435805f5260026020526001600160a01b0360405f2054169182331415806107b3575b6107a55761002092612651565b6282b42960e81b5f5260045ffd5b50825f52600560205260ff6107dc3360405f20906001600160a01b03165f5260205260405f2090565b541615610798565b60a03660031901126102f6576004356107fc816102e5565b602435604435916064359260843567ffffffffffffffff81116102f657610827903690600401610307565b948242116108cb576108c0856108c693610020986108ba885f8099868252600260205281896001600160a01b036040832054169c8d9981604051977f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad89526001600160a01b0360208a01911681526040890192835260608901948552608089019687528160a08a209952525252526126b0565b9161274a565b8261260a565b612651565b635a9165ff60e01b5f5260045ffd5b346102f6575f3660031901126102f65760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b346102f65760203660031901126102f6576004355f52600760205260206001600160a01b0360405f205416604051908152f35b346102f65760203660031901126102f657602061098760043561097281612251565b919082851c60020b9260081c60020b9161292d565b6001600160801b0360405191168152f35b60609060031901126102f6576004356109b0816102e5565b906024356109bd816102e5565b9060443590565b346102f6576109d236610998565b5050506109fe7f0000000000000000000000000000000000000000000000000000000000000000612a3f565b610a115763a24e573d60e01b5f5260045ffd5b6306a582ff60e51b5f5260045ffd5b6101003660031901126102f657600435610a39816102e5565b60c03660231901126102f65760e43567ffffffffffffffff81116102f657610a65903690600401610307565b916060926001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b156102f6576001600160a01b035f80946104c5604051978896879586946302b67b5760e41b8652166004850152610ace60248501611d5f565b6001600160a01b0360a435610ae2816102e5565b1660a485015260c43560c485015261010060e4850152610104840191611e29565b60603660031901126102f657602435600435610b1e826102e5565b60443567ffffffffffffffff81116102f657610b3e903690600401610307565b610b6a9391937f0000000000000000000000000000000000000000000000000000000000000000612a3f565b610a1157610b788333612ab9565b15610c94576001600160a01b03610ba7610b9a855f52600760205260405f2090565b546001600160a01b031690565b1680610c7157505f83815260096020526040902080546001179055610c4190610c3d90610c376001600160a01b03851696610c0988610bee895f52600760205260405f2090565b906001600160a01b03166001600160a01b0319825416179055565b610c296040519384926346abfb5960e11b60208501528960248501611ec2565b03601f198101835282610622565b83612b4e565b1590565b610c6c57507f9709492381f90bdc5938bb4e3b8e35b7e0eac8af058619e27191c5a40ce79fa95f80a3005b612b76565b6312fdec5f60e11b5f5260048490526001600160a01b031660245260445ffd5b5ffd5b6301952d1b60e31b5f523360045260245ffd5b346102f6575f3660031901126102f6576020610cc1611ed9565b604051908152f35b346102f65760203660031901126102f6576004356001600160a01b035f80516020615a728339815191525c16610f4957335f80516020615a728339815191525d610d1281612251565b5090610d2d610d2883516001600160a01b031690565b612d48565b60208301906001600160a01b03610d4e610d2884516001600160a01b031690565b91163314159081610f35575b506107a557610eb282610ecc94610e8c610d745f96612230565b91610d8b33610bee865f52600460205260405f2090565b604051601b60f81b6020820152600360f81b6021820152601960f81b6022820181905260238201526004815293610c2990610dc7602487610622565b610e7c610dd2611fae565b98604051610dec81610c2986602083019190602083019252565b610df58b61207f565b52610dff8a61207f565b50610c29610e1e610e0e611e7f565b60405192839187602084016120d5565b610e278b612091565b52610e318a612091565b5086610e5b610e4787516001600160a01b031690565b610c29866040519485938b602086016120f8565b610e648b6120a1565b52610e6e8a6120a1565b50516001600160a01b031690565b94604051958694602086016120f8565b610e95846120b1565b52610e9f836120b1565b50610c2960405193849260208401612165565b604051809381926348c8949160e01b835260048301610359565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af18015610f3057610f0e575b610020612d21565b610f29903d805f833e610f218183610622565b8101906121c0565b505f610f06565b611e49565b6001600160a01b039150163314155f610d5a565b6337affdbf60e11b5f5260045ffd5b801515036102f657565b60c03660031901126102f657600435610f7a816102e5565b602435610f86816102e5565b60443590610f9382610f58565b6064359260843560a43567ffffffffffffffff81116102f657610fba903690600401610307565b8692919242116108cb578361103a936108c0926108ba885f6100209c8189818f81604051977f6673cb397ee2a50b6b8401653d3638b4ac8b3db9c28aa6870ffceb7574ec2f7689526001600160a01b0360208a0191168152600160408a019316835260608901948552608089019687528160a08a209952525252526126b0565b612dbf565b346102f65761104d36610998565b50505063a24e573d60e01b5f5260045ffd5b346102f6575f3660031901126102f65760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346102f6575f3660031901126102f65760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b9181601f840112156102f65782359167ffffffffffffffff83116102f6576020808501948460051b0101116102f657565b60403660031901126102f65760043567ffffffffffffffff81116102f657611139903690600401610307565b60243567ffffffffffffffff81116102f6576111599036906004016110dc565b916001600160a01b035f80516020615a728339815191525c16610f495761118f93335f80516020615a728339815191525d612e24565b5f5f80516020615a728339815191525d005b346102f65760403660031901126102f6576004356111be816102e5565b6001600160a01b0360243591165f52600660205260405f20905f52602052602060405f2054604051908152f35b346102f6575f3660031901126102f65760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b346102f65760203660031901126102f657602061124c600435612230565b6001600160a01b0360405191168152f35b346102f65760203660031901126102f6576001600160a01b03600435611282816102e5565b1680156112a9575f5260036020526104ed60405f2054604051918291829190602083019252565b60405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606490fd5b346102f6575f3660031901126102f6576020600854604051908152f35b346102f65760203660031901126102f65760c0611318600435612251565b61136260405180936001600160a01b036080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b60a0820152f35b346102f65760203660031901126102f65760043566ffffffffffffff1981168091036102f6575f908152600a60209081526040918290208054600182015460029283015485516001600160a01b0393841681528383169581019590955260a082811c62ffffff169686019690965260b89190911c90920b6060840152166080820152f35b346102f65760203660031901126102f6576004355f526009602052602060405f2054604051908152f35b346102f65760203660031901126102f65760043567ffffffffffffffff81116102f657611448903690600401610307565b906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633036115315760408135189063ffffffff60408201351663ffffffe0601f8201169260608401602084013518179282019260608401359483641fffffffe08760051b16805f905b8881831061150257905060809291500101910110176114f5576060608063ffffffff6114ea961694019201612e24565b6104ed6104e1611e7f565b633b99b53d5f526004601cfd5b8294509263ffffffe0601f60808060209687969801013599848b1817998d0101350116010192018692916114ba565b63570c108560e11b5f5260045ffd5b346102f6575f3660031901126102f6576040515f6001548060011c90600181169081156115eb575b6020831082146107065782855260208501919081156106ed5750600114611599576104ed846104e181860382610622565b60015f9081529250907fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b8184106115d7575050016104e18261068d565b8054848401526020909301926001016115c4565b91607f1691611568565b346102f65760403660031901126102f657610020600435611615816102e5565b6024359061162282610f58565b33612dbf565b346102f6575f3660031901126102f65760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b9080602083519182815201916020808360051b8301019401925f915b83831061169657505050505090565b90919293946020806116b4600193601f198682030187528951610335565b97019301930191939290611687565b90602061036a92818152019061166b565b60203660031901126102f65760043567ffffffffffffffff81116102f6576117009036906004016110dc565b9061170a82612022565b915f5b81811061172257604051806104ed86826116c3565b5f8061172f838587612317565b9081604051928392833781018381520390305af461174b611e93565b9015611771579060019161175f82876120c1565b5261176a81866120c1565b500161170d565b602081519101fd5b60203660031901126102f6576004356117b17f0000000000000000000000000000000000000000000000000000000000000000612a3f565b610a11576117bf8133612ab9565b15610c945761002090612e74565b346102f65760603660031901126102f6576100206004356117ed816102e5565b6024356117f9816102e5565b6044359161180683610f58565b612359565b346102f65760803660031901126102f6576118276004356102e5565b6118326024356102e5565b60643567ffffffffffffffff81116102f657611852903690600401610307565b505063a24e573d60e01b5f5260045ffd5b346102f65760203660031901126102f6576004356040519063e9dc637560e01b825230600483015260248201525f816044816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa8015610f30575f906118de575b6104ed9060405191829182610359565b503d805f833e6118ee8183610622565b8101906020818303126102f65780519067ffffffffffffffff82116102f6570181601f820112156102f6576104ed9181602061192c9351910161218a565b6118ce565b346102f65760403660031901126102f657602060ff61198b600435611955816102e5565b6001600160a01b036024359161196a836102e5565b165f52600b845260405f20906001600160a01b03165f5260205260405f2090565b54166040519015158152f35b346102f6575f3660031901126102f65760205f80516020615a728339815191525c6001600160a01b0360405191168152f35b346102f6575f3660031901126102f65760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b60403660031901126102f65760043567ffffffffffffffff81116102f657611a38903690600401610307565b6024356001600160a01b035f80516020615a728339815191525c16610f4957335f80516020615a728339815191525d804211611aee576040516348c8949160e01b8152602060048201525f8180611a93602482018789611e29565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af18015610f3057611ad457610020612d21565b611ae7903d805f833e610f218183610622565b5080610f06565b63bfb22adf60e01b5f5260045260245ffd5b346102f65760403660031901126102f657602060ff61198b600435611b24816102e5565b6001600160a01b0360243591611b39836102e5565b165f526005845260405f20906001600160a01b03165f5260205260405f2090565b366003190160c081126102f65760a0136102f6576020611b8460a435611b7f816102e5565b61248a565b6040519060020b8152f35b346102f65760603660031901126102f657600435611bac816102e5565b60243590604435611bbc816102e5565b6001600160a01b035f80516020615a728339815191525c16610f4957611bf190335f80516020615a728339815191525d612f86565b604051600360fb1b6020820152600760f91b6021820152909290611cb5905f90611c1e8160228101610c29565b610eb2611c29611fe8565b91604051611c5c81610c2989338c602085016001600160a01b036040929594938160608401971683521660208201520152565b611c658461207f565b52611c6f8361207f565b50604051611ca281610c29898c8c602085016001600160a01b036040929594938160608401971683521660208201520152565b611cab84612091565b52610e9f83612091565b0381836001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af18015610f3057611d34575b506040519081526001600160a01b0392831692339216907f09e613475764e6bd183fff67dc621234089daf8d42da0f8b7905ac3f4a8e8de990602090a4610020612d21565b611d47903d805f833e610f218183610622565b611cef565b359065ffffffffffff821682036102f657565b6001600160a01b03602435611d73816102e5565b1681526001600160a01b03604435611d8a816102e5565b16602082015260643565ffffffffffff81168091036102f657604082015260843565ffffffffffff811681036102f65765ffffffffffff60609116910152565b65ffffffffffff611e23606080936001600160a01b038135611deb816102e5565b1686526001600160a01b036020820135611e04816102e5565b16602087015283611e1760408301611d4c565b16604087015201611d4c565b16910152565b908060209392818452848401375f828201840152601f01601f1916010190565b6040513d5f823e3d90fd5b60405190610305608083610622565b67ffffffffffffffff811161061d57601f01601f191660200190565b60405190611e8e602083610622565b5f8252565b3d15611ebd573d90611ea482611e63565b91611eb26040519384610622565b82523d5f602084013e565b606090565b60409061036a949281528160208201520191611e29565b467f000000000000000000000000000000000000000000000000000000000000000003611f24577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f0000000000000000000000000000000000000000000000000000000000000000604082015246606082015230608082015260808152611f9060a082610622565b51902090565b67ffffffffffffffff811161061d5760051b60200190565b60405160a09190611fbf8382610622565b6004815291601f1901825f5b828110611fd757505050565b806060602080938501015201611fcb565b60405160609190611ff98382610622565b6002815291601f1901825f5b82811061201157505050565b806060602080938501015201612005565b9061202c82611f96565b6120396040519182610622565b828152809261204a601f1991611f96565b01905f5b82811061205a57505050565b80606060208093850101520161204e565b634e487b7160e01b5f52603260045260245ffd5b80511561208c5760200190565b61206b565b80516001101561208c5760400190565b80516002101561208c5760600190565b80516003101561208c5760800190565b805182101561208c5760209160051b010190565b60809061036a939281525f60208201525f60408201528160608201520190610335565b909493926001600160a01b03908160e0946121558561010081019a6001600160a01b036080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b1660a08401521660c08201520152565b909161217c61036a93604084526040840190610335565b91602081840391015261166b565b92919261219682611e63565b916121a46040519384610622565b8294818452818301116102f6578281602093845f96015e010152565b6020818303126102f65780519067ffffffffffffffff82116102f657019080601f830112156102f657815161036a9260200161218a565b156121fe57565b60405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b6044820152606490fd5b5f5260026020526001600160a01b0360405f205416906103058215156121f7565b5f608060405161226081610601565b82815282602082015282604082015282606082015201525f52600960205260405f20548066ffffffffffffff19165f52600a60205260405f206123146123046002604051936122ae85610601565b6001600160a01b0381541685526122f66122ec60018301546001600160a01b038116602089015262ffffff8160a01c16604089015260b81c60020b90565b60020b6060870152565b01546001600160a01b031690565b6001600160a01b03166080830152565b91565b919081101561208c5760051b81013590601e19813603018212156102f657019081359167ffffffffffffffff83116102f65760200182360381136102f6579190565b61236281612d48565b6001600160a01b033391160361244e576001600160a01b0381165f52600b60205260ff6123a38360405f20906001600160a01b03165f5260205260405f2090565b5416151583151514612449576124447f5fac37d3a17a91ebc554d3f0c8b3562b57d5b2853d644de868ed0e0194be6686936001600160a01b0383165f52600b602052612418816124078660405f20906001600160a01b03165f5260205260405f2090565b9060ff801983541691151516179055565b6040519384938491926001600160a01b0360409295948160608601971685521660208401521515910152565b0390a1565b505050565b630ea8593560e41b5f5260045ffd5b8060020b036102f657565b908160209103126102f6575161036a8161245d565b62ffffff8116036102f657565b60405163313b65df60e11b8152906001600160a01b0390816004356124ae816102e5565b166004840152816024356124c1816102e5565b16602484015262ffffff6044356124d78161247d565b1660448401526064356124e98161245d565b60020b6064840152612510608435612500816102e5565b6001600160a01b03166084850152565b1660a482015260208160c4815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af15f918161255e575b5061036a5750627fffff90565b61258191925060203d602011612588575b6125798183610622565b810190612468565b905f612551565b503d61256f565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016331415806125d7575b6125c857565b631c5deabb60e11b5f5260045ffd5b506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163314156125c2565b906001600160a01b03600160ff83161b92165f52600660205260405f209060081c5f5260205260405f2081815418809155161561264357565b623f613760e71b5f5260045ffd5b906001600160a01b038091845f5260046020526126878160405f20906001600160a01b03166001600160a01b0319825416179055565b1691167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a4565b906126b9611ed9565b916040519261190160f01b8452600284015260228301525f604060428420938281528260208201520152565b908160209103126102f6575161036a8161053c565b91908260409103126102f6576020823592013590565b634e487b7160e01b5f52601160045260245ffd5b60ff601b9116019060ff821161273657565b612710565b906040101561208c5760400190565b90833b612894576041810361282157906020926127d3836127ab6127a561277f6127775f988801886126fa565b94909761273b565b357fff000000000000000000000000000000000000000000000000000000000000001690565b60f81c90565b935b604051948594859094939260ff6060936080840197845216602083015260408201520152565b838052039060015afa15610f30576001600160a01b035f5116908115612812576001600160a01b03160361280357565b632057875960e21b5f5260045ffd5b638baa579f60e01b5f5260045ffd5b90604082036128855760209261283e825f946127d39401906126fa565b92909261287f61287a6128747f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c90565b60ff1690565b612724565b936127ad565b634be6321b60e01b5f5260045ffd5b90926128c2936001600160a01b0360209460405196879586948593630b135d3f60e11b855260048501611ec2565b0392165afa908115610f30575f916128fe575b506001600160e01b0319166374eca2c160e11b016128ef57565b632c19a72f60e21b5f5260045ffd5b612920915060203d602011612926575b6129188183610622565b8101906126e5565b5f6128d5565b503d61290e565b92906129689260a092604051956026870152600686015260038501523084525f603a600c8601209481604082015281602082015252206139c9565b6006810180911161273657604080516020818101948552918101929092526129bb9290916129998160608101610c29565b51902060405180938192631e2eaeaf60e01b8352600483019190602083019252565b03816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa8015610f30576001600160801b03915f91612a0357501690565b612a25915060203d602011612a29575b612a1d8183610622565b810190612a30565b1690565b503d612a13565b908160209103126102f6575190565b60206001600160a01b039160246040518094819363789add5560e11b83527fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab236004840152165afa908115610f30575f91612a9a575b50151590565b612ab3915060203d602011612a2957612a1d8183610622565b5f612a94565b6001600160a01b03612aca83612230565b16916001600160a01b038216928314928315612b2d575b508215612aed57505090565b60ff9250906001600160a01b03612b06612b2893612230565b165f52600560205260405f20906001600160a01b03165f5260205260405f2090565b541690565b908093505f5260046020526001600160a01b0360405f20541614915f612ae1565b803b15612b6757815f92918360208194519301915af190565b637c402b2160e01b5f5260045ffd5b6040516390bfb86560e01b81526001600160a01b039190911660048201526346abfb5960e11b602482015260806044820152601f3d01601f191660a0810160648301523d60848301523d5f60a484013e808201600460a482015260c46340f52f4f60e11b91015260e40190fd5b6040516390bfb86560e01b81526001600160a01b0391909116600482015263a9059cbb60e01b602482015260806044820152601f3d01601f191660a0810160648301523d60848301523d5f60a484013e808201600460a482015260c4633c9fd93960e21b91015260e40190fd5b601f19601f3d01166001600160a01b03604051926390bfb86560e01b84521660048301525f6024830152608060448301528060a00160648301523d60848301523d5f60a484013e808201600460a482015260c4633d2cec6f60e21b91015260e40190fd5b6040516390bfb86560e01b81526001600160a01b0391909116600482015263b1a9116f60e01b602482015260806044820152601f3d01601f191660a0810160648301523d60848301523d5f60a484013e808201600460a482015260c463ace9448160e01b91015260e40190fd5b5f5f80516020615a728339815191525d565b908160209103126102f6575161036a816102e5565b6001600160a01b03612d5982612fc7565b1615612dba5760206001600160a01b0391600460405180948193638da5cb5b60e01b8352165afa908115610f30575f91612d91575090565b61036a915060203d602011612db3575b612dab8183610622565b810190612d33565b503d612da1565b505f90565b60206001600160a01b03807f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31931693845f5260058352612e17866124078360405f20906001600160a01b03165f5260205260405f2090565b60405195151586521693a3565b90929193828403612e65575f5b84811015612e5d57600190612e57818501612e4d83888b612317565b913560f81c6130d6565b01612e31565b509350505050565b63aaad13f760e01b5f5260045ffd5b6001600160a01b03612e91610b9a835f52600760205260405f2090565b16908115612f77575f818152600960205260409020805460ff19169055612ed3612ec3825f52600760205260405f2090565b80546001600160a01b0319169055565b813b612f00575b7fa0ebb1de82db929a9153472f37d3a66dbede4436258311ad0f52a35a2c91d1505f80a3565b5a7f0000000000000000000000000000000000000000000000000000000000000000809110612f7257823b156102f657604051632bd1774560e21b815260048101839052905f908290602490829084908890f1612f5e575b50612eda565b806105085f612f6c93610622565b5f612f58565b612fb8565b63046fcd8560e31b5f5260045ffd5b6001600160a01b03811660018103612fac5750505f80516020615a728339815191525c90565b60020361036a57503090565b6376a1e1d360e11b5f5260045ffd5b6001600160a01b03604051916312f7fd6760e11b83521660048201526020816024816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa908115610f30575f91612d91575090565b91908260a09103126102f65760405161303e81610601565b6080808294803561304e816102e5565b8452602081013561305e816102e5565b602085015260408101356130718161247d565b604085015260608101356130848161245d565b6060850152013591613095836102e5565b0152565b9190610100838203126102f6576130b09083613026565b9160a08101356130bf816102e5565b9160e060c08301356130d0816102e5565b92013590565b91906019831461325257601b83146131cf57601883146130f95761030592613716565b61310392506136fe565b6131225f80516020615a728339815191525c5b6001600160a01b031690565b6001600160a01b038316036107a5576131716131166131166001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016956001600160a01b031690565b92803b156102f657604051637a94c56560e11b81526001600160a01b03909316600484015260248301939093526044820152905f908290818381606481015b03925af18015610f30576131c15750565b806105085f61030593610622565b906131dd92508101906105bc565b6131f8610c3d825f80516020615a728339815191525c612ab9565b61322857613218613211825f52600960205260405f2090565b5460ff1690565b61321f5750565b61030590612e74565b6301952d1b60e31b5f526001600160a01b035f80516020615a728339815191525c1660045260245ffd5b906132609250810190613099565b9190926132785f80516020615a728339815191525c90565b9061328a81516001600160a01b031690565b916001600160a01b0380851690841614928315613317575b836132c3575b505050156107a5576001600160a01b03610305931690613347565b6001600160a01b03919293506131166132db91612d48565b91169081149182156132f2575b50505f80806132a8565b61330f919250610d2860206131169201516001600160a01b031690565b145f806132e8565b925061334161333060208401516001600160a01b031690565b6001600160a01b0380871691161490565b926132a2565b91613351836139e9565b80156136f8576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b156102f657604051630b0d9c0960e01b81526001600160a01b03868116600483015285166024820152604481018390525f8160648183865af190816136e4575b5061367c576133d185612d48565b946001600160a01b03861695861561359c57823b156102f657604051630b0d9c0960e01b81526001600160a01b03838116600483015282166024820152604481018590525f8160648183885af19081613588575b506135125761343d6131166001600160a01b03841681565b90833b156102f657604051630ab714fb60e11b81526001600160a01b03919091166004820152602481019190915260448101849052915f908390606490829084905af18015610f30577f8b9d1b193c6deeee3b26c06fd8324edaf97074775ccdf8f630ac9d480a36eda1936001600160a01b03936134f9926134fe575b50604080516001600160a01b035f80516020615a728339815191525c811682529098166020890152870152600160608701529116939081906080820190565b0390a4565b806105085f61350c93610622565b5f6134ba565b506001600160a01b0391506134f97f8b9d1b193c6deeee3b26c06fd8324edaf97074775ccdf8f630ac9d480a36eda1936135575f80516020615a728339815191525c90565b9660405194859416978460609194936001600160a01b035f9481608085019816845216602083015260408201520152565b806105085f61359693610622565b5f613425565b509450906135b36131166001600160a01b03871681565b91803b156102f657604051630ab714fb60e11b81526001600160a01b03861660048201526024810193909352604483018290525f908390606490829084905af1918215610f30577f8b9d1b193c6deeee3b26c06fd8324edaf97074775ccdf8f630ac9d480a36eda192613668575b505f80516020615a728339815191525c604080516001600160a01b0392831681529582166020870181905290860192909252600160608601529094169280608081016134f9565b806105085f61367693610622565b5f613621565b507f8b9d1b193c6deeee3b26c06fd8324edaf97074775ccdf8f630ac9d480a36eda1905f80516020615a728339815191525c604080516001600160a01b03928316815295821660208701819052908601929092525f60608601529094169280608081016134f9565b806105085f6136f293610622565b5f6133c3565b50505050565b906060116114f5578035916040602083013592013590565b909190600b8110156138185780613741575061373590610305926145f2565b949390939291926147a4565b6004810361376057506137579061030592613f37565b93929092614691565b60018103613782575061377690610305926145f2565b94939093929192614634565b600281036137b1575061379b6137ab916103059361433e565b9890979691959295949394612f86565b95614395565b600581036137dd57506137ca6137d7916103059361425c565b9790969591949294612f86565b946142ab565b9160038314613800575050610c9191505b635cda29d760e01b5f52600452602490565b61030592509061380f91613f37565b93929092613f73565b600d8103613834575061382e9061030592613ba0565b90613f0c565b6011810361385c575061384d61385691610305936136fe565b92909192612f86565b91613ef1565b600b8103613890575061388a61387861388492610305946136fe565b93829493929193613d93565b92613dae565b91613df2565b600e81036138c257506138b66138ac6138bc92610305946136fe565b9282949291612f86565b92613d01565b91613d15565b601281036138dd57506138d89061030592613a3c565b613ca8565b601381036138f957506138f39061030592613ba0565b90613bf6565b60148103613920575061391261391a9161030593613ba0565b919091612f86565b90613bb3565b6015810361396e57506139396139699161030593613a3c565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690613a93565b613b43565b9160168314613983575050610c9191506137ee565b61030592506139c49161399591613a3c565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016613a48565b613ad3565b604051602081019182526006604082015260408152611f90606082610622565b613a1481307f000000000000000000000000000000000000000000000000000000000000000061481c565b905f8212613a20575090565b6001600160a01b0390634c085bf160e01b5f521660045260245ffd5b906020116114f5573590565b613a5390309061487a565b600160ff1b8214613a8e578115613a7d575b8111613a6e5790565b631e9acf1760e31b5f5260045ffd5b9050613a885f6148c9565b90613a65565b905090565b90613a9e305f61487a565b90600160ff1b8314613acd578215613abb575b508111613a6e5790565b613ac69192506148c9565b905f613ab1565b50905090565b80613adb5750565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690813b156102f6575f91602483926040519485938492632e1a7d4d60e01b845260048401525af18015610f3057613b395750565b5f61030591610622565b80613b4b5750565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b156102f6575f90600460405180948193630d0e30db60e41b83525af18015610f3057613b395750565b91906040116114f5576020823592013590565b906001600160a01b03613bc583612fc7565b16918215613beb5750613bd782614922565b9081613be257505050565b6103059261496f565b9150613bd782614922565b90613c00826139e9565b908115612449578111613c7f576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691823b156102f65760405163203c2d1360e21b81526001600160a01b0390911660048201526024810191909152905f908290604490829084905af18015610f30576131c15750565b610305915f80516020615a728339815191525c90613d15565b600160ff1b8114612736575f0390565b613cd381307f000000000000000000000000000000000000000000000000000000000000000061481c565b905f80516020615a728339815191525c5f831215613cf75761388a61030593613c98565b6103059291613d15565b9081613d115761036a91506139e9565b5090565b90918015612449576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b156102f657604051630b0d9c0960e01b81526001600160a01b03938416600482015293909216602484015260448301525f908290606490829084905af18015610f3057613b395750565b15613daa575f80516020615a728339815191525c90565b3090565b906001600160a01b03613dc082612fc7565b169182158015613de4575b613dda57505061036a90614922565b61036a92506149fc565b50600160ff1b811415613dcb565b908215612449576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691823b156102f657604051632961046560e21b81526001600160a01b03821660048201525f8160248183885af18015610f3057613edd575b506001600160a01b038116613eac575050602090600460405180948193630476982d60e21b83525af18015610f3057613e915750565b613ea99060203d602011612a2957612a1d8183610622565b50565b5f9360209392613ebb92614a36565b600460405180948193630476982d60e21b83525af18015610f3057613e915750565b806105085f613eeb93610622565b5f613e5b565b91613f0361030593826138bc826139e9565b6138bc826139e9565b9061030591613f2e5f80516020615a728339815191525c918261388a826148c9565b61388a826148c9565b919082359260208101359260408201359263ffffffff60608401351683019063ffffffff823516936020808401938601019101106114f5579190565b9391925f80516020615a728339815191525c613f8f8682612ab9565b156141a25750613f9e85612251565b928360081c60020b958460201c60020b93613fca613fbe868a878d61292d565b6001600160801b031690565b96613fd48a612230565b955f613fe88c5f52600960205260405f2090565b55613ff28b614bce565b8a5f9a8a614026575b50505050505050508160ff16614013575b5050505050565b61401c94614d5a565b5f8080808061400c565b879b5060409061405c959697986140946140476140428f614c83565b613c98565b96614050611e54565b988994859060020b9052565b61406d6020850197889060020b9052565b838501978852606084019586528451632d35e7ed60e11b8152998a948594600486016141d4565b03815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1938415610f30575f955f9561416b575b50849b60a09020926140f05f80516020615a728339815191525c90565b915190519451925160408051600293840b81529690920b60208701529085019290925260608401919091526001600160a01b0316917f54e5dca345d804c4bcfd2d92dae077325838444a21d118beb4d25ec99a5788e590608090a361415491614c9c565b9161415e92614cd0565b5f80808080808a81613ffb565b90945061419191955060403d60401161419b575b6141898183610622565b8101906141be565b949094935f6140d3565b503d61417f565b6001600160a01b03906301952d1b60e31b5f521660045260245ffd5b91908260409103126102f6576020825192015190565b606061036a959361422583610140956001600160a01b036080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b805160020b60a0840152602081015160020b60c0840152604081015160e08401520151610100820152816101208201520191611e29565b91908260a08101359260c08201359260e083013592610100810135926101208201359263ffffffff6101408401351683019063ffffffff823516936020808401938601019101106114f5579190565b90916103059796959493926001600160801b036143376142f760a06142d03688613026565b207f0000000000000000000000000000000000000000000000000000000000000000614dd9565b50505061430384614e5f565b61430c86614e5f565b61431f883561431a816102e5565b6139e9565b9161433160208a013561431a816102e5565b9361518c565b1692614395565b9091819260a08301359260c08101359260e08201359261010083013592610120810135926101408201359263ffffffff6101608401351683019063ffffffff823516936020808401938601019101106114f5579190565b90919496929793959781356143a9816102e5565b6001600160a01b036143ba82612fc7565b1615806145cc575b6145bd576143d86143d33685613026565b615227565b156145ae57896143f0916143eb816102e5565b615273565b6144028960208401356143eb816102e5565b60085492600184016008556001600160a01b038a16998a15614569576144e46145389861453293876103059e61448a61452a96614456614450613116610b9a875f52600260205260405f2090565b15615719565b614471816001600160a01b03165f52600360205260405f2090565b80546001019055610bee845f52600260205260405f2090565b5f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a46144b93688613026565b63ffffff0066ffffff000000009160a066ffffffffffffff199120169260081b169260201b16171790565b92836144f8875f52600960205260405f2090565b5566ffffffffffffff1984165f818152600a6020526040902060010154869060b81c60020b1561453e575b5050614c83565b923690613026565b906153e0565b50615765565b61455d6145629266ffffffffffffff19165f52600a60205260405f2090565b6152f8565b5f85614523565b60405162461bcd60e51b815260206004820152601160248201527f494e56414c49445f524543495049454e540000000000000000000000000000006044820152606490fd5b639c9d882360e01b5f5260045ffd5b6367a18ca960e11b5f5260045ffd5b506001600160a01b036145eb60208501356145e6816102e5565b612fc7565b16156143c2565b909181359260208301359260408101359260608201359263ffffffff60808401351683019063ffffffff823516936020808401938601019101106114f5579190565b90959495939192935f80516020615a728339815191525c6146558382612ab9565b156141a257509561468c9282614042610305989961468061467861468697612251565b939092614c83565b916153e0565b90614c9c565b614cd0565b949394929091926146a181612251565b506146ab81615227565b156145ae576146dd906001600160a01b0360206146c785612230565b926146d58484835116615273565b015116615273565b5f80516020615a728339815191525c6146f68282612ab9565b156141a25750610305949561479f928261471261468694612251565b906146806001600160801b0361479961474e60a085207f0000000000000000000000000000000000000000000000000000000000000000614dd9565b5050506147608660081c60020b614e5f565b61476f8760201c60020b614e5f565b6147826001600160a01b038851166139e9565b916143316001600160a01b0360208a0151166139e9565b16614c83565b615765565b90959495939192936147b582612251565b506147bf81615227565b156145ae576147db906001600160a01b0360206146c786612230565b5f80516020615a728339815191525c6147f48382612ab9565b156141a257509561479f9282614680610305989961481461468696612251565b929091614c83565b6001600160a01b03809381602094165f52168252602460405f20604051948593849263789add5560e11b84526004840152165afa908115610f30575f91614861575090565b61036a915060203d602011612a2957612a1d8183610622565b6001600160a01b03811661488d57503190565b6040516370a0823160e01b81526001600160a01b0392831660048201529160209183916024918391165afa908115610f30575f91614861575090565b6148f481307f000000000000000000000000000000000000000000000000000000000000000061481c565b905f8213614906575061036a90613c98565b6001600160a01b039063019a8d9360e51b5f521660045260245ffd5b6001600160a01b03811661493557504790565b6040516370a0823160e01b815230600482015290602090829060249082906001600160a01b03165afa908115610f30575f91614861575090565b9091906001600160a01b03811661499c57505f80808061499094865af11590565b6149975750565b612c50565b91906001600160a01b036040519263a9059cbb60e01b845216600483015260248201525f604060208260448582885af13d15601f3d116001855114161716928281528260208201520152156149ee5750565b6001600160a01b0316612be3565b90600160ff1b8203614a125761036a9150614922565b81613d115761036a91506148c9565b908160209103126102f6575161036a81610f58565b614a3f81612fc7565b906001600160a01b038216908115614bc05760405163f493cec360e01b81526001600160a01b035f80516020615a728339815191525c81166004830152600160f11b6024830152919091169390602081604481885afa908115610f30575f91614b91575b50156107a557849184916001600160a01b0381163003614af45750614ac8935061496f565b803b156102f657604051630934f6c760e21b815260048101929092525f908290818381602481016131b0565b925050506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691823b156102f657604051631b63c28b60e11b81526001600160a01b0392831660048201528483166024820152858316604482015291166064820152905f908290608490829084905af18015610f3057614b7d575b50614ac8565b806105085f614b8b93610622565b5f614b77565b614bb3915060203d602011614bb9575b614bab8183610622565b810190614a21565b5f614aa3565b503d614ba1565b90506103059392915061552e565b805f5260026020525f6001600160a01b03604082205416614bf08115156121f7565b80825260036020526040822082198154019055614c15835f52600260205260405f2090565b80548360031b906001600160a01b03808616831b921b1916179055614c42835f52600460205260405f2090565b80548360031b906001600160a01b03808616831b921b19161790557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a4565b905f8212614c8d57565b6393dafdf160e01b5f5260045ffd5b614cbf90614cb18360801d8260801d03615618565b92600f0b90600f0b03615618565b6001600160801b03169060801b1790565b929190926001600160801b038160801d9481614ceb87615626565b91169182911610614d4857506001600160801b03929350600f0b9082614d1083615626565b91169283911610614d1f575050565b90614d316001600160801b0392615626565b90630940b79160e11b5f526004521660245260445ffd5b6001600160801b0390614d3186615626565b5f81815260076020526040902080546001600160a01b031981169091556001600160a01b0390811695614dcd95610c3d9593949193909290916040519563b1a9116f60e01b602088015260248701521660448501526064840152608483015260a482015260a48152610c3760c482610622565b614dd45750565b612cb4565b6020906024614df06001600160a01b0395946139c9565b6040519586938492631e2eaeaf60e01b84526004840152165afa918215610f30575f92614e3e575b506001600160a01b038216918060a01c60020b9162ffffff808360b81c169260d01c1690565b614e5891925060203d602011612a2957612a1d8183610622565b905f614e18565b60020b908160ff1d82810118620d89e881116151865763ffffffff9192600182167001fffcb933bd6fad37aa2d162d1a5940010270010000000000000000000000000000000018916002811661516a575b6004811661514e575b60088116615132575b60108116615116575b602081166150fa575b604081166150de575b608081166150c2575b61010081166150a6575b610200811661508a575b610400811661506e575b6108008116615052575b6110008116615036575b612000811661501a575b6140008116614ffe575b6180008116614fe2575b620100008116614fc6575b620200008116614fab575b620400008116614f90575b6208000016614f77575b5f12614f6f575b0160201c90565b5f1904614f68565b6b048a170391f7dc42444e8fa290910260801c90614f61565b6d2216e584f5fa1ea926041bedfe9890920260801c91614f57565b916e5d6af8dedb81196699c329225ee6040260801c91614f4c565b916f09aa508b5b7a84e1c677de54f3e99bc90260801c91614f41565b916f31be135f97d08fd981231505542fcfa60260801c91614f36565b916f70d869a156d2a1b890bb3df62baf32f70260801c91614f2c565b916fa9f746462d870fdf8a65dc1f90e061e50260801c91614f22565b916fd097f3bdfd2022b8845ad8f792aa58250260801c91614f18565b916fe7159475a2c29b7443b29c7fa6e889d90260801c91614f0e565b916ff3392b0822b70005940c7a398e4b70f30260801c91614f04565b916ff987a7253ac413176f2b074cf7815e540260801c91614efa565b916ffcbe86c7900a88aedcffc83b479aa3a40260801c91614ef0565b916ffe5dee046a99a2a811c461f1969c30530260801c91614ee6565b916fff2ea16466c96a3843ec78b326b528610260801c91614edd565b916fff973b41fa98c081472e6896dfb254c00260801c91614ed4565b916fffcb9843d60f6159c9db58835c9266440260801c91614ecb565b916fffe5caca7e10e4e61c3624eaa0941cd00260801c91614ec2565b916ffff2e50f5f656932ef12357cf3c7fdcc0260801c91614eb9565b916ffff97272373d413259a46990580e213a0260801c91614eb0565b8261563c565b936001600160a01b0383166001600160a01b0383161161521f575b6001600160a01b038581169590831686116151c857505061036a9350615681565b92909391946001600160a01b038216115f146152135782916151ee916151f49594615681565b93615651565b6001600160801b0381166001600160801b038316105f14613a8e575090565b91505061036a92615651565b9091906151a7565b6001600160a01b0381511661524b60808301916001600160a01b03835116906156ca565b918261525657505090565b61036a92506001600160a01b0360208192015116915116906156ca565b6001600160a01b0361528482612fc7565b16156152f45760405163f493cec360e01b81526001600160a01b039283166004820152600160f11b60248201529160209183916044918391165afa908115610f30575f916152d5575b50156107a557565b6152ee915060203d602011614bb957614bab8183610622565b5f6152cd565b5050565b600260806103059361532a813561530e816102e5565b85546001600160a01b0319166001600160a01b03909116178555565b6001840161535b602083013561533f816102e5565b82546001600160a01b0319166001600160a01b03909116178255565b60408201356153698161247d565b81547fffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff606085013561539a8161245d565b60b81b62ffffff60b81b169262ffffff60a01b9060a01b169116171790550135916153c4836102e5565b01906001600160a01b03166001600160a01b0319825416179055565b9593949190958060081c60020b60408260201c60020b948961543a615403611e54565b600286900b815292600289900b6020850152878585015289606085015284519b8c948594632d35e7ed60e11b8652600486016141d4565b03815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1938415610f30575f975f95615507575b507f54e5dca345d804c4bcfd2d92dae077325838444a21d118beb4d25ec99a5788e560a086999a20916001600160a01b036154bf5f80516020615a728339815191525c90565b16936154ef89886040519485948590949392606092608083019660020b835260020b602083015260408201520152565b0390a360ff166154fe57505050565b61030592615842565b90945061552491975060403d60401161419b576141898183610622565b969096935f615479565b9091906001600160a01b03831630036155765761030592506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169061496f565b906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b156102f657604051631b63c28b60e11b81526001600160a01b0394851660048201527f00000000000000000000000000000000000000000000000000000000000000008516602482015291841660448301529190921660648301525f908290608490829084905af18015610f30576131c15750565b9081600f0b918203614c8d57565b5f81600f0b12614c8d576001600160801b031690565b6345c3193d60e11b5f5260020b60045260245ffd5b916001600160a01b0361036a93615676938281168383161161567b575b031690615906565b615a5d565b9061566e565b916156769161036a936001600160a01b0382166001600160a01b038216116156c4575b6001600160a01b03906156bb828416838316615991565b920316916159da565b906156a4565b6001600160a01b036156db82612fc7565b16156157125760ff916001600160a01b03612b2892165f52600b60205260405f20906001600160a01b03165f5260205260405f2090565b5050600190565b1561572057565b60405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606490fd5b908160801d600f0b91600f0b915f81128061581f575b6157e85750505f8112806157c3575b615792575050565b906157a2613fbe610c9193613c98565b63031e30ad60e41b5f526001600160801b0391821660045216602452604490565b506001600160801b03806157d683613c98565b16166001600160801b0383161061578a565b906001600160801b036157fd610c9193613c98565b63031e30ad60e41b5f526001600160801b039283166004521616602452604490565b506001600160801b0361583182613c98565b166001600160801b0383161061577b565b6158939192815f5260076020526001600160a01b0360405f205416936040519263d8865c2760e01b60208501526024840152604483015260648201526064815261588d608482610622565b82612b4e565b1561589b5750565b6040516390bfb86560e01b8152600481019190915263d8865c2760e01b602482015260806044820152601f3d01601f191660a0810160648301523d60848301523d5f60a484013e808201600460a482015260c46374a7887160e11b91015260e40190fd5b156102f657565b908160601b905f19600160601b840992828085109403938085039461592c8685116158ff565b1461598a57600160601b82910981805f03168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b5091500490565b81810291905f1982820991838084109303928084039384600160601b11156102f657146159d157600160601b910990828211900360a01b910360601c1790565b50505060601c90565b91818302915f198185099383808610950394808603956159fb8786116158ff565b14615a55579082910981805f03168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b505091500490565b906001600160801b038216809203614c8d5756fe0aedd6bde10e3aa2adec092b02a3e3e805795516cda41f27aa145b8f300af87aa164736f6c634300081a000a290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6'; + } +} diff --git a/src/briefcase/deployers/v4-periphery/PermissionsAdapterFactoryDeployer.sol b/src/briefcase/deployers/v4-periphery/PermissionsAdapterFactoryDeployer.sol new file mode 100644 index 00000000..6288b99e --- /dev/null +++ b/src/briefcase/deployers/v4-periphery/PermissionsAdapterFactoryDeployer.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import {DeployerHelper} from '../DeployerHelper.sol'; + +library PermissionsAdapterFactoryDeployer { + function deploy(address poolManager) internal returns (address factory) { + bytes memory args = abi.encode(poolManager); + bytes memory initcode_ = abi.encodePacked(initcode(), args); + factory = DeployerHelper.create2(initcode_); + } + + /** + * @dev autogenerated - run `./script/util/create_briefcase.sh` to generate current initcode + * + * @notice This initcode is generated from the following contract: + * - Source Contract: src/pkgs/v4-periphery/src/hooks/permissionedPools/PermissionsAdapterFactory.sol + * - solc: 0.8.26 + * - optimizer_runs: 44444444 + * - via_ir: true + * - evm_version: cancun + */ + function initcode() internal pure returns (bytes memory) { + return hex'60a034606d57601f612cc738819003918201601f19168301916001600160401b03831184841017607157808492602094604052833981010312606d57516001600160a01b0381168103606d57608052604051612c4190816100868239608051818181610129015261052d0152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c90816325efface146105515750806362308e85146104e35780637986a358146102a6578063a625fcd41461022e5763acd4625314610053575f80fd5b3461022a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261022a5760043573ffffffffffffffffffffffffffffffffffffffff811680910361022a5760243573ffffffffffffffffffffffffffffffffffffffff811680910361022a576044359073ffffffffffffffffffffffffffffffffffffffff821680920361022a576040519161264b908184019084821067ffffffffffffffff8311176101fd5760809385936105ea853986835273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166020840152604083015260608201520301905ff09081156101f25773ffffffffffffffffffffffffffffffffffffffff60209216805f525f835260405f2073ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905560405191817fc668126f9ef0f53f8ed212e25aa243fdac9e87eb842f5361ab28b6fd65d672285f80a38152f35b6040513d5f823e3d90fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f80fd5b3461022a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261022a5773ffffffffffffffffffffffffffffffffffffffff61027a6105c6565b165f525f602052602073ffffffffffffffffffffffffffffffffffffffff60405f205416604051908152f35b3461022a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261022a5773ffffffffffffffffffffffffffffffffffffffff6102f26105c6565b16805f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f2054169081156104b857805f52600160205273ffffffffffffffffffffffffffffffffffffffff60405f20541661048d576040517f70a08231000000000000000000000000000000000000000000000000000000008152816004820152602081602481865afa9081156101f2575f91610427575b50156103fc57805f52600160205260405f2073ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790557f031ac7092abd11438885b362e3e4ff3b6999ba04494f91211c7f34cf4d2cb49f5f80a3005b7f35d7c67c000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b905060203d602011610486575b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f820116820182811067ffffffffffffffff8211176101fd5760209183916040528101031261022a575183610386565b503d610434565b7f3159709b000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7faa274a37000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b3461022a575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261022a57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461022a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261022a5760209073ffffffffffffffffffffffffffffffffffffffff6105a06105c6565b165f526001825273ffffffffffffffffffffffffffffffffffffffff60405f2054168152f35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361022a5756fe60c0604052346100c057608061264b803803809161001c826100d8565b60c039126100c05761006060c05161003381610126565b60e05161003f81610126565b610100519061004d82610126565b610120519261005b84610126565b610137565b604051611dee908161085d823960805181818161071d01528181610864015281816118c70152818161190d0152611934015260a0518181816106be015281816110fd015281816113f70152818161153f015281816116e10152611c2b0152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b60c0601f91909101601f19168101906001600160401b038211908210176100fe57604052565b6100c4565b601f909101601f19168101906001600160401b038211908210176100fe57604052565b6001600160a01b038116036100c057565b61020d6101fa6101b1610218969561020860018060a01b0386166101e06040916101bf61018e84516101698682610103565b60128152712832b936b4b9b9b4b7b732b2102a37b5b2b760711b602082015283610701565b84519788916a02ab734b9bbb0b8103b1a160ad1b6020840152602b830190610508565b03601f198101885287610103565b8251906101cc8483610103565b6002825261141560f21b60208301526107aa565b9051948591611d8d60f21b60208401526022830190610508565b03601f198101855284610103565b61021a565b60a05260805261051a565b565b815191939290916001600160401b0381116100fe576102438161023e60035461033d565b610375565b6020601f82116001146102b65790806102779261027f9596975f926102ab575b50508160011b915f199060031b1c19161790565b600355610414565b6001600160a01b0381161561029757610218906105fa565b631e4fbdf760e01b5f90815260045260245ffd5b015190505f80610263565b60035f52601f198216957fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b965f5b81811061032557509161027f9596979184600195941061030d575b505050811b01600355610414565b01515f1960f88460031b161c191690555f80806102ff565b838301518955600190980197602093840193016102e4565b90600182811c9216801561036b575b602083101461035757565b634e487b7160e01b5f52602260045260245ffd5b91607f169161034c565b601f8111610381575050565b60035f5260205f20906020601f840160051c830193106103bb575b601f0160051c01905b8181106103b0575050565b5f81556001016103a5565b909150819061039c565b601f82116103d257505050565b5f5260205f20906020601f840160051c8301931061040a575b601f0160051c01905b8181106103ff575050565b5f81556001016103f4565b90915081906103eb565b80519091906001600160401b0381116100fe5761043d8161043660045461033d565b60046103c5565b602092601f82116001146104715761046c929382915f926102ab5750508160011b915f199060031b1c19161790565b600455565b60045f52601f198216937f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b915f5b8681106104d557508360019596106104bd575b505050811b01600455565b01515f1960f88460031b161c191690555f80806104b2565b9192602060018192868501518155019401920161049f565b6001600160401b0381116100fe57601f01601f191660200190565b805191908290602001825e015f815290565b60018060a01b031660205f604051828101906301ffc9a760e01b82526301ffc9a760e01b602482015260248152610552604482610103565b519084617530fa5f513d826105ee575b50816105e4575b50806105d4575b806105c5575b156105b357600780546001600160a01b031916821790557fbca8d38b73c0bd49fed0184fde2164819be3e78422a9c1ab4a8dab2d10ff6b925f80a2565b637a6f66a560e01b5f5260045260245ffd5b506105cf8161082b565b610576565b506105de816107ce565b15610570565b905015155f610569565b6020111591505f610562565b600680546001600160a01b0319908116909155600580549182166001600160a01b0393841690811790915591167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b3d15610677573d9061065e826104ed565b9161066c6040519384610103565b82523d5f602084013e565b606090565b603f1981019190821161068b57565b634e487b7160e01b5f52601160045260245ffd5b6020818303126100c0578051906001600160401b0382116100c0570181601f820112156100c0578051906106d2826104ed565b926106e06040519485610103565b828452602083830101116100c057815f9260208093018386015e8301015290565b5f809160405160208101906306fdde0360e01b825260048152610725602482610103565b51915afa9061073261064d565b9115801561079f575b61079a576020820190815160206040850151911490811591610791575b811561077e575b506107785750602082610775935101019061069f565b90565b91505090565b905061078a845161067c565b105f61075f565b80159150610758565b905090565b50604082511061073b565b5f809160405160208101906395d89b4160e01b825260048152610725602482610103565b5f602091604051838101906301ffc9a760e01b825263ffffffff60e01b6024820152602481526107ff604482610103565b5191617530fa5f513d8261081f575b5081610818575090565b9050151590565b6020111591505f61080e565b5f602091604051838101906301ffc9a760e01b825263274e332360e21b6024820152602481526107ff60448261010356fe60806040526004361015610011575f80fd5b5f3560e01c806306fdde03146101a4578063095ea7b31461019f57806318160ddd1461019a57806323b872dd1461019557806324d3db1c14610190578063313ce5671461018b57806362308e85146101865780636c2091471461018157806370a082311461017c578063715018a6146101775780637185f8581461017257806379ba50971461016d5780638da5cb5b1461016857806395d89b4114610163578063a9059cbb1461015e578063aeb5556914610159578063dd62ed3e14610154578063e30c39781461014f578063e4a4b0101461014a578063e73bce9514610145578063ef59d5c314610140578063f21a2d0e1461013b578063f2fde38b14610136578063f493cec3146101315763fb137ce31461012c575f80fd5b6114f5565b611362565b611276565b6111c0565b611076565b61100a565b610fb7565b610f66565b610ecd565b610e8a565b610e42565b610d6f565b610d1e565b610c14565b610a80565b6109bc565b610956565b610888565b61081a565b6107d7565b61061b565b6104be565b610483565b61035b565b6101f1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602060409481855280519182918282880152018686015e5f8582860101520116010190565b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339576040515f6003548060011c906001811690811561032f575b6020831082146103025782855260208501919081156102cb5750600114610279575b6102758461026981860382611590565b604051918291826101a9565b0390f35b60035f9081529250907fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b8184106102b75750500161026982610259565b8054848401526020909301926001016102a4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682525090151560051b01905061026982610259565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b91607f1691610237565b5f80fd5b73ffffffffffffffffffffffffffffffffffffffff81160361033957565b346103395760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339576004356103968161033d565b60243533156104575773ffffffffffffffffffffffffffffffffffffffff821691821561042b576103f18291335f52600160205260405f209073ffffffffffffffffffffffffffffffffffffffff165f5260205260405f2090565b5560405190815233907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590602090a3602060405160018152f35b7f94280d62000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b7fe602df05000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339576020600254604051908152f35b346103395760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339576004356104f98161033d565b6024356105058161033d565b6044359073ffffffffffffffffffffffffffffffffffffffff831692835f5260016020526105543360405f209073ffffffffffffffffffffffffffffffffffffffff165f5260205260405f2090565b54937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8503610594575b506105899350611751565b602060405160018152f35b8385106105e757801561045757331561042b576105899484915f526001602052036105e03360405f209073ffffffffffffffffffffffffffffffffffffffff165f5260205260405f2090565b555f61057e565b83857ffb8f41b2000000000000000000000000000000000000000000000000000000005f523360045260245260445260645ffd5b346103395760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103395760043561068661068261067b3373ffffffffffffffffffffffffffffffffffffffff165f52600860205260405f2090565b5460ff1690565b1590565b6107ab576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526020816024817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff165afa80156107a657610710915f91610777575b506002549061161d565b80821161074357610741827f00000000000000000000000000000000000000000000000000000000000000006117ee565b005b7fcf479181000000000000000000000000000000000000000000000000000000005f5260049190915260245260445ffd5b5ffd5b610799915060203d60201161079f575b6107918183611590565b8101906115d6565b5f610706565b503d610787565b6115e5565b7f87d4de58000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033957602061080f61168c565b60ff60405191168152f35b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033957602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b346103395760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339576004356108c38161033d565b60243590811515820361033957602073ffffffffffffffffffffffffffffffffffffffff7facf055a373fc18efc9064504f586326ebad3223431207428c553428eaf75461392610911611815565b1692835f526008825260405f20901515907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541660ff8316179055604051908152a2005b346103395760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103395773ffffffffffffffffffffffffffffffffffffffff6004356109a68161033d565b165f525f602052602060405f2054604051908152f35b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339576109f2611815565b7fffffffffffffffffffffffff0000000000000000000000000000000000000000600654166006555f73ffffffffffffffffffffffffffffffffffffffff6005547fffffffffffffffffffffffff00000000000000000000000000000000000000008116600555167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346103395760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103395773ffffffffffffffffffffffffffffffffffffffff600435610ad08161033d565b610ad8611815565b1660205f604051828101907f01ffc9a70000000000000000000000000000000000000000000000000000000082527f01ffc9a700000000000000000000000000000000000000000000000000000000602482015260248152610b3b604482611590565b519084617530fa5f513d82610c08575b5081610bfe575b5080610bee575b80610bdf575b15610bb457807fffffffffffffffffffffffff000000000000000000000000000000000000000060075416176007557fbca8d38b73c0bd49fed0184fde2164819be3e78422a9c1ab4a8dab2d10ff6b925f80a2005b7f7a6f66a5000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b50610be981611d7e565b610b5f565b50610bf881611cef565b15610b59565b905015155f610b52565b6020111591505f610b4b565b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339573373ffffffffffffffffffffffffffffffffffffffff6006541603610cf2577fffffffffffffffffffffffff000000000000000000000000000000000000000060065416600655600554337fffffffffffffffffffffffff000000000000000000000000000000000000000082161760055573ffffffffffffffffffffffffffffffffffffffff3391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b7f118cdaa7000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033957602073ffffffffffffffffffffffffffffffffffffffff60055416604051908152f35b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339576040515f6004548060011c9060018116908115610e38575b6020831082146103025782855260208501919081156102cb5750600114610de6576102758461026981860382611590565b60045f9081529250907f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b818410610e245750500161026982610259565b805484840152602090930192600101610e11565b91607f1691610db5565b346103395760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033957610589600435610e808161033d565b6024359033611751565b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033957602060ff60075460a01c166040519015158152f35b346103395760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339576020610f5d600435610f0d8161033d565b73ffffffffffffffffffffffffffffffffffffffff60243591610f2f8361033d565b165f526001835260405f209073ffffffffffffffffffffffffffffffffffffffff165f5260205260405f2090565b54604051908152f35b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033957602073ffffffffffffffffffffffffffffffffffffffff60065416604051908152f35b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103395760075460405173ffffffffffffffffffffffffffffffffffffffff9091168152602090f35b346103395760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103395773ffffffffffffffffffffffffffffffffffffffff60043561105a8161033d565b165f526008602052602060ff60405f2054166040519015158152f35b346103395760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103395760043560205f60646040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201528460448201528273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af13d15601f3d1160015f5114161716156111625760405190815233907f06434cb6a9670e5da877306015486047189842c1b3b62f49c8bbf65a1868f54e90602090a2005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b346103395760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610339576004358015158091036103395760207f04eddf1a09d47c4653f2d8d8ab3a0e99b462f6032bae11a002b9f919b660c46d91611228611815565b6007547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff74ff00000000000000000000000000000000000000008360a01b16911617600755604051908152a1005b346103395760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103395773ffffffffffffffffffffffffffffffffffffffff6004356112c68161033d565b6112ce611815565b16807fffffffffffffffffffffffff0000000000000000000000000000000000000000600654161760065573ffffffffffffffffffffffffffffffffffffffff600554167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b7fffff00000000000000000000000000000000000000000000000000000000000081160361033957565b346103395760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103395760043561139d8161033d565b61142f6020602435926113af84611338565b6007546040517f9d38cc8c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201527f00000000000000000000000000000000000000000000000000000000000000008316602482015293849290911690829081906044820190565b03915afa9081156107a6575f916114aa575b610275611498848481167fffff000000000000000000000000000000000000000000000000000000000000165b7fffff00000000000000000000000000000000000000000000000000000000000090811691161490565b60405190151581529081906020820190565b90506020813d6020116114ed575b816114c560209383611590565b81010312610339578161146e6102759361149893516114e381611338565b9350935050611441565b3d91506114b8565b34610339575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033957602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176115d157604052565b611563565b90816020910312610339575190565b6040513d5f823e3d90fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b9190820391821161162a57565b6115f0565b3d15611687573d9067ffffffffffffffff82116115d1576040519161167c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184611590565b82523d5f602084013e565b606090565b5f8060405160208101907f313ce567000000000000000000000000000000000000000000000000000000008252600481526116c8602482611590565b519073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa61170b61162f565b90158015611746575b611740578060208061172b935183010191016115d6565b60ff81111561173a5750601290565b60ff1690565b50601290565b506020815110611714565b919073ffffffffffffffffffffffffffffffffffffffff8316156117c25773ffffffffffffffffffffffffffffffffffffffff811615611796576117949261186a565b565b7fec442f05000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b7f96c6fd1e000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b9073ffffffffffffffffffffffffffffffffffffffff82161561179657611794915f61186a565b73ffffffffffffffffffffffffffffffffffffffff600554163303610cf257565b1561183d57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b92919073ffffffffffffffffffffffffffffffffffffffff81168015611a005773ffffffffffffffffffffffffffffffffffffffff8516806118f25750936118ed611794949573ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611836565b611a18565b73ffffffffffffffffffffffffffffffffffffffff939291937f000000000000000000000000000000000000000000000000000000000000000016036119b9577f00000000000000000000000000000000000000000000000000000000000000009273ffffffffffffffffffffffffffffffffffffffff8416146119b9576119808282611985959697611a18565b611bb1565b6119af6117949173ffffffffffffffffffffffffffffffffffffffff165f525f60205260405f2090565b5460025414611836565b7f709ac017000000000000000000000000000000000000000000000000000000005f5273ffffffffffffffffffffffffffffffffffffffff8086166004521660245260445ffd5b506117949293611a18565b9190820180921161162a57565b909173ffffffffffffffffffffffffffffffffffffffff82169182611ae35750611aac81611a71611a6c7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef94600254611a0b565b600255565b73ffffffffffffffffffffffffffffffffffffffff85169485611ab15750611a9c8160025403600255565b6040519081529081906020820190565b0390a3565b611ad89073ffffffffffffffffffffffffffffffffffffffff165f525f60205260405f2090565b818154019055611a9c565b611b0a8173ffffffffffffffffffffffffffffffffffffffff165f525f60205260405f2090565b54828110611b685791611aac91611b62827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef95039173ffffffffffffffffffffffffffffffffffffffff165f525f60205260405f2090565b55611a71565b7fe450d38c000000000000000000000000000000000000000000000000000000005f5273ffffffffffffffffffffffffffffffffffffffff90911660045260245260445260645ffd5b9073ffffffffffffffffffffffffffffffffffffffff8216918215611cc057815f611bdb9261186a565b60446020925f92604051917fa9059cbb000000000000000000000000000000000000000000000000000000008352600483015260248201528273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af13d15601f3d1160015f511416171615611c6257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152fd5b7f96c6fd1e000000000000000000000000000000000000000000000000000000005f526107746024905f600452565b5f602091604051838101907f01ffc9a70000000000000000000000000000000000000000000000000000000082527fffffffff00000000000000000000000000000000000000000000000000000000602482015260248152611d52604482611590565b5191617530fa5f513d82611d72575b5081611d6b575090565b9050151590565b6020111591505f611d61565b5f602091604051838101907f01ffc9a70000000000000000000000000000000000000000000000000000000082527f9d38cc8c00000000000000000000000000000000000000000000000000000000602482015260248152611d5260448261159056fea164736f6c634300081a000aa164736f6c634300081a000a'; + } +} diff --git a/src/briefcase/protocols/lib-external/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol b/src/briefcase/protocols/lib-external/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol new file mode 100644 index 00000000..5908586d --- /dev/null +++ b/src/briefcase/protocols/lib-external/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) + +/** + * @dev Interface of the ERC165 standard, as defined in the + * https://eips.ethereum.org/EIPS/eip-165[EIP]. + * + * Implementers can declare support of contract interfaces, which can then be + * queried by others ({ERC165Checker}). + * + * For an implementation, see {ERC165}. + */ +interface IERC165 { + /** + * @dev Returns true if this contract implements the interface defined by + * `interfaceId`. See the corresponding + * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. + */ + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} diff --git a/src/briefcase/protocols/lib-external/solmate/src/utils/Bytes32AddressLib.sol b/src/briefcase/protocols/lib-external/solmate/src/utils/Bytes32AddressLib.sol new file mode 100644 index 00000000..448fb759 --- /dev/null +++ b/src/briefcase/protocols/lib-external/solmate/src/utils/Bytes32AddressLib.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity >=0.8.0; + +/// @notice Library for converting between addresses and bytes32 values. +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Bytes32AddressLib.sol) +library Bytes32AddressLib { + function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) { + return address(uint160(uint256(bytesValue))); + } + + function fillLast12Bytes(address addressValue) internal pure returns (bytes32) { + return bytes32(bytes20(addressValue)); + } +} diff --git a/src/briefcase/protocols/lib-external/solmate/src/utils/CREATE3.sol b/src/briefcase/protocols/lib-external/solmate/src/utils/CREATE3.sol new file mode 100644 index 00000000..0a5fb2f3 --- /dev/null +++ b/src/briefcase/protocols/lib-external/solmate/src/utils/CREATE3.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity >=0.8.0; + +import {Bytes32AddressLib} from './Bytes32AddressLib.sol'; + +/// @notice Deploy to deterministic addresses without an initcode factor. +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol) +/// @author Modified from 0xSequence (https://github.com/0xSequence/create3/blob/master/contracts/Create3.sol) +library CREATE3 { + using Bytes32AddressLib for bytes32; + + //--------------------------------------------------------------------------------// + // Opcode | Opcode + Arguments | Description | Stack View // + //--------------------------------------------------------------------------------// + // 0x36 | 0x36 | CALLDATASIZE | size // + // 0x3d | 0x3d | RETURNDATASIZE | 0 size // + // 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // + // 0x37 | 0x37 | CALLDATACOPY | // + // 0x36 | 0x36 | CALLDATASIZE | size // + // 0x3d | 0x3d | RETURNDATASIZE | 0 size // + // 0x34 | 0x34 | CALLVALUE | value 0 size // + // 0xf0 | 0xf0 | CREATE | newContract // + //--------------------------------------------------------------------------------// + // Opcode | Opcode + Arguments | Description | Stack View // + //--------------------------------------------------------------------------------// + // 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode // + // 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode // + // 0x52 | 0x52 | MSTORE | // + // 0x60 | 0x6008 | PUSH1 08 | 8 // + // 0x60 | 0x6018 | PUSH1 18 | 24 8 // + // 0xf3 | 0xf3 | RETURN | // + //--------------------------------------------------------------------------------// + bytes internal constant PROXY_BYTECODE = hex'67363d3d37363d34f03d5260086018f3'; + + bytes32 internal constant PROXY_BYTECODE_HASH = keccak256(PROXY_BYTECODE); + + function deploy(bytes32 salt, bytes memory creationCode, uint256 value) internal returns (address deployed) { + bytes memory proxyChildBytecode = PROXY_BYTECODE; + + address proxy; + /// @solidity memory-safe-assembly + assembly { + // Deploy a new contract with our pre-made bytecode via CREATE2. + // We start 32 bytes into the code to avoid copying the byte length. + proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), salt) + } + require(proxy != address(0), 'DEPLOYMENT_FAILED'); + + deployed = getDeployed(salt); + (bool success,) = proxy.call{value: value}(creationCode); + require(success && deployed.code.length != 0, 'INITIALIZATION_FAILED'); + } + + function getDeployed(bytes32 salt) internal view returns (address) { + return getDeployed(salt, address(this)); + } + + function getDeployed(bytes32 salt, address creator) internal pure returns (address) { + address proxy = keccak256( + abi.encodePacked( + // Prefix: + bytes1(0xFF), + // Creator: + creator, + // Salt: + salt, + // Bytecode hash: + PROXY_BYTECODE_HASH + ) + ).fromLast20Bytes(); + + return keccak256( + abi.encodePacked( + // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01) + // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) + hex'd694', + proxy, + hex'01' // Nonce of the proxy contract (1) + ) + ).fromLast20Bytes(); + } +} diff --git a/src/briefcase/protocols/uniswapx/v4/base/ReactorStructs.sol b/src/briefcase/protocols/uniswapx/v4/base/ReactorStructs.sol index 6c7c59c8..2616d211 100644 --- a/src/briefcase/protocols/uniswapx/v4/base/ReactorStructs.sol +++ b/src/briefcase/protocols/uniswapx/v4/base/ReactorStructs.sol @@ -4,15 +4,15 @@ pragma solidity ^0.8.0; import {InputToken, OutputToken} from '../../base/ReactorStructs.sol'; import {IAuctionResolver} from '../interfaces/IAuctionResolver.sol'; import {IPostExecutionHook, IPreExecutionHook} from '../interfaces/IHook.sol'; -import {IReactor} from '../interfaces/IReactor.sol'; +import {IReactor_1} from '../interfaces/IReactor.sol'; /// @dev generic order information /// should be included as the first field in any concrete order types -struct OrderInfo { +struct OrderInfo_1 { // The address of the reactor that this order is targeting // Note that this must be included in every order so the swapper // signature commits to the specific reactor that they trust to fill their order properly - IReactor reactor; + IReactor_1 reactor; // The address of the user which created the order // Note that this must be included so that order hashes are unique by swapper address swapper; @@ -33,8 +33,8 @@ struct OrderInfo { } /// @dev generic concrete order that specifies exact tokens which need to be sent and received -struct ResolvedOrder { - OrderInfo info; +struct ResolvedOrder_1 { + OrderInfo_1 info; InputToken input; OutputToken[] outputs; bytes sig; diff --git a/src/briefcase/protocols/uniswapx/v4/interfaces/IAuctionResolver.sol b/src/briefcase/protocols/uniswapx/v4/interfaces/IAuctionResolver.sol index f2d999b1..07edd6bf 100644 --- a/src/briefcase/protocols/uniswapx/v4/interfaces/IAuctionResolver.sol +++ b/src/briefcase/protocols/uniswapx/v4/interfaces/IAuctionResolver.sol @@ -2,14 +2,14 @@ pragma solidity >=0.6.2; import {SignedOrder} from '../../base/ReactorStructs.sol'; -import {ResolvedOrder} from '../base/ReactorStructs.sol'; +import {ResolvedOrder_1} from '../base/ReactorStructs.sol'; /// @notice Interface for auction mechanism resolvers (for UnifiedReactor) interface IAuctionResolver { /// @notice Resolves a signed order into a resolved order based on auction rules /// @param signedOrder The signed order with auction-specific order data (resolver address already stripped) /// @return resolvedOrder The resolved order with final amounts - function resolve(SignedOrder calldata signedOrder) external view returns (ResolvedOrder memory resolvedOrder); + function resolve(SignedOrder calldata signedOrder) external view returns (ResolvedOrder_1 memory resolvedOrder); /// @notice Get the Permit2 order type string for EIP-712 signature verification /// @return orderType The EIP-712 order type string for this resolver's orders diff --git a/src/briefcase/protocols/uniswapx/v4/interfaces/IHook.sol b/src/briefcase/protocols/uniswapx/v4/interfaces/IHook.sol index 6d9f708a..b6e0641e 100644 --- a/src/briefcase/protocols/uniswapx/v4/interfaces/IHook.sol +++ b/src/briefcase/protocols/uniswapx/v4/interfaces/IHook.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.6.2; -import {ResolvedOrder} from '../base/ReactorStructs.sol'; +import {ResolvedOrder_1} from '../base/ReactorStructs.sol'; /// @notice Hook to be called before order execution, allowing state modifications interface IPreExecutionHook { /// @notice Called by the reactor before order execution for custom validation and state changes /// @param filler The filler of the order /// @param resolvedOrder The resolved order to fill - function preExecutionHook(address filler, ResolvedOrder calldata resolvedOrder) external; + function preExecutionHook(address filler, ResolvedOrder_1 calldata resolvedOrder) external; } /// @notice Hook to be called after transferring output tokens, enabling chained actions @@ -16,5 +16,5 @@ interface IPostExecutionHook { /// @notice Called by the reactor after order execution for chained actions /// @param filler The filler of the order /// @param resolvedOrder The resolved order that was filled - function postExecutionHook(address filler, ResolvedOrder calldata resolvedOrder) external; + function postExecutionHook(address filler, ResolvedOrder_1 calldata resolvedOrder) external; } diff --git a/src/briefcase/protocols/uniswapx/v4/interfaces/IReactor.sol b/src/briefcase/protocols/uniswapx/v4/interfaces/IReactor.sol index ecdf84c7..2cc69e94 100644 --- a/src/briefcase/protocols/uniswapx/v4/interfaces/IReactor.sol +++ b/src/briefcase/protocols/uniswapx/v4/interfaces/IReactor.sol @@ -4,7 +4,7 @@ pragma solidity >=0.6.2; import {SignedOrder} from '../../base/ReactorStructs.sol'; /// @notice Interface for order execution reactors -interface IReactor { +interface IReactor_1 { /// @notice thrown when an auction resolver is not set error EmptyAuctionResolver(); /// @notice thrown when the order targets a different reactor diff --git a/src/briefcase/protocols/universal-router/interfaces/ISwapProxy.sol b/src/briefcase/protocols/universal-router/interfaces/ISwapProxy.sol new file mode 100644 index 00000000..b47bca38 --- /dev/null +++ b/src/briefcase/protocols/universal-router/interfaces/ISwapProxy.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.6.2; + +import {IUniversalRouter} from './IUniversalRouter.sol'; + +/// @title ISwapProxy +/// @notice Interface for the SwapProxy contract that enables 2-tx swap flow without Permit2 +interface ISwapProxy { + /// @notice Pull ERC20 tokens from msg.sender into the Universal Router, then execute commands + /// @param router The Universal Router to execute commands on + /// @param token The ERC20 token to pull from the caller + /// @param amount The amount of tokens to transfer into the UR + /// @param commands The encoded UR commands to execute + /// @param inputs The encoded inputs for each command + /// @param deadline The transaction deadline + function execute( + IUniversalRouter router, + address token, + uint256 amount, + bytes calldata commands, + bytes[] calldata inputs, + uint256 deadline + ) external; +} diff --git a/src/briefcase/protocols/universal-router/libraries/Commands.sol b/src/briefcase/protocols/universal-router/libraries/Commands.sol index 160e1d49..7861feac 100644 --- a/src/briefcase/protocols/universal-router/libraries/Commands.sol +++ b/src/briefcase/protocols/universal-router/libraries/Commands.sol @@ -19,7 +19,7 @@ library Commands { uint256 constant SWEEP = 0x04; uint256 constant TRANSFER = 0x05; uint256 constant PAY_PORTION = 0x06; - // COMMAND_PLACEHOLDER = 0x07; + uint256 constant PAY_PORTION_FULL_PRECISION = 0x07; // Command Types where 0x08<=value<=0x0f, executed in the second nested-if block uint256 constant V2_SWAP_EXACT_IN = 0x08; diff --git a/src/briefcase/protocols/universal-router/libraries/Constants.sol b/src/briefcase/protocols/universal-router/libraries/Constants.sol index 636da1d1..4ce0d342 100644 --- a/src/briefcase/protocols/universal-router/libraries/Constants.sol +++ b/src/briefcase/protocols/universal-router/libraries/Constants.sol @@ -25,4 +25,7 @@ library Constants { /// @dev The minimum length of an encoding that contains 2 or more pools uint256 internal constant MULTIPLE_V3_POOLS_MIN_LENGTH = V3_POP_OFFSET + NEXT_V3_POOL_OFFSET; + + /// @dev Precision multiplier for per-hop price calculations + uint256 internal constant PRICE_PRECISION = 1e36; } diff --git a/src/briefcase/protocols/universal-router/modules/uniswap/v3/BytesLib.sol b/src/briefcase/protocols/universal-router/modules/uniswap/v3/BytesLib.sol index 1e06693f..228fcfd5 100644 --- a/src/briefcase/protocols/universal-router/modules/uniswap/v3/BytesLib.sol +++ b/src/briefcase/protocols/universal-router/modules/uniswap/v3/BytesLib.sol @@ -50,16 +50,18 @@ library BytesLib { pure returns (uint256 length, uint256 offset) { - uint256 relativeOffset; assembly { // The offset of the `_arg`-th element is `32 * arg`, which stores the offset of the length pointer. // shl(5, x) is equivalent to mul(32, x) let lengthPtr := add(_bytes.offset, calldataload(add(_bytes.offset, shl(5, _arg)))) length := calldataload(lengthPtr) offset := add(lengthPtr, 0x20) - relativeOffset := sub(offset, _bytes.offset) + let relativeOffset := sub(offset, _bytes.offset) + if lt(_bytes.length, add(shl(5, length), relativeOffset)) { + mstore(0, 0x3b99b53d) // SliceOutOfBounds() + revert(0x1c, 0x04) + } } - if (_bytes.length < length + relativeOffset) revert SliceOutOfBounds(); } /// @notice Decode the `_arg`-th element in `_bytes` as `address[]` @@ -73,6 +75,17 @@ library BytesLib { } } + /// @notice Decode the `_arg`-th element in `_bytes` as `uint256[]` + /// @param _bytes The input bytes string to extract a uint256 array from + /// @param _arg The index of the argument to extract + function toUint256Array(bytes calldata _bytes, uint256 _arg) internal pure returns (uint256[] calldata res) { + (uint256 length, uint256 offset) = toLengthOffset(_bytes, _arg); + assembly { + res.length := length + res.offset := offset + } + } + /// @notice Equivalent to abi.decode(bytes, bytes[]) /// @param _bytes The input bytes string to extract an parameters from function decodeCommandsAndInputs(bytes calldata _bytes) internal pure returns (bytes calldata, bytes[] calldata) { diff --git a/src/briefcase/protocols/universal-router/types/RouterParameters.sol b/src/briefcase/protocols/universal-router/types/RouterParameters.sol index c5f26e11..742cfd67 100644 --- a/src/briefcase/protocols/universal-router/types/RouterParameters.sol +++ b/src/briefcase/protocols/universal-router/types/RouterParameters.sol @@ -11,6 +11,7 @@ struct RouterParameters { bytes32 pairInitCodeHash; bytes32 poolInitCodeHash; address v4PoolManager; + address permissionsAdapterFactory; // Uniswap v3->v4 migration parameters address v3NFTPositionManager; address v4PositionManager; diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLite.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLite.sol new file mode 100644 index 00000000..c40310bf --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLite.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IFluidDexLite +/// @notice Interface for the Fluid DEX Lite pool +interface IFluidDexLite { + struct DexKey { + address token0; + address token1; + bytes32 salt; + } + + struct DexState { + DexVariables dexVariables; + CenterPriceShift centerPriceShift; + RangeShift rangeShift; + ThresholdShift thresholdShift; + } + + struct DexVariables { + uint256 fee; + uint256 revenueCut; + uint256 rebalancingStatus; + bool isCenterPriceShiftActive; + uint256 centerPrice; + address centerPriceAddress; + bool isRangePercentShiftActive; + uint256 upperRangePercent; + uint256 lowerRangePercent; + bool isThresholdPercentShiftActive; + uint256 upperShiftThresholdPercent; + uint256 lowerShiftThresholdPercent; + uint256 token0Decimals; + uint256 token1Decimals; + uint256 totalToken0AdjustedAmount; + uint256 totalToken1AdjustedAmount; + } + + struct CenterPriceShift { + uint256 lastInteractionTimestamp; + uint256 rebalancingShiftingTime; + uint256 maxCenterPrice; + uint256 minCenterPrice; + uint256 shiftPercentage; + uint256 centerPriceShiftingTime; + uint256 startTimestamp; + } + + struct RangeShift { + uint256 oldUpperRangePercent; + uint256 oldLowerRangePercent; + uint256 shiftingTime; + uint256 startTimestamp; + } + + struct ThresholdShift { + uint256 oldUpperThresholdPercent; + uint256 oldLowerThresholdPercent; + uint256 shiftingTime; + uint256 startTimestamp; + } + + struct Prices { + uint256 poolPrice; + uint256 centerPrice; + uint256 upperRangePrice; + uint256 lowerRangePrice; + uint256 upperThresholdPrice; + uint256 lowerThresholdPrice; + } + + struct Reserves { + uint256 token0RealReserves; + uint256 token1RealReserves; + uint256 token0ImaginaryReserves; + uint256 token1ImaginaryReserves; + } + + struct ConstantViews { + address liquidity; + address deployer; + } + + struct DexEntireData { + bytes8 dexId; + DexKey dexKey; + ConstantViews constantViews; + Prices prices; + Reserves reserves; + DexState dexState; + } + + /// @notice Executes a single-hop swap on the Fluid DEX Lite pool + /// @param dexKey_ The unique key identifying the DEX pool (token0, token1, salt) + /// @param swap0To1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0 + /// @param amountSpecified_ The amount to swap. Positive for exact input, negative for exact output + /// @param amountLimit_ Slippage protection. Min output for exact-in, max input for exact-out + /// @param to_ The recipient address for the output tokens + /// @param isCallback_ If true, uses callback mechanism for token transfer instead of direct transfer + /// @param callbackData_ Arbitrary data passed to the callback function if isCallback_ is true + /// @param extraData_ Additional data for specialized swap logic + /// @return amountUnspecified_ The unspecified amount (output for exact-in, input for exact-out) + function swapSingle( + DexKey calldata dexKey_, + bool swap0To1_, + int256 amountSpecified_, + uint256 amountLimit_, + address to_, + bool isCallback_, + bytes calldata callbackData_, + bytes calldata extraData_ + ) external payable returns (uint256 amountUnspecified_); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLiteCallback.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLiteCallback.sol new file mode 100644 index 00000000..ac8ded44 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLiteCallback.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IFluidDexLiteCallback +/// @notice Callback interface required by Fluid DEX Lite swaps when isCallback is true +interface IFluidDexLiteCallback { + /// @notice Called by Fluid DEX Lite to request token transfer from the caller + /// @dev Must transfer exactly `amount_` of `token_` to msg.sender (the DEX) + /// @param token_ The token address that must be transferred + /// @param amount_ The amount of tokens that must be transferred + /// @param data_ Arbitrary callback data passed through from the swap call + function dexCallback(address token_, uint256 amount_, bytes calldata data_) external; +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLiteResolver.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLiteResolver.sol new file mode 100644 index 00000000..03546f12 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexLite/interfaces/IFluidDexLiteResolver.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IFluidDexLite} from './IFluidDexLite.sol'; + +/// @title IFluidDexLiteResolver +/// @notice Interface for the Fluid DEX Lite resolver +interface IFluidDexLiteResolver { + /// @notice Returns all registered DEX pools + /// @return An array of DexKey structs identifying each pool + function getAllDexes() external view returns (IFluidDexLite.DexKey[] memory); + + /// @notice Retrieves the current state configuration of a DEX pool + /// @param dexKey The unique key identifying the DEX pool + /// @return The current DexState including variables, shifts, and thresholds + function getDexState(IFluidDexLite.DexKey memory dexKey) external view returns (IFluidDexLite.DexState memory); + + /// @notice Retrieves complete data for a DEX pool including state, prices, and reserves + /// @param dexKey The unique key identifying the DEX pool + /// @return Complete DexEntireData struct with all pool information + function getDexEntireData(IFluidDexLite.DexKey memory dexKey) external returns (IFluidDexLite.DexEntireData memory); + + /// @notice Retrieves current prices and reserves for a DEX pool + /// @param dexKey The unique key identifying the DEX pool + /// @return Prices struct with pool, center, range, and threshold prices + /// @return Reserves struct with real and imaginary reserves for both tokens + function getPricesAndReserves(IFluidDexLite.DexKey memory dexKey) + external + returns (IFluidDexLite.Prices memory, IFluidDexLite.Reserves memory); + + /// @notice Estimates the result of a single-hop swap without executing it + /// @param dexKey The unique key identifying the DEX pool + /// @param swap0To1 Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0 + /// @param amountSpecified The amount to swap. Positive for exact input, negative for exact output + /// @return The estimated unspecified amount (output for exact-in, input for exact-out) + function estimateSwapSingle(IFluidDexLite.DexKey calldata dexKey, bool swap0To1, int256 amountSpecified) + external + returns (uint256); + + /// @notice Estimates the result of a multi-hop swap without executing it + /// @param path Array of token addresses representing the swap route + /// @param dexKeys Array of DexKey structs for each hop in the route + /// @param amountSpecified The amount to swap. Positive for exact input, negative for exact output + /// @return The estimated final output amount + function estimateSwapHop(address[] calldata path, IFluidDexLite.DexKey[] calldata dexKeys, int256 amountSpecified) + external + view + returns (uint256); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IDexCallback.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IDexCallback.sol new file mode 100644 index 00000000..649f755d --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IDexCallback.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IDexCallback +/// @notice Callback interface required by Fluid DEX v1 "withCallback" swaps +interface IDexCallback { + /// @notice dex liquidity callback + /// @param token_ The token being transferred + /// @param amount_ The amount being transferred + function dexCallback(address token_, uint256 amount_) external; +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexReservesResolver.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexReservesResolver.sol new file mode 100644 index 00000000..ae2a405e --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexReservesResolver.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IFluidDexT1} from './IFluidDexT1.sol'; + +/// @title IFluidDexReservesResolver +/// @notice Interface for the Fluid DEX T1 reserves resolver +interface IFluidDexReservesResolver { + struct DexLimits { + TokenLimit withdrawableToken0; + TokenLimit withdrawableToken1; + TokenLimit borrowableToken0; + TokenLimit borrowableToken1; + } + + struct TokenLimit { + uint256 available; + uint256 expandsTo; + uint256 expandDuration; + } + + struct PoolWithReserves { + address pool; + address token0; + address token1; + uint256 fee; + uint256 centerPrice; + IFluidDexT1.CollateralReserves collateralReserves; + IFluidDexT1.DebtReserves debtReserves; + DexLimits limits; + } + + /// @notice Get pool data with reserves for a specific DEX + /// @param pool_ The address of the pool + /// @return poolReserves_ The pool data including reserves + /// @dev Matches Fluid's FluidDexReservesResolver.getPoolReserves + function getPoolReserves(address pool_) external view returns (PoolWithReserves memory poolReserves_); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexResolver.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexResolver.sol new file mode 100644 index 00000000..b817302b --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexResolver.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IFluidDexResolver +/// @notice Interface for the Fluid DEX T1 resolver +interface IFluidDexResolver { + /// @notice Get the addresses of the tokens in a DEX + /// @param dex_ The address of the DEX + /// @return token0_ The address of token0 in the DEX + /// @return token1_ The address of token1 in the DEX + function getDexTokens(address dex_) external view returns (address token0_, address token1_); + + /// @notice estimates swap IN tokens execution + /// @param dex_ Dex pool + /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0 + /// @param amountIn_ The exact amount of input tokens to swap + /// @param amountOutMin_ The minimum amount of output tokens the user is willing to accept + /// @return amountOut_ The amount of output tokens received from the swap + function estimateSwapIn(address dex_, bool swap0to1_, uint256 amountIn_, uint256 amountOutMin_) + external + payable + returns (uint256 amountOut_); + + /// @notice estimates swap OUT tokens execution + /// @param dex_ Dex pool + /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0 + /// @param amountOut_ The exact amount of tokens to receive after swap + /// @param amountInMax_ Maximum amount of tokens to swap in + /// @return amountIn_ The amount of input tokens used for the swap + function estimateSwapOut(address dex_, bool swap0to1_, uint256 amountOut_, uint256 amountInMax_) + external + payable + returns (uint256 amountIn_); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexT1.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexT1.sol new file mode 100644 index 00000000..93b0806a --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/FluidDexT1/interfaces/IFluidDexT1.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IFluidDexT1 +/// @notice Interface for the Fluid DEX T1 pool (colloquially Fluid DEX v1) +interface IFluidDexT1 { + struct CollateralReserves { + uint256 token0RealReserves; + uint256 token1RealReserves; + uint256 token0ImaginaryReserves; + uint256 token1ImaginaryReserves; + } + + struct DebtReserves { + uint256 token0Debt; + uint256 token1Debt; + uint256 token0RealReserves; + uint256 token1RealReserves; + uint256 token0ImaginaryReserves; + uint256 token1ImaginaryReserves; + } + + /// @notice Executes a swap with an exact input amount + /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0 + /// @param amountIn_ The exact amount of input tokens to swap + /// @param amountOutMin_ The minimum amount of output tokens the user is willing to accept + /// @param to_ The recipient address for the output tokens + /// @return amountOut_ The amount of output tokens received from the swap + function swapIn(bool swap0to1_, uint256 amountIn_, uint256 amountOutMin_, address to_) + external + payable + returns (uint256 amountOut_); + + /// @notice Executes a swap with an exact output amount + /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0 + /// @param amountOut_ The exact amount of output tokens to receive + /// @param amountInMax_ The maximum amount of input tokens the user is willing to spend + /// @param to_ The recipient address for the output tokens + /// @return amountIn_ The amount of input tokens used for the swap + function swapOut(bool swap0to1_, uint256 amountOut_, uint256 amountInMax_, address to_) + external + payable + returns (uint256 amountIn_); + + /// @notice Executes a swap with an exact input amount using a callback for token transfer + /// @dev The caller must implement IFluidDexCallback to provide the input tokens + /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0 + /// @param amountIn_ The exact amount of input tokens to swap + /// @param amountOutMin_ The minimum amount of output tokens the user is willing to accept + /// @param to_ The recipient address for the output tokens + /// @return amountOut_ The amount of output tokens received from the swap + function swapInWithCallback(bool swap0to1_, uint256 amountIn_, uint256 amountOutMin_, address to_) + external + payable + returns (uint256 amountOut_); + + /// @notice Executes a swap with an exact output amount using a callback for token transfer + /// @dev The caller must implement IFluidDexCallback to provide the input tokens + /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0 + /// @param amountOut_ The exact amount of output tokens to receive + /// @param amountInMax_ The maximum amount of input tokens the user is willing to spend + /// @param to_ The recipient address for the output tokens + /// @return amountIn_ The amount of input tokens used for the swap + function swapOutWithCallback(bool swap0to1_, uint256 amountOut_, uint256 amountInMax_, address to_) + external + payable + returns (uint256 amountIn_); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/PancakeSwapV3/interfaces/IPancakeSwapV3Callback.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/PancakeSwapV3/interfaces/IPancakeSwapV3Callback.sol new file mode 100644 index 00000000..eb178afd --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/PancakeSwapV3/interfaces/IPancakeSwapV3Callback.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IPancakeSwapV3Callback +/// @notice Callback from PancakeSwap V3 compatible pools during swap (matches `IPancakeV3SwapCallback` on-chain name) +interface IPancakeSwapV3Callback { + /// @notice Called to `msg.sender` after executing a swap on the pool + /// @param amount0Delta Owed amount of token0: pay pool if positive, receive from pool if negative + /// @param amount1Delta Owed amount of token1: pay pool if positive, receive from pool if negative + /// @param data Arbitrary data forwarded from the `swap` call, e.g. payer routing + function pancakeV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external; +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/Slipstream/interfaces/IQuoterV2.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/Slipstream/interfaces/IQuoterV2.sol new file mode 100644 index 00000000..25444896 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/Slipstream/interfaces/IQuoterV2.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IQuoterV2 +/// @notice Aerodrome Slipstream Base quoter ABI (`int24 tickSpacing` — Uni QuoterV2 uses `uint24 fee`). +interface IQuoterV2 { + struct QuoteExactInputSingleParams { + address tokenIn; + address tokenOut; + uint256 amountIn; + int24 tickSpacing; + uint160 sqrtPriceLimitX96; + } + + struct QuoteExactOutputSingleParams { + address tokenIn; + address tokenOut; + uint256 amountOut; + int24 tickSpacing; + uint160 sqrtPriceLimitX96; + } + + /// @notice Simulates a single-hop exact-input swap and returns the output amount without state changes + /// @param params Single-hop exact-input quote parameters + /// @return amountOut Amount of `tokenOut` that would be received for `params.amountIn` + function quoteExactInputSingle(QuoteExactInputSingleParams memory params) external returns (uint256 amountOut); + + /// @notice Simulates a single-hop exact-output swap and returns the required input without state changes + /// @param params Single-hop exact-output quote parameters + /// @return amountIn Amount of `tokenIn` required to receive `params.amountOut` + function quoteExactOutputSingle(QuoteExactOutputSingleParams memory params) external returns (uint256 amountIn); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/Slipstream/interfaces/ISlipstreamFactory.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/Slipstream/interfaces/ISlipstreamFactory.sol new file mode 100644 index 00000000..4ea532ba --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/Slipstream/interfaces/ISlipstreamFactory.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title ISlipstreamFactory +/// @notice Slipstream-style concentrated liquidity pools keyed by tickSpacing (e.g. Aerodrome Slipstream) +interface ISlipstreamFactory { + /// @notice Returns the pool address for a pair and tick spacing, or `address(0)` if it does not exist + /// @param tokenA One token of the pair + /// @param tokenB The other token of the pair + /// @param tickSpacing Tick spacing of the pool + /// @return pool The pool contract, or zero address if none deployed + function getPool(address tokenA, address tokenB, int24 tickSpacing) external view returns (address pool); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/ICurveFactory.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/ICurveFactory.sol new file mode 100644 index 00000000..2f304f6b --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/ICurveFactory.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title ICurveFactory +/// @notice Interface for Curve Metapool Factory +/// @dev Based on the factory at https://github.com/curvefi/curve-factory/blob/master/contracts/Factory.vy +interface ICurveFactory { + /// @notice Deploy a new plain pool with all parameters (selector: 0x52f2db69) + /// @param _name Name of the new plain pool + /// @param _symbol Symbol for the new plain pool's LP token + /// @param _coins Fixed array of 4 coin addresses (use address(0) for unused slots) + /// @param _A Amplification coefficient + /// @param _fee Trade fee with 1e10 precision (min 0.04% = 4000000, max 1% = 100000000) + /// @param _asset_type Asset type (0=USD, 1=ETH, 2=BTC, 3=Other) + /// @param _implementation_idx Index of the implementation to use + /// @return The address of the deployed pool + function deploy_plain_pool( + string memory _name, + string memory _symbol, + address[4] memory _coins, + uint256 _A, + uint256 _fee, + uint256 _asset_type, + uint256 _implementation_idx + ) external returns (address); + + /// @notice Deploy a new plain pool with asset_type, impl_idx defaults to 0 (selector: 0x5c16487b) + function deploy_plain_pool( + string memory _name, + string memory _symbol, + address[4] memory _coins, + uint256 _A, + uint256 _fee, + uint256 _asset_type + ) external returns (address); + + /// @notice Deploy a new plain pool with defaults for asset_type and impl_idx (selector: 0xcd419bb5) + function deploy_plain_pool( + string memory _name, + string memory _symbol, + address[4] memory _coins, + uint256 _A, + uint256 _fee + ) external returns (address); + + /// @notice Deploy a new metapool + /// @param _base_pool Address of the base pool to pair with + /// @param _name Name of the new metapool + /// @param _symbol Symbol for the new metapool's LP token + /// @param _coin Address of the coin being used in the metapool + /// @param _A Amplification coefficient + /// @param _fee Trade fee with 1e10 precision + /// @param _implementation_idx Index of the implementation to use + /// @return The address of the deployed metapool + function deploy_metapool( + address _base_pool, + string memory _name, + string memory _symbol, + address _coin, + uint256 _A, + uint256 _fee, + uint256 _implementation_idx + ) external returns (address); + + /// @notice Get plain pool implementation address + /// @param n_coins Number of coins in the pool + /// @param idx Implementation index + /// @return Implementation address + function plain_implementations(uint256 n_coins, uint256 idx) external view returns (address); + + /// @notice Get metapool implementations for a base pool + /// @param _base_pool Base pool address + /// @return Array of implementation addresses + function metapool_implementations(address _base_pool) external view returns (address[10] memory); + + /// @notice Returns the admin address + function admin() external view returns (address); + + /// @notice Returns the fee receiver address + function fee_receiver() external view returns (address); + + /// @notice Returns the number of deployed pools + function pool_count() external view returns (uint256); + + /// @notice Returns the pool address at the given index + function pool_list(uint256 index) external view returns (address); + + /// @notice Get implementation address for a pool + /// @param _pool Pool address + /// @return Implementation address + function get_implementation_address(address _pool) external view returns (address); + + /// @notice Get coins in a pool + /// @param _pool Pool address + /// @return Array of coin addresses + function get_coins(address _pool) external view returns (address[4] memory); + + /// @notice Get number of coins in a pool + /// @param _pool Pool address + /// @return Number of coins and underlying coins + function get_n_coins(address _pool) external view returns (uint256[2] memory); + + /// @notice Get balances of coins in a pool + /// @param _pool Pool address + /// @return Array of balances + function get_balances(address _pool) external view returns (uint256[4] memory); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/IMetaRegistry.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/IMetaRegistry.sol new file mode 100644 index 00000000..ee27b35f --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/IMetaRegistry.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IMetaRegistry +/// @notice Minimal interface for Curve's MetaRegistry to check meta pool status +/// @dev See https://docs.curve.finance/developer/integration/meta-registry#is_meta +interface IMetaRegistry { + /// @notice Check if a pool is a metapool + /// @param _pool Address of the pool + /// @param _handler_id ID of the RegistryHandler + /// @return True if the pool is a metapool + function is_meta(address _pool, uint256 _handler_id) external view returns (bool); + + /// @notice Check if a pool is registered in Curve's registry + /// @param _pool Address of the pool + /// @param _handler_id ID of the RegistryHandler (0 for default) + /// @return True if the pool is registered + /// @dev Reverts if the pool is not in any registry + function is_registered(address _pool, uint256 _handler_id) external view returns (bool); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/IStableSwap.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/IStableSwap.sol new file mode 100644 index 00000000..99af3b0c --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwap/interfaces/IStableSwap.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title ICurveStableSwap +/// @notice Interface for Curve StableSwap pools +/// @dev We have to write our own interface file since the source code is in vyper +interface ICurveStableSwap { + /// @notice Calculates the expected output amount for a swap + /// @param i Index of the input token in the pool + /// @param j Index of the output token in the pool + /// @param dx Amount of input tokens to swap + /// @return The expected amount of output tokens + function get_dy(int128 i, int128 j, uint256 dx) external view returns (uint256); + + /// @notice Executes a token swap + /// @param i Index of the input token in the pool + /// @param j Index of the output token in the pool + /// @param dx Amount of input tokens to swap + /// @param min_dy Minimum amount of output tokens to receive (slippage protection) + /// @return The actual amount of output tokens received + function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable returns (uint256); + + /// @notice Returns the token address at a given index + /// @param i Index of the token in the pool + /// @return The token address at that index + function coins(uint256 i) external view returns (address); + + /// @notice Returns the balance of a token at a given index + /// @param i Index of the token in the pool + /// @return The balance of the token at that index + function balances(uint256 i) external view returns (uint256); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwapNG/interfaces/ICurveStableSwapFactoryNG.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwapNG/interfaces/ICurveStableSwapFactoryNG.sol new file mode 100644 index 00000000..06b80678 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwapNG/interfaces/ICurveStableSwapFactoryNG.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title ICurveStableSwapFactoryNG +/// @notice Interface for Curve StableSwap NG Factory +/// @dev Based on the Vyper implementation at https://github.com/curvefi/stableswap-ng +interface ICurveStableSwapFactoryNG { + /// @notice Deploy a new plain pool + /// @param _name Name of the new plain pool + /// @param _symbol Symbol for the new plain pool + /// @param _coins List of addresses of the coins being used in the pool + /// @param _A Amplification coefficient (suggested: 5-10 for algo stables, 100 for non-redeemable, 200-400 for redeemable) + /// @param _fee Trade fee with 1e10 precision (max 1% = 100000000) + /// @param _offpeg_fee_multiplier Off-peg fee multiplier + /// @param _ma_exp_time Moving average time window (e.g., 866 for 10 min EMA) + /// @param _implementation_idx Index of the implementation to use + /// @param _asset_types Asset types (0=Standard, 1=Oracle, 2=Rebasing, 3=ERC4626) + /// @param _method_ids Method IDs for rate oracles (use bytes4(0) for standard tokens) + /// @param _oracles Oracle addresses (use address(0) for standard tokens) + /// @return The address of the deployed pool + function deploy_plain_pool( + string memory _name, + string memory _symbol, + address[] memory _coins, + uint256 _A, + uint256 _fee, + uint256 _offpeg_fee_multiplier, + uint256 _ma_exp_time, + uint256 _implementation_idx, + uint8[] memory _asset_types, + bytes4[] memory _method_ids, + address[] memory _oracles + ) external returns (address); + + /// @notice Set implementation contracts for pools + /// @param _implementation_index Implementation index where implementation is stored + /// @param _implementation Implementation address to use when deploying plain pools + function set_pool_implementations(uint256 _implementation_index, address _implementation) external; + + /// @notice Set implementation contracts for metapools + /// @param _implementation_index Implementation index where implementation is stored + /// @param _implementation Implementation address to use when deploying metapools + function set_metapool_implementations(uint256 _implementation_index, address _implementation) external; + + /// @notice Set implementation contract for StableSwap Math + /// @param _math_implementation Address of the math implementation contract + function set_math_implementation(address _math_implementation) external; + + /// @notice Set implementation contract for Views methods + /// @param _views_implementation Implementation address of views contract + function set_views_implementation(address _views_implementation) external; + + /// @notice Set gauge implementation address + /// @param _gauge_implementation Address of the gauge implementation + function set_gauge_implementation(address _gauge_implementation) external; + + /// @notice Returns the admin address + function admin() external view returns (address); + + /// @notice Returns the fee receiver address + function fee_receiver() external view returns (address); + + /// @notice Returns the math implementation address + function math_implementation() external view returns (address); + + /// @notice Returns the views implementation address + function views_implementation() external view returns (address); + + /// @notice Returns the pool implementation at the given index + function pool_implementations(uint256 index) external view returns (address); + + /// @notice Returns the number of deployed pools + function pool_count() external view returns (uint256); + + /// @notice Returns the pool address at the given index + function pool_list(uint256 index) external view returns (address); + + /// @notice Check if a pool is a metapool + /// @param _pool Address of the pool + /// @return True if the pool is a metapool + function is_meta(address _pool) external view returns (bool); + + /// @notice Get the number of coins in a pool + /// @param _pool Pool address (must be deployed by this factory) + /// @return Number of coins in the pool + /// @dev Reverts if pool was not deployed by this factory + function get_n_coins(address _pool) external view returns (uint256); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwapNG/interfaces/ICurveStableSwapNG.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwapNG/interfaces/ICurveStableSwapNG.sol new file mode 100644 index 00000000..a1e77b7a --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/StableSwapNG/interfaces/ICurveStableSwapNG.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title ICurveStableSwapNG +/// @notice Interface for Curve StableSwap NG pools +/// @dev Based on the Vyper implementation at https://github.com/curvefi/stableswap-ng +/// @dev We have to write our own interface file since the source code is in vyper +interface ICurveStableSwapNG { + /// @notice Calculates the required input amount for a desired output (inverse quote) + /// @param i Index of the input token in the pool + /// @param j Index of the output token in the pool + /// @param dy Desired amount of output tokens + /// @return The required amount of input tokens + function get_dx(int128 i, int128 j, uint256 dy) external view returns (uint256); + + /// @notice Calculates the expected output amount for a swap + /// @param i Index of the input token in the pool + /// @param j Index of the output token in the pool + /// @param dx Amount of input tokens to swap + /// @return The expected amount of output tokens + function get_dy(int128 i, int128 j, uint256 dx) external view returns (uint256); + + /// @notice Executes a token swap with custom receiver + /// @param i Index of the input token in the pool + /// @param j Index of the output token in the pool + /// @param dx Amount of input tokens to swap + /// @param min_dy Minimum amount of output tokens to receive (slippage protection) + /// @param receiver Address to receive the output tokens + /// @return The actual amount of output tokens received + function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy, address receiver) external returns (uint256); + + /// @notice Returns the number of coins in the pool + /// @return The number of tokens in this pool + function N_COINS() external view returns (uint256); + + /// @notice Returns the token address at a given index + /// @param i Index of the token in the pool + /// @return The token address at that index + function coins(uint256 i) external view returns (address); + + /// @notice Returns the balance of a token at a given index + /// @param i Index of the token in the pool + /// @return The balance of the token at that index + function balances(uint256 i) external view returns (uint256); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/TempoExchange/interfaces/ITIP20.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/TempoExchange/interfaces/ITIP20.sol new file mode 100644 index 00000000..764e7fad --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/TempoExchange/interfaces/ITIP20.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title ITIP20 +/// @notice Interface for Tempo TIP-20 tokens (precompile stablecoins) +/// @dev Each TIP-20 token defines a quoteToken() forming a DEX tree. PathUSD is the root (quoteToken = address(0)). +interface ITIP20 { + /// @notice Returns the token name + function name() external view returns (string memory); + + /// @notice Returns the token symbol + function symbol() external view returns (string memory); + + /// @notice Returns the parent token in the DEX tree + /// @dev PathUSD (the root token) returns address(0) + function quoteToken() external view returns (address); + + /// @notice Returns the total supply of the token + function totalSupply() external view returns (uint256); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/TempoExchange/interfaces/ITempoExchange.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/TempoExchange/interfaces/ITempoExchange.sol new file mode 100644 index 00000000..838099a1 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/TempoExchange/interfaces/ITempoExchange.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title ITempoExchange +/// @notice Interface for Tempo's enshrined stablecoin DEX +/// @dev Tempo uses uint128 for amounts, not uint256. All stablecoins use 6 decimals. +/// @dev The exchange is a precompiled contract at a fixed address on Tempo chain. +interface ITempoExchange { + /// @notice Executes a swap with an exact input amount + /// @param tokenIn The address of the input token + /// @param tokenOut The address of the output token + /// @param amountIn The exact amount of input tokens to swap + /// @param minAmountOut The minimum amount of output tokens to receive (slippage protection) + /// @return amountOut The amount of output tokens received + function swapExactAmountIn(address tokenIn, address tokenOut, uint128 amountIn, uint128 minAmountOut) + external + returns (uint128 amountOut); + + /// @notice Executes a swap with an exact output amount + /// @param tokenIn The address of the input token + /// @param tokenOut The address of the output token + /// @param amountOut The exact amount of output tokens to receive + /// @param maxAmountIn The maximum amount of input tokens to spend (slippage protection) + /// @return amountIn The amount of input tokens spent + function swapExactAmountOut(address tokenIn, address tokenOut, uint128 amountOut, uint128 maxAmountIn) + external + returns (uint128 amountIn); + + /// @notice Calculates the expected output amount for an exact input swap + /// @param tokenIn The address of the input token + /// @param tokenOut The address of the output token + /// @param amountIn The amount of input tokens + /// @return amountOut The expected amount of output tokens + function quoteSwapExactAmountIn(address tokenIn, address tokenOut, uint128 amountIn) + external + view + returns (uint128 amountOut); + + /// @notice Calculates the required input amount for an exact output swap + /// @param tokenIn The address of the input token + /// @param tokenOut The address of the output token + /// @param amountOut The desired amount of output tokens + /// @return amountIn The required amount of input tokens + function quoteSwapExactAmountOut(address tokenIn, address tokenOut, uint128 amountOut) + external + view + returns (uint128 amountIn); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV2/interfaces/IUniswapV2Factory.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV2/interfaces/IUniswapV2Factory.sol new file mode 100644 index 00000000..cf92c0c8 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV2/interfaces/IUniswapV2Factory.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @notice Minimal subset of canonical Uniswap V2 factory surface +interface IUniswapV2Factory { + function getPair(address tokenA, address tokenB) external view returns (address pair); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV2/interfaces/IUniswapV2Pair.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV2/interfaces/IUniswapV2Pair.sol new file mode 100644 index 00000000..7350159d --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV2/interfaces/IUniswapV2Pair.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @notice Minimal subset of canonical Uniswap V2 pair surface +interface IUniswapV2Pair { + function token0() external view returns (address); + function token1() external view returns (address); + + function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); + + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3Factory.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3Factory.sol new file mode 100644 index 00000000..ad2ea9b5 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3Factory.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IUniswapV3Factory +/// @notice Minimal Uniswap V3 factory (fee-tier pool lookup) +interface IUniswapV3Factory { + /// @notice Returns the pool address for a pair and fee tier, or `address(0)` if it does not exist + /// @param tokenA One token of the pair + /// @param tokenB The other token of the pair + /// @param fee Fee tier of the pool + /// @return pool The pool contract, or zero address if none deployed + function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3Pool.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3Pool.sol new file mode 100644 index 00000000..1e6aad4a --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3Pool.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IUniswapV3Pool +/// @notice Minimal Uniswap V3 compatible pool interface +interface IUniswapV3Pool { + /// @notice First token of the pool by address sort order + /// @return Token address of token0 + function token0() external view returns (address); + + /// @notice Second token of the pool by address sort order + /// @return Token address of token1 + function token1() external view returns (address); + + /// @notice Swap fee of the pool, in hundredths of a bip (i.e. 1e6 = 100%) + /// @return Fee tier identifier + function fee() external view returns (uint24); + + /// @notice Minimum number of ticks between initialized ticks + /// @return Spacing between usable ticks + function tickSpacing() external view returns (int24); + + /// @notice Execute a swap against the pool + /// @param recipient Address that receives the output of the swap + /// @param zeroForOne When true, swap token0 for token1; when false, token1 for token0 + /// @param amountSpecified Amount of swap: exact input is positive, exact output is negative (periphery-style) + /// @param sqrtPriceLimitX96 Price limit for the swap (Q64.96); pool price will not cross this bound + /// @param data Opaque bytes passed through to `IUniswapV3SwapCallback.uniswapV3SwapCallback` + /// @return amount0 Delta of the pool's token0 balance (negative if pool received token0) + /// @return amount1 Delta of the pool's token1 balance (negative if pool received token1) + function swap( + address recipient, + bool zeroForOne, + int256 amountSpecified, + uint160 sqrtPriceLimitX96, + bytes calldata data + ) external returns (int256 amount0, int256 amount1); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3SwapCallback.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3SwapCallback.sol new file mode 100644 index 00000000..0fa73c24 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/implementations/UniswapV3/interfaces/IUniswapV3SwapCallback.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @title IUniswapV3SwapCallback +/// @notice Callback from Uniswap V3 compatible pools during swap +interface IUniswapV3SwapCallback { + /// @notice Called to `msg.sender` after executing a swap on the pool + /// @param amount0Delta Owed amount of token0: pay pool if positive, receive from pool if negative + /// @param amount1Delta Owed amount of token1: pay pool if positive, receive from pool if negative + /// @param data Arbitrary data forwarded from the `swap` call, e.g. payer routing + function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external; +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/interfaces/IAggregatorHook.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/interfaces/IAggregatorHook.sol new file mode 100644 index 00000000..76bd9439 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/interfaces/IAggregatorHook.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {PoolId} from '../../../v4-core/types/PoolId.sol'; + +/// @title IAggregatorHook +/// @notice Interface for the AggregatorHook contract. An implemented aggregator hook should be able to use liquidity from external sources +interface IAggregatorHook { + error UnspecifiedAmountExceeded(); + error PoolDoesNotExist(); + error LiquidityNotAllowed(); + + event AggregatorPoolRegistered(PoolId indexed poolId); + event TokenJarUpdated(address indexed tokenJar); + event HookSwap(PoolId indexed poolId, address indexed sender, int256 amount0, int256 amount1, uint24 swapFee); + + /// @notice Quotes amount of unspecified side for a given amount of specified side + /// @param zeroToOne Whether the swap is from token0 to token1 or from token1 to token0 + /// @param amountSpecified The amount of tokens in or out (negative for exact-in, positive for exact-out) + /// @return amountUnspecified amount of unspecified side (always positive to adhere to practices by other quote functions) + /// @dev This function is meant to be called as a view function even though it is not one. This is because the swap + /// might be simulated but not finalized. Applies protocol fee on top of the raw quote from the underlying liquidity source + function quote(bool zeroToOne, int256 amountSpecified, PoolId poolId) + external + payable + returns (uint256 amountUnspecified); + + /// @notice Returns the pseudo TVL: the amount of the UniswapV4 pool's tokens locked in the aggregated pool + /// @param poolId The pool ID of the UniswapV4 pool + /// @return amount0 The amount of token0 in the aggregated pool + /// @return amount1 The amount of token1 in the aggregated pool + function pseudoTotalValueLocked(PoolId poolId) external returns (uint256 amount0, uint256 amount1); +} diff --git a/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/utils/AggregatorHookMiner.sol b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/utils/AggregatorHookMiner.sol new file mode 100644 index 00000000..7bda0558 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/aggregator-hooks/utils/AggregatorHookMiner.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.29; + +import {Hooks} from '../../../v4-core/libraries/Hooks.sol'; + +/// @title AggregatorHookMiner +/// @notice a minimal library for mining aggregator hook addresses +/// @dev This library is a version of HookMiner that incorporates the aggregator hook identification system. +library AggregatorHookMiner { + // mask to slice out the bottom 14 bit of the address + uint160 constant FLAG_MASK = Hooks.ALL_HOOK_MASK; // 0000 ... 0000 0011 1111 1111 1111 + + // Maximum number of iterations to find a salt, avoid infinite loops or MemoryOOG + // (arbitrarily set) + uint256 constant MAX_LOOP = 160_444; + + /// @notice Find a salt that produces a hook address with the desired `flags` and first byte ID + /// @param deployer The address that will deploy the hook. In `forge test`, this will be the test contract `address(this)` or the pranking address + /// In `forge script`, this should be `0x4e59b44847b379578588920cA78FbF26c0B4956C` (CREATE2 Deployer Proxy) + /// @param flags The desired flags for the hook address. Example `uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.AFTER_SWAP_FLAG | ...)` + /// @param firstByte The desired first byte of the hook address (e.g., 0xC1 for StableSwap, 0xC2 for StableSwap-NG, 0xF1 for FluidDexT1, 0x71 for TempoExchange, etc.) + /// @param creationCode The creation code of a hook contract. Example: `type(Counter).creationCode` + /// @param constructorArgs The encoded constructor arguments of a hook contract. Example: `abi.encode(address(manager))` + /// @param saltOffset The starting salt value for the search. Increment by MAX_LOOP for subsequent attempts. + /// @return hookAddress The computed hook address + /// @return salt The salt that produces the hook address + function find( + address deployer, + uint160 flags, + uint8 firstByte, + bytes memory creationCode, + bytes memory constructorArgs, + uint256 saltOffset + ) internal view returns (address, bytes32) { + flags = flags & FLAG_MASK; // mask for only the bottom 14 bits + // Shift first byte to the most significant byte position (bits 152-159) + uint160 firstByteMask = uint160(0xFF) << 152; // 0xFF00000000000000000000000000000000000000 + uint160 desiredFirstByte = uint160(firstByte) << 152; + bytes memory creationCodeWithArgs = abi.encodePacked(creationCode, constructorArgs); + + address hookAddress; + for (uint256 salt = saltOffset; salt < saltOffset + MAX_LOOP; salt++) { + hookAddress = computeAddress(deployer, salt, creationCodeWithArgs); + + // if the hook's bottom 14 bits match the desired flags, first byte matches the desired ID, AND the address does not have bytecode, we found a match + if ( + uint160(hookAddress) & FLAG_MASK == flags && (uint160(hookAddress) & firstByteMask) == desiredFirstByte + && hookAddress.code.length == 0 + ) { + return (hookAddress, bytes32(salt)); + } + } + revert('HookMiner: could not find salt'); + } + + /// @notice Precompute a contract address deployed via CREATE2 + /// @param deployer The address that will deploy the hook. In `forge test`, this will be the test contract `address(this)` or the pranking address + /// In `forge script`, this should be `0x4e59b44847b379578588920cA78FbF26c0B4956C` (CREATE2 Deployer Proxy) + /// @param salt The salt used to deploy the hook + /// @param creationCodeWithArgs The creation code of a hook contract, with encoded constructor arguments appended. Example: `abi.encodePacked(type(Counter).creationCode, abi.encode(constructorArg1, constructorArg2))` + /// @return hookAddress The address of the hook + function computeAddress(address deployer, uint256 salt, bytes memory creationCodeWithArgs) + internal + pure + returns (address hookAddress) + { + return address( + uint160(uint256(keccak256(abi.encodePacked(bytes1(0xFF), deployer, salt, keccak256(creationCodeWithArgs))))) + ); + } +} diff --git a/src/briefcase/protocols/v4-periphery/interfaces/external/IWstETH.sol b/src/briefcase/protocols/v4-hooks-public/interfaces/IWstETH.sol similarity index 100% rename from src/briefcase/protocols/v4-periphery/interfaces/external/IWstETH.sol rename to src/briefcase/protocols/v4-hooks-public/interfaces/IWstETH.sol diff --git a/src/briefcase/protocols/v4-periphery/utils/HookMiner.sol b/src/briefcase/protocols/v4-hooks-public/utils/HookMiner.sol similarity index 100% rename from src/briefcase/protocols/v4-periphery/utils/HookMiner.sol rename to src/briefcase/protocols/v4-hooks-public/utils/HookMiner.sol diff --git a/src/briefcase/protocols/v4-hooks-public/utils/HookMinerCreate3.sol b/src/briefcase/protocols/v4-hooks-public/utils/HookMinerCreate3.sol new file mode 100644 index 00000000..a89cd268 --- /dev/null +++ b/src/briefcase/protocols/v4-hooks-public/utils/HookMinerCreate3.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; + +import {CREATE3} from '../../lib-external/solmate/src/utils/CREATE3.sol'; +import {Hooks} from '../../v4-core/libraries/Hooks.sol'; + +/// @title HookMinerCreate3 +/// @notice A minimal library for mining hook addresses using CREATE3 +library HookMinerCreate3 { + // mask to slice out the bottom 14 bit of the address + uint160 constant FLAG_MASK = Hooks.ALL_HOOK_MASK; // 0000 ... 0000 0011 1111 1111 1111 + + // Maximum number of iterations to find a salt, avoid infinite loops or MemoryOOG + // (arbitrarily set) + uint256 constant MAX_LOOP = 160_444; + + /// @notice Find a salt that produces a hook address with the desired `flags` using CREATE3 + /// @param deployer The address that will deploy the hook. In `forge test`, this will be the test contract `address(this)` or the pranking address + /// In `forge script`, this should be `0x4e59b44847b379578588920cA78FbF26c0B4956C` (CREATE2 Deployer Proxy) + /// @param flags The desired flags for the hook address. Example `uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.AFTER_SWAP_FLAG | ...)` + /// @param creationCode The creation code of a hook contract. Example: `type(Counter).creationCode` + /// @param constructorArgs The encoded constructor arguments of a hook contract. Example: `abi.encode(address(manager))` + /// @return (hookAddress, salt) The hook deploys to `hookAddress` when using `salt` with CREATE3 + function find(address deployer, uint160 flags, bytes memory creationCode, bytes memory constructorArgs) + internal + view + returns (address, bytes32) + { + flags = flags & FLAG_MASK; // mask for only the bottom 14 bits + bytes memory creationCodeWithArgs = abi.encodePacked(creationCode, constructorArgs); + + address hookAddress; + for (uint256 salt; salt < MAX_LOOP; salt++) { + hookAddress = computeAddress(deployer, salt, creationCodeWithArgs); + + // if the hook's bottom 14 bits match the desired flags AND the address does not have bytecode, we found a match + if (uint160(hookAddress) & FLAG_MASK == flags && hookAddress.code.length == 0) { + return (hookAddress, bytes32(salt)); + } + } + revert('HookMinerCreate3: could not find salt'); + } + + /// @notice Precompute a contract address deployed via CREATE3 + /// @param deployer The address that will deploy the hook. In `forge test`, this will be the test contract `address(this)` or the pranking address + /// In `forge script`, this should be `0x4e59b44847b379578588920cA78FbF26c0B4956C` (CREATE2 Deployer Proxy) + /// @param salt The salt used to deploy the hook + function computeAddress(address deployer, uint256 salt, bytes memory) internal pure returns (address hookAddress) { + bytes32 saltBytes = bytes32(salt); + return CREATE3.getDeployed(saltBytes, deployer); + } + + /// @notice Find a salt that produces a hook address with the desired `flags` using CREATE3 with a custom salt prefix + /// @param deployer The address that will deploy the hook + /// @param flags The desired flags for the hook address + /// @param creationCode The creation code of a hook contract + /// @param constructorArgs The encoded constructor arguments of a hook contract + /// @param saltPrefix A prefix to use for the salt (e.g., "permissioned-router-") + /// @return (hookAddress, salt) The hook deploys to `hookAddress` when using `salt` with CREATE3 + function findWithPrefix( + address deployer, + uint160 flags, + bytes memory creationCode, + bytes memory constructorArgs, + string memory saltPrefix + ) internal view returns (address, bytes32) { + flags = flags & FLAG_MASK; // mask for only the bottom 14 bits + bytes memory creationCodeWithArgs = abi.encodePacked(creationCode, constructorArgs); + + address hookAddress; + for (uint256 i; i < MAX_LOOP; i++) { + bytes32 salt = keccak256(abi.encodePacked(saltPrefix, i)); + hookAddress = computeAddress(deployer, uint256(salt), creationCodeWithArgs); + + // if the hook's bottom 14 bits match the desired flags AND the address does not have bytecode, we found a match + if (uint160(hookAddress) & FLAG_MASK == flags && hookAddress.code.length == 0) { + return (hookAddress, salt); + } + } + revert('HookMinerCreate3: could not find salt with prefix'); + } +} diff --git a/src/briefcase/protocols/v4-periphery/base/ImmutableState.sol b/src/briefcase/protocols/v4-periphery/base/ImmutableState.sol deleted file mode 100644 index 96953ee9..00000000 --- a/src/briefcase/protocols/v4-periphery/base/ImmutableState.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {IPoolManager} from '../../v4-core/interfaces/IPoolManager.sol'; -import {IImmutableState} from '../interfaces/IImmutableState.sol'; - -/// @title Immutable State -/// @notice A collection of immutable state variables, commonly used across multiple contracts -contract ImmutableState is IImmutableState { - /// @inheritdoc IImmutableState - IPoolManager public immutable poolManager; - - /// @notice Thrown when the caller is not PoolManager - error NotPoolManager(); - - /// @notice Only allow calls from the PoolManager contract - modifier onlyPoolManager() { - if (msg.sender != address(poolManager)) revert NotPoolManager(); - _; - } - - constructor(IPoolManager _poolManager) { - poolManager = _poolManager; - } -} diff --git a/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IAllowlistChecker.sol b/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IAllowlistChecker.sol new file mode 100644 index 00000000..8a3103df --- /dev/null +++ b/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IAllowlistChecker.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC165} from '../../../../lib-external/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol'; +import {PermissionFlag} from '../libraries/PermissionFlags.sol'; + +interface IAllowlistChecker is IERC165 { + /// @notice Returns the permission flags for `account` with respect to `tokenAddress` + /// @param account The account whose allowlist status is being checked + /// @param tokenAddress The permissioned token the check is being made for + /// @dev `tokenAddress` lets a single allowlist checker serve multiple assets without an extra round-trip into the adapter + function checkAllowlist(address account, address tokenAddress) external view returns (PermissionFlag); +} diff --git a/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IPermissionsAdapter.sol b/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IPermissionsAdapter.sol new file mode 100644 index 00000000..d236f4ac --- /dev/null +++ b/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IPermissionsAdapter.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC20} from '../../../../lib-external/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol'; +import {PermissionFlag} from '../libraries/PermissionFlags.sol'; +import {IAllowlistChecker} from './IAllowlistChecker.sol'; + +interface IPermissionsAdapter is IERC20 { + /// @notice Emitted when the allow list checker is updated + event AllowListCheckerUpdated(IAllowlistChecker indexed newAllowListChecker); + + /// @notice Emitted when an allowed wrapper is updated + event AllowedWrapperUpdated(address indexed wrapper, bool allowed); + + /// @notice Emitted when the swapping enabled status is updated + event SwappingEnabledUpdated(bool enabled); + + /// @notice Emitted when the permissioned token is deposited into this adapter as a verification signal + /// @dev Provides a filterable signal that the asset issuer has allow-listed this adapter, without relying on a vanilla ERC20 Transfer event + event VerificationDeposit(address indexed depositor, uint256 amount); + + /// @notice Thrown when the allow list checker does not implement the IAllowListChecker interface + error InvalidAllowListChecker(IAllowlistChecker newAllowListChecker); + + /// @notice Thrown when the transfer is not interacting with the pool manager + error InvalidTransfer(address from, address to); + + /// @notice Thrown when the wrapper is not allowed to trigger transfers on the permissions adapter + error UnauthorizedWrapper(address wrapper); + + /// @notice Thrown when there is an insufficient amount of permissioned tokens available to wrap + error InsufficientBalance(uint256 amount, uint256 availableBalance); + + /// @notice Wraps the permissioned token to the pool manager + /// @param amount The amount of permissioned tokens to wrap + /// @dev Only callable by allowed wrappers + /// @dev The `amount` must be sent to this contract before calling this function + function wrapToPoolManager(uint256 amount) external; + + /// @notice Deposits the permissioned token into this adapter as an on-chain verification signal + /// @param amount The amount of permissioned tokens to pull from the caller + /// @dev Intended to be called by the asset issuer once the adapter has been allow-listed on the permissioned token. + /// Emits `VerificationDeposit` so off-chain observers have a dedicated event to filter on. The resulting balance also + /// satisfies the on-chain check used by `PermissionsAdapterFactory.verifyPermissionsAdapter`. + function depositForVerification(uint256 amount) external; + + /// @notice Updates the allow list checker + /// @param newAllowListChecker The new allow list checker + /// @dev Only callable by the owner + function updateAllowListChecker(IAllowlistChecker newAllowListChecker) external; + + /// @notice Updates the allowed wrapper that can wrap the permissioned token + /// @param wrapper The wrapper to update + /// @param allowed Whether the wrapper is allowed + /// @dev Only callable by the owner + /// @dev To ensure the permissions adapter cannot be wrapped in an ERC6909 token on the PoolManager, the wrapper must only implement `swap` or `modifyLiquidity` functions + function updateAllowedWrapper(address wrapper, bool allowed) external; + + /// @notice Updates the swapping enabled status + /// @param enabled Whether swapping is enabled + /// @dev Only callable by the owner + function updateSwappingEnabled(bool enabled) external; + + /// @notice Returns whether a transfer is allowed + /// @param account The account to check + function isAllowed(address account, PermissionFlag permission) external view returns (bool); + + /// @notice Returns the allow list checker + function allowListChecker() external view returns (IAllowlistChecker); + + /// @notice Returns the allowed wrappers that can wrap the permissioned token + /// @dev e.g., the permissioned pool manager, quoters or the swap router + /// @dev Wrappers must honestly report `msgSender()` to maintain permission guarantees. + function allowedWrappers(address wrapper) external view returns (bool); + + /// @notice Returns the swapping enabled status + function swappingEnabled() external view returns (bool); + + /// @notice Returns the Uniswap v4 pool manager + function POOL_MANAGER() external view returns (address); + + /// @notice Returns the permissioned token that is deposited in this contract + function PERMISSIONED_TOKEN() external view returns (IERC20); + + /// @notice Returns the admin of the permissions adapter + function owner() external view returns (address); +} diff --git a/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IPermissionsAdapterFactory.sol b/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IPermissionsAdapterFactory.sol new file mode 100644 index 00000000..8913da9c --- /dev/null +++ b/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/interfaces/IPermissionsAdapterFactory.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC20} from '../../../../lib-external/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol'; +import {IAllowlistChecker} from './IAllowlistChecker.sol'; + +interface IPermissionsAdapterFactory { + /// @notice Emitted when a permissions adapter is created + event PermissionsAdapterCreated(address indexed permissionsAdapter, address indexed permissionedToken); + + /// @notice Emitted when a permissions adapter is verified + event PermissionsAdapterVerified(address indexed permissionsAdapter, address indexed permissionedToken); + + /// @notice Thrown when the permissions adapter does not exist + error PermissionsAdapterNotFound(address permissionsAdapter); + + /// @notice Thrown when the permissions adapter is already verified + error PermissionsAdapterAlreadyVerified(address permissionsAdapter); + + /// @notice Thrown when the permissions adapter is not verified + error PermissionsAdapterNotVerified(address permissionsAdapter); + + /// @notice Creates a new permissions adapter + /// @param permissionedToken The permissioned token to wrap + /// @param initialOwner The initial owner of the permissions adapter + /// @param allowListChecker The allow list checker that will be used to check if transfers are allowed + function createPermissionsAdapter( + IERC20 permissionedToken, + address initialOwner, + IAllowlistChecker allowListChecker + ) external returns (address); + + /// @notice Verifies a permissions adapter + /// @param permissionsAdapter The permissions adapter + /// @dev This function verifies that the permissions adapter has a balance of the permissioned token. This means that the permissions adapter is on the allow list of the permissioned token and can be used to wrap and unwrap the permissioned token. + function verifyPermissionsAdapter(address permissionsAdapter) external; + + /// @notice Returns the permissioned token of a permissions adapter + /// @param permissionsAdapter The permissions adapter + /// @return permissionedToken The permissioned token + function permissionsAdapterOf(address permissionsAdapter) external view returns (address permissionedToken); + + /// @notice Returns the verified permissioned token of a permissions adapter + /// @param permissionsAdapter The permissions adapter + /// @return permissionedToken The verified permissioned token + /// @dev A reverse lookup of the permissioned token is required, otherwise anyone could create a permissions adapter for a non-permissioned token + function verifiedPermissionsAdapterOf(address permissionsAdapter) external view returns (address permissionedToken); + + /// @notice Returns the v4 pool manager + /// @return poolManager The v4 pool manager + function POOL_MANAGER() external view returns (address poolManager); +} diff --git a/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/libraries/PermissionFlags.sol b/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/libraries/PermissionFlags.sol new file mode 100644 index 00000000..666667dd --- /dev/null +++ b/src/briefcase/protocols/v4-periphery/hooks/permissionedPools/libraries/PermissionFlags.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +type PermissionFlag is bytes2; + +using {or as |} for PermissionFlag global; +using {and as &} for PermissionFlag global; +using {eq_0 as ==} for PermissionFlag global; + +function or(PermissionFlag a, PermissionFlag b) pure returns (PermissionFlag) { + return PermissionFlag.wrap(PermissionFlag.unwrap(a) | PermissionFlag.unwrap(b)); +} + +function and(PermissionFlag a, PermissionFlag b) pure returns (PermissionFlag) { + return PermissionFlag.wrap(PermissionFlag.unwrap(a) & PermissionFlag.unwrap(b)); +} + +function eq_0(PermissionFlag a, PermissionFlag b) pure returns (bool) { + return PermissionFlag.unwrap(a) == PermissionFlag.unwrap(b); +} + +library PermissionFlags { + PermissionFlag constant NONE = PermissionFlag.wrap(0x0000); + PermissionFlag constant SWAP_ALLOWED = PermissionFlag.wrap(0x0001); + PermissionFlag constant LIQUIDITY_ALLOWED = PermissionFlag.wrap(0x0002); + PermissionFlag constant ALL_ALLOWED = PermissionFlag.wrap(0xFFFF); +} diff --git a/src/briefcase/protocols/v4-periphery/interfaces/IPositionManager.sol b/src/briefcase/protocols/v4-periphery/interfaces/IPositionManager.sol index 5bf15324..680d8757 100644 --- a/src/briefcase/protocols/v4-periphery/interfaces/IPositionManager.sol +++ b/src/briefcase/protocols/v4-periphery/interfaces/IPositionManager.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.6.2; +import {PoolId} from '../../v4-core/types/PoolId.sol'; import {PoolKey} from '../../v4-core/types/PoolKey.sol'; import {PositionInfo} from '../libraries/PositionInfoLibrary.sol'; import {IEIP712_v4} from './IEIP712_v4.sol'; @@ -24,6 +25,12 @@ interface IPositionManager is IUnorderedNonce, IPermit2Forwarder { + /// @notice Emitted by the position manager for each modifyLiquidity call, mirroring PoolManager + /// ModifyLiquidity except `sender` is the unlock locker (end user), not the position manager. + event ModifyPosition( + PoolId indexed id, address indexed sender, int24 tickLower, int24 tickUpper, int256 liquidityDelta, bytes32 salt + ); + /// @notice Thrown when the caller is not approved to modify a position error NotApproved(address caller); /// @notice Thrown when the block.timestamp exceeds the user-provided deadline diff --git a/src/briefcase/protocols/v4-periphery/interfaces/IV4Router.sol b/src/briefcase/protocols/v4-periphery/interfaces/IV4Router.sol index d9b98797..c0c7b1af 100644 --- a/src/briefcase/protocols/v4-periphery/interfaces/IV4Router.sol +++ b/src/briefcase/protocols/v4-periphery/interfaces/IV4Router.sol @@ -13,12 +13,16 @@ interface IV4Router is IImmutableState { error V4TooLittleReceived(uint256 minAmountOutReceived, uint256 amountReceived); /// @notice Emitted when an exactOutput is asked for more than its maxAmountIn error V4TooMuchRequested(uint256 maxAmountInRequested, uint256 amountRequested); - /// @notice Emitted when an exactInput swap does not receive its relative minAmountOut per hop (max price) - error V4TooLittleReceivedPerHop(uint256 hopIndex, uint256 maxPrice, uint256 price); - /// @notice Emitted when an exactOutput is asked for more than its relative maxAmountIn per hop (max price) - error V4TooMuchRequestedPerHop(uint256 hopIndex, uint256 maxPrice, uint256 price); - /// @notice Emitted when the length of the maxHopSlippage array is not zero and not equal to the path length - error InvalidHopSlippageLength(); + /// @notice Emitted when an exactInput swap does not receive its relative minAmountOut per hop (min price) + error V4TooLittleReceivedPerHop(uint256 hopIndex, uint256 minPrice, uint256 price); + /// @notice Emitted when an exactOutput is asked for more than its relative maxAmountIn per hop (min price) + error V4TooMuchRequestedPerHop(uint256 hopIndex, uint256 minPrice, uint256 price); + /// @notice Emitted when a single exactInput swap does not meet its relative price limit + error V4TooLittleReceivedPerHopSingle(uint256 minPrice, uint256 price); + /// @notice Emitted when a single exactOutput swap exceeds its relative price limit + error V4TooMuchRequestedPerHopSingle(uint256 minPrice, uint256 price); + /// @notice Emitted when the length of the per-hop minimum price array is not zero and not equal to the path length + error InvalidHopPriceLength(); /// @notice Parameters for a single-hop exact-input swap struct ExactInputSingleParams { @@ -26,6 +30,7 @@ interface IV4Router is IImmutableState { bool zeroForOne; uint128 amountIn; uint128 amountOutMinimum; + uint256 minHopPriceX36; bytes hookData; } @@ -33,7 +38,7 @@ interface IV4Router is IImmutableState { struct ExactInputParams { Currency currencyIn; PathKey[] path; - uint256[] maxHopSlippage; + uint256[] minHopPriceX36; uint128 amountIn; uint128 amountOutMinimum; } @@ -44,6 +49,7 @@ interface IV4Router is IImmutableState { bool zeroForOne; uint128 amountOut; uint128 amountInMaximum; + uint256 minHopPriceX36; bytes hookData; } @@ -51,7 +57,7 @@ interface IV4Router is IImmutableState { struct ExactOutputParams { Currency currencyOut; PathKey[] path; - uint256[] maxHopSlippage; + uint256[] minHopPriceX36; uint128 amountOut; uint128 amountInMaximum; } diff --git a/src/briefcase/protocols/v4-periphery/libraries/Actions.sol b/src/briefcase/protocols/v4-periphery/libraries/Actions.sol index a33c4e87..57cde9f6 100644 --- a/src/briefcase/protocols/v4-periphery/libraries/Actions.sol +++ b/src/briefcase/protocols/v4-periphery/libraries/Actions.sol @@ -11,7 +11,17 @@ library Actions { uint256 internal constant DECREASE_LIQUIDITY = 0x01; uint256 internal constant MINT_POSITION = 0x02; uint256 internal constant BURN_POSITION = 0x03; + + /// @notice DEPRECATED: Vulnerable to sandwich attacks - do not use. + /// @dev The delta-based approach lacks minimum liquidity slippage protection, allowing + /// attackers to manipulate the price and reduce the liquidity received. + /// Use INCREASE_LIQUIDITY instead. uint256 internal constant INCREASE_LIQUIDITY_FROM_DELTAS = 0x04; + + /// @notice DEPRECATED: Vulnerable to sandwich attacks - do not use. + /// @dev The delta-based approach lacks minimum liquidity slippage protection, allowing + /// attackers to manipulate the price and reduce the liquidity received. + /// Use MINT_POSITION instead. uint256 internal constant MINT_POSITION_FROM_DELTAS = 0x05; // swapping @@ -46,4 +56,11 @@ library Actions { // note this is not supported in the position manager or router uint256 internal constant MINT_6909 = 0x17; uint256 internal constant BURN_6909 = 0x18; + + // permissioned-pools specific actions + // routes a currency's positive delta with a fallback cascade: LP → defaultRecipient → 6909 mint to defaultRecipient + uint256 internal constant UNWIND_WITH_FALLBACK = 0x19; + // subscribing/unsubscribing via position manager + uint256 internal constant SUBSCRIBE = 0x1a; + uint256 internal constant UNSUBSCRIBE = 0x1b; } diff --git a/src/briefcase/protocols/v4-periphery/libraries/CalldataDecoder.sol b/src/briefcase/protocols/v4-periphery/libraries/CalldataDecoder.sol index e4647dcd..5820c870 100644 --- a/src/briefcase/protocols/v4-periphery/libraries/CalldataDecoder.sol +++ b/src/briefcase/protocols/v4-periphery/libraries/CalldataDecoder.sol @@ -182,9 +182,9 @@ library CalldataDecoder { { // ExactInputParams is a variable length struct so we just have to look up its location assembly ('memory-safe') { - // only safety checks for the minimum length, where path is empty - // 0xa0 = 5 * 0x20 -> 3 elements, path offset, and path length 0 - if lt(params.length, 0xa0) { + // only safety checks for the minimum length, where path and minHopPriceX36 are empty + // 0xe0 = 7 * 0x20 -> 3 elements, path offset, minHopPriceX36 offset, path length 0, and minHopPriceX36 length 0 + if lt(params.length, 0xe0) { mstore(0, SLICE_ERROR_SELECTOR) revert(0x1c, 4) } @@ -201,8 +201,8 @@ library CalldataDecoder { // ExactInputSingleParams is a variable length struct so we just have to look up its location assembly ('memory-safe') { // only safety checks for the minimum length, where hookData is empty - // 0x140 = 10 * 0x20 -> 8 elements, bytes offset, and bytes length 0 - if lt(params.length, 0x140) { + // 0x160 = 11 * 0x20 -> 9 elements, bytes offset, and bytes length 0 + if lt(params.length, 0x160) { mstore(0, SLICE_ERROR_SELECTOR) revert(0x1c, 4) } @@ -218,9 +218,9 @@ library CalldataDecoder { { // ExactOutputParams is a variable length struct so we just have to look up its location assembly ('memory-safe') { - // only safety checks for the minimum length, where path is empty - // 0xa0 = 5 * 0x20 -> 3 elements, path offset, and path length 0 - if lt(params.length, 0xa0) { + // only safety checks for the minimum length, where path and minHopPriceX36 are empty + // 0xe0 = 7 * 0x20 -> 3 elements, path offset, minHopPriceX36 offset, path length 0, and minHopPriceX36 length 0 + if lt(params.length, 0xe0) { mstore(0, SLICE_ERROR_SELECTOR) revert(0x1c, 4) } @@ -237,8 +237,8 @@ library CalldataDecoder { // ExactOutputSingleParams is a variable length struct so we just have to look up its location assembly ('memory-safe') { // only safety checks for the minimum length, where hookData is empty - // 0x140 = 10 * 0x20 -> 8 elements, bytes offset, and bytes length 0 - if lt(params.length, 0x140) { + // 0x160 = 11 * 0x20 -> 9 elements, bytes offset, and bytes length 0 + if lt(params.length, 0x160) { mstore(0, SLICE_ERROR_SELECTOR) revert(0x1c, 4) } diff --git a/src/briefcase/protocols/v4-periphery/utils/BaseHook.sol b/src/briefcase/protocols/v4-periphery/utils/BaseHook.sol deleted file mode 100644 index e90d974a..00000000 --- a/src/briefcase/protocols/v4-periphery/utils/BaseHook.sol +++ /dev/null @@ -1,206 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {IHooks} from '../../v4-core/interfaces/IHooks.sol'; -import {IPoolManager} from '../../v4-core/interfaces/IPoolManager.sol'; -import {Hooks} from '../../v4-core/libraries/Hooks.sol'; -import {BalanceDelta} from '../../v4-core/types/BalanceDelta.sol'; -import {BeforeSwapDelta} from '../../v4-core/types/BeforeSwapDelta.sol'; -import {PoolKey} from '../../v4-core/types/PoolKey.sol'; -import {ModifyLiquidityParams, SwapParams} from '../../v4-core/types/PoolOperation.sol'; -import {ImmutableState} from '../base/ImmutableState.sol'; - -/// @title Base Hook -/// @notice abstract contract for hook implementations -abstract contract BaseHook is IHooks, ImmutableState { - error HookNotImplemented(); - - constructor(IPoolManager _manager) ImmutableState(_manager) { - validateHookAddress(this); - } - - /// @notice Returns a struct of permissions to signal which hook functions are to be implemented - /// @dev Used at deployment to validate the address correctly represents the expected permissions - /// @return Permissions struct - function getHookPermissions() public pure virtual returns (Hooks.Permissions memory); - - /// @notice Validates the deployed hook address agrees with the expected permissions of the hook - /// @dev this function is virtual so that we can override it during testing, - /// which allows us to deploy an implementation to any address - /// and then etch the bytecode into the correct address - function validateHookAddress(BaseHook _this) internal pure virtual { - Hooks.validateHookPermissions(_this, getHookPermissions()); - } - - function beforeInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96) - external - onlyPoolManager - returns (bytes4) - { - return _beforeInitialize(sender, key, sqrtPriceX96); - } - - function _beforeInitialize(address, PoolKey calldata, uint160) internal virtual returns (bytes4) { - revert HookNotImplemented(); - } - - function afterInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96, int24 tick) - external - onlyPoolManager - returns (bytes4) - { - return _afterInitialize(sender, key, sqrtPriceX96, tick); - } - - function _afterInitialize(address, PoolKey calldata, uint160, int24) internal virtual returns (bytes4) { - revert HookNotImplemented(); - } - - function beforeAddLiquidity( - address sender, - PoolKey calldata key, - ModifyLiquidityParams calldata params, - bytes calldata hookData - ) external onlyPoolManager returns (bytes4) { - return _beforeAddLiquidity(sender, key, params, hookData); - } - - function _beforeAddLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, bytes calldata) - internal - virtual - returns (bytes4) - { - revert HookNotImplemented(); - } - - function beforeRemoveLiquidity( - address sender, - PoolKey calldata key, - ModifyLiquidityParams calldata params, - bytes calldata hookData - ) external onlyPoolManager returns (bytes4) { - return _beforeRemoveLiquidity(sender, key, params, hookData); - } - - function _beforeRemoveLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, bytes calldata) - internal - virtual - returns (bytes4) - { - revert HookNotImplemented(); - } - - function afterAddLiquidity( - address sender, - PoolKey calldata key, - ModifyLiquidityParams calldata params, - BalanceDelta delta, - BalanceDelta feesAccrued, - bytes calldata hookData - ) external onlyPoolManager returns (bytes4, BalanceDelta) { - return _afterAddLiquidity(sender, key, params, delta, feesAccrued, hookData); - } - - function _afterAddLiquidity( - address, - PoolKey calldata, - ModifyLiquidityParams calldata, - BalanceDelta, - BalanceDelta, - bytes calldata - ) internal virtual returns (bytes4, BalanceDelta) { - revert HookNotImplemented(); - } - - function afterRemoveLiquidity( - address sender, - PoolKey calldata key, - ModifyLiquidityParams calldata params, - BalanceDelta delta, - BalanceDelta feesAccrued, - bytes calldata hookData - ) external onlyPoolManager returns (bytes4, BalanceDelta) { - return _afterRemoveLiquidity(sender, key, params, delta, feesAccrued, hookData); - } - - function _afterRemoveLiquidity( - address, - PoolKey calldata, - ModifyLiquidityParams calldata, - BalanceDelta, - BalanceDelta, - bytes calldata - ) internal virtual returns (bytes4, BalanceDelta) { - revert HookNotImplemented(); - } - - function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata hookData) - external - onlyPoolManager - returns (bytes4, BeforeSwapDelta, uint24) - { - return _beforeSwap(sender, key, params, hookData); - } - - function _beforeSwap(address, PoolKey calldata, SwapParams calldata, bytes calldata) - internal - virtual - returns (bytes4, BeforeSwapDelta, uint24) - { - revert HookNotImplemented(); - } - - function afterSwap( - address sender, - PoolKey calldata key, - SwapParams calldata params, - BalanceDelta delta, - bytes calldata hookData - ) external onlyPoolManager returns (bytes4, int128) { - return _afterSwap(sender, key, params, delta, hookData); - } - - function _afterSwap(address, PoolKey calldata, SwapParams calldata, BalanceDelta, bytes calldata) - internal - virtual - returns (bytes4, int128) - { - revert HookNotImplemented(); - } - - function beforeDonate( - address sender, - PoolKey calldata key, - uint256 amount0, - uint256 amount1, - bytes calldata hookData - ) external onlyPoolManager returns (bytes4) { - return _beforeDonate(sender, key, amount0, amount1, hookData); - } - - function _beforeDonate(address, PoolKey calldata, uint256, uint256, bytes calldata) - internal - virtual - returns (bytes4) - { - revert HookNotImplemented(); - } - - function afterDonate( - address sender, - PoolKey calldata key, - uint256 amount0, - uint256 amount1, - bytes calldata hookData - ) external onlyPoolManager returns (bytes4) { - return _afterDonate(sender, key, amount0, amount1, hookData); - } - - function _afterDonate(address, PoolKey calldata, uint256, uint256, bytes calldata) - internal - virtual - returns (bytes4) - { - revert HookNotImplemented(); - } -} diff --git a/src/pkgs/v4-hooks-public b/src/pkgs/v4-hooks-public new file mode 160000 index 00000000..015f1578 --- /dev/null +++ b/src/pkgs/v4-hooks-public @@ -0,0 +1 @@ +Subproject commit 015f1578b0a26b53c42dfbc95201e87d6297189b From f684acbd61c736b058bca07963f986aa7dd7573e Mon Sep 17 00:00:00 2001 From: SocksNFlops <91764028+SocksNFlops@users.noreply.github.com> Date: Thu, 28 May 2026 11:27:04 -0400 Subject: [PATCH 2/2] fix(permissioned-hooks): adding auto-salt mining into deploy-all script --- script/deploy/Deploy-all.s.sol | 11 +- .../deploy/tasks/11155111/task-pending.json | 664 ++++++++++++++++++ script/deploy/tasks/task_template.json | 3 - 3 files changed, 674 insertions(+), 4 deletions(-) create mode 100644 script/deploy/tasks/11155111/task-pending.json diff --git a/script/deploy/Deploy-all.s.sol b/script/deploy/Deploy-all.s.sol index 4601462d..c31b7866 100644 --- a/script/deploy/Deploy-all.s.sol +++ b/script/deploy/Deploy-all.s.sol @@ -51,6 +51,8 @@ import { } from '../../src/briefcase/deployers/v4-periphery/PermissionsAdapterFactoryDeployer.sol'; import {PositionDescriptorDeployer} from '../../src/briefcase/deployers/v4-periphery/PositionDescriptorDeployer.sol'; import {PositionManagerDeployer} from '../../src/briefcase/deployers/v4-periphery/PositionManagerDeployer.sol'; +import {Hooks} from '../../src/briefcase/protocols/v4-core/libraries/Hooks.sol'; +import {HookMiner} from '../../src/briefcase/protocols/v4-hooks-public/utils/HookMiner.sol'; import {CaliburEntryDeployer} from '../../src/briefcase/deployers/calibur/CaliburEntryDeployer.sol'; import { @@ -383,11 +385,18 @@ contract Deploy is Script { WstETHRoutingHookDeployer.deploy(poolManager, wsteth, salt); } if (deployPermissionedHooks) { - bytes32 salt = config.readBytes32('.protocols.hooks.contracts.PermissionedHooks.params.salt.value'); if (permissionsAdapterFactory == address(0)) { permissionsAdapterFactory = config.readAddress('.protocols.v4.contracts.PermissionsAdapterFactory.address'); } + uint160 flags = + uint160(Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG | Hooks.BEFORE_SWAP_FLAG); + (, bytes32 salt) = HookMiner.find( + 0x4e59b44847b379578588920cA78FbF26c0B4956C, + flags, + PermissionedHooksDeployer.initcode(), + abi.encode(poolManager, permissionsAdapterFactory) + ); console.log('deploying Permissioned Hooks'); PermissionedHooksDeployer.deploy(poolManager, permissionsAdapterFactory, salt); } diff --git a/script/deploy/tasks/11155111/task-pending.json b/script/deploy/tasks/11155111/task-pending.json new file mode 100644 index 00000000..9f28e2dd --- /dev/null +++ b/script/deploy/tasks/11155111/task-pending.json @@ -0,0 +1,664 @@ +{ + "protocols": { + "unsupported-protocol": { + "name": "Unsupported Protocol", + "deploy": false, + "contracts": { + "UnsupportedProtocol": { + "deploy": false, + "address": null + } + } + }, + "permit2": { + "name": "Permit 2", + "deploy": false, + "contracts": { + "Permit2": { + "deploy": false, + "address": null, + "lookup": { + "latest": "Permit2", + "history": [ + "UniversalRouter.input.constructor.params.permit2" + ] + }, + "params": { + "salt": { + "type": "bytes32", + "value": "0x0000000000000000000000000000000000000000d3af2663da51c10215000000" + } + } + } + } + }, + "v2": { + "name": "Uniswap v2", + "deploy": false, + "contracts": { + "UniswapV2Factory": { + "deploy": false, + "address": null, + "lookup": { + "latest": "UniswapV2Factory", + "history": [ + "UniversalRouter.input.constructor.params.v2Factory" + ] + }, + "params": { + "feeToSetter": { + "type": "address" + } + } + }, + "UniswapV2Router02": { + "deploy": false, + "address": null, + "params": { + "factory": { + "name": "Uniswap v2 factory address", + "pointer": "protocols.v2.contracts.UniswapV2Factory" + } + }, + "dependencies": [ + "weth" + ] + } + } + }, + "v3": { + "name": "Uniswap v3", + "deploy": false, + "contracts": { + "UniswapV3Factory": { + "deploy": false, + "address": null, + "lookup": { + "latest": "UniswapV3Factory", + "history": [ + "UniversalRouter.input.constructor.params.v3Factory" + ] + }, + "params": { + "initialOwner": { + "type": "address" + } + } + }, + "UniswapInterfaceMulticall": { + "deploy": false + }, + "QuoterV2": { + "deploy": false, + "address": null, + "params": { + "factory": { + "name": "Uniswap v3 factory address", + "pointer": "protocols.v3.contracts.UniswapV3Factory" + } + }, + "dependencies": [ + "weth" + ] + }, + "TickLens": { + "deploy": false + }, + "NonfungibleTokenPositionDescriptor": { + "deploy": false, + "address": null, + "lookup": { + "latest": "NonfungibleTokenPositionDescriptor" + }, + "params": { + "nativeCurrencyLabel": { + "name": "Native token symbol", + "type": "string", + "value": "ETH" + }, + "proxyAdminOwner": { + "type": "address" + } + }, + "dependencies": [ + "weth" + ] + }, + "NonfungiblePositionManager": { + "deploy": false, + "address": null, + "lookup": { + "latest": "NonfungiblePositionManager" + }, + "params": { + "factory": { + "name": "Uniswap v3 factory address", + "pointer": "protocols.v3.contracts.UniswapV3Factory" + }, + "tokenDescriptor": { + "name": "NFT Position Descriptor address", + "pointer": "protocols.v3.contracts.NonfungibleTokenPositionDescriptor" + } + }, + "dependencies": [ + "weth" + ] + }, + "V3Migrator": { + "deploy": false, + "params": { + "factory": { + "name": "Uniswap v3 factory address", + "pointer": "protocols.v3.contracts.UniswapV3Factory" + }, + "nonfungiblePositionManager": { + "name": "Uniswap v3 position manager address", + "pointer": "protocols.v3.contracts.NonfungiblePositionManager" + } + }, + "dependencies": [ + "weth" + ] + }, + "SwapRouter": { + "deploy": false, + "address": null, + "params": { + "factory": { + "name": "Uniswap v3 factory address", + "pointer": "protocols.v3.contracts.UniswapV3Factory" + } + }, + "dependencies": [ + "weth" + ] + } + } + }, + "v4": { + "name": "Uniswap v4", + "deploy": false, + "contracts": { + "PoolManager": { + "deploy": false, + "address": "0xE03A1074c86CFeDd5C142C4F04F1a1536e203543", + "lookup": { + "latest": "PoolManager" + }, + "params": { + "initialOwner": { + "type": "address" + } + } + }, + "PositionDescriptor": { + "deploy": false, + "address": null, + "lookup": { + "latest": "PositionDescriptor" + }, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "nativeCurrencyLabel": { + "name": "Native token symbol", + "type": "string", + "value": "ETH" + }, + "proxyAdminOwner": { + "type": "address" + } + }, + "dependencies": [ + "weth" + ] + }, + "PositionManager": { + "deploy": false, + "address": null, + "lookup": { + "latest": "PositionManager" + }, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "permit2": { + "name": "Permit 2 address", + "pointer": "protocols.permit2.contracts.Permit2" + }, + "unsubscribeGasLimit": { + "name": "Unsubscribe gas limit", + "type": "uint256" + }, + "positionDescriptor": { + "name": "Position Descriptor address", + "pointer": "protocols.v4.contracts.PositionDescriptor" + } + }, + "dependencies": [ + "weth" + ] + }, + "PermissionsAdapterFactory": { + "deploy": false, + "address": "0x42540aDe1E0f3EC7e11dcEC0f722073d2fa385d3", + "lookup": { + "latest": "PermissionsAdapterFactory" + }, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + } + } + }, + "PermissionedPositionManager": { + "deploy": false, + "address": null, + "lookup": { + "latest": "PermissionedPositionManager" + }, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "permit2": { + "name": "Permit 2 address", + "pointer": "protocols.permit2.contracts.Permit2" + }, + "unsubscribeGasLimit": { + "name": "Unsubscribe gas limit", + "type": "uint256" + }, + "positionDescriptor": { + "name": "Position Descriptor address", + "pointer": "protocols.v4.contracts.PositionDescriptor" + }, + "permissionsAdapterFactory": { + "name": "Permissions Adapter Factory", + "pointer": "protocols.v4.contracts.PermissionsAdapterFactory" + } + }, + "dependencies": [ + "weth" + ] + }, + "V4Quoter": { + "deploy": false, + "address": null, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + } + } + }, + "StateView": { + "deploy": false, + "address": null, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + } + } + } + } + }, + "hooks": { + "name": "v4 Hooks", + "deploy": true, + "contracts": { + "WETHHook": { + "deploy": false, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "salt": { + "type": "bytes32" + } + }, + "dependencies": [ + "weth" + ] + }, + "WstETHHook": { + "deploy": false, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "wstETH": { + "name": "WstETH address", + "type": "address" + }, + "salt": { + "type": "bytes32" + } + } + }, + "WstETHRoutingHook": { + "deploy": false, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "wstETH": { + "name": "WstETH address", + "type": "address" + }, + "salt": { + "type": "bytes32" + } + } + }, + "PermissionedHooks": { + "deploy": true, + "address": null, + "lookup": { + "latest": "PermissionedHooks" + }, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "permissionsAdapterFactory": { + "name": "Permissions Adapter Factory", + "pointer": "protocols.v4.contracts.PermissionsAdapterFactory" + } + } + } + } + }, + "view-quoter-v3": { + "name": "View Quoter v3", + "deploy": false, + "contracts": { + "Quoter": { + "deploy": false, + "params": { + "factory": { + "name": "Uniswap v3 factory address", + "pointer": "protocols.v3.contracts.UniswapV3Factory" + } + } + } + } + }, + "mixed-quoter": { + "name": "Mixed Quoter", + "deploy": false, + "contracts": { + "MixedRouteQuoterV2": { + "deploy": false, + "address": null, + "params": { + "poolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "v3Factory": { + "name": "Uniswap v3 factory address", + "pointer": "protocols.v3.contracts.UniswapV3Factory" + }, + "v2Factory": { + "name": "Uniswap v2 factory address", + "pointer": "protocols.v2.contracts.UniswapV2Factory" + } + } + } + } + }, + "swap-router-contracts": { + "name": "Swap Router Contracts", + "deploy": false, + "contracts": { + "SwapRouter02": { + "deploy": false, + "params": { + "factoryV2": { + "name": "Uniswap v2 factory address", + "pointer": "protocols.v2.contracts.UniswapV2Factory" + }, + "factoryV3": { + "name": "Uniswap v3 factory address", + "pointer": "protocols.v3.contracts.UniswapV3Factory" + }, + "positionManager": { + "name": "Uniswap v3 position manager address", + "pointer": "protocols.v3.contracts.NonfungiblePositionManager" + } + }, + "dependencies": [ + "weth" + ] + } + } + }, + "universal-router": { + "name": "Universal Router (Latest)", + "tag": "v2.2", + "deploy": false, + "contracts": { + "UniversalRouter": { + "deploy": false, + "params": { + "permit2": { + "name": "Permit 2 address", + "pointer": "protocols.permit2.contracts.Permit2" + }, + "v2Factory": { + "name": "Uniswap v2 factory address", + "pointer": "protocols.v2.contracts.UniswapV2Factory" + }, + "v3Factory": { + "name": "Uniswap v3 factory address", + "pointer": "protocols.v3.contracts.UniswapV3Factory" + }, + "v2PairInitCodeHash": { + "name": "Uniswap v2 pair init code hash", + "type": "bytes32", + "value": "0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f", + "lookup": { + "history": [ + "UniversalRouter.input.constructor.params.pairInitCodeHash" + ] + } + }, + "v3PoolInitCodeHash": { + "name": "Uniswap v3 pool init code hash", + "type": "bytes32", + "value": "0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54", + "lookup": { + "history": [ + "UniversalRouter.input.constructor.params.poolInitCodeHash" + ] + } + }, + "v4PoolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "v3NFTPositionManager": { + "name": "Uniswap v3 position manager address", + "pointer": "protocols.v3.contracts.NonfungiblePositionManager" + }, + "v4PositionManager": { + "name": "Uniswap v4 position manager address", + "pointer": "protocols.v4.contracts.PositionManager" + }, + "acrossSpokePool": { + "name": "Across Spoke Pool address", + "type": "address" + }, + "permissionsAdapterFactory": { + "name": "Permissions Adapter Factory", + "pointer": "protocols.v4.contracts.PermissionsAdapterFactory" + } + }, + "dependencies": [ + "weth" + ], + "lookup": { + "latest": "UniversalRouter" + } + } + } + }, + "universal-router-2_0": { + "name": "Universal Router (2.0)", + "tag": "v2.0", + "deploy": false, + "contracts": { + "UniversalRouter": { + "deploy": false, + "params": { + "permit2": { + "name": "Permit 2 address", + "pointer": "protocols.permit2.contracts.Permit2" + }, + "v2Factory": { + "name": "Uniswap v2 factory address", + "pointer": "protocols.v2.contracts.UniswapV2Factory" + }, + "v3Factory": { + "name": "Uniswap v3 factory address", + "pointer": "protocols.v3.contracts.UniswapV3Factory" + }, + "v2PairInitCodeHash": { + "name": "Uniswap v2 pair init code hash", + "type": "bytes32", + "value": "0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f", + "lookup": { + "history": [ + "UniversalRouter.input.constructor.params.pairInitCodeHash" + ] + } + }, + "v3PoolInitCodeHash": { + "name": "Uniswap v3 pool init code hash", + "type": "bytes32", + "value": "0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54", + "lookup": { + "history": [ + "UniversalRouter.input.constructor.params.poolInitCodeHash" + ] + } + }, + "v4PoolManager": { + "name": "Pool Manager", + "pointer": "protocols.v4.contracts.PoolManager" + }, + "v3NFTPositionManager": { + "name": "Uniswap v3 position manager address", + "pointer": "protocols.v3.contracts.NonfungiblePositionManager" + }, + "v4PositionManager": { + "name": "Uniswap v4 position manager address", + "pointer": "protocols.v4.contracts.PositionManager" + } + }, + "dependencies": [ + "weth" + ], + "lookup": { + "latest": "UniversalRouter" + } + } + } + }, + "calibur": { + "name": "Calibur", + "deploy": false, + "contracts": { + "Calibur": { + "deploy": false, + "address": null, + "params": { + "salt": { + "type": "bytes32", + "value": "0x0000000000000000000000000000000000000000eca2ad36bee3874a279d0010" + } + } + } + } + }, + "util-contracts": { + "name": "Utils", + "deploy": false, + "contracts": { + "FeeOnTransferDetector": { + "deploy": false, + "address": null, + "params": { + "factoryV2": { + "name": "Uniswap v2 factory address", + "pointer": "protocols.v2.contracts.UniswapV2Factory" + } + } + }, + "FeeCollector": { + "deploy": false, + "address": null, + "params": { + "owner": { + "type": "address" + }, + "universalRouter": { + "name": "Universal Router address", + "pointer": "protocols.universal-router.contracts.UniversalRouter" + }, + "permit2": { + "name": "Permit 2 address", + "pointer": "protocols.permit2.contracts.Permit2" + }, + "feeToken": { + "name": "Fee token address (usually USDC)", + "type": "address" + } + } + }, + "ERC7914Detector": { + "deploy": false, + "address": "0x000000009B1D0aF20D8C6d0A44e162d11F9b8f00", + "params": { + "caliburAddress": { + "name": "Calibur address for ERC7914 detection", + "pointer": "protocols.calibur.contracts.Calibur" + } + } + } + } + } + }, + "dependencies": { + "weth": { + "type": "address", + "lookup": { + "history": [ + "UniversalRouter.input.constructor.params.weth9", + "QuoterV2.input.constructor._WETH9", + "V3Migrator.input.constructor._WETH9", + "NonfungiblePositionManager.input.constructor._WETH9", + "NonFungibleTokenPositionDescriptor.input.constructor._WETH9", + "SwapRouter.input.constructor._WETH9", + "SwapRouter02.input.constructor._WETH9", + "Quoter.input.constructor._WETH9", + "QuoterV2.input.constructor._WETH9", + "UniswapV2Router02.input.constructor._WETH" + ] + } + } + }, + "rename": true +} \ No newline at end of file diff --git a/script/deploy/tasks/task_template.json b/script/deploy/tasks/task_template.json index d8002b85..a766d875 100644 --- a/script/deploy/tasks/task_template.json +++ b/script/deploy/tasks/task_template.json @@ -349,9 +349,6 @@ "permissionsAdapterFactory": { "name": "Permissions Adapter Factory", "pointer": "protocols.v4.contracts.PermissionsAdapterFactory" - }, - "salt": { - "type": "bytes32" } } }