Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 8 internal transactions
[ Download CSV Export ]
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
DelegateCallProxyManager
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; /** * @dev Because we use the code hashes of the proxy contracts for proxy address * derivation, it is important that other packages have access to the correct * values when they import the salt library. */ library CodeHashes { bytes32 internal constant ONE_TO_ONE_CODEHASH = 0x63d9f7b5931b69188c8f6b806606f25892f1bb17b7f7e966fe3a32c04493aee4; bytes32 internal constant MANY_TO_ONE_CODEHASH = 0xa035ad05a1663db5bfd455b99cd7c6ac6bd49269738458eda140e0b78ed53f79; bytes32 internal constant IMPLEMENTATION_HOLDER_CODEHASH = 0x11c370493a726a0ffa93d42b399ad046f1b5a543b6e72f1a64f1488dc1c58f2c; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity =0.6.12; /* ========== External Libraries ========== */ import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol"; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; /* ========== Proxy Contracts ========== */ import "./ManyToOneImplementationHolder.sol"; import { DelegateCallProxyManyToOne } from "./DelegateCallProxyManyToOne.sol"; import { DelegateCallProxyOneToOne } from "./DelegateCallProxyOneToOne.sol"; /* ========== Internal Libraries ========== */ import { SaltyLib as Salty } from "./SaltyLib.sol"; import { CodeHashes } from "./CodeHashes.sol"; /* ========== Inheritance ========== */ import "./interfaces/IDelegateCallProxyManager.sol"; /** * @dev Contract that manages deployment and upgrades of delegatecall proxies. * * An implementation identifier can be created on the proxy manager which is * used to specify the logic address for a particular contract type, and to * upgrade the implementation as needed. * * ====== Proxy Types ====== * A one-to-one proxy is a single proxy contract with an upgradeable implementation * address. * * A many-to-one proxy is a single upgradeable implementation address that may be * used by many proxy contracts. * * ====== Access Control ====== * The proxy manager has a single address as its owner. * * The owner is the sole account with the following permissions: * - Create new many-to-one implementations * - Create new one-to-one proxies * - Modify the implementation address of existing proxies * - Lock proxies * - Designate approved deployers * - Remove approved deployers * - Modify the owner address * * Approved deployers may only deploy many-to-one proxies. * * ====== Upgrades ====== * Proxies can be upgraded by the owner if they are not locked. * * Many-to-one proxy implementations are upgraded by calling the holder contract * for the implementation ID being upgraded. * One-to-one proxies are upgraded by calling the proxy contract directly. * * The owner can lock a one-to-one proxy or many-to-one implementation ID so that * it becomes impossible to upgrade. */ contract DelegateCallProxyManager is Ownable, IDelegateCallProxyManager { /* ========== Events ========== */ event DeploymentApprovalGranted(address deployer); event DeploymentApprovalRevoked(address deployer); event ManyToOne_ImplementationCreated( bytes32 implementationID, address implementationAddress ); event ManyToOne_ImplementationUpdated( bytes32 implementationID, address implementationAddress ); event ManyToOne_ImplementationLocked(bytes32 implementationID); event ManyToOne_ProxyDeployed( bytes32 implementationID, address proxyAddress ); event OneToOne_ProxyDeployed( address proxyAddress, address implementationAddress ); event OneToOne_ImplementationUpdated( address proxyAddress, address implementationAddress ); event OneToOne_ImplementationLocked(address proxyAddress); /* ========== Storage ========== */ // Addresses allowed to deploy many-to-one proxies. mapping(address => bool) internal _approvedDeployers; // Maps implementation holders to their implementation IDs. mapping(bytes32 => address) internal _implementationHolders; // Maps implementation holders & proxy addresses to bool stating if they are locked. mapping(address => bool) internal _lockedImplementations; // Temporary value used in the many-to-one proxy constructor. // The many-to-one proxy contract is deployed with create2 and // uses static initialization code for simple address derivation, // so it calls the proxy manager in the constructor to get this // address in order to save it as an immutable in the bytecode. address internal _implementationHolder; /* ========== Modifiers ========== */ modifier onlyApprovedDeployer { address sender = _msgSender(); require(_approvedDeployers[sender] || sender == owner(), "ERR_NOT_APPROVED"); _; } /* ========== Constructor ========== */ constructor() public Ownable() {} /* ========== Access Control ========== */ /** * @dev Allows `deployer` to deploy many-to-one proxies. */ function approveDeployer(address deployer) external override onlyOwner { _approvedDeployers[deployer] = true; emit DeploymentApprovalGranted(deployer); } /** * @dev Prevents `deployer` from deploying many-to-one proxies. */ function revokeDeployerApproval(address deployer) external override onlyOwner { _approvedDeployers[deployer] = false; emit DeploymentApprovalRevoked(deployer); } /* ========== Implementation Management ========== */ /** * @dev Creates a many-to-one proxy relationship. * * Deploys an implementation holder contract which stores the * implementation address for many proxies. The implementation * address can be updated on the holder to change the runtime * code used by all its proxies. * * @param implementationID ID for the implementation, used to identify the * proxies that use it. Also used as the salt in the create2 call when * deploying the implementation holder contract. * @param implementation Address with the runtime code the proxies * should use. */ function createManyToOneProxyRelationship( bytes32 implementationID, address implementation ) external override onlyOwner { // Deploy the implementation holder contract with the implementation // ID as the create2 salt. address implementationHolder = Create2.deploy( 0, implementationID, type(ManyToOneImplementationHolder).creationCode ); // Store the implementation holder address _implementationHolders[implementationID] = implementationHolder; // Sets the implementation address. _setImplementation(implementationHolder, implementation); emit ManyToOne_ImplementationCreated( implementationID, implementation ); } /** * @dev Lock the current implementation for `implementationID` so that it can never be upgraded again. */ function lockImplementationManyToOne(bytes32 implementationID) external override onlyOwner { // Read the implementation holder address from storage. address implementationHolder = _implementationHolders[implementationID]; // Verify that the implementation exists. require(implementationHolder != address(0), "ERR_IMPLEMENTATION_ID"); _lockedImplementations[implementationHolder] = true; emit ManyToOne_ImplementationLocked(implementationID); } /** * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again. */ function lockImplementationOneToOne(address proxyAddress) external override onlyOwner { _lockedImplementations[proxyAddress] = true; emit OneToOne_ImplementationLocked(proxyAddress); } /** * @dev Updates the implementation address for a many-to-one * proxy relationship. * * @param implementationID Identifier for the implementation. * @param implementation Address with the runtime code the proxies * should use. */ function setImplementationAddressManyToOne( bytes32 implementationID, address implementation ) external override onlyOwner { // Read the implementation holder address from storage. address implementationHolder = _implementationHolders[implementationID]; // Verify that the implementation exists. require(implementationHolder != address(0), "ERR_IMPLEMENTATION_ID"); // Verify implementation is not locked require(!_lockedImplementations[implementationHolder], "ERR_IMPLEMENTATION_LOCKED"); // Set the implementation address _setImplementation(implementationHolder, implementation); emit ManyToOne_ImplementationUpdated( implementationID, implementation ); } /** * @dev Updates the implementation address for a one-to-one proxy. * * Note: This could work for many-to-one as well if the caller * provides the implementation holder address in place of the * proxy address, as they use the same access control and update * mechanism. * * @param proxyAddress Address of the deployed proxy * @param implementation Address with the runtime code for * the proxy to use. */ function setImplementationAddressOneToOne( address proxyAddress, address implementation ) external override onlyOwner { // Verify proxy is not locked require(!_lockedImplementations[proxyAddress], "ERR_IMPLEMENTATION_LOCKED"); // Set the implementation address _setImplementation(proxyAddress, implementation); emit OneToOne_ImplementationUpdated(proxyAddress, implementation); } /* ========== Proxy Deployment ========== */ /** * @dev Deploy a proxy contract with a one-to-one relationship * with its implementation. * * The proxy will have its own implementation address which can * be updated by the proxy manager. * * @param suppliedSalt Salt provided by the account requesting deployment. * @param implementation Address of the contract with the runtime * code that the proxy should use. */ function deployProxyOneToOne( bytes32 suppliedSalt, address implementation ) external override onlyOwner returns(address proxyAddress) { // Derive the create2 salt from the deployment requester's address // and the requester-supplied salt. bytes32 salt = Salty.deriveOneToOneSalt(_msgSender(), suppliedSalt); // Deploy the proxy proxyAddress = Create2.deploy( 0, salt, type(DelegateCallProxyOneToOne).creationCode ); // Set the implementation address on the new proxy. _setImplementation(proxyAddress, implementation); emit OneToOne_ProxyDeployed(proxyAddress, implementation); } /** * @dev Deploy a proxy with a many-to-one relationship with its implemenation. * * The proxy will call the implementation holder for every transaction to * determine the address to use in calls. * * @param implementationID Identifier for the proxy's implementation. * @param suppliedSalt Salt provided by the account requesting deployment. */ function deployProxyManyToOne(bytes32 implementationID, bytes32 suppliedSalt) external override onlyApprovedDeployer returns(address proxyAddress) { // Read the implementation holder address from storage. address implementationHolder = _implementationHolders[implementationID]; // Verify that the implementation exists. require(implementationHolder != address(0), "ERR_IMPLEMENTATION_ID"); // Derive the create2 salt from the deployment requester's address, the // implementation ID and the requester-supplied salt. bytes32 salt = Salty.deriveManyToOneSalt( _msgSender(), implementationID, suppliedSalt ); // Set the implementation holder address in storage so the proxy // constructor can query it. _implementationHolder = implementationHolder; // Deploy the proxy, which will query the implementation holder address // and save it as an immutable in the contract bytecode. proxyAddress = Create2.deploy( 0, salt, type(DelegateCallProxyManyToOne).creationCode ); // Remove the address from temporary storage. _implementationHolder = address(0); emit ManyToOne_ProxyDeployed( implementationID, proxyAddress ); } /* ========== Queries ========== */ /** * @dev Returns a boolean stating whether `implementationID` is locked. */ function isImplementationLocked(bytes32 implementationID) external override view returns (bool) { // Read the implementation holder address from storage. address implementationHolder = _implementationHolders[implementationID]; // Verify that the implementation exists. require(implementationHolder != address(0), "ERR_IMPLEMENTATION_ID"); return _lockedImplementations[implementationHolder]; } /** * @dev Returns a boolean stating whether `proxyAddress` is locked. */ function isImplementationLocked(address proxyAddress) external override view returns (bool) { return _lockedImplementations[proxyAddress]; } /** * @dev Returns a boolean stating whether `deployer` is allowed to deploy many-to-one * proxies. */ function isApprovedDeployer(address deployer) external override view returns (bool) { return _approvedDeployers[deployer]; } /** * @dev Queries the temporary storage value `_implementationHolder`. * This is used in the constructor of the many-to-one proxy contract * so that the create2 address is static (adding constructor arguments * would change the codehash) and the implementation holder can be * stored as a constant. */ function getImplementationHolder() external override view returns (address) { return _implementationHolder; } /** * @dev Returns the address of the implementation holder contract * for `implementationID`. */ function getImplementationHolder( bytes32 implementationID ) external override view returns (address) { return _implementationHolders[implementationID]; } /** * @dev Computes the create2 address for a one-to-one proxy requested * by `originator` using `suppliedSalt`. * * @param originator Address of the account requesting deployment. * @param suppliedSalt Salt provided by the account requesting deployment. */ function computeProxyAddressOneToOne( address originator, bytes32 suppliedSalt ) external override view returns (address) { bytes32 salt = Salty.deriveOneToOneSalt(originator, suppliedSalt); return Create2.computeAddress(salt, CodeHashes.ONE_TO_ONE_CODEHASH); } /** * @dev Computes the create2 address for a many-to-one proxy for the * implementation `implementationID` requested by `originator` using * `suppliedSalt`. * * @param originator Address of the account requesting deployment. * @param implementationID The identifier for the contract implementation. * @param suppliedSalt Salt provided by the account requesting deployment. */ function computeProxyAddressManyToOne( address originator, bytes32 implementationID, bytes32 suppliedSalt ) external override view returns (address) { bytes32 salt = Salty.deriveManyToOneSalt( originator, implementationID, suppliedSalt ); return Create2.computeAddress(salt, CodeHashes.MANY_TO_ONE_CODEHASH); } /** * @dev Computes the create2 address of the implementation holder * for `implementationID`. * * @param implementationID The identifier for the contract implementation. */ function computeHolderAddressManyToOne(bytes32 implementationID) public override view returns (address) { return Create2.computeAddress( implementationID, CodeHashes.IMPLEMENTATION_HOLDER_CODEHASH ); } /* ========== Internal Functions ========== */ /** * @dev Sets the implementation address for a one-to-one proxy or * many-to-one implementation holder. Both use the same access * control and update mechanism, which is the receipt of a call * from the proxy manager with the abi-encoded implementation address * as the only calldata. * * Note: Verifies that the implementation address is a contract. * * @param proxyOrHolder Address of the one-to-one proxy or * many-to-one implementation holder contract. * @param implementation Address of the contract with the runtime * code that the proxy or proxies should use. */ function _setImplementation( address proxyOrHolder, address implementation ) internal { // Verify that the implementation address is a contract. require(Address.isContract(implementation), "ERR_NOT_CONTRACT"); // Set the implementation address on the contract. // solium-disable-next-line security/no-low-level-calls (bool success,) = proxyOrHolder.call(abi.encode(implementation)); require(success, "ERR_SET_ADDRESS_REVERT"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. * `CREATE2` can be used to compute in advance the address where a smart * contract will be deployed, which allows for interesting new mechanisms known * as 'counterfactual interactions'. * * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more * information. */ library Create2 { /** * @dev Deploys a contract using `CREATE2`. The address where the contract * will be deployed can be known in advance via {computeAddress}. * * The bytecode for a contract can be obtained from Solidity with * `type(contractName).creationCode`. * * Requirements: * * - `bytecode` must not be empty. * - `salt` must have not been used for `bytecode` already. * - the factory must have a balance of at least `amount`. * - if `amount` is non-zero, `bytecode` must have a `payable` constructor. */ function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address) { address addr; require(address(this).balance >= amount, "Create2: insufficient balance"); require(bytecode.length != 0, "Create2: bytecode length is zero"); // solhint-disable-next-line no-inline-assembly assembly { addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) } require(addr != address(0), "Create2: Failed on deploy"); return addr; } /** * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the * `bytecodeHash` or `salt` will result in a new destination address. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) { return computeAddress(salt, bytecodeHash, address(this)); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address) { bytes32 _data = keccak256( abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash) ); return address(uint256(_data)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.2; /** * @dev Collection of functions related to the address type */ library Address { /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (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 functionCall(target, data, "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"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; import "../GSN/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity =0.6.12; /** * @dev The ManyToOneImplementationHolder stores an upgradeable implementation address * in storage, which many-to-one proxies query at execution time to determine which * contract to delegate to. * * The manager can upgrade the implementation address by calling the holder with the * abi-encoded address as calldata. If any other account calls the implementation holder, * it will return the implementation address. * * This pattern was inspired by the DharmaUpgradeBeacon from 0age * https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/upgradeability/smart-wallet/DharmaUpgradeBeacon.sol */ contract ManyToOneImplementationHolder { /* --- Storage --- */ address internal immutable _manager; address internal _implementation; /* --- Constructor --- */ constructor() public { _manager = msg.sender; } /** * @dev Fallback function for the contract. * * Used by proxies to read the implementation address and used * by the proxy manager to set the implementation address. * * If called by the owner, reads the implementation address from * calldata (must be abi-encoded) and stores it to the first slot. * * Otherwise, returns the stored implementation address. */ fallback() external payable { if (msg.sender != _manager) { assembly { mstore(0, sload(0)) return(0, 32) } } assembly { sstore(0, calldataload(0)) } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity =0.6.12; import { Proxy } from "@openzeppelin/contracts/proxy/Proxy.sol"; /** * @dev Proxy contract which uses an implementation address shared with many * other proxies. * * An implementation holder contract stores the upgradeable implementation address. * When the proxy is called, it queries the implementation address from the holder * contract and delegatecalls the returned address, forwarding the received calldata * and ether. * * Note: This contract does not verify that the implementation * address is a valid delegation target. The manager must perform * this safety check before updating the implementation on the holder. */ contract DelegateCallProxyManyToOne is Proxy { /* ========== Constants ========== */ // Address that stores the implementation address. address internal immutable _implementationHolder; /* ========== Constructor ========== */ constructor() public { // Calls the sender rather than receiving the address in the constructor // arguments so that the address is computable using create2. _implementationHolder = ProxyDeployer(msg.sender).getImplementationHolder(); } /* ========== Internal Overrides ========== */ /** * @dev Queries the implementation address from the implementation holder. */ function _implementation() internal override view returns (address) { // Queries the implementation address from the implementation holder. (bool success, bytes memory data) = _implementationHolder.staticcall(""); require(success, string(data)); address implementation = abi.decode((data), (address)); require(implementation != address(0), "ERR_NULL_IMPLEMENTATION"); return implementation; } } interface ProxyDeployer { function getImplementationHolder() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _delegate(address implementation) internal { // solhint-disable-next-line no-inline-assembly assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal virtual view returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _fallback() internal { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback () payable external { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive () payable external { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overriden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual { } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity =0.6.12; import { Proxy } from "@openzeppelin/contracts/proxy/Proxy.sol"; /** * @dev Upgradeable delegatecall proxy for a single contract. * * This proxy stores an implementation address which can be upgraded by the proxy manager. * * To upgrade the implementation, the manager calls the proxy with the abi encoded implementation address. * * If any other account calls the proxy, it will delegatecall the implementation address with the received * calldata and ether. If the call succeeds, it will return with the received returndata. * If it reverts, it will revert with the received revert data. * * Note: The storage slot for the implementation address is: * `bytes32(uint256(keccak256("IMPLEMENTATION_ADDRESS")) + 1)` * This slot must not be used by the implementation contract. * * Note: This contract does not verify that the implementation address is a valid delegation target. * The manager must perform this safety check. */ contract DelegateCallProxyOneToOne is Proxy { /* ========== Constants ========== */ address internal immutable _manager; /* ========== Constructor ========== */ constructor() public { _manager = msg.sender ; } /* ========== Internal Overrides ========== */ /** * @dev Reads the implementation address from storage. */ function _implementation() internal override view returns (address) { address implementation; assembly { implementation := sload( // bytes32(uint256(keccak256("IMPLEMENTATION_ADDRESS")) + 1) 0x913bd12b32b36f36cedaeb6e043912bceb97022755958701789d3108d33a045a ) } return implementation; } /** * @dev Hook that is called before falling back to the implementation. * * Checks if the call is from the owner. * If it is, reads the abi-encoded implementation address from calldata and stores * it at the slot `bytes32(uint256(keccak256("IMPLEMENTATION_ADDRESS")) + 1)`, * then returns with no data. * If it is not, continues execution with the fallback function. */ function _beforeFallback() internal override { if (msg.sender != _manager) { super._beforeFallback(); } else { assembly { sstore( // bytes32(uint256(keccak256("IMPLEMENTATION_ADDRESS")) + 1) 0x913bd12b32b36f36cedaeb6e043912bceb97022755958701789d3108d33a045a, calldataload(0) ) return(0, 0) } } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; /* --- External Libraries --- */ import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol"; /* --- Proxy Contracts --- */ import { CodeHashes } from "./CodeHashes.sol"; /** * @dev Library for computing create2 salts and addresses for proxies * deployed by `DelegateCallProxyManager`. * * Because the proxy factory is meant to be used by multiple contracts, * we use a salt derivation pattern that includes the address of the * contract that requested the proxy deployment, a salt provided by that * contract and the implementation ID used (for many-to-one proxies only). */ library SaltyLib { /* --- Salt Derivation --- */ /** * @dev Derives the create2 salt for a many-to-one proxy. * * Many different contracts in the Indexed framework may use the * same implementation contract, and they all use the same init * code, so we derive the actual create2 salt from a combination * of the implementation ID, the address of the account requesting * deployment and the user-supplied salt. * * @param originator Address of the account requesting deployment. * @param implementationID The identifier for the contract implementation. * @param suppliedSalt Salt provided by the account requesting deployment. */ function deriveManyToOneSalt( address originator, bytes32 implementationID, bytes32 suppliedSalt ) internal pure returns (bytes32) { return keccak256( abi.encodePacked( originator, implementationID, suppliedSalt ) ); } /** * @dev Derives the create2 salt for a one-to-one proxy. * * @param originator Address of the account requesting deployment. * @param suppliedSalt Salt provided by the account requesting deployment. */ function deriveOneToOneSalt( address originator, bytes32 suppliedSalt ) internal pure returns (bytes32) { return keccak256(abi.encodePacked(originator, suppliedSalt)); } /* --- Address Derivation --- */ /** * @dev Computes the create2 address for a one-to-one proxy deployed * by `deployer` (the factory) when requested by `originator` using * `suppliedSalt`. * * @param deployer Address of the proxy factory. * @param originator Address of the account requesting deployment. * @param suppliedSalt Salt provided by the account requesting deployment. */ function computeProxyAddressOneToOne( address deployer, address originator, bytes32 suppliedSalt ) internal pure returns (address) { bytes32 salt = deriveOneToOneSalt(originator, suppliedSalt); return Create2.computeAddress(salt, CodeHashes.ONE_TO_ONE_CODEHASH, deployer); } /** * @dev Computes the create2 address for a many-to-one proxy for the * implementation `implementationID` deployed by `deployer` (the factory) * when requested by `originator` using `suppliedSalt`. * * @param deployer Address of the proxy factory. * @param originator Address of the account requesting deployment. * @param implementationID The identifier for the contract implementation. * @param suppliedSalt Salt provided by the account requesting deployment. */ function computeProxyAddressManyToOne( address deployer, address originator, bytes32 implementationID, bytes32 suppliedSalt ) internal pure returns (address) { bytes32 salt = deriveManyToOneSalt( originator, implementationID, suppliedSalt ); return Create2.computeAddress(salt, CodeHashes.MANY_TO_ONE_CODEHASH, deployer); } /** * @dev Computes the create2 address of the implementation holder * for `implementationID`. * * @param deployer Address of the proxy factory. * @param implementationID The identifier for the contract implementation. */ function computeHolderAddressManyToOne( address deployer, bytes32 implementationID ) internal pure returns (address) { return Create2.computeAddress( implementationID, CodeHashes.IMPLEMENTATION_HOLDER_CODEHASH, deployer ); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; /** * @dev Contract that manages deployment and upgrades of delegatecall proxies. * * An implementation identifier can be created on the proxy manager which is * used to specify the logic address for a particular contract type, and to * upgrade the implementation as needed. * * A one-to-one proxy is a single proxy contract with an upgradeable implementation * address. * * A many-to-one proxy is a single upgradeable implementation address that may be * used by many proxy contracts. */ interface IDelegateCallProxyManager { /* ========== Events ========== */ event DeploymentApprovalGranted(address deployer); event DeploymentApprovalRevoked(address deployer); event ManyToOne_ImplementationCreated( bytes32 implementationID, address implementationAddress ); event ManyToOne_ImplementationUpdated( bytes32 implementationID, address implementationAddress ); event ManyToOne_ProxyDeployed( bytes32 implementationID, address proxyAddress ); event OneToOne_ProxyDeployed( address proxyAddress, address implementationAddress ); event OneToOne_ImplementationUpdated( address proxyAddress, address implementationAddress ); /* ========== Controls ========== */ /** * @dev Allows `deployer` to deploy many-to-one proxies. */ function approveDeployer(address deployer) external; /** * @dev Prevents `deployer` from deploying many-to-one proxies. */ function revokeDeployerApproval(address deployer) external; /* ========== Implementation Management ========== */ /** * @dev Creates a many-to-one proxy relationship. * * Deploys an implementation holder contract which stores the * implementation address for many proxies. The implementation * address can be updated on the holder to change the runtime * code used by all its proxies. * * @param implementationID ID for the implementation, used to identify the * proxies that use it. Also used as the salt in the create2 call when * deploying the implementation holder contract. * @param implementation Address with the runtime code the proxies * should use. */ function createManyToOneProxyRelationship( bytes32 implementationID, address implementation ) external; /** * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again. */ function lockImplementationManyToOne(bytes32 implementationID) external; /** * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again. */ function lockImplementationOneToOne(address proxyAddress) external; /** * @dev Updates the implementation address for a many-to-one * proxy relationship. * * @param implementationID Identifier for the implementation. * @param implementation Address with the runtime code the proxies * should use. */ function setImplementationAddressManyToOne( bytes32 implementationID, address implementation ) external; /** * @dev Updates the implementation address for a one-to-one proxy. * * Note: This could work for many-to-one as well if the caller * provides the implementation holder address in place of the * proxy address, as they use the same access control and update * mechanism. * * @param proxyAddress Address of the deployed proxy * @param implementation Address with the runtime code for * the proxy to use. */ function setImplementationAddressOneToOne( address proxyAddress, address implementation ) external; /* ========== Proxy Deployment ========== */ /** * @dev Deploy a proxy contract with a one-to-one relationship * with its implementation. * * The proxy will have its own implementation address which can * be updated by the proxy manager. * * @param suppliedSalt Salt provided by the account requesting deployment. * @param implementation Address of the contract with the runtime * code that the proxy should use. */ function deployProxyOneToOne( bytes32 suppliedSalt, address implementation ) external returns(address proxyAddress); /** * @dev Deploy a proxy with a many-to-one relationship with its implemenation. * * The proxy will call the implementation holder for every transaction to * determine the address to use in calls. * * @param implementationID Identifier for the proxy's implementation. * @param suppliedSalt Salt provided by the account requesting deployment. */ function deployProxyManyToOne( bytes32 implementationID, bytes32 suppliedSalt ) external returns(address proxyAddress); /* ========== Queries ========== */ /** * @dev Returns a boolean stating whether `implementationID` is locked. */ function isImplementationLocked(bytes32 implementationID) external view returns (bool); /** * @dev Returns a boolean stating whether `proxyAddress` is locked. */ function isImplementationLocked(address proxyAddress) external view returns (bool); /** * @dev Returns a boolean stating whether `deployer` is allowed to deploy many-to-one * proxies. */ function isApprovedDeployer(address deployer) external view returns (bool); /** * @dev Queries the temporary storage value `_implementationHolder`. * This is used in the constructor of the many-to-one proxy contract * so that the create2 address is static (adding constructor arguments * would change the codehash) and the implementation holder can be * stored as a constant. */ function getImplementationHolder() external view returns (address); /** * @dev Returns the address of the implementation holder contract * for `implementationID`. */ function getImplementationHolder(bytes32 implementationID) external view returns (address); /** * @dev Computes the create2 address for a one-to-one proxy requested * by `originator` using `suppliedSalt`. * * @param originator Address of the account requesting deployment. * @param suppliedSalt Salt provided by the account requesting deployment. */ function computeProxyAddressOneToOne( address originator, bytes32 suppliedSalt ) external view returns (address); /** * @dev Computes the create2 address for a many-to-one proxy for the * implementation `implementationID` requested by `originator` using * `suppliedSalt`. * * @param originator Address of the account requesting deployment. * @param implementationID The identifier for the contract implementation. * @param suppliedSalt Salt provided by the account requesting deployment. */ function computeProxyAddressManyToOne( address originator, bytes32 implementationID, bytes32 suppliedSalt ) external view returns (address); /** * @dev Computes the create2 address of the implementation holder * for `implementationID`. * * @param implementationID The identifier for the contract implementation. */ function computeHolderAddressManyToOne(bytes32 implementationID) external view returns (address); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; interface IProxyManagerAccessControl { /* ========== Events ========== */ event AdminAccessGranted(address newAdmin); event AdminAccessRevoked(address newAdmin); /* ========== Queries ========== */ /** * @dev Checks whether `account` has administrator access. */ function hasAdminAccess(address account) external view returns (bool); /** * @dev Gets the address of the proxy manager. */ function proxyManager() external view returns (address); /* ========== Controls ========== */ /** * @dev Allows `deployer` to deploy many-to-one proxies. */ function approveDeployer(address deployer) external; /** * @dev Prevents `deployer` from deploying many-to-one proxies. */ function revokeDeployerApproval(address deployer) external; /** * @dev Grants admin access to `admin`. */ function grantAdminAccess(address admin) external; /** * @dev Revokes admin access from `admin`. */ function revokeAdminAccess(address admin) external; /** * @dev Transfers ownership of the proxy manager. */ function transferManagerOwnership(address newOwner) external; /* ========== Implementation Management ========== */ /** * @dev Creates a many-to-one proxy relationship. * * Deploys an implementation holder contract which stores the * implementation address for many proxies. The implementation * address can be updated on the holder to change the runtime * code used by all its proxies. * * @param implementationID ID for the implementation, used to identify the * proxies that use it. Also used as the salt in the create2 call when * deploying the implementation holder contract. * @param implementation Address with the runtime code the proxies * should use. */ function createManyToOneProxyRelationship( bytes32 implementationID, address implementation ) external; /** * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again. */ function lockImplementationManyToOne(bytes32 implementationID) external; /** * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again. */ function lockImplementationOneToOne(address proxyAddress) external; /** * @dev Updates the implementation address for a many-to-one * proxy relationship. * * @param implementationID Identifier for the implementation. * @param implementation Address with the runtime code the proxies * should use. */ function setImplementationAddressManyToOne( bytes32 implementationID, address implementation ) external; /** * @dev Updates the implementation address for a one-to-one proxy. * * Note: This could work for many-to-one as well if the caller * provides the implementation holder address in place of the * proxy address, as they use the same access control and update * mechanism. * * @param proxyAddress Address of the deployed proxy * @param implementation Address with the runtime code for * the proxy to use. */ function setImplementationAddressOneToOne( address proxyAddress, address implementation ) external; /* ========== Proxy Deployment ========== */ /** * @dev Deploy a proxy contract with a one-to-one relationship * with its implementation. * * The proxy will have its own implementation address which can * be updated by the proxy manager. * * @param suppliedSalt Salt provided by the account requesting deployment. * @param implementation Address of the contract with the runtime * code that the proxy should use. */ function deployProxyOneToOne( bytes32 suppliedSalt, address implementation ) external returns(address proxyAddress); /** * @dev Deploy a proxy with a many-to-one relationship with its implemenation. * * The proxy will call the implementation holder for every transaction to * determine the address to use in calls. * * @param implementationID Identifier for the proxy's implementation. * @param suppliedSalt Salt provided by the account requesting deployment. */ function deployProxyManyToOne( bytes32 implementationID, bytes32 suppliedSalt ) external returns(address proxyAddress); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity =0.6.12; import "@openzeppelin/contracts/access/Ownable.sol"; import "./interfaces/IProxyManagerAccessControl.sol"; import "./interfaces/IDelegateCallProxyManager.sol"; contract ProxyManagerAccessControl is IProxyManagerAccessControl, Ownable { /* ========== Storage ========== */ mapping (address => bool) public override hasAdminAccess; address public immutable override proxyManager; /* ========== Modifiers ========== */ modifier onlyAdminOrOwner { require( hasAdminAccess[msg.sender] || msg.sender == owner(), "ERR_NOT_ADMIN_OR_OWNER" ); _; } /* ========== Constructor ========== */ constructor(address proxyManager_) public Ownable() { proxyManager = proxyManager_; } /* ========== Admin Controls ========== */ /** * @dev Allows `deployer` to deploy many-to-one proxies. */ function approveDeployer(address deployer) external override onlyAdminOrOwner { IDelegateCallProxyManager(proxyManager).approveDeployer(deployer); } /** * @dev Creates a many-to-one proxy relationship. * * Deploys an implementation holder contract which stores the * implementation address for many proxies. The implementation * address can be updated on the holder to change the runtime * code used by all its proxies. * * @param implementationID ID for the implementation, used to identify the * proxies that use it. Also used as the salt in the create2 call when * deploying the implementation holder contract. * @param implementation Address with the runtime code the proxies * should use. */ function createManyToOneProxyRelationship( bytes32 implementationID, address implementation ) external override onlyAdminOrOwner { IDelegateCallProxyManager(proxyManager).createManyToOneProxyRelationship( implementationID, implementation ); } /* ========== Owner Controls ========== */ /** * @dev Grants admin access to `admin`. */ function grantAdminAccess(address admin) external override onlyOwner { hasAdminAccess[admin] = true; emit AdminAccessGranted(admin); } /** * @dev Revokes admin access from `admin`. */ function revokeAdminAccess(address admin) external override onlyOwner { hasAdminAccess[admin] = false; emit AdminAccessRevoked(admin); } /** * @dev Prevents `deployer` from deploying many-to-one proxies. */ function revokeDeployerApproval(address deployer) external override onlyOwner { IDelegateCallProxyManager(proxyManager).revokeDeployerApproval(deployer); } /** * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again. */ function lockImplementationManyToOne(bytes32 implementationID) external override onlyOwner { IDelegateCallProxyManager(proxyManager).lockImplementationManyToOne( implementationID ); } /** * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again. */ function lockImplementationOneToOne(address proxyAddress) external override onlyOwner { IDelegateCallProxyManager(proxyManager).lockImplementationOneToOne( proxyAddress ); } /** * @dev Updates the implementation address for a many-to-one * proxy relationship. * * @param implementationID Identifier for the implementation. * @param implementation Address with the runtime code the proxies * should use. */ function setImplementationAddressManyToOne( bytes32 implementationID, address implementation ) external override onlyOwner { IDelegateCallProxyManager(proxyManager).setImplementationAddressManyToOne( implementationID, implementation ); } /** * @dev Updates the implementation address for a one-to-one proxy. * * Note: This could work for many-to-one as well if the caller * provides the implementation holder address in place of the * proxy address, as they use the same access control and update * mechanism. * * @param proxyAddress Address of the deployed proxy * @param implementation Address with the runtime code for * the proxy to use. */ function setImplementationAddressOneToOne( address proxyAddress, address implementation ) external override onlyOwner { IDelegateCallProxyManager(proxyManager).setImplementationAddressOneToOne( proxyAddress, implementation ); } /** * @dev Transfers ownership of the proxy manager to a new account. */ function transferManagerOwnership(address newOwner) external override onlyOwner { Ownable(proxyManager).transferOwnership(newOwner); } /* ========== Proxy Deployment ========== */ /** * @dev Deploy a proxy contract with a one-to-one relationship * with its implementation. * * The proxy will have its own implementation address which can * be updated by the proxy manager. * * @param suppliedSalt Salt provided by the account requesting deployment. * @param implementation Address of the contract with the runtime * code that the proxy should use. */ function deployProxyOneToOne( bytes32 suppliedSalt, address implementation ) external override onlyAdminOrOwner returns(address) { return IDelegateCallProxyManager(proxyManager).deployProxyOneToOne( suppliedSalt, implementation ); } /** * @dev Deploy a proxy with a many-to-one relationship with its implemenation. * * The proxy will call the implementation holder for every transaction to * determine the address to use in calls. * * @param implementationID Identifier for the proxy's implementation. * @param suppliedSalt Salt provided by the account requesting deployment. */ function deployProxyManyToOne( bytes32 implementationID, bytes32 suppliedSalt ) external override onlyAdminOrOwner returns(address proxyAddress) { return IDelegateCallProxyManager(proxyManager).deployProxyManyToOne( implementationID, suppliedSalt ); } }
{ "metadata": { "useLiteralContent": false }, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"deployer","type":"address"}],"name":"DeploymentApprovalGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"deployer","type":"address"}],"name":"DeploymentApprovalRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"implementationID","type":"bytes32"},{"indexed":false,"internalType":"address","name":"implementationAddress","type":"address"}],"name":"ManyToOne_ImplementationCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"implementationID","type":"bytes32"}],"name":"ManyToOne_ImplementationLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"implementationID","type":"bytes32"},{"indexed":false,"internalType":"address","name":"implementationAddress","type":"address"}],"name":"ManyToOne_ImplementationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"implementationID","type":"bytes32"},{"indexed":false,"internalType":"address","name":"proxyAddress","type":"address"}],"name":"ManyToOne_ProxyDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"proxyAddress","type":"address"}],"name":"OneToOne_ImplementationLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"proxyAddress","type":"address"},{"indexed":false,"internalType":"address","name":"implementationAddress","type":"address"}],"name":"OneToOne_ImplementationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"proxyAddress","type":"address"},{"indexed":false,"internalType":"address","name":"implementationAddress","type":"address"}],"name":"OneToOne_ProxyDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"}],"name":"approveDeployer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"implementationID","type":"bytes32"}],"name":"computeHolderAddressManyToOne","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"originator","type":"address"},{"internalType":"bytes32","name":"implementationID","type":"bytes32"},{"internalType":"bytes32","name":"suppliedSalt","type":"bytes32"}],"name":"computeProxyAddressManyToOne","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"originator","type":"address"},{"internalType":"bytes32","name":"suppliedSalt","type":"bytes32"}],"name":"computeProxyAddressOneToOne","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"implementationID","type":"bytes32"},{"internalType":"address","name":"implementation","type":"address"}],"name":"createManyToOneProxyRelationship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"implementationID","type":"bytes32"},{"internalType":"bytes32","name":"suppliedSalt","type":"bytes32"}],"name":"deployProxyManyToOne","outputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"suppliedSalt","type":"bytes32"},{"internalType":"address","name":"implementation","type":"address"}],"name":"deployProxyOneToOne","outputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getImplementationHolder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"implementationID","type":"bytes32"}],"name":"getImplementationHolder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"}],"name":"isApprovedDeployer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"implementationID","type":"bytes32"}],"name":"isImplementationLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"isImplementationLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"implementationID","type":"bytes32"}],"name":"lockImplementationManyToOne","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"lockImplementationOneToOne","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"}],"name":"revokeDeployerApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"implementationID","type":"bytes32"},{"internalType":"address","name":"implementation","type":"address"}],"name":"setImplementationAddressManyToOne","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"},{"internalType":"address","name":"implementation","type":"address"}],"name":"setImplementationAddressOneToOne","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600061001b61006a565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35061006e565b3390565b61193c8061007d6000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80639225ce23116100ad578063db97034011610071578063db9703401461033c578063dc7faa0714610362578063dde5c32f14610388578063f2fde38b146103b4578063f9628542146103da5761012c565b80639225ce231461026f578063964c406114610295578063c3242d6b146102c1578063d07ad498146102ed578063d083bc861461031f5761012c565b80635e4ccacf116100f45780635e4ccacf146101ee5780636813a3c21461020b5780636daf503514610239578063715018a61461025f5780638da5cb5b146102675761012c565b80631a5e5bc5146101315780631da0505d146101705780632275a830146101785780634f85f3ea146101975780635b54cf96146101c8575b600080fd5b6101546004803603604081101561014757600080fd5b5080359060200135610406565b604080516001600160a01b039092168252519081900360200190f35b6101546105ba565b6101956004803603602081101561018e57600080fd5b50356105c9565b005b6101b4600480360360208110156101ad57600080fd5b50356106df565b604080519115158252519081900360200190f35b610195600480360360208110156101de57600080fd5b50356001600160a01b0316610762565b6101546004803603602081101561020457600080fd5b5035610816565b6101956004803603604081101561022157600080fd5b506001600160a01b0381358116916020013516610848565b6101956004803603602081101561024f57600080fd5b50356001600160a01b031661095d565b610195610a10565b610154610ab2565b6101b46004803603602081101561028557600080fd5b50356001600160a01b0316610ac1565b610195600480360360408110156102ab57600080fd5b50803590602001356001600160a01b0316610adf565b610195600480360360408110156102d757600080fd5b50803590602001356001600160a01b0316610bca565b6101546004803603606081101561030357600080fd5b506001600160a01b038135169060208101359060400135610d40565b6101546004803603602081101561033557600080fd5b5035610d83565b6101956004803603602081101561035257600080fd5b50356001600160a01b0316610d9e565b6101b46004803603602081101561037857600080fd5b50356001600160a01b0316610e4e565b6101546004803603604081101561039e57600080fd5b506001600160a01b038135169060200135610e6c565b610195600480360360208110156103ca57600080fd5b50356001600160a01b0316610ead565b610154600480360360408110156103f057600080fd5b50803590602001356001600160a01b0316610fa5565b600080610411611082565b6001600160a01b03811660009081526001602052604090205490915060ff1680610453575061043e610ab2565b6001600160a01b0316816001600160a01b0316145b610497576040805162461bcd60e51b815260206004820152601060248201526f11549497d393d517d054141493d5915160821b604482015290519081900360640190fd5b6000848152600260205260409020546001600160a01b0316806104f9576040805162461bcd60e51b815260206004820152601560248201527411549497d2535413115351539510551253d397d251605a1b604482015290519081900360640190fd5b600061050d610506611082565b8787611086565b600480546001600160a01b0319166001600160a01b03851617905560405190915061055b9060009083906105436020820161140a565b601f1982820381018352601f909101166040526110d3565b600480546001600160a01b0319169055604080518881526001600160a01b038316602082015281519296507f7b2f1f9260fa3ce14c2f36f34469f302e66164e3da9dbff6b24c723bcd39d115929081900390910190a150505092915050565b6004546001600160a01b031690565b6105d1611082565b6000546001600160a01b03908116911614610621576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b6000818152600260205260409020546001600160a01b031680610683576040805162461bcd60e51b815260206004820152601560248201527411549497d2535413115351539510551253d397d251605a1b604482015290519081900360640190fd5b6001600160a01b038116600090815260036020908152604091829020805460ff19166001179055815184815291517fd62bff6e969424de31ee669b9853f7f90fc209ef41f5721bf62c502e7b2a3d089281900390910190a15050565b6000818152600260205260408120546001600160a01b031680610741576040805162461bcd60e51b815260206004820152601560248201527411549497d2535413115351539510551253d397d251605a1b604482015290519081900360640190fd5b6001600160a01b031660009081526003602052604090205460ff1692915050565b61076a611082565b6000546001600160a01b039081169116146107ba576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260016020818152604092839020805460ff1916909217909155815192835290517fa8320d9911124be4bd8a47fe086523f921e913be4659887a823d16c1a7c567b39281900390910190a150565b6000610842827f11c370493a726a0ffa93d42b399ad046f1b5a543b6e72f1a64f1488dc1c58f2c6111e4565b92915050565b610850611082565b6000546001600160a01b039081169116146108a0576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b6001600160a01b03821660009081526003602052604090205460ff161561090a576040805162461bcd60e51b815260206004820152601960248201527811549497d2535413115351539510551253d397d313d0d2d151603a1b604482015290519081900360640190fd5b61091482826111f8565b604080516001600160a01b0380851682528316602082015281517f52f99278569fbf4dd0ee15eb946bc8d758d614d1917ff0faf9b326dd4aada643929181900390910190a15050565b610965611082565b6000546001600160a01b039081169116146109b5576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260036020908152604091829020805460ff19166001179055815192835290517ff51e53e36caf2e8338b84c69c3919eb728c75e5961f866d09697d8cdce7432df9281900390910190a150565b610a18611082565b6000546001600160a01b03908116911614610a68576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6001600160a01b031660009081526003602052604090205460ff1690565b610ae7611082565b6000546001600160a01b03908116911614610b37576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b6000610b4f6000846040518060200161054390611417565b600084815260026020526040902080546001600160a01b0319166001600160a01b0383161790559050610b8281836111f8565b604080518481526001600160a01b038416602082015281517f06e1ff8de03513a819420b2e2f57764e89938cd88b8769998326edf2703c2338929181900390910190a1505050565b610bd2611082565b6000546001600160a01b03908116911614610c22576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b6000828152600260205260409020546001600160a01b031680610c84576040805162461bcd60e51b815260206004820152601560248201527411549497d2535413115351539510551253d397d251605a1b604482015290519081900360640190fd5b6001600160a01b03811660009081526003602052604090205460ff1615610cee576040805162461bcd60e51b815260206004820152601960248201527811549497d2535413115351539510551253d397d313d0d2d151603a1b604482015290519081900360640190fd5b610cf881836111f8565b604080518481526001600160a01b038416602082015281517f43440a819e0e769fd70fc34ea1c8462915e7170e4396fb7595b450a09d0cdf38929181900390910190a1505050565b600080610d4e858585611086565b9050610d7a817fa035ad05a1663db5bfd455b99cd7c6ac6bd49269738458eda140e0b78ed53f796111e4565b95945050505050565b6000908152600260205260409020546001600160a01b031690565b610da6611082565b6000546001600160a01b03908116911614610df6576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260016020908152604091829020805460ff19169055815192835290517ff0f9ad55989ce899961b5c41524ba369cda0a1fcd9301dd0c868430e69c41b759281900390910190a150565b6001600160a01b031660009081526001602052604090205460ff1690565b600080610e798484611364565b9050610ea5817f63d9f7b5931b69188c8f6b806606f25892f1bb17b7f7e966fe3a32c04493aee46111e4565b949350505050565b610eb5611082565b6000546001600160a01b03908116911614610f05576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b6001600160a01b038116610f4a5760405162461bcd60e51b81526004018080602001828103825260268152602001806118c16026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000610faf611082565b6000546001600160a01b03908116911614610fff576040805162461bcd60e51b815260206004820181905260248201526000805160206118e7833981519152604482015290519081900360640190fd5b600061101261100c611082565b85611364565b905061102a6000826040518060200161054390611423565b915061103682846111f8565b604080516001600160a01b0380851682528516602082015281517f66708f841fd2ea7b5488d47d39951f9f79cb1033a9c5e0d1e98f76cdb8ba1e88929181900390910190a15092915050565b3390565b6040805160609490941b6bffffffffffffffffffffffff19166020808601919091526034850193909352605480850192909252805180850390920182526074909301909252815191012090565b6000808447101561112b576040805162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b825161117e576040805162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f604482015290519081900360640190fd5b8383516020850187f590506001600160a01b038116610ea5576040805162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f7900000000000000604482015290519081900360640190fd5b60006111f18383306113a9565b9392505050565b61120181611404565b611245576040805162461bcd60e51b815260206004820152601060248201526f11549497d393d517d0d3d395149050d560821b604482015290519081900360640190fd5b6000826001600160a01b03168260405160200180826001600160a01b031681526020019150506040516020818303038152906040526040518082805190602001908083835b602083106112a95780518252601f19909201916020918201910161128a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461130b576040519150601f19603f3d011682016040523d82523d6000602084013e611310565b606091505b505090508061135f576040805162461bcd60e51b815260206004820152601660248201527511549497d4d15517d05111149154d4d7d4915591549560521b604482015290519081900360640190fd5b505050565b6000828260405160200180836001600160a01b031660601b81526014018281526020019250505060405160208183030381529060405280519060200120905092915050565b604080516001600160f81b031960208083019190915260609390931b6bffffffffffffffffffffffff191660218201526035810194909452605580850193909352805180850390930183526075909301909252805191012090565b3b151590565b6102b18061143183390190565b60aa806116e283390190565b6101358061178c8339019056fe60a060405234801561001057600080fd5b50336001600160a01b0316631da0505d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561004a57600080fd5b505afa15801561005e573d6000803e3d6000fd5b505050506040513d602081101561007457600080fd5b5051606081901b6001600160601b0319166080526001600160a01b031661020a6100a7600039806046525061020a6000f3fe60806040523661001357610011610017565b005b6100115b61001f61002f565b61002f61002a610031565b6101b0565b565b60405160009081906060906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169083818181855afa9150503d806000811461009d576040519150601f19603f3d011682016040523d82523d6000602084013e6100a2565b606091505b50915091508181906101325760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156100f75781810151838201526020016100df565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600081806020019051602081101561014a57600080fd5b505190506001600160a01b0381166101a9576040805162461bcd60e51b815260206004820152601760248201527f4552525f4e554c4c5f494d504c454d454e544154494f4e000000000000000000604482015290519081900360640190fd5b9250505090565b3660008037600080366000845af43d6000803e8080156101cf573d6000f35b3d6000fdfea26469706673582212209b0f8ebe5564b0d1fb938189635d5a7b33088937e2d48e4ff88b4fcf7c850bb164736f6c634300060c003360a0604052348015600f57600080fd5b5033606081901b608052607d61002d60003980600f5250607d6000f3fe6080604052336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614603f5760005460005260206000f35b60003560005500fea2646970667358221220586d996f67b2b77c909aa0c1fe104107601628c9f7a86cb3c741767b2633202c64736f6c634300060c003360a060405234801561001057600080fd5b5033606081901b60805261010561003060003980603252506101056000f3fe608060405236601057600e6013565b005b600e5b60196027565b602560216087565b60ac565b565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614606057605c6025565b6025565b6000357f913bd12b32b36f36cedaeb6e043912bceb97022755958701789d3108d33a045a55005b7f913bd12b32b36f36cedaeb6e043912bceb97022755958701789d3108d33a045a5490565b3660008037600080366000845af43d6000803e80801560ca573d6000f35b3d6000fdfea26469706673582212201cea50d0a8321e43144e2aa3de79459912e55e2454e4d0ef3a6d4b12f177e0a964736f6c634300060c00334f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220fea140dfc789e92092f05b36a8022b40fefd4d25bf63dae7f19cb3a545f054bb64736f6c634300060c0033
Deployed ByteCode Sourcemap
2236:14093:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10354:1261;;;;;;;;;;;;;;;;-1:-1:-1;10354:1261:6;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;10354:1261:6;;;;;;;;;;;;;;12968:133;;;:::i;6206:469::-;;;;;;;;;;;;;;;;-1:-1:-1;6206:469:6;;:::i;:::-;;11744:417;;;;;;;;;;;;;;;;-1:-1:-1;11744:417:6;;:::i;:::-;;;;;;;;;;;;;;;;;;4303:163;;;;;;;;;;;;;;;;-1:-1:-1;4303:163:6;-1:-1:-1;;;;;4303:163:6;;:::i;14954:241::-;;;;;;;;;;;;;;;;-1:-1:-1;14954:241:6;;:::i;8430:427::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;8430:427:6;;;;;;;;;;:::i;6792:194::-;;;;;;;;;;;;;;;;-1:-1:-1;6792:194:6;-1:-1:-1;;;;;6792:194:6;;:::i;1689:145:1:-;;;:::i;1066:77::-;;;:::i;12247:146:6:-;;;;;;;;;;;;;;;;-1:-1:-1;12247:146:6;-1:-1:-1;;;;;12247:146:6;;:::i;5369:716::-;;;;;;;;;;;;;;;;-1:-1:-1;5369:716:6;;;;;;-1:-1:-1;;;;;5369:716:6;;:::i;7245:739::-;;;;;;;;;;;;;;;;-1:-1:-1;7245:739:6;;;;;;-1:-1:-1;;;;;7245:739:6;;:::i;14385:375::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;14385:375:6;;;;;;;;;;;;;:::i;13214:184::-;;;;;;;;;;;;;;;;-1:-1:-1;13214:184:6;;:::i;4548:171::-;;;;;;;;;;;;;;;;-1:-1:-1;4548:171:6;-1:-1:-1;;;;;4548:171:6;;:::i;12511:130::-;;;;;;;;;;;;;;;;-1:-1:-1;12511:130:6;-1:-1:-1;;;;;12511:130:6;;:::i;13680:299::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;13680:299:6;;;;;;;;:::i;1983:240:1:-;;;;;;;;;;;;;;;;-1:-1:-1;1983:240:1;-1:-1:-1;;;;;1983:240:1;;:::i;9312:666:6:-;;;;;;;;;;;;;;;;-1:-1:-1;9312:666:6;;;;;;-1:-1:-1;;;;;9312:666:6;;:::i;10354:1261::-;10495:20;3979:14;3996:12;:10;:12::i;:::-;-1:-1:-1;;;;;4022:26:6;;;;;;:18;:26;;;;;;3979:29;;-1:-1:-1;4022:26:6;;;:47;;;4062:7;:5;:7::i;:::-;-1:-1:-1;;;;;4052:17:6;:6;-1:-1:-1;;;;;4052:17:6;;4022:47;4014:76;;;;;-1:-1:-1;;;4014:76:6;;;;;;;;;;;;-1:-1:-1;;;4014:76:6;;;;;;;;;;;;;;;10585:28:::1;10616:40:::0;;;:22:::1;:40;::::0;;;;;-1:-1:-1;;;;;10616:40:6::1;10717:34:::0;10709:68:::1;;;::::0;;-1:-1:-1;;;10709:68:6;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;10709:68:6;;;;;;;;;;;;;::::1;;10918:12;10933:95;10966:12;:10;:12::i;:::-;10986:16;11010:12;10933:25;:95::i;:::-;11137:21;:44:::0;;-1:-1:-1;;;;;;11137:44:6::1;-1:-1:-1::0;;;;;11137:44:6;::::1;;::::0;;11383:45:::1;::::0;10918:110;;-1:-1:-1;11340:94:6::1;::::0;-1:-1:-1;;10918:110:6;;11383:45:::1;;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;11383:45:6;;;;;;;::::1;::::0;;::::1;;;::::0;11340:14:::1;:94::i;:::-;11491:21;:34:::0;;-1:-1:-1;;;;;;11491:34:6::1;::::0;;11537:73:::1;::::0;;;;;-1:-1:-1;;;;;11537:73:6;::::1;;::::0;::::1;::::0;;;11325:109;;-1:-1:-1;11537:73:6::1;::::0;;;;;;;;;::::1;4096:1;;10354:1261:::0;;;;;:::o;12968:133::-;13075:21;;-1:-1:-1;;;;;13075:21:6;12968:133;:::o;6206:469::-;1280:12:1;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;6363:28:6::1;6394:40:::0;;;:22:::1;:40;::::0;;;;;-1:-1:-1;;;;;6394:40:6::1;6494:34:::0;6486:68:::1;;;::::0;;-1:-1:-1;;;6486:68:6;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;6486:68:6;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;6560:44:6;::::1;;::::0;;;:22:::1;:44;::::0;;;;;;;;:51;;-1:-1:-1;;6560:51:6::1;6607:4;6560:51;::::0;;6622:48;;;;;;;::::1;::::0;;;;;;;;::::1;1339:1:1;6206:469:6::0;:::o;11744:417::-;11834:4;11937:40;;;:22;:40;;;;;;-1:-1:-1;;;;;11937:40:6;12038:34;12030:68;;;;;-1:-1:-1;;;12030:68:6;;;;;;;;;;;;-1:-1:-1;;;12030:68:6;;;;;;;;;;;;;;;-1:-1:-1;;;;;12112:44:6;;;;;:22;:44;;;;;;;;;11744:417;-1:-1:-1;;11744:417:6:o;4303:163::-;1280:12:1;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;-1:-1:-1;;;;;4380:28:6;::::1;;::::0;;;4411:4:::1;4380:28;::::0;;;;;;;;:35;;-1:-1:-1;;4380:35:6::1;::::0;;::::1;::::0;;;4426;;;;;;;::::1;::::0;;;;;;;;::::1;4303:163:::0;:::o;14954:241::-;15065:7;15089:101;15119:16;592:66:5;15089:22:6;:101::i;:::-;15082:108;14954:241;-1:-1:-1;;14954:241:6:o;8430:427::-;1280:12:1;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;-1:-1:-1;;;;;8621:36:6;::::1;;::::0;;;:22:::1;:36;::::0;;;;;::::1;;8620:37;8612:75;;;::::0;;-1:-1:-1;;;8612:75:6;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;8612:75:6;;;;;;;;;;;;;::::1;;8732:48;8751:12;8765:14;8732:18;:48::i;:::-;8792:60;::::0;;-1:-1:-1;;;;;8792:60:6;;::::1;::::0;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;;;;;;::::1;8430:427:::0;;:::o;6792:194::-;1280:12:1;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;-1:-1:-1;;;;;6884:36:6;::::1;;::::0;;;:22:::1;:36;::::0;;;;;;;;:43;;-1:-1:-1;;6884:43:6::1;6923:4;6884:43;::::0;;6938;;;;;;;::::1;::::0;;;;;;;;::::1;6792:194:::0;:::o;1689:145:1:-;1280:12;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;1795:1:::1;1779:6:::0;;1758:40:::1;::::0;-1:-1:-1;;;;;1779:6:1;;::::1;::::0;1758:40:::1;::::0;1795:1;;1758:40:::1;1825:1;1808:19:::0;;-1:-1:-1;;;;;;1808:19:1::1;::::0;;1689:145::o;1066:77::-;1104:7;1130:6;-1:-1:-1;;;;;1130:6:1;1066:77;:::o;12247:146:6:-;-1:-1:-1;;;;;12352:36:6;12333:4;12352:36;;;:22;:36;;;;;;;;;12247:146::o;5369:716::-;1280:12:1;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;5625:28:6::1;5656:109;5678:1;5687:16;5711:48;;;;;;;;:::i;5656:109::-;5819:40;::::0;;;:22:::1;:40;::::0;;;;:63;;-1:-1:-1;;;;;;5819:63:6::1;-1:-1:-1::0;;;;;5819:63:6;::::1;;::::0;;;-1:-1:-1;5929:56:6::1;5819:63:::0;5970:14;5929:18:::1;:56::i;:::-;5997:83;::::0;;;;;-1:-1:-1;;;;;5997:83:6;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;;;;;;::::1;1339:1:1;5369:716:6::0;;:::o;7245:739::-;1280:12:1;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;7458:28:6::1;7489:40:::0;;;:22:::1;:40;::::0;;;;;-1:-1:-1;;;;;7489:40:6::1;7590:34:::0;7582:68:::1;;;::::0;;-1:-1:-1;;;7582:68:6;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;7582:68:6;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;7709:44:6;::::1;;::::0;;;:22:::1;:44;::::0;;;;;::::1;;7708:45;7700:83;;;::::0;;-1:-1:-1;;;7700:83:6;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;7700:83:6;;;;;;;;;;;;;::::1;;7828:56;7847:20;7869:14;7828:18;:56::i;:::-;7896:83;::::0;;;;;-1:-1:-1;;;;;7896:83:6;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;;;;;;::::1;1339:1:1;7245:739:6::0;;:::o;14385:375::-;14555:7;14573:12;14588:93;14621:10;14639:16;14663:12;14588:25;:93::i;:::-;14573:108;-1:-1:-1;14694:61:6;14573:108;463:66:5;14694:22:6;:61::i;:::-;14687:68;14385:375;-1:-1:-1;;;;;14385:375:6:o;13214:184::-;13329:7;13353:40;;;:22;:40;;;;;;-1:-1:-1;;;;;13353:40:6;;13214:184::o;4548:171::-;1280:12:1;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;-1:-1:-1;;;;;4632:28:6;::::1;4663:5;4632:28:::0;;;:18:::1;:28;::::0;;;;;;;;:36;;-1:-1:-1;;4632:36:6::1;::::0;;4679:35;;;;;;;::::1;::::0;;;;;;;;::::1;4548:171:::0;:::o;12511:130::-;-1:-1:-1;;;;;12608:28:6;12589:4;12608:28;;;:18;:28;;;;;;;;;12511:130::o;13680:299::-;13819:7;13836:12;13851:50;13876:10;13888:12;13851:24;:50::i;:::-;13836:65;-1:-1:-1;13914:60:6;13836:65;344:66:5;13914:22:6;:60::i;:::-;13907:67;13680:299;-1:-1:-1;;;;13680:299:6:o;1983:240:1:-;1280:12;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;-1:-1:-1;;;;;2071:22:1;::::1;2063:73;;;;-1:-1:-1::0;;;2063:73:1::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2172:6;::::0;;2151:38:::1;::::0;-1:-1:-1;;;;;2151:38:1;;::::1;::::0;2172:6;::::1;::::0;2151:38:::1;::::0;::::1;2199:6;:17:::0;;-1:-1:-1;;;;;;2199:17:1::1;-1:-1:-1::0;;;;;2199:17:1;;;::::1;::::0;;;::::1;::::0;;1983:240::o;9312:666:6:-;9451:20;1280:12:1;:10;:12::i;:::-;1270:6;;-1:-1:-1;;;;;1270:6:1;;;:22;;;1262:67;;;;;-1:-1:-1;;;1262:67:1;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1262:67:1;;;;;;;;;;;;;;;9592:12:6::1;9607:52;9632:12;:10;:12::i;:::-;9646;9607:24;:52::i;:::-;9592:67;;9705:93;9727:1;9736:4;9748:44;;;;;;;;:::i;9705:93::-;9690:108;;9861:48;9880:12;9894:14;9861:18;:48::i;:::-;9921:52;::::0;;-1:-1:-1;;;;;9921:52:6;;::::1;::::0;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;;;;;;::::1;1339:1:1;9312:666:6::0;;;;:::o;590:104:0:-;677:10;590:104;:::o;1332:292:11:-;1521:92;;;;;;;;-1:-1:-1;;1521:92:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1504:115;;;;;;1332:292::o;1013:535:4:-;1100:7;1119:12;1174:6;1149:21;:31;;1141:73;;;;;-1:-1:-1;;;1141:73:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;1232:15;;1224:65;;;;;-1:-1:-1;;;1224:65:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1440:4;1429:8;1423:15;1416:4;1406:8;1402:19;1394:6;1386:59;1378:67;-1:-1:-1;;;;;;1472:18:4;;1464:56;;;;;-1:-1:-1;;;1464:56:4;;;;;;;;;;;;;;;;;;;;;;;;;;;1752:165;1835:7;1861:49;1876:4;1882:12;1904:4;1861:14;:49::i;:::-;1854:56;1752:165;-1:-1:-1;;;1752:165:4:o;15862:465:6:-;16033:34;16052:14;16033:18;:34::i;:::-;16025:63;;;;;-1:-1:-1;;;16025:63:6;;;;;;;;;;;;-1:-1:-1;;;16025:63:6;;;;;;;;;;;;;;;16211:12;16228:13;-1:-1:-1;;;;;16228:18:6;16258:14;16247:26;;;;;;-1:-1:-1;;;;;16247:26:6;;;;;;;;;;;;;;;;;;;;16228:46;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;16228:46:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16210:64;;;16288:7;16280:42;;;;;-1:-1:-1;;;16280:42:6;;;;;;;;;;;;-1:-1:-1;;;16280:42:6;;;;;;;;;;;;;;;15862:465;;;:::o;1850:199:11:-;1967:7;2018:10;2030:12;2001:42;;;;;;-1:-1:-1;;;;;2001:42:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;1991:53;;;;;;1984:60;;1850:199;;;;:::o;2160:276:4:-;2319:60;;;-1:-1:-1;;;;;;2319:60:4;;;;;;;;;;;;;-1:-1:-1;;2319:60:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2296:93;;;;;;2160:276::o;718:413:3:-;1078:20;1116:8;;;718:413::o;-1:-1:-1:-;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;:::o
Swarm Source
ipfs://fea140dfc789e92092f05b36a8022b40fefd4d25bf63dae7f19cb3a545f054bb
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.