Transactions
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Read Proxy
Write Contract
Write Proxy
Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB 0xf6d52770453166de85b6b6260cf22196bc460e88.
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
Verify & Publish
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
- Contract name:
- WitnetProxy
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 200
- Verified at
- 2023-08-01T09:29:58.731856Z
/contracts/impls/WitnetProxy.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0 <0.9.0; pragma experimental ABIEncoderV2; import "../patterns/Upgradeable.sol"; /// @title WitnetProxy: upgradable delegate-proxy contract. /// @author The Witnet Foundation. contract WitnetProxy { /// Event emitted every time the implementation gets updated. event Upgraded(address indexed implementation); /// Constructor with no params as to ease eventual support of Singleton pattern (i.e. ERC-2470). constructor () {} receive() virtual external payable {} /// Payable fallback accepts delegating calls to payable functions. fallback() external payable { /* solhint-disable no-complex-fallback */ address _implementation = implementation(); assembly { /* solhint-disable avoid-low-level-calls */ // Gas optimized delegate call to 'implementation' contract. // Note: `msg.data`, `msg.sender` and `msg.value` will be passed over // to actual implementation of `msg.sig` within `implementation` contract. let ptr := mload(0x40) calldatacopy(ptr, 0, calldatasize()) let result := delegatecall(gas(), _implementation, ptr, calldatasize(), 0, 0) let size := returndatasize() returndatacopy(ptr, 0, size) switch result case 0 { // pass back revert message: revert(ptr, size) } default { // pass back same data as returned by 'implementation' contract: return(ptr, size) } } } /// Returns proxy's current implementation address. function implementation() public view returns (address) { return __proxySlot().implementation; } /// Upgrades the `implementation` address. /// @param _newImplementation New implementation address. /// @param _initData Raw data with which new implementation will be initialized. /// @return Returns whether new implementation would be further upgradable, or not. function upgradeTo(address _newImplementation, bytes memory _initData) public returns (bool) { // New implementation cannot be null: require(_newImplementation != address(0), "WitnetProxy: null implementation"); address _oldImplementation = implementation(); if (_oldImplementation != address(0)) { // New implementation address must differ from current one: require(_newImplementation != _oldImplementation, "WitnetProxy: nothing to upgrade"); // Assert whether current implementation is intrinsically upgradable: try Upgradeable(_oldImplementation).isUpgradable() returns (bool _isUpgradable) { require(_isUpgradable, "WitnetProxy: not upgradable"); } catch { revert("WitnetProxy: unable to check upgradability"); } // Assert whether current implementation allows `msg.sender` to upgrade the proxy: (bool _wasCalled, bytes memory _result) = _oldImplementation.delegatecall( abi.encodeWithSignature( "isUpgradableFrom(address)", msg.sender ) ); require(_wasCalled, "WitnetProxy: not compliant"); require(abi.decode(_result, (bool)), "WitnetProxy: not authorized"); require( Upgradeable(_oldImplementation).proxiableUUID() == Upgradeable(_newImplementation).proxiableUUID(), "WitnetProxy: proxiableUUIDs mismatch" ); } // Initialize new implementation within proxy-context storage: (bool _wasInitialized,) = _newImplementation.delegatecall( abi.encodeWithSignature( "initialize(bytes)", _initData ) ); require(_wasInitialized, "WitnetProxy: unable to initialize"); // If all checks and initialization pass, update implementation address: __proxySlot().implementation = _newImplementation; emit Upgraded(_newImplementation); // Asserts new implementation complies w/ minimal implementation of Upgradeable interface: try Upgradeable(_newImplementation).isUpgradable() returns (bool _isUpgradable) { return _isUpgradable; } catch { revert ("WitnetProxy: not compliant"); } } /// @dev Complying with EIP-1967, retrieves storage struct containing proxy's current implementation address. function __proxySlot() private pure returns (Proxiable.ProxiableSlot storage _slot) { assembly { // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) _slot.slot := 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc } } }
/contracts/patterns/Initializable.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
/contracts/patterns/Proxiable.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.9.0; abstract contract Proxiable { /// @dev Complying with EIP-1822: Universal Upgradeable Proxy Standard (UUPS) /// @dev See https://eips.ethereum.org/EIPS/eip-1822. function proxiableUUID() virtual external view returns (bytes32); struct ProxiableSlot { address implementation; address proxy; } function __implementation() internal view returns (address) { return __proxiable().implementation; } function __proxy() internal view returns (address) { return __proxiable().proxy; } function __proxiable() internal pure returns (ProxiableSlot storage proxiable) { assembly { // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) proxiable.slot := 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc } } }
/contracts/patterns/Upgradeable.sol
// SPDX-License-Identifier: MIT /* solhint-disable var-name-mixedcase */ pragma solidity >=0.6.0 <0.9.0; import "./Initializable.sol"; import "./Proxiable.sol"; abstract contract Upgradeable is Initializable, Proxiable { address internal immutable _BASE; bytes32 internal immutable _CODEHASH; bool internal immutable _UPGRADABLE; modifier onlyDelegateCalls virtual { require( address(this) != _BASE, "Upgradeable: not a delegate call" ); _; } /// Emitted every time the contract gets upgraded. /// @param from The address who ordered the upgrading. Namely, the WRB operator in "trustable" implementations. /// @param baseAddr The address of the new implementation contract. /// @param baseCodehash The EVM-codehash of the new implementation contract. /// @param versionTag Ascii-encoded version literal with which the implementation deployer decided to tag it. event Upgraded( address indexed from, address indexed baseAddr, bytes32 indexed baseCodehash, string versionTag ); constructor (bool _isUpgradable) { address _base = address(this); bytes32 _codehash; assembly { _codehash := extcodehash(_base) } _BASE = _base; _CODEHASH = _codehash; _UPGRADABLE = _isUpgradable; } /// @dev Retrieves base contract. Differs from address(this) when called via delegate-proxy pattern. function base() public view returns (address) { return _BASE; } /// @dev Retrieves the immutable codehash of this contract, even if invoked as delegatecall. function codehash() public view returns (bytes32) { return _CODEHASH; } /// @dev Determines whether the logic of this contract is potentially upgradable. function isUpgradable() public view returns (bool) { return _UPGRADABLE; } /// @dev Tells whether provided address could eventually upgrade the contract. function isUpgradableFrom(address from) virtual external view returns (bool); /// @notice Re-initialize contract's storage context upon a new upgrade from a proxy. /// @dev Must fail when trying to upgrade to same logic contract more than once. function initialize(bytes memory) virtual external; /// @dev Retrieves human-redable named version of current implementation. function version() virtual public view returns (string memory); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Internal function that returns the initialized version. Returns `_initialized` */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Internal function that returns the initialized version. Returns `_initializing` */ function _isInitializing() internal view returns (bool) { return _initializing; } }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{},"evmVersion":"london"}
Contract ABI
[{"type":"constructor","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"implementation","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"upgradeTo","inputs":[{"type":"address","name":"_newImplementation","internalType":"address"},{"type":"bytes","name":"_initData","internalType":"bytes"}]},{"type":"event","name":"Upgraded","inputs":[{"type":"address","name":"implementation","indexed":true}],"anonymous":false},{"type":"receive"},{"type":"fallback"}]
Contract Creation Code
0x608060405234801561001057600080fd5b50610912806100206000396000f3fe60806040526004361061002d5760003560e01c80635c60da1b146100655780636fbc15e91461009757610034565b3661003457005b600061003e6100c7565b905060405136600082376000803683855af43d806000843e818015610061578184f35b8184fd5b34801561007157600080fd5b5061007a6100c7565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100a357600080fd5b506100b76100b2366004610757565b6100f5565b604051901515815260200161008e565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60006001600160a01b0383166101525760405162461bcd60e51b815260206004820181905260248201527f5769746e657450726f78793a206e756c6c20696d706c656d656e746174696f6e60448201526064015b60405180910390fd5b600061015c6100c7565b90506001600160a01b0381161561053857806001600160a01b0316846001600160a01b0316036101ce5760405162461bcd60e51b815260206004820152601f60248201527f5769746e657450726f78793a206e6f7468696e6720746f2075706772616465006044820152606401610149565b806001600160a01b0316635479d9406040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610228575060408051601f3d908101601f1916820190925261022591810190610827565b60015b6102875760405162461bcd60e51b815260206004820152602a60248201527f5769746e657450726f78793a20756e61626c6520746f20636865636b207570676044820152697261646162696c69747960b01b6064820152608401610149565b806102d45760405162461bcd60e51b815260206004820152601b60248201527f5769746e657450726f78793a206e6f742075706772616461626c6500000000006044820152606401610149565b5060405133602482015260009081906001600160a01b0384169060440160408051601f198184030181529181526020820180516001600160e01b03166335ac4b0560e11b179052516103269190610874565b600060405180830381855af49150503d8060008114610361576040519150601f19603f3d011682016040523d82523d6000602084013e610366565b606091505b5091509150816103b85760405162461bcd60e51b815260206004820152601a60248201527f5769746e657450726f78793a206e6f7420636f6d706c69616e740000000000006044820152606401610149565b808060200190518101906103cc9190610827565b6104185760405162461bcd60e51b815260206004820152601b60248201527f5769746e657450726f78793a206e6f7420617574686f72697a656400000000006044820152606401610149565b856001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610456573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047a9190610890565b836001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104dc9190610890565b146105355760405162461bcd60e51b8152602060048201526024808201527f5769746e657450726f78793a2070726f786961626c655555494473206d69736d6044820152630c2e8c6d60e31b6064820152608401610149565b50505b6000846001600160a01b03168460405160240161055591906108a9565b60408051601f198184030181529181526020820180516001600160e01b031663439fab9160e01b1790525161058a9190610874565b600060405180830381855af49150503d80600081146105c5576040519150601f19603f3d011682016040523d82523d6000602084013e6105ca565b606091505b50509050806106255760405162461bcd60e51b815260206004820152602160248201527f5769746e657450726f78793a20756e61626c6520746f20696e697469616c697a6044820152606560f81b6064820152608401610149565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0387169081179091556040517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2846001600160a01b0316635479d9406040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106e5575060408051601f3d908101601f191682019092526106e291810190610827565b60015b6107315760405162461bcd60e51b815260206004820152601a60248201527f5769746e657450726f78793a206e6f7420636f6d706c69616e740000000000006044820152606401610149565b925061073b915050565b92915050565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561076a57600080fd5b82356001600160a01b038116811461078157600080fd5b9150602083013567ffffffffffffffff8082111561079e57600080fd5b818501915085601f8301126107b257600080fd5b8135818111156107c4576107c4610741565b604051601f8201601f19908116603f011681019083821181831017156107ec576107ec610741565b8160405282815288602084870101111561080557600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60006020828403121561083957600080fd5b8151801515811461084957600080fd5b9392505050565b60005b8381101561086b578181015183820152602001610853565b50506000910152565b60008251610886818460208701610850565b9190910192915050565b6000602082840312156108a257600080fd5b5051919050565b60208152600082518060208401526108c8816040850160208701610850565b601f01601f1916919091016040019291505056fea26469706673582212200771bc4bad015c089efb2351eb3266c8aad36c8daccf86bbf3421605ef5fc23c64736f6c63430008110033
Deployed ByteCode
0x60806040526004361061002d5760003560e01c80635c60da1b146100655780636fbc15e91461009757610034565b3661003457005b600061003e6100c7565b905060405136600082376000803683855af43d806000843e818015610061578184f35b8184fd5b34801561007157600080fd5b5061007a6100c7565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100a357600080fd5b506100b76100b2366004610757565b6100f5565b604051901515815260200161008e565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60006001600160a01b0383166101525760405162461bcd60e51b815260206004820181905260248201527f5769746e657450726f78793a206e756c6c20696d706c656d656e746174696f6e60448201526064015b60405180910390fd5b600061015c6100c7565b90506001600160a01b0381161561053857806001600160a01b0316846001600160a01b0316036101ce5760405162461bcd60e51b815260206004820152601f60248201527f5769746e657450726f78793a206e6f7468696e6720746f2075706772616465006044820152606401610149565b806001600160a01b0316635479d9406040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610228575060408051601f3d908101601f1916820190925261022591810190610827565b60015b6102875760405162461bcd60e51b815260206004820152602a60248201527f5769746e657450726f78793a20756e61626c6520746f20636865636b207570676044820152697261646162696c69747960b01b6064820152608401610149565b806102d45760405162461bcd60e51b815260206004820152601b60248201527f5769746e657450726f78793a206e6f742075706772616461626c6500000000006044820152606401610149565b5060405133602482015260009081906001600160a01b0384169060440160408051601f198184030181529181526020820180516001600160e01b03166335ac4b0560e11b179052516103269190610874565b600060405180830381855af49150503d8060008114610361576040519150601f19603f3d011682016040523d82523d6000602084013e610366565b606091505b5091509150816103b85760405162461bcd60e51b815260206004820152601a60248201527f5769746e657450726f78793a206e6f7420636f6d706c69616e740000000000006044820152606401610149565b808060200190518101906103cc9190610827565b6104185760405162461bcd60e51b815260206004820152601b60248201527f5769746e657450726f78793a206e6f7420617574686f72697a656400000000006044820152606401610149565b856001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610456573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047a9190610890565b836001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104dc9190610890565b146105355760405162461bcd60e51b8152602060048201526024808201527f5769746e657450726f78793a2070726f786961626c655555494473206d69736d6044820152630c2e8c6d60e31b6064820152608401610149565b50505b6000846001600160a01b03168460405160240161055591906108a9565b60408051601f198184030181529181526020820180516001600160e01b031663439fab9160e01b1790525161058a9190610874565b600060405180830381855af49150503d80600081146105c5576040519150601f19603f3d011682016040523d82523d6000602084013e6105ca565b606091505b50509050806106255760405162461bcd60e51b815260206004820152602160248201527f5769746e657450726f78793a20756e61626c6520746f20696e697469616c697a6044820152606560f81b6064820152608401610149565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0387169081179091556040517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2846001600160a01b0316635479d9406040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106e5575060408051601f3d908101601f191682019092526106e291810190610827565b60015b6107315760405162461bcd60e51b815260206004820152601a60248201527f5769746e657450726f78793a206e6f7420636f6d706c69616e740000000000006044820152606401610149565b925061073b915050565b92915050565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561076a57600080fd5b82356001600160a01b038116811461078157600080fd5b9150602083013567ffffffffffffffff8082111561079e57600080fd5b818501915085601f8301126107b257600080fd5b8135818111156107c4576107c4610741565b604051601f8201601f19908116603f011681019083821181831017156107ec576107ec610741565b8160405282815288602084870101111561080557600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60006020828403121561083957600080fd5b8151801515811461084957600080fd5b9392505050565b60005b8381101561086b578181015183820152602001610853565b50506000910152565b60008251610886818460208701610850565b9190910192915050565b6000602082840312156108a257600080fd5b5051919050565b60208152600082518060208401526108c8816040850160208701610850565b601f01601f1916919091016040019291505056fea26469706673582212200771bc4bad015c089efb2351eb3266c8aad36c8daccf86bbf3421605ef5fc23c64736f6c63430008110033