Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CoboSafeAccount
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.19; import "./base/BaseAccount.sol"; contract Enum { enum Operation { Call, DelegateCall } } interface IGnosisSafe { /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data function execTransactionFromModuleReturnData( address to, uint256 value, bytes memory data, Enum.Operation operation ) external returns (bool success, bytes memory returnData); function enableModule(address module) external; function isModuleEnabled(address module) external view returns (bool); } /// @title CoboSafeAccount - A GnosisSafe module that implements customized access control /// @author Cobo Safe Dev Team https://www.cobo.com/ contract CoboSafeAccount is BaseAccount { using TxFlags for uint256; bytes32 public constant NAME = "CoboSafeAccount"; uint256 public constant VERSION = 2; constructor(address _owner) BaseAccount(_owner) {} /// @notice The Safe of the CoboSafeAccount. function safe() public view returns (address) { return owner; } /// @dev Execute the transaction from the Safe. function _executeTransaction( TransactionData memory transaction ) internal override returns (TransactionResult memory result) { // execute the transaction from Gnosis Safe, note this call will bypass // Safe owners confirmation. (result.success, result.data) = IGnosisSafe(payable(safe())).execTransactionFromModuleReturnData( transaction.to, transaction.value, transaction.data, transaction.flag.isDelegateCall() ? Enum.Operation.DelegateCall : Enum.Operation.Call ); } /// @dev The account address is the Safe address. function _getAccountAddress() internal view override returns (address account) { account = safe(); } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.19; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "../Types.sol"; import "./BaseOwnable.sol"; import "../../interfaces/IAuthorizer.sol"; import "../../interfaces/IAccount.sol"; /// @title BaseAccount - A basic smart contract wallet with access control supported. /// @author Cobo Safe Dev Team https://www.cobo.com/ /// @dev Extend this and implement `_executeTransaction()` and `_getFromAddress()`. abstract contract BaseAccount is IAccount, BaseOwnable { using EnumerableSet for EnumerableSet.AddressSet; using TxFlags for uint256; using AuthFlags for uint256; address public roleManager; address public authorizer; // Simple and basic delegate check. EnumerableSet.AddressSet delegates; event RoleManagerSet(address indexed roleManager); event AuthorizerSet(address indexed authorizer); event DelegateAdded(address indexed delegate); event DelegateRemoved(address indexed delegate); event TransactionExecuted( address indexed to, bytes4 indexed selector, uint256 indexed value, TransactionData transaction ); /// @param _owner Who owns the wallet. constructor(address _owner) BaseOwnable(_owner) {} /// @dev Only used in proxy mode. Can be called only once. function initialize(address _owner, address _roleManager, address _authorizer) public { initialize(_owner); _setRoleManager(_roleManager); _setAuthorizer(_authorizer); } /// Modifiers /// @dev Only added delegates are allowed to call `execTransaction`. This provides a kind /// of catch-all rule and simple but strong protection from malicious/compromised/buggy /// authorizers which permit any operations. modifier onlyDelegate() { require(hasDelegate(msg.sender), Errors.INVALID_DELEGATE); _; } // Public/External functions. function setRoleManager(address _roleManager) external onlyOwner { _setRoleManager(_roleManager); } function setAuthorizer(address _authorizer) external onlyOwner { _setAuthorizer(_authorizer); } function addDelegate(address _delegate) external onlyOwner { _addDelegate(_delegate); } function addDelegates(address[] calldata _delegates) external onlyOwner { for (uint256 i = 0; i < _delegates.length; i++) { _addDelegate(_delegates[i]); } } function removeDelegate(address _delegate) external onlyOwner { _removeDelegate(_delegate); } function removeDelegates(address[] calldata _delegates) external onlyOwner { for (uint256 i = 0; i < _delegates.length; i++) { _removeDelegate(_delegates[i]); } } /// @notice Called by authenticated delegates to execute transaction on behalf of the wallet account. function execTransaction( CallData calldata callData ) external onlyDelegate returns (TransactionResult memory result) { TransactionData memory transaction; transaction.from = _getAccountAddress(); transaction.delegate = msg.sender; transaction.flag = callData.flag; transaction.to = callData.to; transaction.value = callData.value; transaction.data = callData.data; transaction.hint = callData.hint; transaction.extra = callData.extra; result = _executeTransactionWithCheck(transaction); emit TransactionExecuted(callData.to, bytes4(callData.data), callData.value, transaction); } /// @notice A Multicall method. /// @param callDataList `CallData` array to execute in sequence. function execTransactions( CallData[] calldata callDataList ) external onlyDelegate returns (TransactionResult[] memory resultList) { TransactionData memory transaction; transaction.from = _getAccountAddress(); transaction.delegate = msg.sender; resultList = new TransactionResult[](callDataList.length); for (uint256 i = 0; i < callDataList.length; i++) { CallData calldata callData = callDataList[i]; transaction.to = callData.to; transaction.value = callData.value; transaction.data = callData.data; transaction.flag = callData.flag; transaction.hint = callData.hint; transaction.extra = callData.extra; resultList[i] = _executeTransactionWithCheck(transaction); emit TransactionExecuted(callData.to, bytes4(callData.data), callData.value, transaction); } } /// Public/External view functions. function hasDelegate(address _delegate) public view returns (bool) { return delegates.contains(_delegate); } function getAllDelegates() external view returns (address[] memory) { return delegates.values(); } /// @notice The real address of your smart contract wallet address where /// stores your assets and sends transactions from. function getAccountAddress() external view returns (address account) { account = _getAccountAddress(); } /// Internal functions. function _addDelegate(address _delegate) internal { if (delegates.add(_delegate)) { emit DelegateAdded(_delegate); } } function _removeDelegate(address _delegate) internal { if (delegates.remove(_delegate)) { emit DelegateRemoved(_delegate); } } function _setRoleManager(address _roleManager) internal { roleManager = _roleManager; emit RoleManagerSet(_roleManager); } function _setAuthorizer(address _authorizer) internal { authorizer = _authorizer; emit AuthorizerSet(_authorizer); } /// @dev Override this if we prefer not to revert the entire transaction in // out wallet contract implementation. function _preExecCheck( TransactionData memory transaction ) internal virtual returns (AuthorizerReturnData memory authData) { authData = IAuthorizer(authorizer).preExecCheck(transaction); require(authData.result == AuthResult.SUCCESS, authData.message); } function _revertIfTxFails(TransactionResult memory callResult) internal pure { bool success = callResult.success; bytes memory data = callResult.data; if (!success) { assembly { revert(add(data, 32), data) } } } function _postExecCheck( TransactionData memory transaction, TransactionResult memory callResult, AuthorizerReturnData memory predata ) internal virtual returns (AuthorizerReturnData memory authData) { authData = IAuthorizer(authorizer).postExecCheck(transaction, callResult, predata); require(authData.result == AuthResult.SUCCESS, authData.message); } function _preExecProcess(TransactionData memory transaction) internal virtual { IAuthorizer(authorizer).preExecProcess(transaction); } function _postExecProcess( TransactionData memory transaction, TransactionResult memory callResult ) internal virtual { IAuthorizer(authorizer).postExecProcess(transaction, callResult); } function _executeTransactionWithCheck( TransactionData memory transaction ) internal virtual returns (TransactionResult memory result) { require(authorizer != address(0), Errors.AUTHORIZER_NOT_SET); uint256 flag = IAuthorizer(authorizer).flag(); bool doCollectHint = transaction.hint.length == 0; // Ensures either _preExecCheck or _postExecCheck (or both) will run. require(flag.isValid(), Errors.INVALID_AUTHORIZER_FLAG); // 1. Do pre check, revert the entire txn if failed. AuthorizerReturnData memory preData; if (doCollectHint || flag.hasPreCheck()) { // Always run _preExecCheck When collecting hint. // If not collecting hint, only run if the sub authorizer requires. preData = _preExecCheck(transaction); } // 2. Do pre process. if (flag.hasPreProcess()) _preExecProcess(transaction); // 3. Execute the transaction. result = _executeTransaction(transaction); if (!transaction.flag.allowsRevert()) _revertIfTxFails(result); // 4. Do post check, revert the entire txn if failed. AuthorizerReturnData memory postData; if (doCollectHint || flag.hasPostCheck()) { postData = _postExecCheck(transaction, result, preData); } // 5. Do post process. if (flag.hasPostProcess()) _postExecProcess(transaction, result); // 6. Collect hint if when (1) no hint provided and (2) the authorizer supports hint mode. if (doCollectHint && flag.supportHint()) { result.hint = IAuthorizerSupportingHint(authorizer).collectHint(preData, postData); } } /// @dev Instance should implement at least two `virtual` function below. /// @param transaction Transaction to execute. /// @return result `TransactionResult` which contains call status and return/revert data. function _executeTransaction( TransactionData memory transaction ) internal virtual returns (TransactionResult memory result); /// @dev The address of wallet which sends the transaction a.k.a `msg.sender` function _getAccountAddress() internal view virtual returns (address account); // To receive ETH as a wallet. receive() external payable {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.20; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position is the index of the value in the `values` array plus 1. // Position 0 is used to mean a value is not in the set. mapping(bytes32 value => uint256) _positions; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._positions[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We cache the value's position to prevent multiple reads from the same storage slot uint256 position = set._positions[value]; if (position != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 valueIndex = position - 1; uint256 lastIndex = set._values.length - 1; if (valueIndex != lastIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the lastValue to the index where the value to delete is set._values[valueIndex] = lastValue; // Update the tracked position of the lastValue (that was just moved) set._positions[lastValue] = position; } // Delete the slot where the moved value was stored set._values.pop(); // Delete the tracked position for the deleted slot delete set._positions[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._positions[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.19; struct CallData { uint256 flag; // 0x1 delegate call, 0x0 call. address to; uint256 value; bytes data; // calldata bytes hint; bytes extra; // for future support: signatures etc. } struct TransactionData { address from; // `msg.sender` who performs the transaction a.k.a wallet address. address delegate; // Delegate who calls executeTransactions(). // Same as CallData uint256 flag; // 0x1 delegate call, 0x0 call. address to; uint256 value; bytes data; // calldata bytes hint; bytes extra; } /// @dev Use enum instead of bool in case of when other status, like PENDING, /// is needed in the future. enum AuthResult { FAILED, SUCCESS } struct AuthorizerReturnData { AuthResult result; string message; bytes data; // Authorizer return data. usually used for hint purpose. } struct TransactionResult { bool success; // Call status. bytes data; // Return/Revert data. bytes hint; } library TxFlags { uint256 internal constant DELEGATE_CALL_MASK = 0x1; // 1 for delegatecall, 0 for call uint256 internal constant ALLOW_REVERT_MASK = 0x2; // 1 for allow, 0 for not function isDelegateCall(uint256 flag) internal pure returns (bool) { return flag & DELEGATE_CALL_MASK > 0; } function allowsRevert(uint256 flag) internal pure returns (bool) { return flag & ALLOW_REVERT_MASK > 0; } } library AuthType { bytes32 internal constant FUNC = "FunctionType"; bytes32 internal constant TRANSFER = "TransferType"; bytes32 internal constant DEX = "DexType"; bytes32 internal constant LENDING = "LendingType"; bytes32 internal constant COMMON = "CommonType"; bytes32 internal constant SET = "SetType"; bytes32 internal constant VM = "VM"; } library AuthFlags { uint256 internal constant HAS_PRE_CHECK_MASK = 0x1; uint256 internal constant HAS_POST_CHECK_MASK = 0x2; uint256 internal constant HAS_PRE_PROC_MASK = 0x4; uint256 internal constant HAS_POST_PROC_MASK = 0x8; uint256 internal constant SUPPORT_HINT_MASK = 0x40; uint256 internal constant FULL_MODE = HAS_PRE_CHECK_MASK | HAS_POST_CHECK_MASK | HAS_PRE_PROC_MASK | HAS_POST_PROC_MASK; function isValid(uint256 flag) internal pure returns (bool) { // At least one check handler is activated. return hasPreCheck(flag) || hasPostCheck(flag); } function hasPreCheck(uint256 flag) internal pure returns (bool) { return flag & HAS_PRE_CHECK_MASK > 0; } function hasPostCheck(uint256 flag) internal pure returns (bool) { return flag & HAS_POST_CHECK_MASK > 0; } function hasPreProcess(uint256 flag) internal pure returns (bool) { return flag & HAS_PRE_PROC_MASK > 0; } function hasPostProcess(uint256 flag) internal pure returns (bool) { return flag & HAS_POST_PROC_MASK > 0; } function supportHint(uint256 flag) internal pure returns (bool) { return flag & SUPPORT_HINT_MASK > 0; } } // For Rule VM. // For each VariantType, an extractor should be implement. enum VariantType { INVALID, // Mark for delete. EXTRACT_CALLDATA, // extract calldata by path bytes. NAME, // name for user-defined variant. RAW, // encoded solidity values. VIEW, // staticcall view non-side-effect function and get return value. CALL, // call state changing function and get returned value. RULE, // rule expression. ANY } // How the data should be decoded. enum SolidityType { _invalid, // Mark for delete. _any, _bytes, _bool, ///// START 1 ///// Generated by gen_rulelib.py (start) _address, _uint256, _int256, ///// Generated by gen_rulelib.py (end) ///// END 1 _end } // A common operand in rule. struct Variant { VariantType varType; SolidityType solType; bytes data; } library VarName { bytes5 internal constant TEMP = "temp."; function isTemp(bytes32 name) internal pure returns (bool) { return bytes5(name) == TEMP; } } // OpCode for rule expression which returns v0. enum OP { INVALID, // One opnd. VAR, // v1 NOT, // !v1 // Two opnds. // checkBySolType() which returns boolean. EQ, // v1 == v2 NE, // v1 != v2 GT, // v1 > v2 GE, // v1 >= v2 LT, // v1 < v2 LE, // v1 <= v2 IN, // v1 in [...] NOTIN, // v1 not in [...] // computeBySolType() which returns bytes (with same solType) AND, // v1 & v2 OR, // v1 | v2 ADD, // v1 + v2 SUB, // v1 - v2 MUL, // v1 * v2 DIV, // v1 / v2 MOD, // v1 % v2 // Three opnds. IF, // v1? v2: v3 // Side-effect ones. ASSIGN, // v1 := v2 VM, // rule list bytes. NOP // as end. } struct Rule { OP op; Variant[] vars; }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.19; import "../Errors.sol"; import "./BaseVersion.sol"; /// @title BaseOwnable - Simple ownership access control contract. /// @author Cobo Safe Dev Team https://www.cobo.com/ /// @dev Can be used in both proxy and non-proxy mode. abstract contract BaseOwnable is BaseVersion { address public owner; address public pendingOwner; bool private initialized = false; event PendingOwnerSet(address indexed to); event NewOwnerSet(address indexed owner); modifier onlyOwner() { require(owner == msg.sender, Errors.CALLER_IS_NOT_OWNER); _; } /// @dev `owner` is set by argument, thus the owner can any address. /// When used in non-proxy mode, `initialize` can not be called /// after deployment. constructor(address _owner) { initialize(_owner); } /// @dev When used in proxy mode, `initialize` can be called by anyone /// to claim the ownership. /// This function can be called only once. function initialize(address _owner) public { require(!initialized, "Already initialized"); _setOwner(_owner); initialized = true; } /// @notice User should ensure the corrent owner address set, or the /// ownership may be transferred to blackhole. It is recommended to /// take a safer way with setPendingOwner() + acceptOwner(). function transferOwnership(address newOwner) external onlyOwner { require(newOwner != address(0), "New Owner is zero"); _setOwner(newOwner); } /// @notice The original owner calls `setPendingOwner(newOwner)` and the new /// owner calls `acceptOwner()` to take the ownership. function setPendingOwner(address to) external onlyOwner { pendingOwner = to; emit PendingOwnerSet(pendingOwner); } function acceptOwner() external { require(msg.sender == pendingOwner); _setOwner(pendingOwner); } /// @notice Make the contract immutable. function renounceOwnership() external onlyOwner { _setOwner(address(0)); } // Internal functions /// @dev Clear pendingOwner to prevent from reclaiming the ownership. function _setOwner(address _owner) internal { owner = _owner; pendingOwner = address(0); emit NewOwnerSet(owner); } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.19; import "../src/Types.sol"; interface IAuthorizer { function flag() external view returns (uint256 authFlags); function setCaller(address _caller) external; function preExecCheck(TransactionData calldata transaction) external returns (AuthorizerReturnData memory authData); function postExecCheck( TransactionData calldata transaction, TransactionResult calldata callResult, AuthorizerReturnData calldata preAuthData ) external returns (AuthorizerReturnData memory authData); function preExecProcess(TransactionData calldata transaction) external; function postExecProcess(TransactionData calldata transaction, TransactionResult calldata callResult) external; } interface IAuthorizerSupportingHint is IAuthorizer { // When IAuthorizer(auth).flag().supportHint() == true; function collectHint( AuthorizerReturnData calldata preAuthData, AuthorizerReturnData calldata postAuthData ) external view returns (bytes memory hint); }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.19; import "../src/Types.sol"; interface IAccount { function execTransaction(CallData calldata callData) external returns (TransactionResult memory result); function execTransactions( CallData[] calldata callDataList ) external returns (TransactionResult[] memory resultList); function setAuthorizer(address _authorizer) external; function setRoleManager(address _roleManager) external; function addDelegate(address _delegate) external; function addDelegates(address[] calldata _delegates) external; /// @dev Sub instance should override this to set `from` for transaction /// @return account The address for the contract wallet, also the /// `msg.sender` address which send the transaction. function getAccountAddress() external view returns (address account); function roleManager() external view returns (address _roleManager); function authorizer() external view returns (address _authorizer); }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.19; /// @dev Common errors. This helps reducing the contract size. library Errors { // "E1"; // Call/Static-call failed. string constant CALL_FAILED = "E2"; // Argument's type not supported in View Variant. string constant INVALID_VIEW_ARG_SOL_TYPE = "E3"; // Invalid length for variant raw data. string constant INVALID_VARIANT_RAW_DATA = "E4"; // "E5"; // Invalid variant type. string constant INVALID_VAR_TYPE = "E6"; // Rule not exists string constant RULE_NOT_EXISTS = "E7"; // Variant name not found. string constant VAR_NAME_NOT_FOUND = "E8"; // Rule: v1/v2 solType mismatch string constant SOL_TYPE_MISMATCH = "E9"; // "E10"; // Invalid rule OP. string constant INVALID_RULE_OP = "E11"; // "E12"; // "E13"; // "E14"; // "E15"; // "E16"; // "E17"; // "E18"; // "E19"; // "E20"; // checkCmpOp: OP not support string constant CMP_OP_NOT_SUPPORT = "E21"; // checkBySolType: Invalid op for bool string constant INVALID_BOOL_OP = "E22"; // checkBySolType: Invalid op string constant CHECK_INVALID_OP = "E23"; // Invalid solidity type. string constant INVALID_SOL_TYPE = "E24"; // computeBySolType: invalid vm op string constant INVALID_VM_BOOL_OP = "E25"; // computeBySolType: invalid vm arith op string constant INVALID_VM_ARITH_OP = "E26"; // onlyCaller: Invalid caller string constant INVALID_CALLER = "E27"; // "E28"; // Side-effect is not allowed here. string constant SIDE_EFFECT_NOT_ALLOWED = "E29"; // Invalid variant count for the rule op. string constant INVALID_VAR_COUNT = "E30"; // extractCallData: Invalid op. string constant INVALID_EXTRACTOR_OP = "E31"; // extractCallData: Invalid array index. string constant INVALID_ARRAY_INDEX = "E32"; // extractCallData: No extract op. string constant NO_EXTRACT_OP = "E33"; // extractCallData: No extract path. string constant NO_EXTRACT_PATH = "E34"; // BaseOwnable: caller is not owner string constant CALLER_IS_NOT_OWNER = "E35"; // BaseOwnable: Already initialized string constant ALREADY_INITIALIZED = "E36"; // "E37"; // "E38"; // BaseACL: ACL check method should not return anything. string constant ACL_FUNC_RETURNS_NON_EMPTY = "E39"; // "E40"; // BaseAccount: Invalid delegate. string constant INVALID_DELEGATE = "E41"; // RootAuthorizer: delegateCallAuthorizer not set string constant DELEGATE_CALL_AUTH_NOT_SET = "E42"; // RootAuthorizer: callAuthorizer not set. string constant CALL_AUTH_NOT_SET = "E43"; // BaseAccount: Authorizer not set. string constant AUTHORIZER_NOT_SET = "E44"; // BaseAccount: Invalid authorizer flag. string constant INVALID_AUTHORIZER_FLAG = "E45"; // BaseAuthorizer: Authorizer paused. string constant AUTHORIZER_PAUSED = "E46"; // Authorizer set: Invalid hint. string constant INVALID_HINT = "E47"; // Authorizer set: All auth deny. string constant ALL_AUTH_FAILED = "E48"; // BaseACL: Method not allow. string constant METHOD_NOT_ALLOW = "E49"; // AuthorizerUnionSet: Invalid hint collected. string constant INVALID_HINT_COLLECTED = "E50"; // AuthorizerSet: Empty auth set string constant EMPTY_AUTH_SET = "E51"; // AuthorizerSet: hint not implement. string constant HINT_NOT_IMPLEMENT = "E52"; // RoleAuthorizer: Empty role set string constant EMPTY_ROLE_SET = "E53"; // RoleAuthorizer: No auth for the role string constant NO_AUTH_FOR_THE_ROLE = "E54"; // BaseACL: No in contract white list. string constant NOT_IN_CONTRACT_LIST = "E55"; // BaseACL: Same process not allowed to install twice. string constant SAME_PROCESS_TWICE = "E56"; // BaseAuthorizer: Account not set (then can not find roleManger) string constant ACCOUNT_NOT_SET = "E57"; // BaseAuthorizer: roleManger not set string constant ROLE_MANAGER_NOT_SET = "E58"; }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.19; import "../../interfaces/IVersion.sol"; /// @title BaseVersion - Provides version information /// @author Cobo Safe Dev Team https://www.cobo.com/ /// @dev /// Implement NAME() and VERSION() methods according to IVersion interface. /// /// Or just: /// bytes32 public constant NAME = "<Your contract name>"; /// uint256 public constant VERSION = <Your contract version>; /// /// Change the NAME when writing new kind of contract. /// Change the VERSION when upgrading existing contract. abstract contract BaseVersion is IVersion { /// @dev Convert to `string` which looks prettier on Etherscan viewer. function _NAME() external view virtual returns (string memory) { return string(abi.encodePacked(this.NAME())); } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.19; interface IVersion { function NAME() external view returns (bytes32 name); function VERSION() external view returns (uint256 version); }
{ "remappings": [ "openzeppelin/=lib/openzeppelin-contracts/", "forge-std/=lib/forge-std/src/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"}],"name":"AuthorizerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"}],"name":"DelegateAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"}],"name":"DelegateRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"NewOwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PendingOwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"roleManager","type":"address"}],"name":"RoleManagerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"bytes4","name":"selector","type":"bytes4"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"delegate","type":"address"},{"internalType":"uint256","name":"flag","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"hint","type":"bytes"},{"internalType":"bytes","name":"extra","type":"bytes"}],"indexed":false,"internalType":"struct TransactionData","name":"transaction","type":"tuple"}],"name":"TransactionExecuted","type":"event"},{"inputs":[],"name":"NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"addDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_delegates","type":"address[]"}],"name":"addDelegates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authorizer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"flag","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"hint","type":"bytes"},{"internalType":"bytes","name":"extra","type":"bytes"}],"internalType":"struct CallData","name":"callData","type":"tuple"}],"name":"execTransaction","outputs":[{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"hint","type":"bytes"}],"internalType":"struct TransactionResult","name":"result","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"flag","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"hint","type":"bytes"},{"internalType":"bytes","name":"extra","type":"bytes"}],"internalType":"struct CallData[]","name":"callDataList","type":"tuple[]"}],"name":"execTransactions","outputs":[{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"hint","type":"bytes"}],"internalType":"struct TransactionResult[]","name":"resultList","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAccountAddress","outputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllDelegates","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"hasDelegate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_roleManager","type":"address"},{"internalType":"address","name":"_authorizer","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"removeDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_delegates","type":"address[]"}],"name":"removeDelegates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"roleManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"safe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_authorizer","type":"address"}],"name":"setAuthorizer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"setPendingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_roleManager","type":"address"}],"name":"setRoleManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60803460a957601f611b0d38819003918201601f19168301916001600160401b0383118484101760ad5780849260209460405283398101031260a957516001600160a01b0381169081900360a9576001545f80546001600160a01b0319168317815560405192907f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b9080a26001600160a81b031916600160a01b17600155611a4b90816100c28239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080604052600436101561001a575b3615610018575f80fd5b005b5f3560e01c8062435da51461019e578063058a628f1461019957806308dbebf6146101945780630e2562d914610171578063186f03541461017157806347ab91491461018f578063480005cd1461018a57806367e7646f14610185578063715018a614610180578063747235551461017b5780637a4f3764146101765780638da5cb5b14610171578063a3f4df7e1461016c578063c0c53b8b14610167578063c42069ec14610162578063c4d66de81461015d578063d09edf3114610158578063e30c397814610153578063e71bdf411461014e578063eb70037314610149578063ebbc496514610144578063f1d588c51461013f578063f2fde38b1461013a578063f5ff8ef2146101355763ffa1ad740361000e57610c23565b610a8a565b6109a6565b61096f565b610942565b6108ee565b6108b2565b61088a565b610862565b610842565b6107c9565b610780565b610753565b6102ff565b6106d3565b61063d565b61057b565b61053f565b6104f7565b61036d565b610257565b6101db565b346101c6575f3660031901126101c6576002546040516001600160a01b039091168152602090f35b5f80fd5b6001600160a01b038116036101c657565b346101c65760203660031901126101c6576100186004356101fb816101ca565b5f5461021a906001600160a01b0316610212610cae565b903314610ccf565b611009565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90602061025492818152019061021f565b90565b346101c6575f3660031901126101c6576040516351fa6fbf60e11b8152602081600481305afa9081156102fa575f916102c6575b6102c26102a86102b6846040519283916020830160209181520190565b03601f198101835282610c72565b60405191829182610243565b0390f35b90506020813d6020116102f2575b816102e160209383610c72565b810103126101c657516102a861028b565b3d91506102d4565b610cff565b346101c6575f3660031901126101c6575f546040516001600160a01b039091168152602090f35b61025491815115158152604061034b602084015160606020850152606084019061021f565b92015190604081840391015261021f565b906020610254928181520190610326565b346101c65760203660031901126101c6576004356001600160401b0381116101c6578060040160c060031983360301126101c6576102c2916103ad610d0a565b506103d46103c6335f52600560205260405f2054151590565b6103ce610d29565b90610ccf565b6103dc610d4a565b5f549092906103fc906001600160a01b03165b6001600160a01b03168452565b33602084015280356040840152602482019261042a61041a85610d97565b6001600160a01b03166060830152565b7e0f8708785e90dac3172a799e69be02455af248d971acdd26dc38e07cdb596b6104e86104c46104be6044870135968760808701526104a161047960a46064840193610480610479868d610da1565b3691610dd3565b60a08b0152610495610479608483018d610da1565b60c08b01520189610da1565b60e08701526104b86104b287611183565b99610d97565b96610da1565b90610e09565b6040516001600160e01b0319909116946001600160a01b0316939091829182610ecd565b0390a46040519182918261035c565b346101c65760203660031901126101c6576020610535600435610519816101ca565b6001600160a01b03165f90815260056020526040902054151590565b6040519015158152f35b346101c65760203660031901126101c65761001860043561055f816101ca565b5f54610576906001600160a01b0316610212610cae565b6113a1565b346101c6575f3660031901126101c6575f546105a2906001600160a01b0316610212610cae565b6001600160601b0360a01b5f54165f556001600160601b0360a01b600154166001555f7f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b8180a2005b9060206003198301126101c6576004356001600160401b0381116101c65760040182601f820112156101c6578035926001600160401b0384116101c6576020808301928560051b0101116101c6579190565b346101c65761064b366105eb565b5f54909190610665906001600160a01b0316610212610cae565b5f5b82811061067057005b8061068b6106816001938686610ef2565b35610576816101ca565b01610667565b60206040818301928281528451809452019201905f5b8181106106b45750505090565b82516001600160a01b03168452602093840193909201916001016106a7565b346101c6575f3660031901126101c65760405180602060045491828152019060045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b905f5b81811061073d576102c28561073181870382610c72565b60405191829182610691565b825484526020909301926001928301920161071a565b346101c6575f3660031901126101c6576040516e10dbd89bd4d859995058d8dbdd5b9d608a1b8152602090f35b346101c65760603660031901126101c6576100186004356107a0816101ca565b61021a6024356107af816101ca565b6107c4604435936107bf856101ca565b610f07565b611432565b346101c65760203660031901126101c6576004356107e6816101ca565b5f546107fd906001600160a01b0316610212610cae565b600180546001600160a01b0319166001600160a01b039290921691821790557f68f49b346b94582a8b5f9d10e3fe3365318fe8f191ff8dce7c59c6cad06b02f55f80a2005b346101c65760203660031901126101c6576100186004356107bf816101ca565b346101c6575f3660031901126101c6576003546040516001600160a01b039091168152602090f35b346101c6575f3660031901126101c6576001546040516001600160a01b039091168152602090f35b346101c65760203660031901126101c6576100186004356108d2816101ca565b5f546108e9906001600160a01b0316610212610cae565b611477565b346101c6576108fc366105eb565b5f54909190610916906001600160a01b0316610212610cae565b5f5b82811061092157005b8061093c6109326001938686610ef2565b356108e9816101ca565b01610918565b346101c6575f3660031901126101c6576001546001600160a01b0316338190036101c657610018906113e0565b346101c65760203660031901126101c65761001860043561098f816101ca565b5f546107c4906001600160a01b0316610212610cae565b346101c65760203660031901126101c6576004356109c3816101ca565b5f546109da906001600160a01b0316610212610cae565b6001600160a01b038116156109f257610018906113e0565b60405162461bcd60e51b81526020600482015260116024820152704e6577204f776e6572206973207a65726f60781b6044820152606490fd5b602081016020825282518091526040820191602060408360051b8301019401925f915b838310610a5d57505050505090565b9091929394602080610a7b600193603f198682030187528951610326565b97019301930191939290610a4e565b346101c657610a98366105eb565b90610ab16103c6335f52600560205260405f2054151590565b610ab9610d4a565b5f54909290610ad0906001600160a01b03166103ef565b336020840152610adf81610f84565b925f906060810192608082019360a0830193604084019260c085019060e08601925b818110610b1657604051806102c28d82610a2b565b610b2181838c610fd3565b8b6020820191610b3083610d97565b6001600160a01b03168852604081013592838d526060820192610b538484610da1565b3690610b5e92610dd3565b8d5282358b52610b716080840184610da1565b3690610b7c92610dd3565b8852610b8b60a0840184610da1565b3690610b9692610dd3565b895285610ba28d611183565b610bac8284610ff5565b52610bb691610ff5565b50610bc090610d97565b91610bca91610da1565b610bd391610e09565b6040516001600160e01b0319909116916001600160a01b03169080610bf88c82610ecd565b037e0f8708785e90dac3172a799e69be02455af248d971acdd26dc38e07cdb596b91a4600101610b01565b346101c6575f3660031901126101c657602060405160028152f35b634e487b7160e01b5f52604160045260245ffd5b606081019081106001600160401b03821117610c6d57604052565b610c3e565b90601f801991011681019081106001600160401b03821117610c6d57604052565b6001600160401b038111610c6d57601f01601f191660200190565b60405190610cbd604083610c72565b600382526245333560e81b6020830152565b15610cd75750565b60405162461bcd60e51b815260206004820152908190610cfb90602483019061021f565b0390fd5b6040513d5f823e3d90fd5b60405190610d1782610c52565b60606040835f81528260208201520152565b60405190610d38604083610c72565b600382526245343160e81b6020830152565b6040519061010082018281106001600160401b03821117610c6d57604052606060e0835f81525f60208201525f60408201525f838201525f60808201528260a08201528260c08201520152565b35610254816101ca565b903590601e19813603018212156101c657018035906001600160401b0382116101c6576020019181360383136101c657565b929192610ddf82610c93565b91610ded6040519384610c72565b8294818452818301116101c6578281602093845f960137010152565b356001600160e01b0319811692919060048210610e24575050565b6001600160e01b031960049290920360031b82901b16169150565b80516001600160a01b03168252610254916020828101516001600160a01b031690820152604082810151908201526060808301516001600160a01b0316908201526080820151608082015260e0610ebc610eaa60a085015161010060a086015261010085019061021f565b60c085015184820360c086015261021f565b9201519060e081840391015261021f565b906020610254928181520190610e3f565b634e487b7160e01b5f52603260045260245ffd5b9190811015610f025760051b0190565b610ede565b60ff60015460a01c16610f3257610f1d906113e0565b6001805460ff60a01b1916600160a01b179055565b60405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606490fd5b6001600160401b038111610c6d5760051b60200190565b90610f8e82610f6d565b610f9b6040519182610c72565b8281528092610fac601f1991610f6d565b01905f5b828110610fbc57505050565b602090610fc7610d0a565b82828501015201610fb0565b9190811015610f025760051b8101359060be19813603018212156101c6570190565b8051821015610f025760209160051b010190565b600380546001600160a01b0319166001600160a01b039290921691821790557fb251079a3e59729d2256949e48e44b7959908cdf34789078b6a1462ec32767205f80a2565b6040519061105d604083610c72565b6003825262114d0d60ea1b6020830152565b908160209103126101c6575190565b6040519061108d604083610c72565b600382526245343560e81b6020830152565b9291926110ab82610c93565b916110b96040519384610c72565b8294818452818301116101c6578281602093845f96015e010152565b9080601f830112156101c65781516102549260200161109f565b906020828203126101c65781516001600160401b0381116101c65761025492016110d5565b6002111561111e57565b634e487b7160e01b5f52602160045260245ffd5b61025491815161114181611114565b8152604061034b602084015160606020850152606084019061021f565b909161117561025493604084526040840190611132565b916020818403910152611132565b9061118c610d0a565b506003546004906020906111cf906111c3906001600160a01b03166111c36111b261104e565b6001600160a01b0383161515610ccf565b6001600160a01b031690565b604051631121d74d60e31b815292839182905afa9081156102fa575f91611372575b5060c0830151511561120d611205836114b6565b6103ce61107e565b611215610d0a565b90809281159384611366575b611355575b60048116611347575b611238866116d7565b9561125061124c6040830151600216151590565b1590565b611339575b61125d610d0a565b94839061132d575b61131a575b866008831661130a575b5050816112fd575b50611285575050565b6003546112c1925f9290916112a4906111c3906001600160a01b031681565b90604051809581948293636f6a565960e01b84526004840161115e565b03915afa9081156102fa575f916112db575b506040830152565b6112f791503d805f833e6112ef8183610c72565b8101906110ef565b5f6112d3565b604016151590505f61127c565b61131391611825565b5f86611274565b93506113278387866117b8565b9361126a565b50600282161515611265565b611342876117a2565b611255565b6113508661160e565b61122f565b91506113608561156b565b91611226565b50600181161515611221565b611394915060203d60201161139a575b61138c8183610c72565b81019061106f565b5f6111f1565b503d611382565b6001600160a01b03166113b381611909565b6113ba5750565b7f5a362b199d4fb2bd4e51a3436d86df24cb19b1b0890da774e2b54253d53aa4eb5f80a2565b60018060a01b0316806001600160601b0360a01b5f5416175f556001600160601b0360a01b600154166001557f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b5f80a2565b600280546001600160a01b0319166001600160a01b039290921691821790557f765235f6b1f9df25a0fa901c365a8db93771de0abb8f48ffed12959c5c4d59b95f80a2565b6001600160a01b0316611489816119a7565b6114905750565b7f3be018e2afae1fe2bb23bb3cc019524cfe3872f2863d1c80b7a228c57bc1065a5f80a2565b6001811615908115916114c7575090565b6002915016151590565b6020818303126101c6578051906001600160401b0382116101c657016060818303126101c6576040519161150483610c52565b815160028110156101c657835260208201516001600160401b0381116101c657820181601f820112156101c657818160206115419351910161109f565b602084015260408201516001600160401b0381116101c65761156392016110d5565b604082015290565b905f6115af819361157a610d0a565b5060035460405163f266002760e01b8152602060048201529586936001600160a01b0390921692849283916024830190610e3f565b03925af19182156102fa575f926115ea575b506115e882600160208251926115d684611114565b6115df84611114565b01519114610ccf565b565b6116079192503d805f833e6115ff8183610c72565b8101906114d1565b905f6115c1565b6003546001600160a01b0316803b156101c65760405163d58c3fc360e01b815260206004820152915f91839182908490829061164e906024830190610e3f565b03925af180156102fa5761165f5750565b5f6115e891610c72565b9190916040818403126101c657805180151581036101c6579260208201516001600160401b0381116101c65761025492016110d5565b9493926060926116c99260018060a01b03168752602087015260806040870152608086019061021f565b936116d383611114565b0152565b906116e0610d0a565b915f6116fb6111c36111c36111c3845460018060a01b031690565b60608301519092906001600160a01b0316926080820151611727604060a0850151940151600116151590565b841461179a57836001955b61175260405197889687958694635229073f60e01b86526004860161169f565b03925af19081156102fa576115e8915f915f91611776575b50602085015215158352565b905061179491503d805f833e61178c8183610c72565b810190611669565b5f61176a565b838095611732565b6020815115910151906117b25750565b60208101fd5b9061181393926118015f80946117cc610d0a565b506115af60018060a01b036003541694604051998a97889687956313aa451d60e31b8752606060048801526064870190610e3f565b85810360031901602487015290610326565b83810360031901604485015290611132565b6003546001600160a01b031691823b156101c65761164e926118685f809460405196879586948593637c4c833b60e01b8552604060048601526044850190610e3f565b83810360031901602485015290610326565b5f1981019190821161188857565b634e487b7160e01b5f52601160045260245ffd5b8054821015610f02575f5260205f2001905f90565b916118ca9183549060031b91821b915f19901b19161790565b9055565b805480156118f5575f1901906118e4828261189c565b8154905f199060031b1b1916905555565b634e487b7160e01b5f52603160045260245ffd5b5f818152600560205260409020549081156119a1575f19820190828211611888575f926119609261193b60045461187a565b90818103611966575b50505061195160046118ce565b6005905f5260205260405f2090565b55600190565b6119516119929161198861197e61199895600461189c565b90549060031b1c90565b928391600461189c565b906118b1565b555f8080611944565b50505f90565b5f81815260056020526040902054611a105760045468010000000000000000811015610c6d576119f96119e3826001859401600455600461189c565b819391549060031b91821b915f19901b19161790565b9055600454905f52600560205260405f2055600190565b505f9056fea26469706673582212202d7565aee5f1d800c26100383566f80d0a0d0ed3bd34f23089b988cca6282b6564736f6c634300081a00330000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436101561001a575b3615610018575f80fd5b005b5f3560e01c8062435da51461019e578063058a628f1461019957806308dbebf6146101945780630e2562d914610171578063186f03541461017157806347ab91491461018f578063480005cd1461018a57806367e7646f14610185578063715018a614610180578063747235551461017b5780637a4f3764146101765780638da5cb5b14610171578063a3f4df7e1461016c578063c0c53b8b14610167578063c42069ec14610162578063c4d66de81461015d578063d09edf3114610158578063e30c397814610153578063e71bdf411461014e578063eb70037314610149578063ebbc496514610144578063f1d588c51461013f578063f2fde38b1461013a578063f5ff8ef2146101355763ffa1ad740361000e57610c23565b610a8a565b6109a6565b61096f565b610942565b6108ee565b6108b2565b61088a565b610862565b610842565b6107c9565b610780565b610753565b6102ff565b6106d3565b61063d565b61057b565b61053f565b6104f7565b61036d565b610257565b6101db565b346101c6575f3660031901126101c6576002546040516001600160a01b039091168152602090f35b5f80fd5b6001600160a01b038116036101c657565b346101c65760203660031901126101c6576100186004356101fb816101ca565b5f5461021a906001600160a01b0316610212610cae565b903314610ccf565b611009565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90602061025492818152019061021f565b90565b346101c6575f3660031901126101c6576040516351fa6fbf60e11b8152602081600481305afa9081156102fa575f916102c6575b6102c26102a86102b6846040519283916020830160209181520190565b03601f198101835282610c72565b60405191829182610243565b0390f35b90506020813d6020116102f2575b816102e160209383610c72565b810103126101c657516102a861028b565b3d91506102d4565b610cff565b346101c6575f3660031901126101c6575f546040516001600160a01b039091168152602090f35b61025491815115158152604061034b602084015160606020850152606084019061021f565b92015190604081840391015261021f565b906020610254928181520190610326565b346101c65760203660031901126101c6576004356001600160401b0381116101c6578060040160c060031983360301126101c6576102c2916103ad610d0a565b506103d46103c6335f52600560205260405f2054151590565b6103ce610d29565b90610ccf565b6103dc610d4a565b5f549092906103fc906001600160a01b03165b6001600160a01b03168452565b33602084015280356040840152602482019261042a61041a85610d97565b6001600160a01b03166060830152565b7e0f8708785e90dac3172a799e69be02455af248d971acdd26dc38e07cdb596b6104e86104c46104be6044870135968760808701526104a161047960a46064840193610480610479868d610da1565b3691610dd3565b60a08b0152610495610479608483018d610da1565b60c08b01520189610da1565b60e08701526104b86104b287611183565b99610d97565b96610da1565b90610e09565b6040516001600160e01b0319909116946001600160a01b0316939091829182610ecd565b0390a46040519182918261035c565b346101c65760203660031901126101c6576020610535600435610519816101ca565b6001600160a01b03165f90815260056020526040902054151590565b6040519015158152f35b346101c65760203660031901126101c65761001860043561055f816101ca565b5f54610576906001600160a01b0316610212610cae565b6113a1565b346101c6575f3660031901126101c6575f546105a2906001600160a01b0316610212610cae565b6001600160601b0360a01b5f54165f556001600160601b0360a01b600154166001555f7f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b8180a2005b9060206003198301126101c6576004356001600160401b0381116101c65760040182601f820112156101c6578035926001600160401b0384116101c6576020808301928560051b0101116101c6579190565b346101c65761064b366105eb565b5f54909190610665906001600160a01b0316610212610cae565b5f5b82811061067057005b8061068b6106816001938686610ef2565b35610576816101ca565b01610667565b60206040818301928281528451809452019201905f5b8181106106b45750505090565b82516001600160a01b03168452602093840193909201916001016106a7565b346101c6575f3660031901126101c65760405180602060045491828152019060045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b905f5b81811061073d576102c28561073181870382610c72565b60405191829182610691565b825484526020909301926001928301920161071a565b346101c6575f3660031901126101c6576040516e10dbd89bd4d859995058d8dbdd5b9d608a1b8152602090f35b346101c65760603660031901126101c6576100186004356107a0816101ca565b61021a6024356107af816101ca565b6107c4604435936107bf856101ca565b610f07565b611432565b346101c65760203660031901126101c6576004356107e6816101ca565b5f546107fd906001600160a01b0316610212610cae565b600180546001600160a01b0319166001600160a01b039290921691821790557f68f49b346b94582a8b5f9d10e3fe3365318fe8f191ff8dce7c59c6cad06b02f55f80a2005b346101c65760203660031901126101c6576100186004356107bf816101ca565b346101c6575f3660031901126101c6576003546040516001600160a01b039091168152602090f35b346101c6575f3660031901126101c6576001546040516001600160a01b039091168152602090f35b346101c65760203660031901126101c6576100186004356108d2816101ca565b5f546108e9906001600160a01b0316610212610cae565b611477565b346101c6576108fc366105eb565b5f54909190610916906001600160a01b0316610212610cae565b5f5b82811061092157005b8061093c6109326001938686610ef2565b356108e9816101ca565b01610918565b346101c6575f3660031901126101c6576001546001600160a01b0316338190036101c657610018906113e0565b346101c65760203660031901126101c65761001860043561098f816101ca565b5f546107c4906001600160a01b0316610212610cae565b346101c65760203660031901126101c6576004356109c3816101ca565b5f546109da906001600160a01b0316610212610cae565b6001600160a01b038116156109f257610018906113e0565b60405162461bcd60e51b81526020600482015260116024820152704e6577204f776e6572206973207a65726f60781b6044820152606490fd5b602081016020825282518091526040820191602060408360051b8301019401925f915b838310610a5d57505050505090565b9091929394602080610a7b600193603f198682030187528951610326565b97019301930191939290610a4e565b346101c657610a98366105eb565b90610ab16103c6335f52600560205260405f2054151590565b610ab9610d4a565b5f54909290610ad0906001600160a01b03166103ef565b336020840152610adf81610f84565b925f906060810192608082019360a0830193604084019260c085019060e08601925b818110610b1657604051806102c28d82610a2b565b610b2181838c610fd3565b8b6020820191610b3083610d97565b6001600160a01b03168852604081013592838d526060820192610b538484610da1565b3690610b5e92610dd3565b8d5282358b52610b716080840184610da1565b3690610b7c92610dd3565b8852610b8b60a0840184610da1565b3690610b9692610dd3565b895285610ba28d611183565b610bac8284610ff5565b52610bb691610ff5565b50610bc090610d97565b91610bca91610da1565b610bd391610e09565b6040516001600160e01b0319909116916001600160a01b03169080610bf88c82610ecd565b037e0f8708785e90dac3172a799e69be02455af248d971acdd26dc38e07cdb596b91a4600101610b01565b346101c6575f3660031901126101c657602060405160028152f35b634e487b7160e01b5f52604160045260245ffd5b606081019081106001600160401b03821117610c6d57604052565b610c3e565b90601f801991011681019081106001600160401b03821117610c6d57604052565b6001600160401b038111610c6d57601f01601f191660200190565b60405190610cbd604083610c72565b600382526245333560e81b6020830152565b15610cd75750565b60405162461bcd60e51b815260206004820152908190610cfb90602483019061021f565b0390fd5b6040513d5f823e3d90fd5b60405190610d1782610c52565b60606040835f81528260208201520152565b60405190610d38604083610c72565b600382526245343160e81b6020830152565b6040519061010082018281106001600160401b03821117610c6d57604052606060e0835f81525f60208201525f60408201525f838201525f60808201528260a08201528260c08201520152565b35610254816101ca565b903590601e19813603018212156101c657018035906001600160401b0382116101c6576020019181360383136101c657565b929192610ddf82610c93565b91610ded6040519384610c72565b8294818452818301116101c6578281602093845f960137010152565b356001600160e01b0319811692919060048210610e24575050565b6001600160e01b031960049290920360031b82901b16169150565b80516001600160a01b03168252610254916020828101516001600160a01b031690820152604082810151908201526060808301516001600160a01b0316908201526080820151608082015260e0610ebc610eaa60a085015161010060a086015261010085019061021f565b60c085015184820360c086015261021f565b9201519060e081840391015261021f565b906020610254928181520190610e3f565b634e487b7160e01b5f52603260045260245ffd5b9190811015610f025760051b0190565b610ede565b60ff60015460a01c16610f3257610f1d906113e0565b6001805460ff60a01b1916600160a01b179055565b60405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606490fd5b6001600160401b038111610c6d5760051b60200190565b90610f8e82610f6d565b610f9b6040519182610c72565b8281528092610fac601f1991610f6d565b01905f5b828110610fbc57505050565b602090610fc7610d0a565b82828501015201610fb0565b9190811015610f025760051b8101359060be19813603018212156101c6570190565b8051821015610f025760209160051b010190565b600380546001600160a01b0319166001600160a01b039290921691821790557fb251079a3e59729d2256949e48e44b7959908cdf34789078b6a1462ec32767205f80a2565b6040519061105d604083610c72565b6003825262114d0d60ea1b6020830152565b908160209103126101c6575190565b6040519061108d604083610c72565b600382526245343560e81b6020830152565b9291926110ab82610c93565b916110b96040519384610c72565b8294818452818301116101c6578281602093845f96015e010152565b9080601f830112156101c65781516102549260200161109f565b906020828203126101c65781516001600160401b0381116101c65761025492016110d5565b6002111561111e57565b634e487b7160e01b5f52602160045260245ffd5b61025491815161114181611114565b8152604061034b602084015160606020850152606084019061021f565b909161117561025493604084526040840190611132565b916020818403910152611132565b9061118c610d0a565b506003546004906020906111cf906111c3906001600160a01b03166111c36111b261104e565b6001600160a01b0383161515610ccf565b6001600160a01b031690565b604051631121d74d60e31b815292839182905afa9081156102fa575f91611372575b5060c0830151511561120d611205836114b6565b6103ce61107e565b611215610d0a565b90809281159384611366575b611355575b60048116611347575b611238866116d7565b9561125061124c6040830151600216151590565b1590565b611339575b61125d610d0a565b94839061132d575b61131a575b866008831661130a575b5050816112fd575b50611285575050565b6003546112c1925f9290916112a4906111c3906001600160a01b031681565b90604051809581948293636f6a565960e01b84526004840161115e565b03915afa9081156102fa575f916112db575b506040830152565b6112f791503d805f833e6112ef8183610c72565b8101906110ef565b5f6112d3565b604016151590505f61127c565b61131391611825565b5f86611274565b93506113278387866117b8565b9361126a565b50600282161515611265565b611342876117a2565b611255565b6113508661160e565b61122f565b91506113608561156b565b91611226565b50600181161515611221565b611394915060203d60201161139a575b61138c8183610c72565b81019061106f565b5f6111f1565b503d611382565b6001600160a01b03166113b381611909565b6113ba5750565b7f5a362b199d4fb2bd4e51a3436d86df24cb19b1b0890da774e2b54253d53aa4eb5f80a2565b60018060a01b0316806001600160601b0360a01b5f5416175f556001600160601b0360a01b600154166001557f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b5f80a2565b600280546001600160a01b0319166001600160a01b039290921691821790557f765235f6b1f9df25a0fa901c365a8db93771de0abb8f48ffed12959c5c4d59b95f80a2565b6001600160a01b0316611489816119a7565b6114905750565b7f3be018e2afae1fe2bb23bb3cc019524cfe3872f2863d1c80b7a228c57bc1065a5f80a2565b6001811615908115916114c7575090565b6002915016151590565b6020818303126101c6578051906001600160401b0382116101c657016060818303126101c6576040519161150483610c52565b815160028110156101c657835260208201516001600160401b0381116101c657820181601f820112156101c657818160206115419351910161109f565b602084015260408201516001600160401b0381116101c65761156392016110d5565b604082015290565b905f6115af819361157a610d0a565b5060035460405163f266002760e01b8152602060048201529586936001600160a01b0390921692849283916024830190610e3f565b03925af19182156102fa575f926115ea575b506115e882600160208251926115d684611114565b6115df84611114565b01519114610ccf565b565b6116079192503d805f833e6115ff8183610c72565b8101906114d1565b905f6115c1565b6003546001600160a01b0316803b156101c65760405163d58c3fc360e01b815260206004820152915f91839182908490829061164e906024830190610e3f565b03925af180156102fa5761165f5750565b5f6115e891610c72565b9190916040818403126101c657805180151581036101c6579260208201516001600160401b0381116101c65761025492016110d5565b9493926060926116c99260018060a01b03168752602087015260806040870152608086019061021f565b936116d383611114565b0152565b906116e0610d0a565b915f6116fb6111c36111c36111c3845460018060a01b031690565b60608301519092906001600160a01b0316926080820151611727604060a0850151940151600116151590565b841461179a57836001955b61175260405197889687958694635229073f60e01b86526004860161169f565b03925af19081156102fa576115e8915f915f91611776575b50602085015215158352565b905061179491503d805f833e61178c8183610c72565b810190611669565b5f61176a565b838095611732565b6020815115910151906117b25750565b60208101fd5b9061181393926118015f80946117cc610d0a565b506115af60018060a01b036003541694604051998a97889687956313aa451d60e31b8752606060048801526064870190610e3f565b85810360031901602487015290610326565b83810360031901604485015290611132565b6003546001600160a01b031691823b156101c65761164e926118685f809460405196879586948593637c4c833b60e01b8552604060048601526044850190610e3f565b83810360031901602485015290610326565b5f1981019190821161188857565b634e487b7160e01b5f52601160045260245ffd5b8054821015610f02575f5260205f2001905f90565b916118ca9183549060031b91821b915f19901b19161790565b9055565b805480156118f5575f1901906118e4828261189c565b8154905f199060031b1b1916905555565b634e487b7160e01b5f52603160045260245ffd5b5f818152600560205260409020549081156119a1575f19820190828211611888575f926119609261193b60045461187a565b90818103611966575b50505061195160046118ce565b6005905f5260205260405f2090565b55600190565b6119516119929161198861197e61199895600461189c565b90549060031b1c90565b928391600461189c565b906118b1565b555f8080611944565b50505f90565b5f81815260056020526040902054611a105760045468010000000000000000811015610c6d576119f96119e3826001859401600455600461189c565b819391549060031b91821b915f19901b19161790565b9055600454905f52600560205260405f2055600190565b505f9056fea26469706673582212202d7565aee5f1d800c26100383566f80d0a0d0ed3bd34f23089b988cca6282b6564736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _owner (address): 0x0000000000000000000000000000000000000000
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.