UNPKG

@mantleio/contracts

Version:
178 lines 30.1 kB
{ "address": "0x95fC37A27a2f68e3A647CDc081F0A89bb47c3012", "abi": [ { "inputs": [ { "internalType": "address", "name": "_owner", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "stateMutability": "payable", "type": "fallback" }, { "inputs": [], "name": "getImplementation", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "getOwner", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "bytes", "name": "_code", "type": "bytes" } ], "name": "setCode", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "_owner", "type": "address" } ], "name": "setOwner", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "bytes32", "name": "_key", "type": "bytes32" }, { "internalType": "bytes32", "name": "_value", "type": "bytes32" } ], "name": "setStorage", "outputs": [], "stateMutability": "nonpayable", "type": "function" } ], "transactionHash": "0x8dc9c57510db291b3dea6a8c0a8a6d6580b03150cf57958f38485a1ab4182996", "receipt": { "to": null, "from": "0x2A2954F3989a83Cc43DD58B0f038D5F276f21333", "contractAddress": "0x95fC37A27a2f68e3A647CDc081F0A89bb47c3012", "transactionIndex": 23, "gasUsed": "489762", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x1560ad7f781588db0d2bb6d17287e930ffea32baf758394a6198ed5756cb0c3d", "transactionHash": "0x8dc9c57510db291b3dea6a8c0a8a6d6580b03150cf57958f38485a1ab4182996", "logs": [], "blockNumber": 17577718, "cumulativeGasUsed": "5717576", "status": 1, "byzantium": true }, "args": [ "0x2A2954F3989a83Cc43DD58B0f038D5F276f21333" ], "numDeployments": 1, "solcInputHash": "b23d30c64588a09e5667df3d0b30ee18", "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"getImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"setCode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_value\",\"type\":\"bytes32\"}],\"name\":\"setStorage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_owner\":\"Address of the initial contract owner.\"}},\"getImplementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"getOwner()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"setCode(bytes)\":{\"params\":{\"_code\":\"New contract code to run inside this contract.\"}},\"setOwner(address)\":{\"params\":{\"_owner\":\"New owner of the proxy contract.\"}},\"setStorage(bytes32,bytes32)\":{\"params\":{\"_key\":\"Storage key to modify.\",\"_value\":\"New value for the storage key.\"}}},\"title\":\"L1ChugSplashProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getImplementation()\":{\"notice\":\"Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"getOwner()\":{\"notice\":\"Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"setCode(bytes)\":{\"notice\":\"Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner.\"},\"setOwner(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"setStorage(bytes32,bytes32)\":{\"notice\":\"Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":\"L1ChugSplashProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { iL1ChugSplashDeployer } from \\\"./interfaces/iL1ChugSplashDeployer.sol\\\";\\n\\n/**\\n * @title L1ChugSplashProxy\\n * @dev Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\\n * functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty!\\n *\\n * Note for future developers: do NOT make anything in this contract 'public' unless you know what\\n * you're doing. Anything public can potentially have a function signature that conflicts with a\\n * signature attached to the implementation contract. Public functions SHOULD always have the\\n * 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that\\n * modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\\n */\\ncontract L1ChugSplashProxy {\\n /*************\\n * Constants *\\n *************/\\n\\n // \\\"Magic\\\" prefix. When prepended to some arbitrary bytecode and used to create a contract, the\\n // appended bytecode will be deployed as given.\\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _owner Address of the initial contract owner.\\n */\\n constructor(address _owner) {\\n _setOwner(_owner);\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n /**\\n * Blocks a function from being called when the parent signals that the system should be paused\\n * via an isUpgrading function.\\n */\\n modifier onlyWhenNotPaused() {\\n address owner = _getOwner();\\n\\n // We do a low-level call because there's no guarantee that the owner actually *is* an\\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\\n // it turns out that it isn't the right type of contract.\\n (bool success, bytes memory returndata) = owner.staticcall(\\n abi.encodeWithSelector(iL1ChugSplashDeployer.isUpgrading.selector)\\n );\\n\\n // If the call was unsuccessful then we assume that there's no \\\"isUpgrading\\\" method and we\\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\\n // long. If this isn't the case then we can safely ignore the result.\\n if (success && returndata.length == 32) {\\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\\n // case that the isUpgrading function returned something other than 0 or 1. But we only\\n // really care about the case where this value is 0 (= false).\\n uint256 ret = abi.decode(returndata, (uint256));\\n require(ret == 0, \\\"L1ChugSplashProxy: system is currently being upgraded\\\");\\n }\\n\\n _;\\n }\\n\\n /**\\n * Makes a proxy call instead of triggering the given function when the caller is either the\\n * owner or the zero address. Caller can only ever be the zero address if this function is\\n * being called off-chain via eth_call, which is totally fine and can be convenient for\\n * client-side tooling. Avoids situations where the proxy and implementation share a sighash\\n * and the proxy function ends up being called instead of the implementation one.\\n *\\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a\\n * way for someone to send a transaction with msg.sender == address(0) in any real context then\\n * we have much bigger problems. Primary reason to include this additional allowed sender is\\n * because the owner address can be changed dynamically and we do not want clients to have to\\n * keep track of the current owner in order to make an eth_call that doesn't trigger the\\n * proxied contract.\\n */\\n // slither-disable-next-line incorrect-modifier\\n modifier proxyCallIfNotOwner() {\\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the code that should be running behind this proxy. Note that this scheme is a bit\\n * different from the standard proxy scheme where one would typically deploy the code\\n * separately and then set the implementation address. We're doing it this way because it gives\\n * us a lot more freedom on the client side. Can only be triggered by the contract owner.\\n * @param _code New contract code to run inside this contract.\\n */\\n // slither-disable-next-line external-function\\n function setCode(bytes memory _code) public proxyCallIfNotOwner {\\n // Get the code hash of the current implementation.\\n address implementation = _getImplementation();\\n\\n // If the code hash matches the new implementation then we return early.\\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\\n return;\\n }\\n\\n // Create the deploycode by appending the magic prefix.\\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\\n\\n // Deploy the code and set the new implementation address.\\n address newImplementation;\\n assembly {\\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\\n }\\n\\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\\n // actually fail this check. Should only happen if the contract creation from above runs\\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\\n // should be doing this check anyway though.\\n require(\\n _getAccountCodeHash(newImplementation) == keccak256(_code),\\n \\\"L1ChugSplashProxy: code was not correctly deployed.\\\"\\n );\\n\\n _setImplementation(newImplementation);\\n }\\n\\n /**\\n * Modifies some storage slot within the proxy contract. Gives us a lot of power to perform\\n * upgrades in a more transparent way. Only callable by the owner.\\n * @param _key Storage key to modify.\\n * @param _value New value for the storage key.\\n */\\n // slither-disable-next-line external-function\\n function setStorage(bytes32 _key, bytes32 _value) public proxyCallIfNotOwner {\\n assembly {\\n sstore(_key, _value)\\n }\\n }\\n\\n /**\\n * Changes the owner of the proxy contract. Only callable by the owner.\\n * @param _owner New owner of the proxy contract.\\n */\\n // slither-disable-next-line external-function\\n function setOwner(address _owner) public proxyCallIfNotOwner {\\n _setOwner(_owner);\\n }\\n\\n /**\\n * Queries the owner of the proxy contract. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Owner address.\\n */\\n // slither-disable-next-line external-function\\n function getOwner() public proxyCallIfNotOwner returns (address) {\\n return _getOwner();\\n }\\n\\n /**\\n * Queries the implementation address. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Implementation address.\\n */\\n // slither-disable-next-line external-function\\n function getImplementation() public proxyCallIfNotOwner returns (address) {\\n return _getImplementation();\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Sets the implementation address.\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n }\\n\\n /**\\n * Queries the implementation address.\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address implementation;\\n assembly {\\n implementation := sload(IMPLEMENTATION_KEY)\\n }\\n return implementation;\\n }\\n\\n /**\\n * Changes the owner of the proxy contract.\\n * @param _owner New owner of the proxy contract.\\n */\\n function _setOwner(address _owner) internal {\\n assembly {\\n sstore(OWNER_KEY, _owner)\\n }\\n }\\n\\n /**\\n * Queries the owner of the proxy contract.\\n * @return Owner address.\\n */\\n function _getOwner() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n\\n /**\\n * Gets the code hash for a given account.\\n * @param _account Address of the account to get a code hash for.\\n * @return Code hash for the account.\\n */\\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\\n bytes32 codeHash;\\n assembly {\\n codeHash := extcodehash(_account)\\n }\\n return codeHash;\\n }\\n\\n /**\\n * Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal onlyWhenNotPaused {\\n address implementation = _getImplementation();\\n\\n require(implementation != address(0), \\\"L1ChugSplashProxy: implementation is not set yet\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3cb52dfdc2706992572dd5621ae89ba919fd20539b73488a455d564f16f1b8d\",\"license\":\"MIT\"},\"contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title iL1ChugSplashDeployer\\n */\\ninterface iL1ChugSplashDeployer {\\n function isUpgrading() external view returns (bool);\\n}\\n\",\"keccak256\":\"0x9a496d99f111c1091f0c33d6bfc7802a522baa7235614b0014f35e4bbe280e57\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x608060405234801561001057600080fd5b5060405161081138038061081183398101604081905261002f9161005d565b610057817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b5061008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b6107758061009c6000396000f3fe60806040526004361061004a5760003560e01c806313af4035146100545780636c5d4ad014610074578063893d20e8146100945780639b0b0fda146100c5578063aaf10f42146100e5575b6100526100fa565b005b34801561006057600080fd5b5061005261006f366004610556565b6102e8565b34801561008057600080fd5b5061005261008f36600461059c565b61033b565b3480156100a057600080fd5b506100a961046d565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d157600080fd5b506100526100e036600461064d565b6104c6565b3480156100f157600080fd5b506100a9610508565b60006101126000805160206107008339815191525490565b60408051600481526024810182526020810180516001600160e01b0316635bca393160e11b179052905191925060009182916001600160a01b0385169161015991906106aa565b600060405180830381855afa9150503d8060008114610194576040519150601f19603f3d011682016040523d82523d6000602084013e610199565b606091505b50915091508180156101ac575080516020145b1561023c576000818060200190518101906101c791906106b6565b9050801561023a5760405162461bcd60e51b815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d206973206375726044820152741c995b9d1b1e4818995a5b99c81d5c19dc98591959605a1b60648201526084015b60405180910390fd5b505b60006102546000805160206107208339815191525490565b90506001600160a01b0381166102c55760405162461bcd60e51b815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201526f1b881a5cc81b9bdd081cd95d081e595d60821b6064820152608401610231565b3660008037600080366000845af43d6000803e806102e2573d6000fd5b503d6000f35b600080516020610700833981519152546001600160a01b0316336001600160a01b03161480610315575033155b15610333576103308160008051602061070083398151915255565b50565b6103306100fa565b600080516020610700833981519152546001600160a01b0316336001600160a01b03161480610368575033155b156103335760006103856000805160206107208339815191525490565b9050803f82516020840120141561039a575050565b6040516000906103c0906c600d380380600d6000396000f360981b9085906020016106cf565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146104515760405162461bcd60e51b815260206004820152603360248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527231b7b93932b1ba363c903232b83637bcb2b21760691b6064820152608401610231565b6104678160008051602061072083398151915255565b50505050565b60006104856000805160206107008339815191525490565b6001600160a01b0316336001600160a01b031614806104a2575033155b156104bb57506000805160206107008339815191525490565b6104c36100fa565b90565b600080516020610700833981519152546001600160a01b0316336001600160a01b031614806104f3575033155b156104fc579055565b6105046100fa565b5050565b60006105206000805160206107008339815191525490565b6001600160a01b0316336001600160a01b0316148061053d575033155b156104bb57506000805160206107208339815191525490565b60006020828403121561056857600080fd5b81356001600160a01b038116811461057f57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156105ae57600080fd5b813567ffffffffffffffff808211156105c657600080fd5b818401915084601f8301126105da57600080fd5b8135818111156105ec576105ec610586565b604051601f8201601f19908116603f0116810190838211818310171561061457610614610586565b8160405282815287602084870101111561062d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806040838503121561066057600080fd5b50508035926020909101359150565b6000815160005b818110156106905760208185018101518683015201610676565b8181111561069f576000828601525b509290920192915050565b600061057f828461066f565b6000602082840312156106c857600080fd5b5051919050565b72ffffffffffffffffffffffffffffffffffffff198316815260006106f7600d83018461066f565b94935050505056feb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220a2b9ac5ee1a01cc226ef31c36d5125ab2eb4383b5896a35053c0d882360df2ea64736f6c63430008090033", "deployedBytecode": "0x60806040526004361061004a5760003560e01c806313af4035146100545780636c5d4ad014610074578063893d20e8146100945780639b0b0fda146100c5578063aaf10f42146100e5575b6100526100fa565b005b34801561006057600080fd5b5061005261006f366004610556565b6102e8565b34801561008057600080fd5b5061005261008f36600461059c565b61033b565b3480156100a057600080fd5b506100a961046d565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d157600080fd5b506100526100e036600461064d565b6104c6565b3480156100f157600080fd5b506100a9610508565b60006101126000805160206107008339815191525490565b60408051600481526024810182526020810180516001600160e01b0316635bca393160e11b179052905191925060009182916001600160a01b0385169161015991906106aa565b600060405180830381855afa9150503d8060008114610194576040519150601f19603f3d011682016040523d82523d6000602084013e610199565b606091505b50915091508180156101ac575080516020145b1561023c576000818060200190518101906101c791906106b6565b9050801561023a5760405162461bcd60e51b815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d206973206375726044820152741c995b9d1b1e4818995a5b99c81d5c19dc98591959605a1b60648201526084015b60405180910390fd5b505b60006102546000805160206107208339815191525490565b90506001600160a01b0381166102c55760405162461bcd60e51b815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201526f1b881a5cc81b9bdd081cd95d081e595d60821b6064820152608401610231565b3660008037600080366000845af43d6000803e806102e2573d6000fd5b503d6000f35b600080516020610700833981519152546001600160a01b0316336001600160a01b03161480610315575033155b15610333576103308160008051602061070083398151915255565b50565b6103306100fa565b600080516020610700833981519152546001600160a01b0316336001600160a01b03161480610368575033155b156103335760006103856000805160206107208339815191525490565b9050803f82516020840120141561039a575050565b6040516000906103c0906c600d380380600d6000396000f360981b9085906020016106cf565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146104515760405162461bcd60e51b815260206004820152603360248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527231b7b93932b1ba363c903232b83637bcb2b21760691b6064820152608401610231565b6104678160008051602061072083398151915255565b50505050565b60006104856000805160206107008339815191525490565b6001600160a01b0316336001600160a01b031614806104a2575033155b156104bb57506000805160206107008339815191525490565b6104c36100fa565b90565b600080516020610700833981519152546001600160a01b0316336001600160a01b031614806104f3575033155b156104fc579055565b6105046100fa565b5050565b60006105206000805160206107008339815191525490565b6001600160a01b0316336001600160a01b0316148061053d575033155b156104bb57506000805160206107208339815191525490565b60006020828403121561056857600080fd5b81356001600160a01b038116811461057f57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156105ae57600080fd5b813567ffffffffffffffff808211156105c657600080fd5b818401915084601f8301126105da57600080fd5b8135818111156105ec576105ec610586565b604051601f8201601f19908116603f0116810190838211818310171561061457610614610586565b8160405282815287602084870101111561062d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806040838503121561066057600080fd5b50508035926020909101359150565b6000815160005b818110156106905760208185018101518683015201610676565b8181111561069f576000828601525b509290920192915050565b600061057f828461066f565b6000602082840312156106c857600080fd5b5051919050565b72ffffffffffffffffffffffffffffffffffffff198316815260006106f7600d83018461066f565b94935050505056feb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220a2b9ac5ee1a01cc226ef31c36d5125ab2eb4383b5896a35053c0d882360df2ea64736f6c63430008090033", "devdoc": { "details": "Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!", "kind": "dev", "methods": { "constructor": { "params": { "_owner": "Address of the initial contract owner." } }, "getImplementation()": { "returns": { "_0": "Implementation address." } }, "getOwner()": { "returns": { "_0": "Owner address." } }, "setCode(bytes)": { "params": { "_code": "New contract code to run inside this contract." } }, "setOwner(address)": { "params": { "_owner": "New owner of the proxy contract." } }, "setStorage(bytes32,bytes32)": { "params": { "_key": "Storage key to modify.", "_value": "New value for the storage key." } } }, "title": "L1ChugSplashProxy", "version": 1 }, "userdoc": { "kind": "user", "methods": { "getImplementation()": { "notice": "Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)." }, "getOwner()": { "notice": "Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)." }, "setCode(bytes)": { "notice": "Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner." }, "setOwner(address)": { "notice": "Changes the owner of the proxy contract. Only callable by the owner." }, "setStorage(bytes32,bytes32)": { "notice": "Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner." } }, "version": 1 }, "storageLayout": { "storage": [], "types": null } }