UNPKG

witnet-solidity-bridge

Version:

Witnet Solidity Bridge contracts for EVM-compatible chains

60 lines 22.6 kB
{ "_format": "hh3-sol-build-info-1", "id": "solc-0_8_25-ce8172167daa48b4892afaba6c32c75ec477f9f8", "solcVersion": "0.8.25", "solcLongVersion": "0.8.25+commit.b61c2a91", "userSourceNameMap": { "contracts/core/WitnetProxy.sol": "project/contracts/core/WitnetProxy.sol" }, "input": { "language": "Solidity", "settings": { "evmVersion": "paris", "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "": [ "ast" ], "*": [ "abi", "evm.bytecode", "evm.deployedBytecode", "evm.methodIdentifiers", "metadata" ] } }, "remappings": [ "project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@5.4.0/", "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/" ] }, "sources": { "npm/@openzeppelin/contracts-upgradeable@5.4.0/proxy/utils/Initializable.sol": { "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Storage of the initializable contract.\n *\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n * when using with upgradeable contracts.\n *\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n */\n struct InitializableStorage {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n uint64 _initialized;\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool _initializing;\n }\n\n // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n /**\n * @dev The contract is already initialized.\n */\n error InvalidInitialization();\n\n /**\n * @dev The contract is not initializing.\n */\n error NotInitializing();\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint64 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n * production.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n // Cache values to avoid duplicated sloads\n bool isTopLevelCall = !$._initializing;\n uint64 initialized = $._initialized;\n\n // Allowed calls:\n // - initialSetup: the contract is not in the initializing state and no previous version was\n // initialized\n // - construction: the contract is initialized at version 1 (no reinitialization) and the\n // current contract is just being deployed\n bool initialSetup = initialized == 0 && isTopLevelCall;\n bool construction = initialized == 1 && address(this).code.length == 0;\n\n if (!initialSetup && !construction) {\n revert InvalidInitialization();\n }\n $._initialized = 1;\n if (isTopLevelCall) {\n $._initializing = true;\n }\n _;\n if (isTopLevelCall) {\n $._initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint64 version) {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n if ($._initializing || $._initialized >= version) {\n revert InvalidInitialization();\n }\n $._initialized = version;\n $._initializing = true;\n _;\n $._initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n _checkInitializing();\n _;\n }\n\n /**\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n */\n function _checkInitializing() internal view virtual {\n if (!_isInitializing()) {\n revert NotInitializing();\n }\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n if ($._initializing) {\n revert InvalidInitialization();\n }\n if ($._initialized != type(uint64).max) {\n $._initialized = type(uint64).max;\n emit Initialized(type(uint64).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint64) {\n return _getInitializableStorage()._initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _getInitializableStorage()._initializing;\n }\n\n /**\n * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.\n *\n * NOTE: Consider following the ERC-7201 formula to derive storage locations.\n */\n function _initializableStorageSlot() internal pure virtual returns (bytes32) {\n return INITIALIZABLE_STORAGE;\n }\n\n /**\n * @dev Returns a pointer to the storage namespace.\n */\n // solhint-disable-next-line var-name-mixedcase\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n bytes32 slot = _initializableStorageSlot();\n assembly {\n $.slot := slot\n }\n }\n}\n" }, "npm/@openzeppelin/contracts@5.4.0/utils/introspection/ERC165.sol": { "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" }, "npm/@openzeppelin/contracts@5.4.0/utils/introspection/IERC165.sol": { "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" }, "project/contracts/core/WitnetProxy.sol": { "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity >=0.7.0 <0.9.0;\r\npragma experimental ABIEncoderV2;\r\n\r\nimport \"../patterns/Upgradeable.sol\";\r\n\r\n/// @title WitnetProxy: upgradable delegate-proxy contract. \r\n/// @author Guillermo Díaz <guillermo@witnet.io>\r\ncontract WitnetProxy {\r\n\r\n /// Event emitted every time the implementation gets updated.\r\n event Upgraded(address indexed implementation); \r\n\r\n /// Constructor with no params as to ease eventual support of Singleton pattern (i.e. ERC-2470).\r\n constructor () {}\r\n\r\n receive() virtual external payable {}\r\n\r\n /// Payable fallback accepts delegating calls to payable functions. \r\n fallback() external payable { /* solhint-disable no-complex-fallback */\r\n address _implementation = implementation();\r\n assembly { /* solhint-disable avoid-low-level-calls */\r\n // Gas optimized delegate call to 'implementation' contract.\r\n // Note: `msg.data`, `msg.sender` and `msg.value` will be passed over \r\n // to actual implementation of `msg.sig` within `implementation` contract.\r\n let ptr := mload(0x40)\r\n calldatacopy(ptr, 0, calldatasize())\r\n let result := delegatecall(gas(), _implementation, ptr, calldatasize(), 0, 0)\r\n let size := returndatasize()\r\n returndatacopy(ptr, 0, size)\r\n switch result\r\n case 0 { \r\n // pass back revert message:\r\n revert(ptr, size) \r\n }\r\n default {\r\n // pass back same data as returned by 'implementation' contract:\r\n return(ptr, size) \r\n }\r\n }\r\n }\r\n\r\n /// Returns proxy's current implementation address.\r\n function implementation() public view returns (address) {\r\n return __proxySlot().implementation;\r\n }\r\n\r\n /// Upgrades the `implementation` address.\r\n /// @param _newImplementation New implementation address.\r\n /// @param _initData Raw data with which new implementation will be initialized.\r\n /// @return Returns whether new implementation would be further upgradable, or not.\r\n function upgradeTo(address _newImplementation, bytes memory _initData)\r\n public returns (bool)\r\n {\r\n // New implementation cannot be null:\r\n require(_newImplementation != address(0), \"WitnetProxy: null implementation\");\r\n\r\n address _oldImplementation = implementation();\r\n if (_oldImplementation != address(0)) {\r\n // New implementation address must differ from current one:\r\n require(_newImplementation != _oldImplementation, \"WitnetProxy: nothing to upgrade\");\r\n\r\n // Assert whether current implementation is intrinsically upgradable:\r\n try Upgradeable(_oldImplementation).isUpgradable() returns (bool _isUpgradable) {\r\n require(_isUpgradable, \"WitnetProxy: not upgradable\");\r\n } catch {\r\n revert(\"WitnetProxy: unable to check upgradability\");\r\n }\r\n\r\n // Assert whether current implementation allows `msg.sender` to upgrade the proxy:\r\n (bool _wasCalled, bytes memory _result) = _oldImplementation.delegatecall(\r\n abi.encodeWithSignature(\r\n \"isUpgradableFrom(address)\",\r\n msg.sender\r\n )\r\n );\r\n require(_wasCalled, \"WitnetProxy: uncompliant implementation\");\r\n require(abi.decode(_result, (bool)), \"WitnetProxy: not authorized\");\r\n require(\r\n Upgradeable(_oldImplementation).proxiableUUID() == Upgradeable(_newImplementation).proxiableUUID(),\r\n \"WitnetProxy: proxiableUUIDs mismatch\"\r\n );\r\n }\r\n\r\n // Initialize new implementation within proxy-context storage:\r\n (bool _wasInitialized, bytes memory _returnData) = _newImplementation.delegatecall(\r\n abi.encodeWithSignature(\r\n \"initialize(bytes)\",\r\n _initData\r\n )\r\n );\r\n if (!_wasInitialized) {\r\n if (_returnData.length < 68) {\r\n revert(\"WitnetProxy: initialization failed\");\r\n } else {\r\n assembly {\r\n _returnData := add(_returnData, 0x04)\r\n }\r\n revert(abi.decode(_returnData, (string)));\r\n }\r\n }\r\n\r\n // If all checks and initialization pass, update implementation address:\r\n __proxySlot().implementation = _newImplementation;\r\n \r\n emit Upgraded(_newImplementation);\r\n\r\n // Asserts new implementation complies w/ minimal implementation of Upgradeable interface:\r\n try Upgradeable(_newImplementation).isUpgradable() returns (bool _isUpgradable) {\r\n return _isUpgradable;\r\n }\r\n catch {\r\n revert (\"WitnetProxy: uncompliant implementation\");\r\n }\r\n }\r\n\r\n /// @dev Complying with EIP-1967, retrieves storage struct containing proxy's current implementation address.\r\n function __proxySlot() private pure returns (Proxiable.ProxiableSlot storage _slot) {\r\n assembly {\r\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\r\n _slot.slot := 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\r\n }\r\n }\r\n\r\n}\r\n" }, "project/contracts/patterns/Initializable.sol": { "content": "// SPDX-License-Identifier: MIT\r\npragma solidity >=0.8.0 <0.9.0;\r\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";" }, "project/contracts/patterns/Proxiable.sol": { "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity >=0.6.0 <0.9.0;\r\n\r\nabstract contract Proxiable {\r\n /// @dev Complying with EIP-1822: Universal Upgradeable Proxy Standard (UUPS)\r\n /// @dev See https://eips.ethereum.org/EIPS/eip-1822.\r\n function proxiableUUID() virtual external view returns (bytes32);\r\n\r\n struct ProxiableSlot {\r\n address implementation;\r\n address proxy;\r\n bytes32 codehash;\r\n }\r\n\r\n function __implementation() internal view returns (address) {\r\n return __proxiable().implementation;\r\n }\r\n\r\n function __proxy() internal view returns (address) {\r\n return __proxiable().proxy;\r\n }\r\n\r\n function __proxiable() internal pure returns (ProxiableSlot storage proxiable) {\r\n assembly {\r\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\r\n proxiable.slot := 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\r\n }\r\n }\r\n}\r\n" }, "project/contracts/patterns/Upgradeable.sol": { "content": "// SPDX-License-Identifier: MIT\r\n\r\n/* solhint-disable var-name-mixedcase */\r\n\r\npragma solidity >=0.6.0 <0.9.0;\r\n\r\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\r\n\r\nimport \"./Initializable.sol\";\r\nimport \"./Proxiable.sol\";\r\n\r\nabstract contract Upgradeable is Initializable, Proxiable {\r\n\r\n address internal immutable _BASE;\r\n bytes32 internal immutable _CODEHASH;\r\n bool internal immutable _UPGRADABLE;\r\n\r\n modifier onlyDelegateCalls virtual {\r\n require(\r\n address(this) != _BASE,\r\n \"Upgradeable: not a delegate call\"\r\n );\r\n _;\r\n }\r\n\r\n /// Emitted every time the contract gets upgraded.\r\n /// @param from The address who ordered the upgrading. Namely, the WRB operator in \"trustable\" implementations.\r\n /// @param baseAddr The address of the new implementation contract.\r\n /// @param baseCodehash The EVM-codehash of the new implementation contract.\r\n /// @param versionTag Ascii-encoded version literal with which the implementation deployer decided to tag it.\r\n event Upgraded(\r\n address indexed from,\r\n address indexed baseAddr,\r\n bytes32 indexed baseCodehash,\r\n string versionTag\r\n );\r\n\r\n constructor (bool _isUpgradable) {\r\n address _base = address(this);\r\n _BASE = _base;\r\n _UPGRADABLE = _isUpgradable;\r\n }\r\n\r\n /// @dev Retrieves base contract. Differs from address(this) when called via delegate-proxy pattern.\r\n function base() virtual public view returns (address) {\r\n return _BASE;\r\n }\r\n\r\n /// @dev Retrieves the immutable codehash of this contract, even if invoked as delegatecall.\r\n function codehash() public view returns (bytes32 _codehash) {\r\n address _base = _BASE;\r\n assembly {\r\n _codehash := extcodehash(_base)\r\n }\r\n }\r\n\r\n /// @dev Determines whether the logic of this contract is potentially upgradable.\r\n function isUpgradable() public view returns (bool) {\r\n return _UPGRADABLE;\r\n }\r\n\r\n /// @dev Tells whether provided address could eventually upgrade the contract.\r\n function isUpgradableFrom(address from) virtual external view returns (bool);\r\n\r\n /// @notice Re-initialize contract's storage context upon a new upgrade from a proxy. \r\n /// @dev Must fail when trying to upgrade to same logic contract more than once.\r\n function initialize(bytes memory) virtual external;\r\n function __initializeUpgradableData(bytes memory _initData) virtual internal;\r\n\r\n /// @dev Retrieves human-redable named version of current implementation.\r\n function version() virtual public view returns (string memory); \r\n}" } } } }