/
0xe2e1bfbe36d976ea980d3a6402412b73e87e59eccac865a6c8a39ee96d8406e0.json
69 lines (69 loc) · 50.6 KB
/
0xe2e1bfbe36d976ea980d3a6402412b73e87e59eccac865a6c8a39ee96d8406e0.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
{
"language": "Solidity",
"sources": {
"temp-contracts/CodeHashes.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Because we use the code hashes of the proxy contracts for proxy address\n * derivation, it is important that other packages have access to the correct\n * values when they import the salt library.\n */\nlibrary CodeHashes {\n bytes32 internal constant ONE_TO_ONE_CODEHASH = 0x63d9f7b5931b69188c8f6b806606f25892f1bb17b7f7e966fe3a32c04493aee4;\n bytes32 internal constant MANY_TO_ONE_CODEHASH = 0xa035ad05a1663db5bfd455b99cd7c6ac6bd49269738458eda140e0b78ed53f79;\n bytes32 internal constant IMPLEMENTATION_HOLDER_CODEHASH = 0x11c370493a726a0ffa93d42b399ad046f1b5a543b6e72f1a64f1488dc1c58f2c;\n}"
},
"temp-contracts/DelegateCallProxyManager.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity =0.6.12;\n\n/* ========== External Libraries ========== */\nimport { Create2 } from \"@openzeppelin/contracts/utils/Create2.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/* ========== Proxy Contracts ========== */\nimport \"./ManyToOneImplementationHolder.sol\";\nimport { DelegateCallProxyManyToOne } from \"./DelegateCallProxyManyToOne.sol\";\nimport { DelegateCallProxyOneToOne } from \"./DelegateCallProxyOneToOne.sol\";\n\n/* ========== Internal Libraries ========== */\nimport { SaltyLib as Salty } from \"./SaltyLib.sol\";\nimport { CodeHashes } from \"./CodeHashes.sol\";\n\n/* ========== Inheritance ========== */\nimport \"./interfaces/IDelegateCallProxyManager.sol\";\n\n\n/**\n * @dev Contract that manages deployment and upgrades of delegatecall proxies.\n *\n * An implementation identifier can be created on the proxy manager which is\n * used to specify the logic address for a particular contract type, and to\n * upgrade the implementation as needed.\n *\n * ====== Proxy Types ======\n * A one-to-one proxy is a single proxy contract with an upgradeable implementation\n * address.\n *\n * A many-to-one proxy is a single upgradeable implementation address that may be\n * used by many proxy contracts.\n *\n * ====== Access Control ======\n * The proxy manager has a single address as its owner.\n *\n * The owner is the sole account with the following permissions:\n * - Create new many-to-one implementations\n * - Create new one-to-one proxies\n * - Modify the implementation address of existing proxies\n * - Lock proxies\n * - Designate approved deployers\n * - Remove approved deployers\n * - Modify the owner address\n *\n * Approved deployers may only deploy many-to-one proxies.\n *\n * ====== Upgrades ======\n * Proxies can be upgraded by the owner if they are not locked.\n *\n * Many-to-one proxy implementations are upgraded by calling the holder contract\n * for the implementation ID being upgraded.\n * One-to-one proxies are upgraded by calling the proxy contract directly.\n *\n * The owner can lock a one-to-one proxy or many-to-one implementation ID so that\n * it becomes impossible to upgrade.\n */\ncontract DelegateCallProxyManager is Ownable, IDelegateCallProxyManager {\n/* ========== Events ========== */\n\n event DeploymentApprovalGranted(address deployer);\n event DeploymentApprovalRevoked(address deployer);\n\n event ManyToOne_ImplementationCreated(\n bytes32 implementationID,\n address implementationAddress\n );\n\n event ManyToOne_ImplementationUpdated(\n bytes32 implementationID,\n address implementationAddress\n );\n\n event ManyToOne_ImplementationLocked(bytes32 implementationID);\n\n event ManyToOne_ProxyDeployed(\n bytes32 implementationID,\n address proxyAddress\n );\n\n event OneToOne_ProxyDeployed(\n address proxyAddress,\n address implementationAddress\n );\n\n event OneToOne_ImplementationUpdated(\n address proxyAddress,\n address implementationAddress\n );\n\n event OneToOne_ImplementationLocked(address proxyAddress);\n\n/* ========== Storage ========== */\n\n // Addresses allowed to deploy many-to-one proxies.\n mapping(address => bool) internal _approvedDeployers;\n\n // Maps implementation holders to their implementation IDs.\n mapping(bytes32 => address) internal _implementationHolders;\n\n // Maps implementation holders & proxy addresses to bool stating if they are locked.\n mapping(address => bool) internal _lockedImplementations;\n\n // Temporary value used in the many-to-one proxy constructor.\n // The many-to-one proxy contract is deployed with create2 and\n // uses static initialization code for simple address derivation,\n // so it calls the proxy manager in the constructor to get this\n // address in order to save it as an immutable in the bytecode.\n address internal _implementationHolder;\n\n/* ========== Modifiers ========== */\n\n modifier onlyApprovedDeployer {\n address sender = _msgSender();\n require(_approvedDeployers[sender] || sender == owner(), \"ERR_NOT_APPROVED\");\n _;\n }\n\n/* ========== Constructor ========== */\n\n constructor() public Ownable() {}\n\n/* ========== Access Control ========== */\n\n /**\n * @dev Allows `deployer` to deploy many-to-one proxies.\n */\n function approveDeployer(address deployer) external override onlyOwner {\n _approvedDeployers[deployer] = true;\n emit DeploymentApprovalGranted(deployer);\n }\n\n /**\n * @dev Prevents `deployer` from deploying many-to-one proxies.\n */\n function revokeDeployerApproval(address deployer) external override onlyOwner {\n _approvedDeployers[deployer] = false;\n emit DeploymentApprovalRevoked(deployer);\n }\n\n/* ========== Implementation Management ========== */\n\n /**\n * @dev Creates a many-to-one proxy relationship.\n *\n * Deploys an implementation holder contract which stores the\n * implementation address for many proxies. The implementation\n * address can be updated on the holder to change the runtime\n * code used by all its proxies.\n *\n * @param implementationID ID for the implementation, used to identify the\n * proxies that use it. Also used as the salt in the create2 call when\n * deploying the implementation holder contract.\n * @param implementation Address with the runtime code the proxies\n * should use.\n */\n function createManyToOneProxyRelationship(\n bytes32 implementationID,\n address implementation\n )\n external\n override\n onlyOwner\n {\n // Deploy the implementation holder contract with the implementation\n // ID as the create2 salt.\n address implementationHolder = Create2.deploy(\n 0,\n implementationID,\n type(ManyToOneImplementationHolder).creationCode\n );\n\n // Store the implementation holder address\n _implementationHolders[implementationID] = implementationHolder;\n\n // Sets the implementation address.\n _setImplementation(implementationHolder, implementation);\n\n emit ManyToOne_ImplementationCreated(\n implementationID,\n implementation\n );\n }\n\n /**\n * @dev Lock the current implementation for `implementationID` so that it can never be upgraded again.\n */\n function lockImplementationManyToOne(bytes32 implementationID) external override onlyOwner {\n // Read the implementation holder address from storage.\n address implementationHolder = _implementationHolders[implementationID];\n // Verify that the implementation exists.\n require(implementationHolder != address(0), \"ERR_IMPLEMENTATION_ID\");\n _lockedImplementations[implementationHolder] = true;\n emit ManyToOne_ImplementationLocked(implementationID);\n }\n\n /**\n * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again.\n */\n function lockImplementationOneToOne(address proxyAddress) external override onlyOwner {\n _lockedImplementations[proxyAddress] = true;\n emit OneToOne_ImplementationLocked(proxyAddress);\n }\n\n /**\n * @dev Updates the implementation address for a many-to-one\n * proxy relationship.\n *\n * @param implementationID Identifier for the implementation.\n * @param implementation Address with the runtime code the proxies\n * should use.\n */\n function setImplementationAddressManyToOne(\n bytes32 implementationID,\n address implementation\n )\n external\n override\n onlyOwner\n {\n // Read the implementation holder address from storage.\n address implementationHolder = _implementationHolders[implementationID];\n\n // Verify that the implementation exists.\n require(implementationHolder != address(0), \"ERR_IMPLEMENTATION_ID\");\n\n // Verify implementation is not locked\n require(!_lockedImplementations[implementationHolder], \"ERR_IMPLEMENTATION_LOCKED\");\n\n // Set the implementation address\n _setImplementation(implementationHolder, implementation);\n\n emit ManyToOne_ImplementationUpdated(\n implementationID,\n implementation\n );\n }\n\n /**\n * @dev Updates the implementation address for a one-to-one proxy.\n *\n * Note: This could work for many-to-one as well if the caller\n * provides the implementation holder address in place of the\n * proxy address, as they use the same access control and update\n * mechanism.\n *\n * @param proxyAddress Address of the deployed proxy\n * @param implementation Address with the runtime code for\n * the proxy to use.\n */\n function setImplementationAddressOneToOne(\n address proxyAddress,\n address implementation\n )\n external\n override\n onlyOwner\n {\n // Verify proxy is not locked\n require(!_lockedImplementations[proxyAddress], \"ERR_IMPLEMENTATION_LOCKED\");\n\n // Set the implementation address\n _setImplementation(proxyAddress, implementation);\n\n emit OneToOne_ImplementationUpdated(proxyAddress, implementation);\n }\n\n/* ========== Proxy Deployment ========== */\n\n /**\n * @dev Deploy a proxy contract with a one-to-one relationship\n * with its implementation.\n *\n * The proxy will have its own implementation address which can\n * be updated by the proxy manager.\n *\n * @param suppliedSalt Salt provided by the account requesting deployment.\n * @param implementation Address of the contract with the runtime\n * code that the proxy should use.\n */\n function deployProxyOneToOne(\n bytes32 suppliedSalt,\n address implementation\n )\n external\n override\n onlyOwner\n returns(address proxyAddress)\n {\n // Derive the create2 salt from the deployment requester's address\n // and the requester-supplied salt.\n bytes32 salt = Salty.deriveOneToOneSalt(_msgSender(), suppliedSalt);\n\n // Deploy the proxy\n proxyAddress = Create2.deploy(\n 0,\n salt,\n type(DelegateCallProxyOneToOne).creationCode\n );\n\n // Set the implementation address on the new proxy.\n _setImplementation(proxyAddress, implementation);\n\n emit OneToOne_ProxyDeployed(proxyAddress, implementation);\n }\n\n /**\n * @dev Deploy a proxy with a many-to-one relationship with its implemenation.\n *\n * The proxy will call the implementation holder for every transaction to\n * determine the address to use in calls.\n *\n * @param implementationID Identifier for the proxy's implementation.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function deployProxyManyToOne(bytes32 implementationID, bytes32 suppliedSalt)\n external\n override\n onlyApprovedDeployer\n returns(address proxyAddress)\n {\n // Read the implementation holder address from storage.\n address implementationHolder = _implementationHolders[implementationID];\n\n // Verify that the implementation exists.\n require(implementationHolder != address(0), \"ERR_IMPLEMENTATION_ID\");\n\n // Derive the create2 salt from the deployment requester's address, the\n // implementation ID and the requester-supplied salt.\n bytes32 salt = Salty.deriveManyToOneSalt(\n _msgSender(),\n implementationID,\n suppliedSalt\n );\n\n // Set the implementation holder address in storage so the proxy\n // constructor can query it.\n _implementationHolder = implementationHolder;\n\n // Deploy the proxy, which will query the implementation holder address\n // and save it as an immutable in the contract bytecode.\n proxyAddress = Create2.deploy(\n 0,\n salt,\n type(DelegateCallProxyManyToOne).creationCode\n );\n\n // Remove the address from temporary storage.\n _implementationHolder = address(0);\n\n emit ManyToOne_ProxyDeployed(\n implementationID,\n proxyAddress\n );\n }\n\n/* ========== Queries ========== */\n\n /**\n * @dev Returns a boolean stating whether `implementationID` is locked.\n */\n function isImplementationLocked(bytes32 implementationID) external override view returns (bool) {\n // Read the implementation holder address from storage.\n address implementationHolder = _implementationHolders[implementationID];\n\n // Verify that the implementation exists.\n require(implementationHolder != address(0), \"ERR_IMPLEMENTATION_ID\");\n\n return _lockedImplementations[implementationHolder];\n }\n\n /**\n * @dev Returns a boolean stating whether `proxyAddress` is locked.\n */\n function isImplementationLocked(address proxyAddress) external override view returns (bool) {\n return _lockedImplementations[proxyAddress];\n }\n\n /**\n * @dev Returns a boolean stating whether `deployer` is allowed to deploy many-to-one\n * proxies.\n */\n function isApprovedDeployer(address deployer) external override view returns (bool) {\n return _approvedDeployers[deployer];\n }\n\n /**\n * @dev Queries the temporary storage value `_implementationHolder`.\n * This is used in the constructor of the many-to-one proxy contract\n * so that the create2 address is static (adding constructor arguments\n * would change the codehash) and the implementation holder can be\n * stored as a constant.\n */\n function getImplementationHolder()\n external\n override\n view\n returns (address)\n {\n return _implementationHolder;\n }\n\n /**\n * @dev Returns the address of the implementation holder contract\n * for `implementationID`.\n */\n function getImplementationHolder(\n bytes32 implementationID\n )\n external\n override\n view\n returns (address)\n {\n return _implementationHolders[implementationID];\n }\n\n /**\n * @dev Computes the create2 address for a one-to-one proxy requested\n * by `originator` using `suppliedSalt`.\n *\n * @param originator Address of the account requesting deployment.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function computeProxyAddressOneToOne(\n address originator,\n bytes32 suppliedSalt\n )\n external\n override\n view\n returns (address)\n {\n bytes32 salt = Salty.deriveOneToOneSalt(originator, suppliedSalt);\n return Create2.computeAddress(salt, CodeHashes.ONE_TO_ONE_CODEHASH);\n }\n\n /**\n * @dev Computes the create2 address for a many-to-one proxy for the\n * implementation `implementationID` requested by `originator` using\n * `suppliedSalt`.\n *\n * @param originator Address of the account requesting deployment.\n * @param implementationID The identifier for the contract implementation.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function computeProxyAddressManyToOne(\n address originator,\n bytes32 implementationID,\n bytes32 suppliedSalt\n )\n external\n override\n view\n returns (address)\n {\n\n bytes32 salt = Salty.deriveManyToOneSalt(\n originator,\n implementationID,\n suppliedSalt\n );\n return Create2.computeAddress(salt, CodeHashes.MANY_TO_ONE_CODEHASH);\n }\n\n /**\n * @dev Computes the create2 address of the implementation holder\n * for `implementationID`.\n *\n * @param implementationID The identifier for the contract implementation.\n */\n function computeHolderAddressManyToOne(bytes32 implementationID)\n public\n override\n view\n returns (address)\n {\n return Create2.computeAddress(\n implementationID,\n CodeHashes.IMPLEMENTATION_HOLDER_CODEHASH\n );\n }\n\n/* ========== Internal Functions ========== */\n\n /**\n * @dev Sets the implementation address for a one-to-one proxy or\n * many-to-one implementation holder. Both use the same access\n * control and update mechanism, which is the receipt of a call\n * from the proxy manager with the abi-encoded implementation address\n * as the only calldata.\n *\n * Note: Verifies that the implementation address is a contract.\n *\n * @param proxyOrHolder Address of the one-to-one proxy or\n * many-to-one implementation holder contract.\n * @param implementation Address of the contract with the runtime\n * code that the proxy or proxies should use.\n */\n function _setImplementation(\n address proxyOrHolder,\n address implementation\n ) internal {\n // Verify that the implementation address is a contract.\n require(Address.isContract(implementation), \"ERR_NOT_CONTRACT\");\n // Set the implementation address on the contract.\n\n // solium-disable-next-line security/no-low-level-calls\n (bool success,) = proxyOrHolder.call(abi.encode(implementation));\n require(success, \"ERR_SET_ADDRESS_REVERT\");\n }\n}"
},
"@openzeppelin/contracts/utils/Create2.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.\n * `CREATE2` can be used to compute in advance the address where a smart\n * contract will be deployed, which allows for interesting new mechanisms known\n * as 'counterfactual interactions'.\n *\n * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more\n * information.\n */\nlibrary Create2 {\n /**\n * @dev Deploys a contract using `CREATE2`. The address where the contract\n * will be deployed can be known in advance via {computeAddress}.\n *\n * The bytecode for a contract can be obtained from Solidity with\n * `type(contractName).creationCode`.\n *\n * Requirements:\n *\n * - `bytecode` must not be empty.\n * - `salt` must have not been used for `bytecode` already.\n * - the factory must have a balance of at least `amount`.\n * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.\n */\n function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address) {\n address addr;\n require(address(this).balance >= amount, \"Create2: insufficient balance\");\n require(bytecode.length != 0, \"Create2: bytecode length is zero\");\n // solhint-disable-next-line no-inline-assembly\n assembly {\n addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)\n }\n require(addr != address(0), \"Create2: Failed on deploy\");\n return addr;\n }\n\n /**\n * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the\n * `bytecodeHash` or `salt` will result in a new destination address.\n */\n function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {\n return computeAddress(salt, bytecodeHash, address(this));\n }\n\n /**\n * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at\n * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.\n */\n function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address) {\n bytes32 _data = keccak256(\n abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash)\n );\n return address(uint256(_data));\n }\n}\n"
},
"@openzeppelin/contracts/utils/Address.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
},
"@openzeppelin/contracts/access/Ownable.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
},
"@openzeppelin/contracts/GSN/Context.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
},
"temp-contracts/ManyToOneImplementationHolder.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity =0.6.12;\n\n\n/**\n * @dev The ManyToOneImplementationHolder stores an upgradeable implementation address\n * in storage, which many-to-one proxies query at execution time to determine which\n * contract to delegate to.\n *\n * The manager can upgrade the implementation address by calling the holder with the\n * abi-encoded address as calldata. If any other account calls the implementation holder,\n * it will return the implementation address.\n *\n * This pattern was inspired by the DharmaUpgradeBeacon from 0age\n * https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/upgradeability/smart-wallet/DharmaUpgradeBeacon.sol\n */\ncontract ManyToOneImplementationHolder {\n/* --- Storage --- */\n address internal immutable _manager;\n address internal _implementation;\n\n/* --- Constructor --- */\n constructor() public {\n _manager = msg.sender;\n }\n\n /**\n * @dev Fallback function for the contract.\n *\n * Used by proxies to read the implementation address and used\n * by the proxy manager to set the implementation address.\n *\n * If called by the owner, reads the implementation address from\n * calldata (must be abi-encoded) and stores it to the first slot.\n *\n * Otherwise, returns the stored implementation address.\n */\n fallback() external payable {\n if (msg.sender != _manager) {\n assembly {\n mstore(0, sload(0))\n return(0, 32)\n }\n }\n assembly { sstore(0, calldataload(0)) }\n }\n}"
},
"temp-contracts/DelegateCallProxyManyToOne.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity =0.6.12;\n\nimport { Proxy } from \"@openzeppelin/contracts/proxy/Proxy.sol\";\n\n\n/**\n * @dev Proxy contract which uses an implementation address shared with many\n * other proxies.\n *\n * An implementation holder contract stores the upgradeable implementation address.\n * When the proxy is called, it queries the implementation address from the holder\n * contract and delegatecalls the returned address, forwarding the received calldata\n * and ether.\n *\n * Note: This contract does not verify that the implementation\n * address is a valid delegation target. The manager must perform\n * this safety check before updating the implementation on the holder.\n */\ncontract DelegateCallProxyManyToOne is Proxy {\n/* ========== Constants ========== */\n\n // Address that stores the implementation address.\n address internal immutable _implementationHolder;\n\n/* ========== Constructor ========== */\n\n constructor() public {\n // Calls the sender rather than receiving the address in the constructor\n // arguments so that the address is computable using create2.\n _implementationHolder = ProxyDeployer(msg.sender).getImplementationHolder();\n }\n\n/* ========== Internal Overrides ========== */\n\n /**\n * @dev Queries the implementation address from the implementation holder.\n */\n function _implementation() internal override view returns (address) {\n // Queries the implementation address from the implementation holder.\n (bool success, bytes memory data) = _implementationHolder.staticcall(\"\");\n require(success, string(data));\n address implementation = abi.decode((data), (address));\n require(implementation != address(0), \"ERR_NULL_IMPLEMENTATION\");\n return implementation;\n }\n}\n\ninterface ProxyDeployer {\n function getImplementationHolder() external view returns (address);\n}"
},
"@openzeppelin/contracts/proxy/Proxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n * \n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n * \n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n * \n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal virtual view returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n * \n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () payable external {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () payable external {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n * \n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
},
"temp-contracts/DelegateCallProxyOneToOne.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity =0.6.12;\n\nimport { Proxy } from \"@openzeppelin/contracts/proxy/Proxy.sol\";\n\n\n/**\n * @dev Upgradeable delegatecall proxy for a single contract.\n *\n * This proxy stores an implementation address which can be upgraded by the proxy manager.\n *\n * To upgrade the implementation, the manager calls the proxy with the abi encoded implementation address.\n *\n * If any other account calls the proxy, it will delegatecall the implementation address with the received\n * calldata and ether. If the call succeeds, it will return with the received returndata.\n * If it reverts, it will revert with the received revert data.\n *\n * Note: The storage slot for the implementation address is:\n * `bytes32(uint256(keccak256(\"IMPLEMENTATION_ADDRESS\")) + 1)`\n * This slot must not be used by the implementation contract.\n *\n * Note: This contract does not verify that the implementation address is a valid delegation target.\n * The manager must perform this safety check.\n */\ncontract DelegateCallProxyOneToOne is Proxy {\n/* ========== Constants ========== */\n address internal immutable _manager;\n\n/* ========== Constructor ========== */\n constructor() public {\n _manager = msg.sender ;\n }\n\n/* ========== Internal Overrides ========== */\n\n /**\n * @dev Reads the implementation address from storage.\n */\n function _implementation() internal override view returns (address) {\n address implementation;\n assembly {\n implementation := sload(\n // bytes32(uint256(keccak256(\"IMPLEMENTATION_ADDRESS\")) + 1)\n 0x913bd12b32b36f36cedaeb6e043912bceb97022755958701789d3108d33a045a\n )\n }\n return implementation;\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation.\n *\n * Checks if the call is from the owner.\n * If it is, reads the abi-encoded implementation address from calldata and stores\n * it at the slot `bytes32(uint256(keccak256(\"IMPLEMENTATION_ADDRESS\")) + 1)`,\n * then returns with no data.\n * If it is not, continues execution with the fallback function.\n */\n function _beforeFallback() internal override {\n if (msg.sender != _manager) {\n super._beforeFallback();\n } else {\n assembly {\n sstore(\n // bytes32(uint256(keccak256(\"IMPLEMENTATION_ADDRESS\")) + 1)\n 0x913bd12b32b36f36cedaeb6e043912bceb97022755958701789d3108d33a045a,\n calldataload(0)\n )\n return(0, 0)\n }\n }\n }\n}\n"
},
"temp-contracts/SaltyLib.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.6.0;\n\n/* --- External Libraries --- */\nimport { Create2 } from \"@openzeppelin/contracts/utils/Create2.sol\";\n\n/* --- Proxy Contracts --- */\nimport { CodeHashes } from \"./CodeHashes.sol\";\n\n\n/**\n * @dev Library for computing create2 salts and addresses for proxies\n * deployed by `DelegateCallProxyManager`.\n *\n * Because the proxy factory is meant to be used by multiple contracts,\n * we use a salt derivation pattern that includes the address of the\n * contract that requested the proxy deployment, a salt provided by that\n * contract and the implementation ID used (for many-to-one proxies only).\n */\nlibrary SaltyLib {\n/* --- Salt Derivation --- */\n\n /**\n * @dev Derives the create2 salt for a many-to-one proxy.\n *\n * Many different contracts in the Indexed framework may use the\n * same implementation contract, and they all use the same init\n * code, so we derive the actual create2 salt from a combination\n * of the implementation ID, the address of the account requesting\n * deployment and the user-supplied salt.\n *\n * @param originator Address of the account requesting deployment.\n * @param implementationID The identifier for the contract implementation.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function deriveManyToOneSalt(\n address originator,\n bytes32 implementationID,\n bytes32 suppliedSalt\n )\n internal\n pure\n returns (bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originator,\n implementationID,\n suppliedSalt\n )\n );\n }\n\n /**\n * @dev Derives the create2 salt for a one-to-one proxy.\n *\n * @param originator Address of the account requesting deployment.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function deriveOneToOneSalt(\n address originator,\n bytes32 suppliedSalt\n )\n internal\n pure\n returns (bytes32)\n {\n return keccak256(abi.encodePacked(originator, suppliedSalt));\n }\n\n/* --- Address Derivation --- */\n\n /**\n * @dev Computes the create2 address for a one-to-one proxy deployed\n * by `deployer` (the factory) when requested by `originator` using\n * `suppliedSalt`.\n *\n * @param deployer Address of the proxy factory.\n * @param originator Address of the account requesting deployment.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function computeProxyAddressOneToOne(\n address deployer,\n address originator,\n bytes32 suppliedSalt\n )\n internal\n pure\n returns (address)\n {\n bytes32 salt = deriveOneToOneSalt(originator, suppliedSalt);\n return Create2.computeAddress(salt, CodeHashes.ONE_TO_ONE_CODEHASH, deployer);\n }\n\n /**\n * @dev Computes the create2 address for a many-to-one proxy for the\n * implementation `implementationID` deployed by `deployer` (the factory)\n * when requested by `originator` using `suppliedSalt`.\n *\n * @param deployer Address of the proxy factory.\n * @param originator Address of the account requesting deployment.\n * @param implementationID The identifier for the contract implementation.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function computeProxyAddressManyToOne(\n address deployer,\n address originator,\n bytes32 implementationID,\n bytes32 suppliedSalt\n )\n internal\n pure\n returns (address)\n {\n bytes32 salt = deriveManyToOneSalt(\n originator,\n implementationID,\n suppliedSalt\n );\n return Create2.computeAddress(salt, CodeHashes.MANY_TO_ONE_CODEHASH, deployer);\n }\n\n /**\n * @dev Computes the create2 address of the implementation holder\n * for `implementationID`.\n *\n * @param deployer Address of the proxy factory.\n * @param implementationID The identifier for the contract implementation.\n */\n function computeHolderAddressManyToOne(\n address deployer,\n bytes32 implementationID\n )\n internal\n pure\n returns (address)\n {\n return Create2.computeAddress(\n implementationID,\n CodeHashes.IMPLEMENTATION_HOLDER_CODEHASH,\n deployer\n );\n }\n}"
},
"temp-contracts/interfaces/IDelegateCallProxyManager.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Contract that manages deployment and upgrades of delegatecall proxies.\n *\n * An implementation identifier can be created on the proxy manager which is\n * used to specify the logic address for a particular contract type, and to\n * upgrade the implementation as needed.\n *\n * A one-to-one proxy is a single proxy contract with an upgradeable implementation\n * address.\n *\n * A many-to-one proxy is a single upgradeable implementation address that may be\n * used by many proxy contracts.\n */\ninterface IDelegateCallProxyManager {\n/* ========== Events ========== */\n\n event DeploymentApprovalGranted(address deployer);\n event DeploymentApprovalRevoked(address deployer);\n\n event ManyToOne_ImplementationCreated(\n bytes32 implementationID,\n address implementationAddress\n );\n\n event ManyToOne_ImplementationUpdated(\n bytes32 implementationID,\n address implementationAddress\n );\n\n event ManyToOne_ProxyDeployed(\n bytes32 implementationID,\n address proxyAddress\n );\n\n event OneToOne_ProxyDeployed(\n address proxyAddress,\n address implementationAddress\n );\n\n event OneToOne_ImplementationUpdated(\n address proxyAddress,\n address implementationAddress\n );\n\n/* ========== Controls ========== */\n\n /**\n * @dev Allows `deployer` to deploy many-to-one proxies.\n */\n function approveDeployer(address deployer) external;\n\n /**\n * @dev Prevents `deployer` from deploying many-to-one proxies.\n */\n function revokeDeployerApproval(address deployer) external;\n\n/* ========== Implementation Management ========== */\n\n /**\n * @dev Creates a many-to-one proxy relationship.\n *\n * Deploys an implementation holder contract which stores the\n * implementation address for many proxies. The implementation\n * address can be updated on the holder to change the runtime\n * code used by all its proxies.\n *\n * @param implementationID ID for the implementation, used to identify the\n * proxies that use it. Also used as the salt in the create2 call when\n * deploying the implementation holder contract.\n * @param implementation Address with the runtime code the proxies\n * should use.\n */\n function createManyToOneProxyRelationship(\n bytes32 implementationID,\n address implementation\n ) external;\n\n /**\n * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again.\n */\n function lockImplementationManyToOne(bytes32 implementationID) external;\n\n /**\n * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again.\n */\n function lockImplementationOneToOne(address proxyAddress) external;\n\n /**\n * @dev Updates the implementation address for a many-to-one\n * proxy relationship.\n *\n * @param implementationID Identifier for the implementation.\n * @param implementation Address with the runtime code the proxies\n * should use.\n */\n function setImplementationAddressManyToOne(\n bytes32 implementationID,\n address implementation\n ) external;\n\n /**\n * @dev Updates the implementation address for a one-to-one proxy.\n *\n * Note: This could work for many-to-one as well if the caller\n * provides the implementation holder address in place of the\n * proxy address, as they use the same access control and update\n * mechanism.\n *\n * @param proxyAddress Address of the deployed proxy\n * @param implementation Address with the runtime code for\n * the proxy to use.\n */\n function setImplementationAddressOneToOne(\n address proxyAddress,\n address implementation\n ) external;\n\n/* ========== Proxy Deployment ========== */\n\n /**\n * @dev Deploy a proxy contract with a one-to-one relationship\n * with its implementation.\n *\n * The proxy will have its own implementation address which can\n * be updated by the proxy manager.\n *\n * @param suppliedSalt Salt provided by the account requesting deployment.\n * @param implementation Address of the contract with the runtime\n * code that the proxy should use.\n */\n function deployProxyOneToOne(\n bytes32 suppliedSalt,\n address implementation\n ) external returns(address proxyAddress);\n\n /**\n * @dev Deploy a proxy with a many-to-one relationship with its implemenation.\n *\n * The proxy will call the implementation holder for every transaction to\n * determine the address to use in calls.\n *\n * @param implementationID Identifier for the proxy's implementation.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function deployProxyManyToOne(\n bytes32 implementationID,\n bytes32 suppliedSalt\n ) external returns(address proxyAddress);\n\n/* ========== Queries ========== */\n\n /**\n * @dev Returns a boolean stating whether `implementationID` is locked.\n */\n function isImplementationLocked(bytes32 implementationID) external view returns (bool);\n\n /**\n * @dev Returns a boolean stating whether `proxyAddress` is locked.\n */\n function isImplementationLocked(address proxyAddress) external view returns (bool);\n\n /**\n * @dev Returns a boolean stating whether `deployer` is allowed to deploy many-to-one\n * proxies.\n */\n function isApprovedDeployer(address deployer) external view returns (bool);\n\n /**\n * @dev Queries the temporary storage value `_implementationHolder`.\n * This is used in the constructor of the many-to-one proxy contract\n * so that the create2 address is static (adding constructor arguments\n * would change the codehash) and the implementation holder can be\n * stored as a constant.\n */\n function getImplementationHolder() external view returns (address);\n\n /**\n * @dev Returns the address of the implementation holder contract\n * for `implementationID`.\n */\n function getImplementationHolder(bytes32 implementationID) external view returns (address);\n\n /**\n * @dev Computes the create2 address for a one-to-one proxy requested\n * by `originator` using `suppliedSalt`.\n *\n * @param originator Address of the account requesting deployment.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function computeProxyAddressOneToOne(\n address originator,\n bytes32 suppliedSalt\n ) external view returns (address);\n\n /**\n * @dev Computes the create2 address for a many-to-one proxy for the\n * implementation `implementationID` requested by `originator` using\n * `suppliedSalt`.\n *\n * @param originator Address of the account requesting deployment.\n * @param implementationID The identifier for the contract implementation.\n * @param suppliedSalt Salt provided by the account requesting deployment.\n */\n function computeProxyAddressManyToOne(\n address originator,\n bytes32 implementationID,\n bytes32 suppliedSalt\n ) external view returns (address);\n\n /**\n * @dev Computes the create2 address of the implementation holder\n * for `implementationID`.\n *\n * @param implementationID The identifier for the contract implementation.\n */\n function computeHolderAddressManyToOne(bytes32 implementationID) external view returns (address);\n}"
}
},
"settings": {
"metadata": {
"useLiteralContent": false
},
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"id",
"ast"
]
}
}
}
}