diff --git a/src/PRBProxyAnnex.sol b/src/PRBProxyAnnex.sol index e1fb1d0..cb806dd 100644 --- a/src/PRBProxyAnnex.sol +++ b/src/PRBProxyAnnex.sol @@ -30,7 +30,7 @@ contract PRBProxyAnnex is PRBProxyStorage // 1 inherited component { /*////////////////////////////////////////////////////////////////////////// - PUBLIC STORAGE + USER-FACING STORAGE //////////////////////////////////////////////////////////////////////////*/ /// @inheritdoc IPRBProxyAnnex diff --git a/src/PRBProxyRegistry.sol b/src/PRBProxyRegistry.sol index fa9e19b..8f08f55 100644 --- a/src/PRBProxyRegistry.sol +++ b/src/PRBProxyRegistry.sol @@ -34,7 +34,7 @@ contract PRBProxyRegistry is IPRBProxyRegistry { string public constant override VERSION = "4.0.0-beta.5"; /*////////////////////////////////////////////////////////////////////////// - PUBLIC STORAGE + USER-FACING STORAGE //////////////////////////////////////////////////////////////////////////*/ /// @inheritdoc IPRBProxyRegistry @@ -43,8 +43,12 @@ contract PRBProxyRegistry is IPRBProxyRegistry { /// @inheritdoc IPRBProxyRegistry mapping(address origin => bytes32 seed) public override nextSeeds; - /// @inheritdoc IPRBProxyRegistry - mapping(address owner => IPRBProxy proxy) public override proxies; + /*////////////////////////////////////////////////////////////////////////// + INTERNAL STORAGE + //////////////////////////////////////////////////////////////////////////*/ + + /// @dev Maps owner addresses to proxy contracts. + mapping(address owner => IPRBProxy proxy) internal _proxies; /*////////////////////////////////////////////////////////////////////////// MODIFIERS @@ -52,7 +56,7 @@ contract PRBProxyRegistry is IPRBProxyRegistry { /// @notice Check that the owner does not have a proxy. modifier noProxy(address owner) { - IPRBProxy proxy = proxies[owner]; + IPRBProxy proxy = _proxies[owner]; if (address(proxy) != address(0)) { revert PRBProxyRegistry_OwnerHasProxy(owner, proxy); } @@ -60,17 +64,21 @@ contract PRBProxyRegistry is IPRBProxyRegistry { } /*////////////////////////////////////////////////////////////////////////// - USER-FACING NON-CONSTANT FUNCTIONS + USER-FACING CONSTANT FUNCTIONS //////////////////////////////////////////////////////////////////////////*/ /// @inheritdoc IPRBProxyRegistry - function deploy() external override noProxy(msg.sender) returns (IPRBProxy proxy) { - proxy = _deploy({ owner: msg.sender }); + function getProxy(address owner) external view returns (IPRBProxy proxy) { + proxy = _proxies[owner]; } + /*////////////////////////////////////////////////////////////////////////// + USER-FACING NON-CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + /// @inheritdoc IPRBProxyRegistry - function deployFor(address owner) public override noProxy(owner) returns (IPRBProxy proxy) { - proxy = _deploy(owner); + function deploy() external override noProxy(msg.sender) returns (IPRBProxy proxy) { + proxy = _deploy({ owner: msg.sender }); } /// @inheritdoc IPRBProxyRegistry @@ -98,7 +106,7 @@ contract PRBProxyRegistry is IPRBProxyRegistry { delete constructorParams; // Associate the the owner with the proxy in the mapping. - proxies[owner] = proxy; + _proxies[owner] = proxy; // Increment the seed. // Using unchecked arithmetic here because this cannot realistically overflow, ever. @@ -118,11 +126,16 @@ contract PRBProxyRegistry is IPRBProxyRegistry { }); } + /// @inheritdoc IPRBProxyRegistry + function deployFor(address owner) public override noProxy(owner) returns (IPRBProxy proxy) { + proxy = _deploy(owner); + } + /*////////////////////////////////////////////////////////////////////////// INTERNAL NON-CONSTANT FUNCTIONS //////////////////////////////////////////////////////////////////////////*/ - /// @dev See the documentation for the public functions that call this internal function. + /// @dev See the documentation for the user-facing functions that call this internal function. function _deploy(address owner) internal returns (IPRBProxy proxy) { // Load the next seed. bytes32 seed = nextSeeds[tx.origin]; @@ -138,7 +151,7 @@ contract PRBProxyRegistry is IPRBProxyRegistry { delete constructorParams; // Associate the the owner with the proxy in the mapping. - proxies[owner] = proxy; + _proxies[owner] = proxy; // Increment the seed. // We're using unchecked arithmetic here because this cannot realistically overflow, ever. diff --git a/src/interfaces/IPRBProxyRegistry.sol b/src/interfaces/IPRBProxyRegistry.sol index 0a0a135..c834d8d 100644 --- a/src/interfaces/IPRBProxyRegistry.sol +++ b/src/interfaces/IPRBProxyRegistry.sol @@ -57,14 +57,14 @@ interface IPRBProxyRegistry { /// @dev The proxy constructor fetches these parameters. function constructorParams() external view returns (address owner, address target, bytes memory data); + /// @notice Retrieves the proxy for the provided owner. + /// @param owner The address of the user to make the query for. + function getProxy(address owner) external view returns (IPRBProxy proxy); + /// @notice The seed that will be used to deploy the next proxy for the provided origin. /// @param origin The externally owned account (EOA) that is part of the CREATE2 salt. function nextSeeds(address origin) external view returns (bytes32 seed); - /// @notice The address of the current proxy for the provided owner. - /// @param owner The address of the user to make the query for. - function proxies(address owner) external view returns (IPRBProxy proxy); - /*////////////////////////////////////////////////////////////////////////// NON-CONSTANT FUNCTIONS //////////////////////////////////////////////////////////////////////////*/ diff --git a/test/registry/deploy-and-execute/deployAndExecute.t.sol b/test/registry/deploy-and-execute/deployAndExecute.t.sol index eabf0f2..7f792bf 100644 --- a/test/registry/deploy-and-execute/deployAndExecute.t.sol +++ b/test/registry/deploy-and-execute/deployAndExecute.t.sol @@ -72,7 +72,7 @@ contract DeployAndExecute_Test is Registry_Test { changePrank({ txOrigin: origin, msgSender: owner }); registry.deployAndExecute(target, data); - address actualProxyAddress = address(registry.proxies(owner)); + address actualProxyAddress = address(registry.getProxy(owner)); address expectedProxyAddress = computeProxyAddress(origin, SEED_ZERO); assertEq(actualProxyAddress, expectedProxyAddress, "proxy address mismatch"); } diff --git a/test/registry/deploy-for/deployFor.t.sol b/test/registry/deploy-for/deployFor.t.sol index 3bd6adb..0403185 100644 --- a/test/registry/deploy-for/deployFor.t.sol +++ b/test/registry/deploy-for/deployFor.t.sol @@ -79,7 +79,7 @@ contract DeployFor_Test is Registry_Test { changePrank({ txOrigin: origin, msgSender: operator }); registry.deployFor(owner); - address actualProxyAddress = address(registry.proxies(owner)); + address actualProxyAddress = address(registry.getProxy(owner)); address expectedProxyAddress = computeProxyAddress(origin, SEED_ZERO); assertEq(actualProxyAddress, expectedProxyAddress, "proxy address mismatch"); } diff --git a/test/registry/deploy/deploy.t.sol b/test/registry/deploy/deploy.t.sol index 1abe531..0beed63 100644 --- a/test/registry/deploy/deploy.t.sol +++ b/test/registry/deploy/deploy.t.sol @@ -50,7 +50,7 @@ contract Deploy_Test is Registry_Test { function testFuzz_Deploy_UpdateProxies(address origin, address owner) external whenOwnerDoesNotHaveProxy { changePrank({ txOrigin: origin, msgSender: owner }); registry.deploy(); - address actualProxy = address(registry.proxies(owner)); + address actualProxy = address(registry.getProxy(owner)); address expectedProxy = computeProxyAddress({ origin: origin, seed: SEED_ZERO }); assertEq(actualProxy, expectedProxy, "proxy mapping mismatch"); } diff --git a/test/utils/Precompiles.sol b/test/utils/Precompiles.sol index c5b1829..c6746a1 100644 --- a/test/utils/Precompiles.sol +++ b/test/utils/Precompiles.sol @@ -16,7 +16,7 @@ contract Precompiles { hex"6080806040523461001657610526908161001c8239f35b600080fdfe6080604081815260048036101561001557600080fd5b600092833560e01c9081631f9838b5146103ba5750806338a40908146103795780634bddd93a146102a3578063aa4b826a14610213578063b96784031461010a5763ffa1ad741461006557600080fd5b346101065782600319360112610106578151908282019082821067ffffffffffffffff8311176100f357508252600c81526020906b342e302e302d626574612e3560a01b8282015282519382859384528251928382860152825b8481106100dd57505050828201840152601f01601f19168101030190f35b81810183015188820188015287955082016100bf565b634e487b7160e01b855260419052602484fd5b8280fd5b5034610106576020918260031936011261020f5781356001600160a01b038116939084900361020b57815163ecdb286560e01b81528581858183895af19081156102015786916101df575b5080519384156101c85750855b8481106101925786867f88b2a910c369b31905e184140cbb1e5ec72817e11c4d6c5993f736716f8546598280a280f35b6001906001600160e01b03196101a882856104fc565b5116885287845284882080546001600160a01b0319168817905501610162565b835163b702f33560e01b8152908101869052602490fd5b6101fb91503d8088833e6101f38183610437565b81019061046f565b38610155565b83513d88823e3d90fd5b8480fd5b8380fd5b50503461029f57606036600319011261029f5761022e610406565b610236610421565b916044359081151580920361020b577f730824739164a9503317b3e878e816553b62d6763c1ba6df1390dea687e4d36c9160209160018060a01b038095169485885260018452818820961695868852835280872060ff1981541660ff841617905551908152a380f35b5080fd5b5034610106576020918260031936011261020f5781356001600160a01b038116939084900361020b57815163ecdb286560e01b81528581858183895af190811561020157869161035f575b5080519384156101c85750855b84811061032b5786867f7207021e3ba5dd0d191feb5efcbb1a8dcf615fa597fc5e1a49ecc13c2b7dd92b8280a280f35b6001906001600160e01b031961034182856104fc565b5116885287845284882080546001600160a01b0319169055016102fb565b61037391503d8088833e6101f38183610437565b386102ee565b5034610106576020366003190112610106573563ffffffff60e01b81168091036101065782526020828152918190205490516001600160a01b039091168152f35b8490843461010657806003193601126101065760ff906020936103db610406565b6103e3610421565b6001600160a01b0391821683526001875283832091168252855220541615158152f35b600435906001600160a01b038216820361041c57565b600080fd5b602435906001600160a01b038216820361041c57565b90601f8019910116810190811067ffffffffffffffff82111761045957604052565b634e487b7160e01b600052604160045260246000fd5b90602090818382031261041c57825167ffffffffffffffff9384821161041c570181601f8201121561041c578051938411610459578360051b90604051946104b985840187610437565b8552838086019282010192831161041c578301905b8282106104dc575050505090565b81516001600160e01b03198116810361041c5781529083019083016104ce565b80518210156105105760209160051b010190565b634e487b7160e01b600052603260045260246000fd"; bytes public constant BYTECODE_REGISTRY = - hex"608080604052346100165761149e908161001c8239f35b600080fdfe6080604090808252600491823610156200001857600080fd5b600091823560e01c908163092af8131462000371575080632c27a01f146200033657806366b0182d146200023157806374912cd214620001b2578063775c300c1462000139578063c455279114620000f75763ffa1ad74146200007a57600080fd5b34620000f35781600319360112620000f3578051918183019083821067ffffffffffffffff831117620000e05750620000dc93508152600c82526b342e302e302d626574612e3560a01b6020830152519182916020835260208301906200078b565b0390f35b634e487b7160e01b815260418552602490fd5b5080fd5b5082346200013557602036600319011262000135576020926001600160a01b03918391908362000126620006dc565b16825285522054169051908152f35b8280fd5b509034620001af5780600319360112620001af573381526020839052819020546001600160a01b0390811692836200018257602083836200017a3362000878565b915191168152f35b91516356352f0b60e11b8152339281019283526001600160a01b0390931660208301525081906040010390fd5b80fd5b5082346200013557602036600319011262000135578190620001d3620006dc565b6001600160a01b03808216865260208390529290942054821680620002015750506200017a60209362000878565b92516356352f0b60e11b81526001600160a01b039485169181019182529390921660208301525081906040010390fd5b5034620000f35781600319360112620000f35760018060a01b03918281541691600193845416938151928091600254916200026c83620006f8565b80875292828116908115620003075750600114620002b8575b50505082916200029e620000dc94606093038462000768565b80519586958652602086015284015260608301906200078b565b9250600283526000805160206200147e8339815191525b828410620002ee575050508201602001816200029e620000dc62000285565b80546020858801810191909152909301928101620002cf565b60ff191660208089019190915293151560051b870190930193508492506200029e9150620000dc905062000285565b5034620000f3576020366003190112620000f35760209181906001600160a01b0362000361620006dc565b1681526003845220549051908152f35b84838534620001af5781600319360112620001af5762000390620006dc565b936024359167ffffffffffffffff95868411620000f35736602385011215620000f357838601359287841162000135573660248587010111620001355733835260208781528684205490986001600160a01b03929091831680620006b25750503280855260038a52878520548851808c0192835260208301829052909791849081908b9089908f9086604082010396601f1997888101825262000434908262000768565b5190209b80845194620004478662000735565b338652868487019d168d5251988389601f8401160162000468908b62000768565b818a52602401838a013787010152848c8201525116956001600160601b0360a01b96878954161788555116620004b59060018060a01b03166001600160601b0360a01b6001541617600155565b8151918383116200069f57908291620004d0600254620006f8565b8d601f821162000652575b50508c91601f8411600114620005de57508792620005d2575b50508160011b916000199060031b1c1916176002555b86519061093d80830191821183831017620005bf57918091879362000b418339039085f58015620005b557169562000541620007e6565b338084529088528583208054929092168717909155328083526003885291859020600185019055845193845260208401929092526001600160a01b038516604084015290918291907f6aafca263a35a9d2a6e4e4659a84688092f4ae153df2f95cd7659508d95c187090606090a451908152f35b86513d85823e3d90fd5b634e487b7160e01b865260418a52602486fd5b015190508b80620004f4565b600289526000805160206200147e8339815191529316888e5b828210620006395750509084600195949392106200061f575b505050811b016002556200050a565b015160001960f88460031b161c191690558b808062000610565b80600186978294978701518155019601940190620005f7565b6200068c9160028b526000805160206200147e83398151915290601f870160051c820192871062000694575b601f0160051c0190620007cd565b8d8d620004db565b90915081906200067e565b634e487b7160e01b875260418b52602487fd5b6356352f0b60e11b8252338a83019081526001600160a01b03909116602082015281906040010390fd5b600435906001600160a01b0382168203620006f357565b600080fd5b90600182811c921680156200072a575b60208310146200071457565b634e487b7160e01b600052602260045260246000fd5b91607f169162000708565b6060810190811067ffffffffffffffff8211176200075257604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff8211176200075257604052565b919082519283825260005b848110620007b8575050826000602080949584010152601f8019910116010190565b60208183018101518483018201520162000796565b818110620007d9575050565b60008155600101620007cd565b60008080556001818155620007fd600254620006f8565b90816200080957505050565b601f82116001146200081c575050600255565b60028352601f6000805160206200147e833981519152920160051c82017f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf5b8181106200086d575050508160025555565b84815582016200085b565b326000818152600360209081526040808320548151808401958652808301829052828152601f199796959394919390620008b460608262000768565b51902093825195620008c68762000735565b6001600160a01b039081168088528288018481528551909a919867ffffffffffffffff92908286018481118482101762000b2c5785620009419281928b52898652858b82015251169d6001600160601b0360a01b9e8f8a5416178955511660018060a01b03166001600160601b0360a01b6001541617600155565b81519183831162000b18579082916200095c600254620006f8565b601f811162000ad8575b508691601f841160011462000a665750879262000a5a575b50508160011b916000199060031b1c1916176002555b84519061093d8083019182118383101762000a4657918091899362000b418339039085f5801562000a3c5716977f6aafca263a35a9d2a6e4e4659a84688092f4ae153df2f95cd7659508d95c1870939291600391620009f2620007e6565b888452600482528484208054919091168b1790553280845291905290829020600185019055905192835260208301939093526001600160a01b0386166040830152339291606090a4565b84513d85823e3d90fd5b634e487b7160e01b86526041600452602486fd5b0151905038806200097e565b600289526000805160206200147e8339815191529316885b8882821062000ac157505090846001959493921062000aa7575b505050811b0160025562000994565b015160001960f88460031b161c1916905538808062000a98565b600185968293968601518155019501930162000a7e565b62000b119060028a526000805160206200147e833981519152601f860160051c8101918a87106200069457601f0160051c0190620007cd565b3862000966565b634e487b7160e01b87526041600452602487fd5b634e487b7160e01b88526041600452602488fdfe60c08060405234620000b5573360a0526366b0182d60e01b8152600081600481335afa8015620000af5760008092819262000086575b506080526001600160a01b03821662000072575b6040516105ef90816200034e823960805181818161025b0152610467015260a051816102160152f35b6200007d916200029d565b50388062000049565b909150620000a692503d8092823e6200009f82620000d0565b0162000179565b90913862000035565b6200020c565b600080fd5b634e487b7160e01b600052604160045260246000fd5b60c0601f91909101601f19168101906001600160401b03821190821017620000f757604052565b620000ba565b601f909101601f19168101906001600160401b03821190821017620000f757604052565b60e051906001600160a01b0382168203620000b557565b6001600160401b038111620000f757601f01601f191660200190565b60005b838110620001685750506000910152565b818101518382015260200162000157565b606060bf19820112620000b55760c0516001600160a01b0381168103620000b55791620001a562000121565b610100519092906001600160401b038111620000b5578160df82011215620000b5578060c00151620001d78162000138565b92620001e76040519485620000fd565b81845260e08284010111620000b557620002099160e060208501910162000154565b90565b6040513d6000823e3d90fd5b3d1562000248573d906200022c8262000138565b916200023c6040519384620000fd565b82523d6000602084013e565b606090565b90602091620002688151809281855285808601910162000154565b601f01601f1916010190565b90916200028e62000209936040845260408401906200024d565b9160208184039101526200024d565b9190823b156200032c57600080825160208401865af4907fb24ebe141c5f2a744b103bea65fce6c40e0dc65d7341d092c09b160f40447990620002df62000218565b60405190956001600160a01b0316928190620002fe9088908362000274565b0390a2156200030957565b508051156200031a57602081519101fd5b60405163061a160d60e41b8152600490fd5b604051636d17e5ef60e11b81526001600160a01b0384166004820152602490fdfe60806040526004361015610027575b36156100255761001d3661035c565b602081519101f35b005b6000803560e01c9081631cff79cd1461007a575080631f9838b51461007557806338a40908146100705780637b1039991461006b57638da5cb5b0361000e57610245565b610200565b6101bb565b610158565b60403660031901126100e65761008e6100e9565b60243567ffffffffffffffff928382116100e657366023830112156100e65781600401359384116100e65736602485840101116100e6576100e26100d685602485018661045a565b60405191829182610144565b0390f35b80fd5b600435906001600160a01b03821682036100ff57565b600080fd5b919082519283825260005b848110610130575050826000602080949584010152601f8019910116010190565b60208183018101518483018201520161010f565b906020610155928181520190610104565b90565b346100ff5760403660031901126100ff576101716100e9565b602435906001600160a01b039081831683036100ff571660009081526001602090815260408083206001600160a01b03909416835292815291902060ff9054166040519015158152f35b346100ff5760203660031901126100ff5760043563ffffffff60e01b81168091036100ff576000526000602052602060018060a01b0360406000205416604051908152f35b346100ff5760003660031901126100ff576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346100ff5760003660031901126100ff576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b908160008237016000815290565b634e487b7160e01b600052604160045260246000fd5b6040519190601f01601f1916820167ffffffffffffffff8111838210176102d457604052565b610298565b67ffffffffffffffff81116102d457601f01601f191660200190565b3d1561031b573d9061030e610309836102d9565b6102ae565b9182523d6000602084013e565b606090565b606090610155939260408252806040830152806000848401376000838284010152601f8019910116810190602083828403019101520190610104565b600080356001600160e01b0319168082526020829052604090912091929161038b90546001600160a01b031690565b906001600160a01b0382169081156104305750600080604051806103af818961028a565b0390845af4907fc4dabe0d7ef7462e2218f2c398c21ef217803e1c46f5cf802d1a5d1d9b503f2f6103de6102f5565b80966103ef60405192839283610320565b0390a2156103fa5750565b82519091501561040d5750805190602001fd5b60405163023c045d60e21b81526001600160a01b03919091166004820152602490fd5b60405163300eff3960e21b81523360048201526001600160e01b0319919091166024820152604490fd5b9091906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169033821415806104ed575b6104c95750506104a5610309836102d9565b9180835236818501116100ff57602081600092610155968387013784010152610546565b606492604051926355d1750960e01b84526004840152336024840152166044820152fd5b5033600052600160205260ff6105198460406000209060018060a01b0316600052602052604060002090565b541615610493565b909161053861015593604084526040840190610104565b916020818403910152610104565b9190823b156105ce57600080825160208401865af4907fb24ebe141c5f2a744b103bea65fce6c40e0dc65d7341d092c09b160f404479906105856102f5565b60405190956001600160a01b03169281906105a290889083610521565b0390a2156105ac57565b508051156105bc57602081519101fd5b60405163061a160d60e41b8152600490fd5b604051636d17e5ef60e11b81526001600160a01b0384166004820152602490fd405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace"; + hex"608080604052346100165761149e908161001c8239f35b600080fdfe6080604090808252600491823610156200001857600080fd5b600091823560e01c908163092af8131462000371575080632c27a01f146200033657806366b0182d146200023157806374912cd214620001b2578063775c300c1462000139578063b7fba4d314620000f75763ffa1ad74146200007a57600080fd5b34620000f35781600319360112620000f3578051918183019083821067ffffffffffffffff831117620000e05750620000dc93508152600c82526b342e302e302d626574612e3560a01b6020830152519182916020835260208301906200078b565b0390f35b634e487b7160e01b815260418552602490fd5b5080fd5b5082346200013557602036600319011262000135576020926001600160a01b03918391908362000126620006dc565b16825285522054169051908152f35b8280fd5b509034620001af5780600319360112620001af573381526020839052819020546001600160a01b0390811692836200018257602083836200017a3362000878565b915191168152f35b91516356352f0b60e11b8152339281019283526001600160a01b0390931660208301525081906040010390fd5b80fd5b5082346200013557602036600319011262000135578190620001d3620006dc565b6001600160a01b03808216865260208390529290942054821680620002015750506200017a60209362000878565b92516356352f0b60e11b81526001600160a01b039485169181019182529390921660208301525081906040010390fd5b5034620000f35781600319360112620000f35760018060a01b03918281541691600193845416938151928091600254916200026c83620006f8565b80875292828116908115620003075750600114620002b8575b50505082916200029e620000dc94606093038462000768565b80519586958652602086015284015260608301906200078b565b9250600283526000805160206200147e8339815191525b828410620002ee575050508201602001816200029e620000dc62000285565b80546020858801810191909152909301928101620002cf565b60ff191660208089019190915293151560051b870190930193508492506200029e9150620000dc905062000285565b5034620000f3576020366003190112620000f35760209181906001600160a01b0362000361620006dc565b1681526003845220549051908152f35b84838534620001af5781600319360112620001af5762000390620006dc565b936024359167ffffffffffffffff95868411620000f35736602385011215620000f357838601359287841162000135573660248587010111620001355733835260208781528684205490986001600160a01b03929091831680620006b25750503280855260038a52878520548851808c0192835260208301829052909791849081908b9089908f9086604082010396601f1997888101825262000434908262000768565b5190209b80845194620004478662000735565b338652868487019d168d5251988389601f8401160162000468908b62000768565b818a52602401838a013787010152848c8201525116956001600160601b0360a01b96878954161788555116620004b59060018060a01b03166001600160601b0360a01b6001541617600155565b8151918383116200069f57908291620004d0600254620006f8565b8d601f821162000652575b50508c91601f8411600114620005de57508792620005d2575b50508160011b916000199060031b1c1916176002555b86519061093d80830191821183831017620005bf57918091879362000b418339039085f58015620005b557169562000541620007e6565b338084529088528583208054929092168717909155328083526003885291859020600185019055845193845260208401929092526001600160a01b038516604084015290918291907f6aafca263a35a9d2a6e4e4659a84688092f4ae153df2f95cd7659508d95c187090606090a451908152f35b86513d85823e3d90fd5b634e487b7160e01b865260418a52602486fd5b015190508b80620004f4565b600289526000805160206200147e8339815191529316888e5b828210620006395750509084600195949392106200061f575b505050811b016002556200050a565b015160001960f88460031b161c191690558b808062000610565b80600186978294978701518155019601940190620005f7565b6200068c9160028b526000805160206200147e83398151915290601f870160051c820192871062000694575b601f0160051c0190620007cd565b8d8d620004db565b90915081906200067e565b634e487b7160e01b875260418b52602487fd5b6356352f0b60e11b8252338a83019081526001600160a01b03909116602082015281906040010390fd5b600435906001600160a01b0382168203620006f357565b600080fd5b90600182811c921680156200072a575b60208310146200071457565b634e487b7160e01b600052602260045260246000fd5b91607f169162000708565b6060810190811067ffffffffffffffff8211176200075257604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff8211176200075257604052565b919082519283825260005b848110620007b8575050826000602080949584010152601f8019910116010190565b60208183018101518483018201520162000796565b818110620007d9575050565b60008155600101620007cd565b60008080556001818155620007fd600254620006f8565b90816200080957505050565b601f82116001146200081c575050600255565b60028352601f6000805160206200147e833981519152920160051c82017f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf5b8181106200086d575050508160025555565b84815582016200085b565b326000818152600360209081526040808320548151808401958652808301829052828152601f199796959394919390620008b460608262000768565b51902093825195620008c68762000735565b6001600160a01b039081168088528288018481528551909a919867ffffffffffffffff92908286018481118482101762000b2c5785620009419281928b52898652858b82015251169d6001600160601b0360a01b9e8f8a5416178955511660018060a01b03166001600160601b0360a01b6001541617600155565b81519183831162000b18579082916200095c600254620006f8565b601f811162000ad8575b508691601f841160011462000a665750879262000a5a575b50508160011b916000199060031b1c1916176002555b84519061093d8083019182118383101762000a4657918091899362000b418339039085f5801562000a3c5716977f6aafca263a35a9d2a6e4e4659a84688092f4ae153df2f95cd7659508d95c1870939291600391620009f2620007e6565b888452600482528484208054919091168b1790553280845291905290829020600185019055905192835260208301939093526001600160a01b0386166040830152339291606090a4565b84513d85823e3d90fd5b634e487b7160e01b86526041600452602486fd5b0151905038806200097e565b600289526000805160206200147e8339815191529316885b8882821062000ac157505090846001959493921062000aa7575b505050811b0160025562000994565b015160001960f88460031b161c1916905538808062000a98565b600185968293968601518155019501930162000a7e565b62000b119060028a526000805160206200147e833981519152601f860160051c8101918a87106200069457601f0160051c0190620007cd565b3862000966565b634e487b7160e01b87526041600452602487fd5b634e487b7160e01b88526041600452602488fdfe60c08060405234620000b5573360a0526366b0182d60e01b8152600081600481335afa8015620000af5760008092819262000086575b506080526001600160a01b03821662000072575b6040516105ef90816200034e823960805181818161025b0152610467015260a051816102160152f35b6200007d916200029d565b50388062000049565b909150620000a692503d8092823e6200009f82620000d0565b0162000179565b90913862000035565b6200020c565b600080fd5b634e487b7160e01b600052604160045260246000fd5b60c0601f91909101601f19168101906001600160401b03821190821017620000f757604052565b620000ba565b601f909101601f19168101906001600160401b03821190821017620000f757604052565b60e051906001600160a01b0382168203620000b557565b6001600160401b038111620000f757601f01601f191660200190565b60005b838110620001685750506000910152565b818101518382015260200162000157565b606060bf19820112620000b55760c0516001600160a01b0381168103620000b55791620001a562000121565b610100519092906001600160401b038111620000b5578160df82011215620000b5578060c00151620001d78162000138565b92620001e76040519485620000fd565b81845260e08284010111620000b557620002099160e060208501910162000154565b90565b6040513d6000823e3d90fd5b3d1562000248573d906200022c8262000138565b916200023c6040519384620000fd565b82523d6000602084013e565b606090565b90602091620002688151809281855285808601910162000154565b601f01601f1916010190565b90916200028e62000209936040845260408401906200024d565b9160208184039101526200024d565b9190823b156200032c57600080825160208401865af4907fb24ebe141c5f2a744b103bea65fce6c40e0dc65d7341d092c09b160f40447990620002df62000218565b60405190956001600160a01b0316928190620002fe9088908362000274565b0390a2156200030957565b508051156200031a57602081519101fd5b60405163061a160d60e41b8152600490fd5b604051636d17e5ef60e11b81526001600160a01b0384166004820152602490fdfe60806040526004361015610027575b36156100255761001d3661035c565b602081519101f35b005b6000803560e01c9081631cff79cd1461007a575080631f9838b51461007557806338a40908146100705780637b1039991461006b57638da5cb5b0361000e57610245565b610200565b6101bb565b610158565b60403660031901126100e65761008e6100e9565b60243567ffffffffffffffff928382116100e657366023830112156100e65781600401359384116100e65736602485840101116100e6576100e26100d685602485018661045a565b60405191829182610144565b0390f35b80fd5b600435906001600160a01b03821682036100ff57565b600080fd5b919082519283825260005b848110610130575050826000602080949584010152601f8019910116010190565b60208183018101518483018201520161010f565b906020610155928181520190610104565b90565b346100ff5760403660031901126100ff576101716100e9565b602435906001600160a01b039081831683036100ff571660009081526001602090815260408083206001600160a01b03909416835292815291902060ff9054166040519015158152f35b346100ff5760203660031901126100ff5760043563ffffffff60e01b81168091036100ff576000526000602052602060018060a01b0360406000205416604051908152f35b346100ff5760003660031901126100ff576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346100ff5760003660031901126100ff576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b908160008237016000815290565b634e487b7160e01b600052604160045260246000fd5b6040519190601f01601f1916820167ffffffffffffffff8111838210176102d457604052565b610298565b67ffffffffffffffff81116102d457601f01601f191660200190565b3d1561031b573d9061030e610309836102d9565b6102ae565b9182523d6000602084013e565b606090565b606090610155939260408252806040830152806000848401376000838284010152601f8019910116810190602083828403019101520190610104565b600080356001600160e01b0319168082526020829052604090912091929161038b90546001600160a01b031690565b906001600160a01b0382169081156104305750600080604051806103af818961028a565b0390845af4907fc4dabe0d7ef7462e2218f2c398c21ef217803e1c46f5cf802d1a5d1d9b503f2f6103de6102f5565b80966103ef60405192839283610320565b0390a2156103fa5750565b82519091501561040d5750805190602001fd5b60405163023c045d60e21b81526001600160a01b03919091166004820152602490fd5b60405163300eff3960e21b81523360048201526001600160e01b0319919091166024820152604490fd5b9091906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169033821415806104ed575b6104c95750506104a5610309836102d9565b9180835236818501116100ff57602081600092610155968387013784010152610546565b606492604051926355d1750960e01b84526004840152336024840152166044820152fd5b5033600052600160205260ff6105198460406000209060018060a01b0316600052602052604060002090565b541615610493565b909161053861015593604084526040840190610104565b916020818403910152610104565b9190823b156105ce57600080825160208401865af4907fb24ebe141c5f2a744b103bea65fce6c40e0dc65d7341d092c09b160f404479906105856102f5565b60405190956001600160a01b03169281906105a290889083610521565b0390a2156105ac57565b508051156105bc57602081519101fd5b60405163061a160d60e41b8152600490fd5b604051636d17e5ef60e11b81526001600160a01b0384166004820152602490fd405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace"; /*////////////////////////////////////////////////////////////////////////// DEPLOYERS