0%
HomeSmart contracts
L1ChugSplashProxy

L1ChugSplashProxy

Deploy on Alchemy
    Verified
  • Verified
  • Optimism
  • Layer 2
  • Bridge
  • Proxy

This contract is a proxy and the implementation details are not yet known.

0x99c9fc46f92e8a1c0dec1b1747d010903e884be1
Copied
Copied
L1ChugSplashProxy Source Code
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; import { iL1ChugSplashDeployer } from "./interfaces/iL1ChugSplashDeployer.sol"; /** * @title L1ChugSplashProxy * @dev 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! */ contract L1ChugSplashProxy { /************* * Constants * *************/ // "Magic" prefix. When prepended to some arbitrary bytecode and used to create a contract, the // appended bytecode will be deployed as given. bytes13 constant internal DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3; // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) bytes32 constant internal IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1) bytes32 constant internal OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /*************** * Constructor * ***************/ /** * @param _owner Address of the initial contract owner. */ constructor( address _owner ) { _setOwner(_owner); } /********************** * Function Modifiers * **********************/ /** * Blocks a function from being called when the parent signals that the system should be paused * via an isUpgrading function. */ modifier onlyWhenNotPaused() { address owner = _getOwner(); // We do a low-level call because there's no guarantee that the owner actually *is* an // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and // it turns out that it isn't the right type of contract. (bool success, bytes memory returndata) = owner.staticcall( abi.encodeWithSelector( iL1ChugSplashDeployer.isUpgrading.selector ) ); // If the call was unsuccessful then we assume that there's no "isUpgrading" method and we // can just continue as normal. We also expect that the return value is exactly 32 bytes // long. If this isn't the case then we can safely ignore the result. if (success &amp;&amp; returndata.length == 32) { // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the // case that the isUpgrading function returned something other than 0 or 1. But we only // really care about the case where this value is 0 (= false). uint256 ret = abi.decode(returndata, (uint256)); require( ret == 0, "L1ChugSplashProxy: system is currently being upgraded" ); } _; } /** * Makes a proxy call instead of triggering the given function when the caller is either the * owner or the zero address. Caller can only ever be the zero address if this function is * being called off-chain via eth_call, which is totally fine and can be convenient for * client-side tooling. Avoids situations where the proxy and implementation share a sighash * and the proxy function ends up being called instead of the implementation one. * * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a * way for someone to send a transaction with msg.sender == address(0) in any real context then * we have much bigger problems. Primary reason to include this additional allowed sender is * because the owner address can be changed dynamically and we do not want clients to have to * keep track of the current owner in order to make an eth_call that doesn't trigger the * proxied contract. */ modifier proxyCallIfNotOwner() { if (msg.sender == _getOwner() || msg.sender == address(0)) { _; } else { // This WILL halt the call frame on completion. _doProxyCall(); } } /********************* * Fallback Function * *********************/ fallback() external payable { // Proxy call by default. _doProxyCall(); } /******************** * Public Functions * ********************/ /** * 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. * @param _code New contract code to run inside this contract. */ function setCode( bytes memory _code ) proxyCallIfNotOwner public { // Get the code hash of the current implementation. address implementation = _getImplementation(); // If the code hash matches the new implementation then we return early. if (keccak256(_code) == _getAccountCodeHash(implementation)) { return; } // Create the deploycode by appending the magic prefix. bytes memory deploycode = abi.encodePacked( DEPLOY_CODE_PREFIX, _code ); // Deploy the code and set the new implementation address. address newImplementation; assembly { newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode)) } // Check that the code was actually deployed correctly. I'm not sure if you can ever // actually fail this check. Should only happen if the contract creation from above runs // out of gas but this parent execution thread does NOT run out of gas. Seems like we // should be doing this check anyway though. require( _getAccountCodeHash(newImplementation) == keccak256(_code), "L1ChugSplashProxy: code was not correctly deployed." ); _setImplementation(newImplementation); } /** * 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. * @param _key Storage key to modify. * @param _value New value for the storage key. */ function setStorage( bytes32 _key, bytes32 _value ) proxyCallIfNotOwner public { assembly { sstore(_key, _value) } } /** * Changes the owner of the proxy contract. Only callable by the owner. * @param _owner New owner of the proxy contract. */ function setOwner( address _owner ) proxyCallIfNotOwner public { _setOwner(_owner); } /** * 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). * @return Owner address. */ function getOwner() proxyCallIfNotOwner public returns ( address ) { return _getOwner(); } /** * 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). * @return Implementation address. */ function getImplementation() proxyCallIfNotOwner public returns ( address ) { return _getImplementation(); } /********************** * Internal Functions * **********************/ /** * Sets the implementation address. * @param _implementation New implementation address. */ function _setImplementation( address _implementation ) internal { assembly { sstore(IMPLEMENTATION_KEY, _implementation) } } /** * Queries the implementation address. * @return Implementation address. */ function _getImplementation() internal view returns ( address ) { address implementation; assembly { implementation := sload(IMPLEMENTATION_KEY) } return implementation; } /** * Changes the owner of the proxy contract. * @param _owner New owner of the proxy contract. */ function _setOwner( address _owner ) internal { assembly { sstore(OWNER_KEY, _owner) } } /** * Queries the owner of the proxy contract. * @return Owner address. */ function _getOwner() internal view returns ( address ) { address owner; assembly { owner := sload(OWNER_KEY) } return owner; } /** * Gets the code hash for a given account. * @param _account Address of the account to get a code hash for. * @return Code hash for the account. */ function _getAccountCodeHash( address _account ) internal view returns ( bytes32 ) { bytes32 codeHash; assembly { codeHash := extcodehash(_account) } return codeHash; } /** * Performs the proxy call via a delegatecall. */ function _doProxyCall() onlyWhenNotPaused internal { address implementation = _getImplementation(); require( implementation != address(0), "L1ChugSplashProxy: implementation is not set yet" ); assembly { // Copy calldata into memory at 0x0....calldatasize. calldatacopy(0x0, 0x0, calldatasize()) // Perform the delegatecall, make sure to pass all available gas. let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0) // Copy returndata into memory at 0x0....returndatasize. Note that this *will* // overwrite the calldata that we just copied into memory but that doesn't really // matter because we'll be returning in a second anyway. returndatacopy(0x0, 0x0, returndatasize()) // Success == 0 means a revert. We'll revert too and pass the data up. if iszero(success) { revert(0x0, returndatasize()) } // Otherwise we'll just return and pass the data up. return(0x0, returndatasize()) } } } // SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; /** * @title iL1ChugSplashDeployer */ interface iL1ChugSplashDeployer { function isUpgrading() external view returns ( bool ); }
L1ChugSplashProxy ABI
Copied
[{"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"}]
L1ChugSplashProxy Bytecode
Copied
608060405234801561001057600080fd5b506040516107983803806107988339818101604052602081101561003357600080fd5b505161003e81610044565b50610068565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b610721806100776000396000f3fe60806040526004361061004a5760003560e01c806313af4035146100545780636c5d4ad014610087578063893d20e81461013a5780639b0b0fda1461016b578063aaf10f421461019b575b6100526101b0565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661036c565b34801561009357600080fd5b50610052600480360360208110156100aa57600080fd5b8101906020810181356401000000008111156100c557600080fd5b8201836020820111156100d757600080fd5b803590602001918460018302840111640100000000831117156100f957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103af945050505050565b34801561014657600080fd5b5061014f610505565b604080516001600160a01b039092168252519081900360200190f35b34801561017757600080fd5b506100526004803603604081101561018e57600080fd5b508035906020013561054b565b3480156101a757600080fd5b5061014f610589565b60006101ba6105bd565b60408051600481526024810182526020810180516001600160e01b0316635bca393160e11b1781529151815193945060009384936001600160a01b0387169392918291908083835b602083106102215780518252601f199092019160209182019101610202565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114610281576040519150601f19603f3d011682016040523d82523d6000602084013e610286565b606091505b5091509150818015610299575080516020145b156102f85760008180602001905160208110156102b557600080fd5b5051905080156102f65760405162461bcd60e51b81526004018080602001828103825260358152602001806106b76035913960400191505060405180910390fd5b505b60006103026105e2565b90506001600160a01b0381166103495760405162461bcd60e51b81526004018080602001828103825260308152602001806106546030913960400191505060405180910390fd5b3660008037600080366000845af43d6000803e80610366573d6000fd5b503d6000f35b6103746105bd565b6001600160a01b0316336001600160a01b03161480610391575033155b156103a45761039f81610607565b6103ac565b6103ac6101b0565b50565b6103b76105bd565b6001600160a01b0316336001600160a01b031614806103d4575033155b156103a45760006103e36105e2565b90506103ee8161062b565b825160208401201415610401575061039f565b60006c600d380380600d6000396000f360981b83604051602001808372ffffffffffffffffffffffffffffffffffffff19168152600d0182805190602001908083835b602083106104635780518252601f199092019160209182019101610444565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052905060008151602083016000f0905083805190602001206104b88261062b565b146104f45760405162461bcd60e51b81526004018080602001828103825260338152602001806106846033913960400191505060405180910390fd5b6104fd8161062f565b5050506103ac565b600061050f6105bd565b6001600160a01b0316336001600160a01b0316148061052c575033155b15610540576105396105bd565b9050610548565b6105486101b0565b90565b6105536105bd565b6001600160a01b0316336001600160a01b03161480610570575033155b1561057d57808255610585565b6105856101b0565b5050565b60006105936105bd565b6001600160a01b0316336001600160a01b031614806105b0575033155b15610540576105396105e2565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b3f90565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5556fe4c314368756753706c61736850726f78793a20696d706c656d656e746174696f6e206973206e6f7420736574207965744c314368756753706c61736850726f78793a20636f646520776173206e6f7420636f72726563746c79206465706c6f7965642e4c314368756753706c61736850726f78793a2073797374656d2069732063757272656e746c79206265696e67207570677261646564a26469706673582212202e20c1d0062b5a698d49624edce72a713b117e88f4cd70877869b53519c1d1f964736f6c634300070600330000000000000000000000009996571372066a1545d3435c6935e3f9593a7ef5
Smart Contracts contract page background

Checkout more smart contracts

    Ethereum  logo

    SHILAINU

    Verified

    The following smart contract is the SHILAINU token contract, which is an ERC20 token with a total supply of 1 trillion. It includes features such as transaction limits, fees, and automatic liquidity provision. The contract also has a blacklist mode and the ability to set fee and transaction exemptions for specific addresses. The purpose of the contract is to provide a decentralized currency for the Shiba Inu community.

    0x20c3fa331a385b63ee39137e99d0cf2db142fce1
    Copied
    • Verified
    • Fungible Token
    • ERC20
    Ethereum  logo

    Token

    Verified

    The following smart contract is a token contract that implements the ERC20 standard. It includes features such as a fee system, wallet and transaction limits, and liquidity provision. The contract also allows for the destruction of tokens through a fee system. The contract is designed to be used with the Uniswap decentralized exchange.

    0xd015422879a1308ba557510345e944b912b9ab73
    Copied
    • Verified
    Ethereum  logo

    OptimizedTransparentUpgradeableProxy

    Verified

    This contract is a proxy and the implementation details are not yet known.

    0x644192291cc835a93d6330b24ea5f5fedd0eef9e
    Copied
    • Verified
    • Proxy
Section background image

Build blockchain magic

Alchemy combines the most powerful web3 developer products and tools with resources, community and legendary support.

Get your API key