Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
FlatRoleManager
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 "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "../../interfaces/IRoleManager.sol"; import "../base/BaseOwnable.sol"; /// @title TransferAuthorizer - Manages delegate-role mapping. /// @author Cobo Safe Dev Team https://www.cobo.com/ contract FlatRoleManager is IFlatRoleManager, BaseOwnable { bytes32 public constant NAME = "FlatRoleManager"; uint256 public constant VERSION = 1; using EnumerableSet for EnumerableSet.Bytes32Set; using EnumerableSet for EnumerableSet.AddressSet; event DelegateAdded(address indexed delegate, address indexed sender); event DelegateRemoved(address indexed delegate, address indexed sender); event RoleAdded(bytes32 indexed role, address indexed sender); event RoleGranted(bytes32 indexed role, address indexed delegate, address indexed sender); event RoleRevoked(bytes32 indexed role, address indexed delegate, address indexed sender); EnumerableSet.AddressSet delegates; EnumerableSet.Bytes32Set roles; /// @dev mapping from `delegate` address => `role` set; mapping(address => EnumerableSet.Bytes32Set) delegateToRoles; constructor(address _owner) BaseOwnable(_owner) {} /// @notice Add new roles without delegates assigned. function addRoles(bytes32[] calldata _roles) external onlyOwner { for (uint256 i = 0; i < _roles.length; i++) { if (roles.add(_roles[i])) { emit RoleAdded(_roles[i], msg.sender); } } } /// @notice Grant roles to delegates. Roles and delegates should be one-to-one. function grantRoles(bytes32[] calldata _roles, address[] calldata _delegates) external onlyOwner { require( _roles.length > 0 && _roles.length == _delegates.length, "FlatRoleManager: Invalid _roles or _delegates" ); for (uint256 i = 0; i < _roles.length; i++) { if (!delegateToRoles[_delegates[i]].add(_roles[i])) { // If already bound, skip. continue; } // In case when role is not added. if (roles.add(_roles[i])) { // Only fired when new one is added. emit RoleAdded(_roles[i], msg.sender); } // Emit `DelegateAdded` before `RoleGranted` to allow // subgraph event handler to process in sensible order. if (delegates.add(_delegates[i])) { emit DelegateAdded(_delegates[i], msg.sender); } emit RoleGranted(_roles[i], _delegates[i], msg.sender); } } /// @notice Revoke roles from delegates. Roles and delegates should be one-to-one. function revokeRoles(bytes32[] calldata _roles, address[] calldata _delegates) external onlyOwner { require( _roles.length > 0 && _roles.length == _delegates.length, "FlatRoleManager: Invalid _roles or _delegates" ); for (uint256 i = 0; i < _roles.length; i++) { if (!delegateToRoles[_delegates[i]].remove(_roles[i])) { continue; } // Ensure `RoleRevoked` is fired before `DelegateRemoved` // so that the event handlers in subgraphs are triggered in the // right order. emit RoleRevoked(_roles[i], _delegates[i], msg.sender); if (delegateToRoles[_delegates[i]].length() == 0) { delegates.remove(_delegates[i]); emit DelegateRemoved(_delegates[i], msg.sender); } } } /// @notice Get all the roles owned by the delegate function getRoles(address delegate) external view returns (bytes32[] memory) { return delegateToRoles[delegate].values(); } /// @notice Check if the delegate owns the role. function hasRole(address delegate, bytes32 role) external view returns (bool) { return delegateToRoles[delegate].contains(role); } /// @notice Get the entire delegates list in the account. function getDelegates() external view returns (address[] memory) { return delegates.values(); } /// @notice Get the entire roles list in the account. function getAllRoles() external view returns (bytes32[] memory) { return roles.values(); } }
// 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; import "../src/Types.sol"; interface IRoleManager { function getRoles(address delegate) external view returns (bytes32[] memory); function hasRole(address delegate, bytes32 role) external view returns (bool); } interface IFlatRoleManager is IRoleManager { function addRoles(bytes32[] calldata roles) external; function grantRoles(bytes32[] calldata roles, address[] calldata delegates) external; function revokeRoles(bytes32[] calldata roles, address[] calldata delegates) external; function getDelegates() external view returns (address[] memory); function getAllRoles() external view returns (bytes32[] memory); }
// 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; 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; /// @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":"delegate","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"DelegateAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":true,"internalType":"address","name":"sender","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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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":"bytes32[]","name":"_roles","type":"bytes32[]"}],"name":"addRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllRoles","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDelegates","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegate","type":"address"}],"name":"getRoles","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_roles","type":"bytes32[]"},{"internalType":"address[]","name":"_delegates","type":"address[]"}],"name":"grantRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegate","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_roles","type":"bytes32[]"},{"internalType":"address[]","name":"_delegates","type":"address[]"}],"name":"revokeRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"setPendingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60803460a957601f610fe938819003918201601f19168301916001600160401b0383118484101760ad5780849260209460405283398101031260a957516001600160a01b0381169081900360a9576001545f80546001600160a01b0319168317815560405192907f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b9080a26001600160a81b031916600160a01b17600155610f2790816100c28239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c90816308dbebf61461093d575080630e54e58d146107af5780631c27e22d146106435780635e7c67db14610595578063715018a6146105255780638da5cb5b146104fe578063a3f4df7e146104d1578063ac4ab3fb1461047f578063c42069ec1461040a578063c4d66de81461038b578063c838ccb6146102cc578063ce6ccfaf1461025a578063e30c397814610232578063ebbc496514610205578063f2bcac3d14610181578063f2fde38b146100f65763ffa1ad74146100d7575f80fd5b346100f2575f3660031901126100f257602060405160018152f35b5f80fd5b346100f25760203660031901126100f25761010f610a81565b5f5461012e906001600160a01b0316610126610b06565b903314610b36565b6001600160a01b038116156101485761014690610bf8565b005b60405162461bcd60e51b81526020600482015260116024820152704e6577204f776e6572206973207a65726f60781b6044820152606490fd5b346100f2575f3660031901126100f25760405180602060045491828152019060045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b905f5b8181106101ef576101eb856101df81870382610ad0565b60405191829182610a97565b0390f35b82548452602090930192600192830192016101c8565b346100f2575f3660031901126100f2576001546001600160a01b0316338190036100f25761014690610bf8565b346100f2575f3660031901126100f2576001546040516001600160a01b039091168152602090f35b346100f25760203660031901126100f2576001600160a01b0361027b610a81565b165f52600660205260405f206040519081602082549182815201915f5260205f20905f5b8181106102b6576101eb856101df81870382610ad0565b825484526020909301926001928301920161029f565b346100f2575f3660031901126100f2576040518060206002549283815201809260025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace905f5b818110610375575050508161032a910382610ad0565b604051918291602083019060208452518091526040830191905f5b818110610353575050500390f35b82516001600160a01b0316845285945060209384019390920191600101610345565b8254845260209093019260019283019201610314565b346100f25760203660031901126100f2576103a4610a81565b60ff60015460a01c166103cf576103ba90610bf8565b6001805460ff60a01b1916600160a01b179055005b60405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606490fd5b346100f25760203660031901126100f257610423610a81565b5f5461043a906001600160a01b0316610126610b06565b600180546001600160a01b0319166001600160a01b039290921691821790557f68f49b346b94582a8b5f9d10e3fe3365318fe8f191ff8dce7c59c6cad06b02f55f80a2005b346100f25760403660031901126100f2576001600160a01b036104a0610a81565b165f52600660205260206104c760243560405f206001915f520160205260405f2054151590565b6040519015158152f35b346100f2575f3660031901126100f2576040516e233630ba2937b632a6b0b730b3b2b960891b8152602090f35b346100f2575f3660031901126100f2575f546040516001600160a01b039091168152602090f35b346100f2575f3660031901126100f2575f5461054c906001600160a01b0316610126610b06565b6001600160601b0360a01b5f54165f556001600160601b0360a01b600154166001555f7f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b8180a2005b346100f25760203660031901126100f25760043567ffffffffffffffff81116100f2576105c69036906004016109fe565b5f549091906105e0906001600160a01b0316610126610b06565b5f5b8281106105eb57005b806106026105fc6001938686610bc0565b35610c5f565b61060d575b016105e2565b33610619828686610bc0565b357f400b1a91f3c12e695abb38f7fc20dd2cf26f6d9c4d1dc817d39a98b51f146f785f80a3610607565b346100f25761065136610a2f565b5f5492939290919061066e906001600160a01b0316610126610b06565b831515806107a6575b61068090610b5e565b5f5b84811061068b57005b6001906001600160a01b036106a96106a4838787610bc0565b610be4565b165f5260066020526106ca60405f206106c3838989610bc0565b3590610e40565b156107a1576106da818787610bc0565b353390838060a01b036106f16106a4858989610bc0565b16907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b5f80a4818060a01b0361072b6106a4838787610bc0565b165f52600660205260405f205415610744575b01610682565b610761828060a01b0361075b6106a4848888610bc0565b16610d6d565b5033828060a01b036107776106a4848888610bc0565b167fe8514dd4be968431135580c26314ec35afafc8178268603f99625584960d9c165f80a361073e565b61073e565b50838214610677565b346100f2576107bd36610a2f565b5f549293929091906107da906001600160a01b0316610126610b06565b83151580610934575b6107ec90610b5e565b5f5b8481106107f757005b6001906001600160a01b036108106106a4838787610bc0565b165f52600660205261083160405f2061082a838989610bc0565b3590610d1a565b1561092f576108446105fc828888610bc0565b6108f9575b610866828060a01b036108606106a4848888610bc0565b16610cca565b6108ba575b610876818787610bc0565b353390838060a01b0361088d6106a4858989610bc0565b16907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a45b016107ee565b33828060a01b036108cf6106a4848888610bc0565b167f12dade473695d73bd34e031c850d5e815fa17a42b1b5ba13ff72de2497c5e3095f80a361086b565b33610905828888610bc0565b357f400b1a91f3c12e695abb38f7fc20dd2cf26f6d9c4d1dc817d39a98b51f146f785f80a3610849565b6108b4565b508382146107e3565b346100f2575f3660031901126100f2576351fa6fbf60e11b8152602081600481305afa80156109c9575f90610995575b6101eb9060405190602082015260208152610989604082610ad0565b604051918291826109d4565b506020813d6020116109c1575b816109af60209383610ad0565b810103126100f2576101eb905161096d565b3d91506109a2565b6040513d5f823e3d90fd5b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b9181601f840112156100f25782359167ffffffffffffffff83116100f2576020808501948460051b0101116100f257565b60406003198201126100f25760043567ffffffffffffffff81116100f25781610a5a916004016109fe565b929092916024359067ffffffffffffffff82116100f257610a7d916004016109fe565b9091565b600435906001600160a01b03821682036100f257565b60206040818301928281528451809452019201905f5b818110610aba5750505090565b8251845260209384019390920191600101610aad565b90601f8019910116810190811067ffffffffffffffff821117610af257604052565b634e487b7160e01b5f52604160045260245ffd5b604051906040820182811067ffffffffffffffff821117610af257604052600382526245333560e81b6020830152565b15610b3e5750565b60405162461bcd60e51b8152908190610b5a90600483016109d4565b0390fd5b15610b6557565b60405162461bcd60e51b815260206004820152602d60248201527f466c6174526f6c654d616e616765723a20496e76616c6964205f726f6c65732060448201526c6f72205f64656c65676174657360981b6064820152608490fd5b9190811015610bd05760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036100f25790565b60018060a01b0316806001600160601b0360a01b5f5416175f556001600160601b0360a01b600154166001557f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b5f80a2565b8054821015610bd0575f5260205f2001905f90565b805f52600560205260405f2054155f14610cc557600454600160401b811015610af257610cae610c988260018594016004556004610c4a565b819391549060031b91821b915f19901b19161790565b9055600454905f52600560205260405f2055600190565b505f90565b805f52600360205260405f2054155f14610cc557600254600160401b811015610af257610d03610c988260018594016002556002610c4a565b9055600254905f52600360205260405f2055600190565b5f828152600182016020526040902054610d6757805490600160401b821015610af25782610d52610c98846001809601855584610c4a565b90558054925f520160205260405f2055600190565b50505f90565b5f818152600360205260409020548015610d67575f198101818111610e2c576002545f19810191908211610e2c57818103610df4575b5050506002548015610de0575f1901610dbd816002610c4a565b8154905f199060031b1b191690556002555f5260036020525f6040812055600190565b634e487b7160e01b5f52603160045260245ffd5b610e16610e05610c98936002610c4a565b90549060031b1c9283926002610c4a565b90555f52600360205260405f20555f8080610da3565b634e487b7160e01b5f52601160045260245ffd5b906001820191815f528260205260405f20548015155f14610ee9575f198101818111610e2c5782545f19810191908211610e2c57818103610eb4575b50505080548015610de0575f190190610e958282610c4a565b8154905f199060031b1b19169055555f526020525f6040812055600190565b610ed4610ec4610c989386610c4a565b90549060031b1c92839286610c4a565b90555f528360205260405f20555f8080610e7c565b505050505f9056fea2646970667358221220fdea897c6e009a3814fb673f604ab86905e654d26439fd91bf349ffe156c83d264736f6c634300081a00330000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f3560e01c90816308dbebf61461093d575080630e54e58d146107af5780631c27e22d146106435780635e7c67db14610595578063715018a6146105255780638da5cb5b146104fe578063a3f4df7e146104d1578063ac4ab3fb1461047f578063c42069ec1461040a578063c4d66de81461038b578063c838ccb6146102cc578063ce6ccfaf1461025a578063e30c397814610232578063ebbc496514610205578063f2bcac3d14610181578063f2fde38b146100f65763ffa1ad74146100d7575f80fd5b346100f2575f3660031901126100f257602060405160018152f35b5f80fd5b346100f25760203660031901126100f25761010f610a81565b5f5461012e906001600160a01b0316610126610b06565b903314610b36565b6001600160a01b038116156101485761014690610bf8565b005b60405162461bcd60e51b81526020600482015260116024820152704e6577204f776e6572206973207a65726f60781b6044820152606490fd5b346100f2575f3660031901126100f25760405180602060045491828152019060045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b905f5b8181106101ef576101eb856101df81870382610ad0565b60405191829182610a97565b0390f35b82548452602090930192600192830192016101c8565b346100f2575f3660031901126100f2576001546001600160a01b0316338190036100f25761014690610bf8565b346100f2575f3660031901126100f2576001546040516001600160a01b039091168152602090f35b346100f25760203660031901126100f2576001600160a01b0361027b610a81565b165f52600660205260405f206040519081602082549182815201915f5260205f20905f5b8181106102b6576101eb856101df81870382610ad0565b825484526020909301926001928301920161029f565b346100f2575f3660031901126100f2576040518060206002549283815201809260025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace905f5b818110610375575050508161032a910382610ad0565b604051918291602083019060208452518091526040830191905f5b818110610353575050500390f35b82516001600160a01b0316845285945060209384019390920191600101610345565b8254845260209093019260019283019201610314565b346100f25760203660031901126100f2576103a4610a81565b60ff60015460a01c166103cf576103ba90610bf8565b6001805460ff60a01b1916600160a01b179055005b60405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606490fd5b346100f25760203660031901126100f257610423610a81565b5f5461043a906001600160a01b0316610126610b06565b600180546001600160a01b0319166001600160a01b039290921691821790557f68f49b346b94582a8b5f9d10e3fe3365318fe8f191ff8dce7c59c6cad06b02f55f80a2005b346100f25760403660031901126100f2576001600160a01b036104a0610a81565b165f52600660205260206104c760243560405f206001915f520160205260405f2054151590565b6040519015158152f35b346100f2575f3660031901126100f2576040516e233630ba2937b632a6b0b730b3b2b960891b8152602090f35b346100f2575f3660031901126100f2575f546040516001600160a01b039091168152602090f35b346100f2575f3660031901126100f2575f5461054c906001600160a01b0316610126610b06565b6001600160601b0360a01b5f54165f556001600160601b0360a01b600154166001555f7f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b8180a2005b346100f25760203660031901126100f25760043567ffffffffffffffff81116100f2576105c69036906004016109fe565b5f549091906105e0906001600160a01b0316610126610b06565b5f5b8281106105eb57005b806106026105fc6001938686610bc0565b35610c5f565b61060d575b016105e2565b33610619828686610bc0565b357f400b1a91f3c12e695abb38f7fc20dd2cf26f6d9c4d1dc817d39a98b51f146f785f80a3610607565b346100f25761065136610a2f565b5f5492939290919061066e906001600160a01b0316610126610b06565b831515806107a6575b61068090610b5e565b5f5b84811061068b57005b6001906001600160a01b036106a96106a4838787610bc0565b610be4565b165f5260066020526106ca60405f206106c3838989610bc0565b3590610e40565b156107a1576106da818787610bc0565b353390838060a01b036106f16106a4858989610bc0565b16907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b5f80a4818060a01b0361072b6106a4838787610bc0565b165f52600660205260405f205415610744575b01610682565b610761828060a01b0361075b6106a4848888610bc0565b16610d6d565b5033828060a01b036107776106a4848888610bc0565b167fe8514dd4be968431135580c26314ec35afafc8178268603f99625584960d9c165f80a361073e565b61073e565b50838214610677565b346100f2576107bd36610a2f565b5f549293929091906107da906001600160a01b0316610126610b06565b83151580610934575b6107ec90610b5e565b5f5b8481106107f757005b6001906001600160a01b036108106106a4838787610bc0565b165f52600660205261083160405f2061082a838989610bc0565b3590610d1a565b1561092f576108446105fc828888610bc0565b6108f9575b610866828060a01b036108606106a4848888610bc0565b16610cca565b6108ba575b610876818787610bc0565b353390838060a01b0361088d6106a4858989610bc0565b16907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a45b016107ee565b33828060a01b036108cf6106a4848888610bc0565b167f12dade473695d73bd34e031c850d5e815fa17a42b1b5ba13ff72de2497c5e3095f80a361086b565b33610905828888610bc0565b357f400b1a91f3c12e695abb38f7fc20dd2cf26f6d9c4d1dc817d39a98b51f146f785f80a3610849565b6108b4565b508382146107e3565b346100f2575f3660031901126100f2576351fa6fbf60e11b8152602081600481305afa80156109c9575f90610995575b6101eb9060405190602082015260208152610989604082610ad0565b604051918291826109d4565b506020813d6020116109c1575b816109af60209383610ad0565b810103126100f2576101eb905161096d565b3d91506109a2565b6040513d5f823e3d90fd5b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b9181601f840112156100f25782359167ffffffffffffffff83116100f2576020808501948460051b0101116100f257565b60406003198201126100f25760043567ffffffffffffffff81116100f25781610a5a916004016109fe565b929092916024359067ffffffffffffffff82116100f257610a7d916004016109fe565b9091565b600435906001600160a01b03821682036100f257565b60206040818301928281528451809452019201905f5b818110610aba5750505090565b8251845260209384019390920191600101610aad565b90601f8019910116810190811067ffffffffffffffff821117610af257604052565b634e487b7160e01b5f52604160045260245ffd5b604051906040820182811067ffffffffffffffff821117610af257604052600382526245333560e81b6020830152565b15610b3e5750565b60405162461bcd60e51b8152908190610b5a90600483016109d4565b0390fd5b15610b6557565b60405162461bcd60e51b815260206004820152602d60248201527f466c6174526f6c654d616e616765723a20496e76616c6964205f726f6c65732060448201526c6f72205f64656c65676174657360981b6064820152608490fd5b9190811015610bd05760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036100f25790565b60018060a01b0316806001600160601b0360a01b5f5416175f556001600160601b0360a01b600154166001557f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b5f80a2565b8054821015610bd0575f5260205f2001905f90565b805f52600560205260405f2054155f14610cc557600454600160401b811015610af257610cae610c988260018594016004556004610c4a565b819391549060031b91821b915f19901b19161790565b9055600454905f52600560205260405f2055600190565b505f90565b805f52600360205260405f2054155f14610cc557600254600160401b811015610af257610d03610c988260018594016002556002610c4a565b9055600254905f52600360205260405f2055600190565b5f828152600182016020526040902054610d6757805490600160401b821015610af25782610d52610c98846001809601855584610c4a565b90558054925f520160205260405f2055600190565b50505f90565b5f818152600360205260409020548015610d67575f198101818111610e2c576002545f19810191908211610e2c57818103610df4575b5050506002548015610de0575f1901610dbd816002610c4a565b8154905f199060031b1b191690556002555f5260036020525f6040812055600190565b634e487b7160e01b5f52603160045260245ffd5b610e16610e05610c98936002610c4a565b90549060031b1c9283926002610c4a565b90555f52600360205260405f20555f8080610da3565b634e487b7160e01b5f52601160045260245ffd5b906001820191815f528260205260405f20548015155f14610ee9575f198101818111610e2c5782545f19810191908211610e2c57818103610eb4575b50505080548015610de0575f190190610e958282610c4a565b8154905f199060031b1b19169055555f526020525f6040812055600190565b610ed4610ec4610c989386610c4a565b90549060031b1c92839286610c4a565b90555f528360205260405f20555f8080610e7c565b505050505f9056fea2646970667358221220fdea897c6e009a3814fb673f604ab86905e654d26439fd91bf349ffe156c83d264736f6c634300081a0033
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.