Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
16485595 | 728 days ago | Contract Creation | 0 ETH |
Loading...
Loading
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:
EnsoWalletFactory
Compiler Version
v0.8.16+commit.07a7930e
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.16; import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import "./libraries/BeaconClones.sol"; import "./access/Ownable.sol"; import "./interfaces/IEnsoWallet.sol"; contract EnsoWalletFactory is Ownable, UUPSUpgradeable { using StorageAPI for bytes32; using BeaconClones for address; address public immutable ensoBeacon; event Deployed(IEnsoWallet instance, string label, address deployer); error AlreadyInit(); error NoLabel(); constructor(address ensoBeacon_) { ensoBeacon = ensoBeacon_; // Set owner to 0xff so that the implementation cannot be initialized OWNER.setAddress(address(type(uint160).max)); } // @notice A function to initialize state on the proxy the delegates to this contract // @param newOwner The new owner of this contract function initialize(address newOwner) external { if (newOwner == address(0)) revert InvalidAccount(); if (OWNER.getAddress() != address(0)) revert AlreadyInit(); OWNER.setAddress(newOwner); } // @notice Deploy a wallet using the msg.sender as the salt // @param shortcutId The bytes32 value representing a shortcut // @param commands The optional commands for executing a shortcut after deployment // @param state The optional state for executing a shortcut after deployment function deploy( bytes32 shortcutId, bytes32[] calldata commands, bytes[] calldata state ) public payable returns (IEnsoWallet) { bytes32 salt = bytes32(uint256(uint160(msg.sender))); return _deploy(salt, "", shortcutId, commands, state); } // @notice Deploy a wallet using a hash of the msg.sender and a label as the salt // @param label The label to identify deployment // @param shortcutId The bytes32 value representing a shortcut // @param commands The optional commands for executing a shortcut after deployment // @param state The optional state for executing a shortcut after deployment function deployCustom( string memory label, bytes32 shortcutId, bytes32[] calldata commands, bytes[] calldata state ) public payable returns (IEnsoWallet) { if (bytes(label).length == 0) revert NoLabel(); bytes32 salt = _customSalt(msg.sender, label); return _deploy(salt, label, shortcutId, commands, state); } // @notice Get the deployment address for the msg.sender function getAddress() public view returns (address payable) { return getUserAddress(msg.sender); } // @notice Get the deployment address for the user // @param user The address of the user that is used to determine the deployment address function getUserAddress(address user) public view returns (address payable) { bytes32 salt = bytes32(uint256(uint160(user))); return _predictDeterministicAddress(salt); } // @notice Get the deployment address for a user and label // @param user The address of the user that is used to determine the deployment address // @param label The label that is used to determine the deployment address function getCustomAddress(address user, string memory label) external view returns (address payable) { if (bytes(label).length == 0) revert NoLabel(); bytes32 salt = _customSalt(user, label); return _predictDeterministicAddress(salt); } // @notice The internal function for deploying a new wallet // @param salt The salt for deploy the address deterministically // @param label The label to identify deployment in the emitted event // @param shortcutId The bytes32 value representing a shortcut // @param commands The optional commands for executing a shortcut after deployment // @param state The optional state for executing a shortcut after deployment function _deploy( bytes32 salt, string memory label, bytes32 shortcutId, bytes32[] calldata commands, bytes[] calldata state ) internal returns (IEnsoWallet instance) { instance = IEnsoWallet(payable(ensoBeacon.cloneDeterministic(salt))); instance.initialize{value: msg.value}(msg.sender, salt, shortcutId, commands, state); emit Deployed(instance, label, msg.sender); } // @notice Internal function to generate a custom salt using a user address and label // @param user The address of the user // @param label The label to identify the deployment function _customSalt(address user, string memory label) internal pure returns (bytes32) { return keccak256(abi.encode(user, label)); } // @notice Internal function to derive the deployment address from a salt // @param salt The bytes32 salt to generate the deployment address function _predictDeterministicAddress(bytes32 salt) internal view returns (address payable) { return payable(ensoBeacon.predictDeterministicAddress(salt, address(this))); } // @notice Internal function to support UUPS upgrades of the implementing proxy // @notice newImplementation Address of the new implementation function _authorizeUpgrade(address newImplementation) internal view override { (newImplementation); if (msg.sender != OWNER.getAddress()) revert NotOwner(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967Upgrade { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822.sol"; import "../ERC1967/ERC1967Upgrade.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade { /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library 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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.16; import "../libraries/StorageAPI.sol"; // @notice The OWNER slot must be set in the importing contract's constructor or initialize function abstract contract Ownable { using StorageAPI for bytes32; // Using same slot generation technique as eip-1967 -- https://eips.ethereum.org/EIPS/eip-1967 bytes32 internal constant OWNER = bytes32(uint256(keccak256("enso.access.owner")) - 1); bytes32 internal constant PENDING_OWNER = bytes32(uint256(keccak256("enso.access.pendingOwner")) - 1); event OwnershipTransferred(address previousOwner, address newOwner); event OwnershipTransferStarted(address previousOwner, address newOwner); error NotOwner(); error NotPermitted(); error InvalidAccount(); modifier onlyOwner() { if (msg.sender != OWNER.getAddress()) revert NotOwner(); _; } // @notice Transfer ownership of this contract, ownership is only transferred after new owner accepts // @param newOwner The address of the new owner function transferOwnership(address newOwner) external onlyOwner { if (newOwner == address(0)) revert InvalidAccount(); address currentOwner = OWNER.getAddress(); if (newOwner == currentOwner) revert InvalidAccount(); PENDING_OWNER.setAddress(newOwner); emit OwnershipTransferStarted(currentOwner, newOwner); } // @notice Accept ownership of this contract function acceptOwnership() external { if (msg.sender != PENDING_OWNER.getAddress()) revert NotPermitted(); PENDING_OWNER.setAddress(address(0)); address previousOwner = OWNER.getAddress(); OWNER.setAddress(msg.sender); emit OwnershipTransferred(previousOwner, msg.sender); } // @notice The current owner of this contract // @return The address of the current owner function owner() external view returns (address) { return OWNER.getAddress(); } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.16; interface IEnsoWallet { function initialize( address owner, bytes32 salt, bytes32 shortcutId, bytes32[] calldata commands, bytes[] calldata state ) external payable; }
// SPDX-License-Identifier: GPL-3.0-only // OpenZeppelin Contracts v4.4.1 (proxy/Clones.sol) // Modified from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Clones.sol pragma solidity ^0.8.16; library BeaconClones { /** * @dev Deploys and returns the address of a clone that gets an implementation * from the `beacon` and mimics its behaviour. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `beacon` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address beacon, bytes32 salt) internal returns (address instance) { assembly { let ptr := mload(0x40) mstore(ptr, 0x6080604052348015600f57600080fd5b5060a88061001e6000396000f3fe6080) mstore(add(ptr, 0x20), 0x6040526040517f5c60da1b000000000000000000000000000000000000000000) mstore(add(ptr, 0x40), 0x0000000000000081526000600160208260048573000000000000000000000000) mstore(add(ptr, 0x54), shl(0x60, beacon)) mstore(add(ptr, 0x68), 0x5afa0360705780513682833781823684845af490503d82833e808015606c573d) mstore(add(ptr, 0x88), 0x83f35b3d83fd5b00fea264697066735822122002f8a2f5acabeb1d754972351e) mstore(add(ptr, 0xa8), 0xc784958a7f99e64f368c267a38bb375594c03c64736f6c634300081000330000) instance := create2(0, ptr, 0xc6, salt) } require(instance != address(0), "create2 failed"); } /** * @dev Computes the address of a clone deployed using {cloneDeterministic}. */ function predictDeterministicAddress( address beacon, bytes32 salt, address deployer ) internal pure returns (address predicted) { assembly { let ptr := mload(0x40) mstore(ptr, 0x6080604052348015600f57600080fd5b5060a88061001e6000396000f3fe6080) mstore(add(ptr, 0x20), 0x6040526040517f5c60da1b000000000000000000000000000000000000000000) mstore(add(ptr, 0x40), 0x0000000000000081526000600160208260048573000000000000000000000000) mstore(add(ptr, 0x54), shl(0x60, beacon)) mstore(add(ptr, 0x68), 0x5afa0360705780513682833781823684845af490503d82833e808015606c573d) mstore(add(ptr, 0x88), 0x83f35b3d83fd5b00fea264697066735822122002f8a2f5acabeb1d754972351e) mstore(add(ptr, 0xa8), 0xc784958a7f99e64f368c267a38bb375594c03c64736f6c63430008100033ff00) mstore(add(ptr, 0xc7), shl(0x60, deployer)) mstore(add(ptr, 0xdb), salt) mstore(add(ptr, 0xfb), keccak256(ptr, 0xc6)) predicted := keccak256(add(ptr, 0xc6), 0x55) } } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.16; library StorageAPI { function setBytes(bytes32 key, bytes memory data) internal { bytes32 slot = keccak256(abi.encodePacked(key)); assembly { let length := mload(data) switch gt(length, 0x1F) case 0x00 { sstore(key, or(mload(add(data, 0x20)), mul(length, 2))) } case 0x01 { sstore(key, add(mul(length, 2), 1)) for { let i := 0 } lt(mul(i, 0x20), length) { i := add(i, 0x01) } { sstore(add(slot, i), mload(add(data, mul(add(i, 1), 0x20)))) } } } } function setBytes32(bytes32 key, bytes32 val) internal { assembly { sstore(key, val) } } function setAddress(bytes32 key, address a) internal { assembly { sstore(key, a) } } function setUint256(bytes32 key, uint256 val) internal { assembly { sstore(key, val) } } function setInt256(bytes32 key, int256 val) internal { assembly { sstore(key, val) } } function setBool(bytes32 key, bool val) internal { assembly { sstore(key, val) } } function getBytes(bytes32 key) internal view returns (bytes memory data) { bytes32 slot = keccak256(abi.encodePacked(key)); assembly { let length := sload(key) switch and(length, 0x01) case 0x00 { let decodedLength := div(and(length, 0xFF), 2) mstore(data, decodedLength) mstore(add(data, 0x20), and(length, not(0xFF))) mstore(0x40, add(data, 0x40)) } case 0x01 { let decodedLength := div(length, 2) let i := 0 mstore(data, decodedLength) for { } lt(mul(i, 0x20), decodedLength) { i := add(i, 0x01) } { mstore(add(add(data, 0x20), mul(i, 0x20)), sload(add(slot, i))) } mstore(0x40, add(data, add(0x20, mul(i, 0x20)))) } } } function getBytes32(bytes32 key) internal view returns (bytes32 val) { assembly { val := sload(key) } } function getAddress(bytes32 key) internal view returns (address a) { assembly { a := sload(key) } } function getUint256(bytes32 key) internal view returns (uint256 val) { assembly { val := sload(key) } } function getInt256(bytes32 key) internal view returns (int256 val) { assembly { val := sload(key) } } function getBool(bytes32 key) internal view returns (bool val) { assembly { val := sload(key) } } }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 100000000 }, "remappings": [], "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"ensoBeacon_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInit","type":"error"},{"inputs":[],"name":"InvalidAccount","type":"error"},{"inputs":[],"name":"NoLabel","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotPermitted","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IEnsoWallet","name":"instance","type":"address"},{"indexed":false,"internalType":"string","name":"label","type":"string"},{"indexed":false,"internalType":"address","name":"deployer","type":"address"}],"name":"Deployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"shortcutId","type":"bytes32"},{"internalType":"bytes32[]","name":"commands","type":"bytes32[]"},{"internalType":"bytes[]","name":"state","type":"bytes[]"}],"name":"deploy","outputs":[{"internalType":"contract IEnsoWallet","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"bytes32","name":"shortcutId","type":"bytes32"},{"internalType":"bytes32[]","name":"commands","type":"bytes32[]"},{"internalType":"bytes[]","name":"state","type":"bytes[]"}],"name":"deployCustom","outputs":[{"internalType":"contract IEnsoWallet","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"ensoBeacon","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"string","name":"label","type":"string"}],"name":"getCustomAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60c0346100b757601f611c1038819003918201601f19168301916001600160401b038311848410176100bc578084926020946040528339810103126100b757516001600160a01b039081811681036100b7573060805260a0527febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d055604051611b3d90816100d382396080518181816104250152818161069e0152610743015260a051818181610599015281816117a20152611a3d0152f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe60806040526004361015610013575b600080fd5b60003560e01c80631289ad05146101175780633659cfe61461010e57806338cc48311461010557806349061ae6146100fc5780634d6849d2146100f35780634f1ef286146100ea57806352d1902d146100e157806379ba5097146100d85780638454525b146100cf5780638da5cb5b146100c6578063c4d66de8146100bd578063f2fde38b146100b45763ffa2ca3b146100ac57600080fd5b61000e610be8565b5061000e610ae9565b5061000e610a14565b5061000e6109a2565b5061000e61092f565b5061000e610818565b5061000e6106fc565b5061000e61061f565b5061000e6105bd565b5061000e61054d565b5061000e6104f4565b5061000e6103d2565b5061000e6102b9565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b67ffffffffffffffff811161016457604052565b61016c610120565b604052565b6020810190811067ffffffffffffffff82111761016457604052565b6060810190811067ffffffffffffffff82111761016457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761016457604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610226575b01160190565b61022e610120565b610220565b92919261023f826101ea565b9161024d60405193846101a9565b82948184528183011161000e578281602093846000960137010152565b9080601f8301121561000e5781602061028593359101610233565b90565b9181601f8401121561000e5782359167ffffffffffffffff831161000e576020808501948460051b01011161000e57565b5060807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5767ffffffffffffffff60043581811161000e5761030590369060040161026a565b60443582811161000e5761031d903690600401610288565b909260643590811161000e57610337903690600401610288565b91835115610385576103819461035a9460243590610355813361195a565b611716565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b60046040517f19240aab000000000000000000000000000000000000000000000000000000008152fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361000e57565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5761040a6103af565b73ffffffffffffffffffffffffffffffffffffffff61047b817f00000000000000000000000000000000000000000000000000000000000000001661045181301415610c89565b827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc541614610d14565b7febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d0541633036104bf576040516104bd916104b482610171565b60008252610e46565b005b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b600091031261000e57565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602061052f336119c7565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602073ffffffffffffffffffffffffffffffffffffffff610616816106106103af565b166119c7565b60405191168152f35b5060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576106526103af565b60243567ffffffffffffffff811161000e573660238201121561000e57610683903690602481600401359101610233565b73ffffffffffffffffffffffffffffffffffffffff6106ca817f00000000000000000000000000000000000000000000000000000000000000001661045181301415610c89565b7febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d0541633036104bf576104bd91610fc3565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163003610794576040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152602090f35b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e577f4be222fb9f9e9f4aed563932b8b081b3887ff710df7cb9700c19ef7af1497d8e73ffffffffffffffffffffffffffffffffffffffff815416330361090557600090557febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d0805433918290556040805173ffffffffffffffffffffffffffffffffffffffff909216825260208201929092527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091819081015b0390a1005b60046040517f39218f3b000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576109676103af565b60243567ffffffffffffffff811161000e5761098790369060040161026a565b8051156103855761099d61052f9160209361195a565b6119c7565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760207febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d05473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57610a4c6103af565b73ffffffffffffffffffffffffffffffffffffffff80821615610abf577febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d090815416610a955755005b60046040517fef34ca5c000000000000000000000000000000000000000000000000000000008152fd5b60046040517f6d187b28000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57610b216103af565b7febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d0549073ffffffffffffffffffffffffffffffffffffffff808316908133036104bf5782168015610abf5714610abf577f4be222fb9f9e9f4aed563932b8b081b3887ff710df7cb9700c19ef7af1497d8e8190556040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700919081908101610900565b5060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5767ffffffffffffffff60243581811161000e57610c34903690600401610288565b91906044359180831161000e57602093610c5561052f943690600401610288565b6040519094919387820190811182821017610c7c575b604052600081526004359033611716565b610c84610120565b610c6b565b15610c9057565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152fd5b15610d1b57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152fd5b9081602091031261000e575190565b506040513d6000823e3d90fd5b15610dc257565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152fd5b90610e727f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1690565b15610e835750610e819061112a565b565b604051917f52d1902d00000000000000000000000000000000000000000000000000000000835260208360048173ffffffffffffffffffffffffffffffffffffffff85165afa60009381610f93575b50610f60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608490fd5b0390fd5b610f8e7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610e819414610dbb565b611216565b610fb591945060203d8111610fbc575b610fad81836101a9565b810190610d9f565b9238610ed2565b503d610fa3565b90610fef7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1690565b15610ffe5750610e819061112a565b604051917f52d1902d00000000000000000000000000000000000000000000000000000000835260208360048173ffffffffffffffffffffffffffffffffffffffff85165afa6000938161110a575b506110d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608490fd5b6111057f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610e819414610dbb565b611327565b61112391945060203d8111610fbc57610fad81836101a9565b923861104d565b803b156111925773ffffffffffffffffffffffffffffffffffffffff7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152fd5b61121f8161112a565b6040519060009073ffffffffffffffffffffffffffffffffffffffff81167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8385a2835115801590611320575b611277575b50505050565b818061130d956112868661018d565b602786527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208701527f206661696c6564000000000000000000000000000000000000000000000000006040870152602081519101845af4903d15611317573d6112f0816101ea565b906112fe60405192836101a9565b8152809360203d92013e61142e565b5038808080611271565b6060925061142e565b508161126c565b6113308161112a565b6040519073ffffffffffffffffffffffffffffffffffffffff81167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600084a2825115801590611426575b61138457505050565b60008061141b946113948561018d565b602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208601527f206661696c6564000000000000000000000000000000000000000000000000006040860152602081519101845af43d1561141e573d916113fe836101ea565b9261140c60405194856101a9565b83523d6000602085013e61142e565b50565b60609161142e565b50600161137b565b919290156114a95750815115611442575090565b3b1561144b5790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156114bc5750805190602001fd5b610f5c906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301905b919082519283825260005b8481106115405750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b602081830181015184830182015201611501565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b939194929073ffffffffffffffffffffffffffffffffffffffff9097969716845260209485850152604084015260a060608401528160a08401527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821161000e5784939295949160051b809160c088013785019460c0860190608060c0828903019101525260e084019360e08360051b82010194846000925b85841061163d575050505050505090565b909192939495967fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2082820301845287357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181121561000e57830186810191903567ffffffffffffffff811161000e57803603831361000e576116c888928392600195611554565b99019401940192959493919061162c565b919061170f60409295949573ffffffffffffffffffffffffffffffffffffffff80931685526060602086015260608501906114f6565b9416910152565b9396959490929173ffffffffffffffffffffffffffffffffffffffff8560c66040517f6080604052348015600f57600080fd5b5060a88061001e6000396000f3fe608081527f6040526040517f5c60da1b0000000000000000000000000000000000000000006020820152788152600060016020826004857300000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060601b60548201527f5afa0360705780513682833781823684845af490503d82833e808015606c573d60688201527f83f35b3d83fd5b00fea264697066735822122002f8a2f5acabeb1d754972351e60888201527fc784958a7f99e64f368c267a38bb375594c03c64736f6c63430008100033000060a88201526000f5169485156118fc578598863b1561000e577ffb896a1c46a5b12a7e44f5f16c83d1bb4d9598a3501f4eb920f2966e0def0523976000946118ad9260405197889687967ff4adeb750000000000000000000000000000000000000000000000000000000088523360048901611593565b038134875af180156118ef575b6118d6575b506118d16040519283923391846116d9565b0390a1565b806118e36118e992610150565b806104e9565b386118bf565b6118f7610dae565b6118ba565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f63726561746532206661696c65640000000000000000000000000000000000006044820152fd5b906119c16119959160405192839173ffffffffffffffffffffffffffffffffffffffff602084019616865260408084015260608301906114f6565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018352826101a9565b51902090565b605560c661028592604051907f6080604052348015600f57600080fd5b5060a88061001e6000396000f3fe608082527f6040526040517f5c60da1b0000000000000000000000000000000000000000006020830152788152600060016020826004857300000000000000000000000060408301527f000000000000000000000000000000000000000000000000000000000000000060601b60548301527f5afa0360705780513682833781823684845af490503d82833e808015606c573d60688301527f83f35b3d83fd5b00fea264697066735822122002f8a2f5acabeb1d754972351e60888301527fc784958a7f99e64f368c267a38bb375594c03c64736f6c63430008100033ff0060a88301523060601b60c783015260db82015281812060fb820152012073ffffffffffffffffffffffffffffffffffffffff169056fea26469706673582212207777c6fc2a0ebecbe240ee783e01cb618360093568379d4ca81a0301c8868c5d64736f6c63430008100033000000000000000000000000277d98d33b7f44921d4230697def8d1d56abaa62
Deployed Bytecode
0x60806040526004361015610013575b600080fd5b60003560e01c80631289ad05146101175780633659cfe61461010e57806338cc48311461010557806349061ae6146100fc5780634d6849d2146100f35780634f1ef286146100ea57806352d1902d146100e157806379ba5097146100d85780638454525b146100cf5780638da5cb5b146100c6578063c4d66de8146100bd578063f2fde38b146100b45763ffa2ca3b146100ac57600080fd5b61000e610be8565b5061000e610ae9565b5061000e610a14565b5061000e6109a2565b5061000e61092f565b5061000e610818565b5061000e6106fc565b5061000e61061f565b5061000e6105bd565b5061000e61054d565b5061000e6104f4565b5061000e6103d2565b5061000e6102b9565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b67ffffffffffffffff811161016457604052565b61016c610120565b604052565b6020810190811067ffffffffffffffff82111761016457604052565b6060810190811067ffffffffffffffff82111761016457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761016457604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610226575b01160190565b61022e610120565b610220565b92919261023f826101ea565b9161024d60405193846101a9565b82948184528183011161000e578281602093846000960137010152565b9080601f8301121561000e5781602061028593359101610233565b90565b9181601f8401121561000e5782359167ffffffffffffffff831161000e576020808501948460051b01011161000e57565b5060807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5767ffffffffffffffff60043581811161000e5761030590369060040161026a565b60443582811161000e5761031d903690600401610288565b909260643590811161000e57610337903690600401610288565b91835115610385576103819461035a9460243590610355813361195a565b611716565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b60046040517f19240aab000000000000000000000000000000000000000000000000000000008152fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361000e57565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5761040a6103af565b73ffffffffffffffffffffffffffffffffffffffff61047b817f00000000000000000000000066fc62c1748e45435b06cf8dd105b73e9855f93e1661045181301415610c89565b827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc541614610d14565b7febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d0541633036104bf576040516104bd916104b482610171565b60008252610e46565b005b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b600091031261000e57565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602061052f336119c7565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000277d98d33b7f44921d4230697def8d1d56abaa62168152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602073ffffffffffffffffffffffffffffffffffffffff610616816106106103af565b166119c7565b60405191168152f35b5060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576106526103af565b60243567ffffffffffffffff811161000e573660238201121561000e57610683903690602481600401359101610233565b73ffffffffffffffffffffffffffffffffffffffff6106ca817f00000000000000000000000066fc62c1748e45435b06cf8dd105b73e9855f93e1661045181301415610c89565b7febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d0541633036104bf576104bd91610fc3565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000066fc62c1748e45435b06cf8dd105b73e9855f93e163003610794576040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152602090f35b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e577f4be222fb9f9e9f4aed563932b8b081b3887ff710df7cb9700c19ef7af1497d8e73ffffffffffffffffffffffffffffffffffffffff815416330361090557600090557febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d0805433918290556040805173ffffffffffffffffffffffffffffffffffffffff909216825260208201929092527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091819081015b0390a1005b60046040517f39218f3b000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576109676103af565b60243567ffffffffffffffff811161000e5761098790369060040161026a565b8051156103855761099d61052f9160209361195a565b6119c7565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760207febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d05473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57610a4c6103af565b73ffffffffffffffffffffffffffffffffffffffff80821615610abf577febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d090815416610a955755005b60046040517fef34ca5c000000000000000000000000000000000000000000000000000000008152fd5b60046040517f6d187b28000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57610b216103af565b7febef2b212afb6c9cfdbd10b61834a8dc955e5fbf0aacd1c641d5cbdedf4022d0549073ffffffffffffffffffffffffffffffffffffffff808316908133036104bf5782168015610abf5714610abf577f4be222fb9f9e9f4aed563932b8b081b3887ff710df7cb9700c19ef7af1497d8e8190556040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700919081908101610900565b5060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5767ffffffffffffffff60243581811161000e57610c34903690600401610288565b91906044359180831161000e57602093610c5561052f943690600401610288565b6040519094919387820190811182821017610c7c575b604052600081526004359033611716565b610c84610120565b610c6b565b15610c9057565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152fd5b15610d1b57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152fd5b9081602091031261000e575190565b506040513d6000823e3d90fd5b15610dc257565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152fd5b90610e727f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1690565b15610e835750610e819061112a565b565b604051917f52d1902d00000000000000000000000000000000000000000000000000000000835260208360048173ffffffffffffffffffffffffffffffffffffffff85165afa60009381610f93575b50610f60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608490fd5b0390fd5b610f8e7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610e819414610dbb565b611216565b610fb591945060203d8111610fbc575b610fad81836101a9565b810190610d9f565b9238610ed2565b503d610fa3565b90610fef7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1690565b15610ffe5750610e819061112a565b604051917f52d1902d00000000000000000000000000000000000000000000000000000000835260208360048173ffffffffffffffffffffffffffffffffffffffff85165afa6000938161110a575b506110d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608490fd5b6111057f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610e819414610dbb565b611327565b61112391945060203d8111610fbc57610fad81836101a9565b923861104d565b803b156111925773ffffffffffffffffffffffffffffffffffffffff7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152fd5b61121f8161112a565b6040519060009073ffffffffffffffffffffffffffffffffffffffff81167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8385a2835115801590611320575b611277575b50505050565b818061130d956112868661018d565b602786527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208701527f206661696c6564000000000000000000000000000000000000000000000000006040870152602081519101845af4903d15611317573d6112f0816101ea565b906112fe60405192836101a9565b8152809360203d92013e61142e565b5038808080611271565b6060925061142e565b508161126c565b6113308161112a565b6040519073ffffffffffffffffffffffffffffffffffffffff81167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600084a2825115801590611426575b61138457505050565b60008061141b946113948561018d565b602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208601527f206661696c6564000000000000000000000000000000000000000000000000006040860152602081519101845af43d1561141e573d916113fe836101ea565b9261140c60405194856101a9565b83523d6000602085013e61142e565b50565b60609161142e565b50600161137b565b919290156114a95750815115611442575090565b3b1561144b5790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156114bc5750805190602001fd5b610f5c906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301905b919082519283825260005b8481106115405750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b602081830181015184830182015201611501565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b939194929073ffffffffffffffffffffffffffffffffffffffff9097969716845260209485850152604084015260a060608401528160a08401527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821161000e5784939295949160051b809160c088013785019460c0860190608060c0828903019101525260e084019360e08360051b82010194846000925b85841061163d575050505050505090565b909192939495967fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2082820301845287357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181121561000e57830186810191903567ffffffffffffffff811161000e57803603831361000e576116c888928392600195611554565b99019401940192959493919061162c565b919061170f60409295949573ffffffffffffffffffffffffffffffffffffffff80931685526060602086015260608501906114f6565b9416910152565b9396959490929173ffffffffffffffffffffffffffffffffffffffff8560c66040517f6080604052348015600f57600080fd5b5060a88061001e6000396000f3fe608081527f6040526040517f5c60da1b0000000000000000000000000000000000000000006020820152788152600060016020826004857300000000000000000000000060408201527f000000000000000000000000277d98d33b7f44921d4230697def8d1d56abaa6260601b60548201527f5afa0360705780513682833781823684845af490503d82833e808015606c573d60688201527f83f35b3d83fd5b00fea264697066735822122002f8a2f5acabeb1d754972351e60888201527fc784958a7f99e64f368c267a38bb375594c03c64736f6c63430008100033000060a88201526000f5169485156118fc578598863b1561000e577ffb896a1c46a5b12a7e44f5f16c83d1bb4d9598a3501f4eb920f2966e0def0523976000946118ad9260405197889687967ff4adeb750000000000000000000000000000000000000000000000000000000088523360048901611593565b038134875af180156118ef575b6118d6575b506118d16040519283923391846116d9565b0390a1565b806118e36118e992610150565b806104e9565b386118bf565b6118f7610dae565b6118ba565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f63726561746532206661696c65640000000000000000000000000000000000006044820152fd5b906119c16119959160405192839173ffffffffffffffffffffffffffffffffffffffff602084019616865260408084015260608301906114f6565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018352826101a9565b51902090565b605560c661028592604051907f6080604052348015600f57600080fd5b5060a88061001e6000396000f3fe608082527f6040526040517f5c60da1b0000000000000000000000000000000000000000006020830152788152600060016020826004857300000000000000000000000060408301527f000000000000000000000000277d98d33b7f44921d4230697def8d1d56abaa6260601b60548301527f5afa0360705780513682833781823684845af490503d82833e808015606c573d60688301527f83f35b3d83fd5b00fea264697066735822122002f8a2f5acabeb1d754972351e60888301527fc784958a7f99e64f368c267a38bb375594c03c64736f6c63430008100033ff0060a88301523060601b60c783015260db82015281812060fb820152012073ffffffffffffffffffffffffffffffffffffffff169056fea26469706673582212207777c6fc2a0ebecbe240ee783e01cb618360093568379d4ca81a0301c8868c5d64736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000277d98d33b7f44921d4230697def8d1d56abaa62
-----Decoded View---------------
Arg [0] : ensoBeacon_ (address): 0x277D98D33b7F44921d4230697DeF8d1D56aBAa62
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000277d98d33b7f44921d4230697def8d1d56abaa62
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.