Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ArgusRootAuthorizer
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 "../base/BaseAuthorizer.sol"; /// @title ArgusRootAuthorizer - Default root authorizers for Argus platform. /// @author Cobo Safe Dev Team https://www.cobo.com/ /// @notice ArgusRootAuthorizer is a authorizer manager which dispatch the correct /// sub authorizer according to role of delegate and call type. /// Hint is supported here so user can get the hint, the correct authorizer /// in this case, off-chain (this can be expensive on-chain) and preform /// on-chain transaction to save gas. contract ArgusRootAuthorizer is BaseAuthorizer, IAuthorizerSupportingHint { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.Bytes32Set; using TxFlags for uint256; using AuthFlags for uint256; bytes32 public constant NAME = "ArgusRootAuthorizer"; uint256 public constant VERSION = 1; bytes32 public constant override TYPE = AuthType.SET; /// @dev This changes when authorizer adds. uint256 private _unionFlag; // Roles in the authorizer. Only used for enumeration. EnumerableSet.Bytes32Set roles; // `isDelegateCall` => `Role` => `Authorizer address set` // true for delegatecall, false for call. mapping(bool => mapping(bytes32 => EnumerableSet.AddressSet)) internal authorizerSet; // Authorizers who implement process handler (with flag `HAS_POST_PROC_MASK` or `HAS_POST_PROC_MASK`) // will added into `processSet` and will be invoked unconditionally at each tx. mapping(bool => EnumerableSet.AddressSet) internal processSet; /// Events. event NewAuthorizerAdded(bool indexed isDelegateCall, bytes32 indexed role, address indexed authorizer); event NewProcessAdded(bool indexed isDelegateCall, address indexed authorizer); event AuthorizerRemoved(bool indexed isDelegateCall, bytes32 indexed role, address indexed authorizer); event ProcessRemoved(bool indexed isDelegateCall, address indexed authorizer); constructor(address _owner, address _caller, address _account) BaseAuthorizer(_owner, _caller) { // We need role manager. account = _account; } /// @dev pack/unpack should match. function _packHint(bytes32 role, address auth, bytes memory subHint) internal pure returns (bytes memory hint) { return abi.encodePacked(abi.encode(role, auth), subHint); } function _unpackHint(bytes calldata hint) internal pure returns (bytes32 role, address auth, bytes memory subHint) { (role, auth) = abi.decode(hint[0:64], (bytes32, address)); subHint = hint[64:]; } /// @dev Catch error of sub authorizers to prevent the case when one authorizer fails reverts the entire /// check chain process. function _safePreExecCheck( address auth, TransactionData calldata transaction ) internal returns (AuthorizerReturnData memory preData) { try IAuthorizer(auth).preExecCheck(transaction) returns (AuthorizerReturnData memory _preData) { return _preData; } catch Error(string memory reason) { preData.result = AuthResult.FAILED; preData.message = reason; } catch (bytes memory reason) { preData.result = AuthResult.FAILED; preData.message = string(reason); } } function _safePostExecCheck( address auth, TransactionData calldata transaction, TransactionResult calldata callResult, AuthorizerReturnData memory preData ) internal returns (AuthorizerReturnData memory postData) { try IAuthorizer(auth).postExecCheck(transaction, callResult, preData) returns ( AuthorizerReturnData memory _postData ) { return _postData; } catch Error(string memory reason) { postData.result = AuthResult.FAILED; postData.message = reason; } catch (bytes memory reason) { postData.result = AuthResult.FAILED; postData.message = string(reason); } } function _safeCollectHint( address auth, AuthorizerReturnData memory preData, AuthorizerReturnData memory postData ) internal returns (bytes memory subHint) { try IAuthorizerSupportingHint(auth).collectHint(preData, postData) returns (bytes memory _subHint) { return _subHint; } catch { return subHint; } } /// @dev preExecCheck and postExecCheck use extractly the same hint thus /// the same sub authorizer is called. function _preExecCheckWithHint( TransactionData calldata transaction ) internal returns (AuthorizerReturnData memory authData) { (bytes32 role, address auth, bytes memory subHint) = _unpackHint(transaction.hint); uint256 _flag = IAuthorizer(auth).flag(); // The authorizer from hint should have either PreCheck or PostCheck. require(_flag.isValid(), Errors.INVALID_AUTHORIZER_FLAG); if (!_flag.hasPreCheck()) { // If pre check handler not exist, default success. authData.result = AuthResult.SUCCESS; return authData; } // Important: Validate the hint. // (1) The role from hint should be validated. require(_hasRole(transaction, role), Errors.INVALID_HINT); // (2) The authorizer from hint should have been registered with the role. bool isDelegateCall = transaction.flag.isDelegateCall(); require(authorizerSet[isDelegateCall][role].contains(auth), Errors.INVALID_HINT); // Cut the hint to sub hint. TransactionData memory txn = transaction; txn.hint = subHint; // In hint path, this should never revert so `_safePreExecCheck()` is not used here. return IAuthorizer(auth).preExecCheck(txn); } function _postExecCheckWithHint( TransactionData calldata transaction, TransactionResult calldata callResult, AuthorizerReturnData calldata preData ) internal returns (AuthorizerReturnData memory authData) { (bytes32 role, address auth, bytes memory subHint) = _unpackHint(transaction.hint); uint256 _flag = IAuthorizer(auth).flag(); require(_flag.isValid(), Errors.INVALID_AUTHORIZER_FLAG); if (!_flag.hasPostCheck()) { // If post check handler not exist, default success. authData.result = AuthResult.SUCCESS; return authData; } // Important: Validate the hint. // (1) The role from hint should be validated. require(_hasRole(transaction, role), Errors.INVALID_HINT); // (2) The authorizer from hint should have been registered with the role. bool isDelegateCall = transaction.flag.isDelegateCall(); require(authorizerSet[isDelegateCall][role].contains(auth), Errors.INVALID_HINT); TransactionData memory txn = transaction; txn.hint = subHint; return IAuthorizer(auth).postExecCheck(txn, callResult, preData); } struct PreCheckData { bytes32 role; address authorizer; AuthorizerReturnData authData; } // This is very expensive on-chain. // Should only used to collect hint off-chain. PreCheckData[] internal preCheckDataCache; function _preExecCheck( TransactionData calldata transaction ) internal override returns (AuthorizerReturnData memory authData) { if (transaction.hint.length > 0) { return _preExecCheckWithHint(transaction); } authData.result = AuthResult.FAILED; bytes32[] memory txRoles = _getRoles(transaction); uint256 roleLength = txRoles.length; if (roleLength == 0) { authData.message = Errors.EMPTY_ROLE_SET; return authData; } bool isDelegateCall = transaction.flag.isDelegateCall(); for (uint256 i = 0; i < roleLength; ++i) { bytes32 role = txRoles[i]; EnumerableSet.AddressSet storage authSet = authorizerSet[isDelegateCall][role]; uint256 length = authSet.length(); // Run all pre checks and record auth results. for (uint256 j = 0; j < length; ++j) { address auth = authSet.at(j); AuthorizerReturnData memory preData = _safePreExecCheck(auth, transaction); if (preData.result == AuthResult.SUCCESS) { authData.result = AuthResult.SUCCESS; // Only save success results. preCheckDataCache.push(PreCheckData(role, auth, preData)); } } } if (authData.result == AuthResult.SUCCESS) { // Temporary data for post checker to collect hint. authData.data = abi.encode(preCheckDataCache); } else { authData.message = Errors.ALL_AUTH_FAILED; } delete preCheckDataCache; // gas refund. } function _postExecCheck( TransactionData calldata transaction, TransactionResult calldata callResult, AuthorizerReturnData calldata preData ) internal override returns (AuthorizerReturnData memory postData) { if (transaction.hint.length > 0) { return _postExecCheckWithHint(transaction, callResult, preData); } // Get pre check results from preData. PreCheckData[] memory preResults = abi.decode(preData.data, (PreCheckData[])); uint256 length = preResults.length; // We should have reverted in preExecCheck. But safer is better. require(length > 0, Errors.INVALID_HINT_COLLECTED); bool isDelegateCall = transaction.flag.isDelegateCall(); for (uint256 i = 0; i < length; ++i) { bytes32 role = preResults[i].role; address authAddress = preResults[i].authorizer; require(authorizerSet[isDelegateCall][role].contains(authAddress), Errors.INVALID_HINT_COLLECTED); // Run post check. AuthorizerReturnData memory preCheckData = preResults[i].authData; postData = _safePostExecCheck(authAddress, transaction, callResult, preCheckData); // If pre and post both succeeded, we pass. if (postData.result == AuthResult.SUCCESS) { // Collect hint of sub authorizer if needed. bytes memory subHint; if (IAuthorizer(authAddress).flag().supportHint()) { subHint = _safeCollectHint(authAddress, preCheckData, postData); } postData.data = _packHint(role, authAddress, subHint); return postData; } } postData.result = AuthResult.FAILED; postData.message = Errors.ALL_AUTH_FAILED; } function collectHint( AuthorizerReturnData calldata preAuthData, AuthorizerReturnData calldata postAuthData ) public view returns (bytes memory hint) { // Use post data as hint. hint = postAuthData.data; } /// @dev All sub preExecProcess / postExecProcess handlers are supposed be called. function _preExecProcess(TransactionData calldata transaction) internal virtual override { if (!_unionFlag.hasPreProcess()) return; bool isDelegateCall = transaction.flag.isDelegateCall(); EnumerableSet.AddressSet storage procSet = processSet[isDelegateCall]; uint256 length = procSet.length(); for (uint256 i = 0; i < length; i++) { IAuthorizer auth = IAuthorizer(procSet.at(i)); if (auth.flag().hasPreProcess()) { // Ignore reverts. try auth.preExecProcess(transaction) {} catch {} } } } function _postExecProcess( TransactionData calldata transaction, TransactionResult calldata callResult ) internal virtual override { if (!_unionFlag.hasPostProcess()) return; bool isDelegateCall = transaction.flag.isDelegateCall(); EnumerableSet.AddressSet storage procSet = processSet[isDelegateCall]; uint256 length = procSet.length(); for (uint256 i = 0; i < length; i++) { IAuthorizer auth = IAuthorizer(procSet.at(i)); if (auth.flag().hasPostProcess()) { // Ignore reverts. try auth.postExecProcess(transaction, callResult) {} catch {} } } } /// External / Public funtions. function addAuthorizer(bool isDelegateCall, bytes32 role, address authorizer) external onlyOwner { uint256 _flag = IAuthorizer(authorizer).flag(); roles.add(role); if (authorizerSet[isDelegateCall][role].add(authorizer)) { emit NewAuthorizerAdded(isDelegateCall, role, authorizer); // Collect flag. _unionFlag |= _flag; if (_flag.hasPreProcess() || _flag.hasPostProcess()) { // An authorizer with process handler can NOT be installed twice as this cause // confusion when running process handler twice in one transaction. require(processSet[isDelegateCall].add(authorizer), Errors.SAME_PROCESS_TWICE); emit NewProcessAdded(isDelegateCall, authorizer); } } } function removeAuthorizer(bool isDelegateCall, bytes32 role, address authorizer) external onlyOwner { uint256 _flag = IAuthorizer(authorizer).flag(); if (authorizerSet[isDelegateCall][role].remove(authorizer)) { emit AuthorizerRemoved(isDelegateCall, role, authorizer); if (_flag.hasPreProcess() || _flag.hasPostProcess()) { // It is ok to remove here as we has checked duplication in `addAuthorizer()`. if (processSet[isDelegateCall].remove(authorizer)) { emit ProcessRemoved(isDelegateCall, authorizer); if (processSet[isDelegateCall].length() == 0 && processSet[!isDelegateCall].length() == 0) { _unionFlag -= (_unionFlag & (AuthFlags.HAS_PRE_PROC_MASK | AuthFlags.HAS_POST_PROC_MASK)); } } } } } /// External view funtions. function flag() external view returns (uint256) { return _unionFlag | AuthFlags.SUPPORT_HINT_MASK; } function authorizerSize(bool isDelegateCall, bytes32 role) external view returns (uint256) { return authorizerSet[isDelegateCall][role].length(); } function hasAuthorizer(bool isDelegateCall, bytes32 role, address auth) external view returns (bool) { return authorizerSet[isDelegateCall][role].contains(auth); } function getAuthorizer(bool isDelegateCall, bytes32 role, uint256 i) external view returns (address) { return authorizerSet[isDelegateCall][role].at(i); } /// @dev View function allow user to specify the range in case we have very big set /// which can exhaust the gas of block limit when enumerating the entire list. function getAuthorizers( bool isDelegateCall, bytes32 role, uint256 start, uint256 end ) external view returns (address[] memory auths) { uint256 authorizerSetSize = authorizerSet[isDelegateCall][role].length(); if (end > authorizerSetSize) end = authorizerSetSize; auths = new address[](end - start); for (uint256 i = 0; i < end - start; i++) { auths[i] = authorizerSet[isDelegateCall][role].at(start + i); } } function getAllAuthorizers(bool isDelegateCall, bytes32 role) external view returns (address[] memory) { return authorizerSet[isDelegateCall][role].values(); } 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 "./BaseOwnable.sol"; import "../Errors.sol"; import "../../interfaces/IAuthorizer.sol"; import "../../interfaces/IAccount.sol"; import "../../interfaces/IRoleManager.sol"; /// @title BaseAuthorizer - A basic pausable authorizer with caller restriction. /// @author Cobo Safe Dev Team https://www.cobo.com/ /// @dev Base contract to extend to implement specific authorizer. abstract contract BaseAuthorizer is IAuthorizer, BaseOwnable { /// @dev Override such constants while extending BaseAuthorizer. bool public paused = false; // Often used for off-chain system. // Each contract instance has its own value. bytes32 public tag = ""; // The caller which is able to call this contract's pre/postExecProcess // and pre/postExecCheck having side-effect. // It is usually the account or the parent authorizer(set) on higher level. address public caller; // This is the account this authorizer works for. // Currently only used to lookup `roleManager`. // If not used it is OK to keep it unset. address public account; event CallerSet(address indexed caller); event AccountSet(address indexed account); event TagSet(bytes32 indexed tag); event PausedSet(bool indexed status); constructor(address _owner, address _caller) BaseOwnable(_owner) { caller = _caller; } function initialize(address _owner, address _caller) public { initialize(_owner); caller = _caller; emit CallerSet(_caller); } function initialize(address _owner, address _caller, address _account) public { initialize(_owner, _caller); account = _account; emit AccountSet(_account); } modifier onlyCaller() virtual { require(msg.sender == caller, Errors.INVALID_CALLER); _; } /// @notice Change the caller. /// @param _caller the caller which calls the authorizer. function setCaller(address _caller) external onlyOwner { require(_caller != address(0), "Invalid caller"); caller = _caller; emit CallerSet(_caller); } /// @notice Change the account. /// @param _account the account which the authorizer get role manager from. function setAccount(address _account) external onlyOwner { require(_account != address(0), "Invalid account"); account = _account; emit AccountSet(_account); } /// @notice Change the tag for the contract instance. /// @dev For off-chain index. /// @param _tag the tag function setTag(bytes32 _tag) external onlyOwner { tag = _tag; emit TagSet(_tag); } /// @notice Set the pause status. Authorizer just denies all when paused. /// @param _paused the paused status: true or false. function setPaused(bool _paused) external onlyOwner { paused = _paused; emit PausedSet(_paused); } /// @dev `onlyCaller` check is forced on pre/post Check/Process handlers /// to prevent attackers from polluting our data by calling this directly. /// @notice Check if the transaction can be executed. /// @return authData Return check status, error message and other data. function preExecCheck( TransactionData calldata transaction ) external virtual onlyCaller returns (AuthorizerReturnData memory authData) { if (paused) { authData.result = AuthResult.FAILED; authData.message = Errors.AUTHORIZER_PAUSED; } else { authData = _preExecCheck(transaction); } } /// @notice Check after transaction execution. /// @param callResult Transaction call status and return data. function postExecCheck( TransactionData calldata transaction, TransactionResult calldata callResult, AuthorizerReturnData calldata preData ) external virtual onlyCaller returns (AuthorizerReturnData memory authData) { if (paused) { authData.result = AuthResult.FAILED; authData.message = Errors.AUTHORIZER_PAUSED; } else { authData = _postExecCheck(transaction, callResult, preData); } } /// @dev Perform actions before the transaction execution. function preExecProcess(TransactionData calldata transaction) external virtual onlyCaller { if (!paused) _preExecProcess(transaction); } /// @dev Perform actions after the transaction execution. function postExecProcess( TransactionData calldata transaction, TransactionResult calldata callResult ) external virtual onlyCaller { if (!paused) _postExecProcess(transaction, callResult); } /// @dev Extract the roles of the delegate. If no roleManager set return empty lists. function _getRoleManager() internal view returns (address roleManager) { require(account != address(0), Errors.ACCOUNT_NOT_SET); roleManager = IAccount(account).roleManager(); require(roleManager != address(0), Errors.ROLE_MANAGER_NOT_SET); } function _getRoles(TransactionData calldata transaction) internal view returns (bytes32[] memory roles) { address roleManager = _getRoleManager(); roles = IRoleManager(roleManager).getRoles(transaction.delegate); } /// @dev Call `roleManager` to validate the role of delegate. function _hasRole(TransactionData calldata transaction, bytes32 role) internal view returns (bool) { address roleManager = _getRoleManager(); return IRoleManager(roleManager).hasRole(transaction.delegate, role); } /// @dev Override these functions to while extending this contract. function _preExecCheck( TransactionData calldata transaction ) internal virtual returns (AuthorizerReturnData memory authData) {} function _postExecCheck( TransactionData calldata transaction, TransactionResult calldata callResult, AuthorizerReturnData calldata preData ) internal virtual returns (AuthorizerReturnData memory) {} function _preExecProcess(TransactionData calldata transaction) internal virtual {} function _postExecProcess( TransactionData calldata transaction, TransactionResult calldata callResult ) internal virtual {} /// @dev Override this if you implement new type of authorizer. function TYPE() external view virtual returns (bytes32) { return AuthType.COMMON; } }
// 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; /// @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 "../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; 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 "../../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; 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; 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"},{"internalType":"address","name":"_caller","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isDelegateCall","type":"bool"},{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"authorizer","type":"address"}],"name":"AuthorizerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"}],"name":"CallerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isDelegateCall","type":"bool"},{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"authorizer","type":"address"}],"name":"NewAuthorizerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"NewOwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isDelegateCall","type":"bool"},{"indexed":true,"internalType":"address","name":"authorizer","type":"address"}],"name":"NewProcessAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"status","type":"bool"}],"name":"PausedSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PendingOwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isDelegateCall","type":"bool"},{"indexed":true,"internalType":"address","name":"authorizer","type":"address"}],"name":"ProcessRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"tag","type":"bytes32"}],"name":"TagSet","type":"event"},{"inputs":[],"name":"NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TYPE","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":[],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isDelegateCall","type":"bool"},{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"authorizer","type":"address"}],"name":"addAuthorizer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isDelegateCall","type":"bool"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"authorizerSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"caller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"enum AuthResult","name":"result","type":"uint8"},{"internalType":"string","name":"message","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AuthorizerReturnData","name":"preAuthData","type":"tuple"},{"components":[{"internalType":"enum AuthResult","name":"result","type":"uint8"},{"internalType":"string","name":"message","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AuthorizerReturnData","name":"postAuthData","type":"tuple"}],"name":"collectHint","outputs":[{"internalType":"bytes","name":"hint","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flag","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isDelegateCall","type":"bool"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getAllAuthorizers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllRoles","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isDelegateCall","type":"bool"},{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"i","type":"uint256"}],"name":"getAuthorizer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isDelegateCall","type":"bool"},{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"getAuthorizers","outputs":[{"internalType":"address[]","name":"auths","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isDelegateCall","type":"bool"},{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"auth","type":"address"}],"name":"hasAuthorizer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_caller","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_caller","type":"address"},{"internalType":"address","name":"_account","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":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"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"}],"internalType":"struct TransactionData","name":"transaction","type":"tuple"},{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"hint","type":"bytes"}],"internalType":"struct TransactionResult","name":"callResult","type":"tuple"},{"components":[{"internalType":"enum AuthResult","name":"result","type":"uint8"},{"internalType":"string","name":"message","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AuthorizerReturnData","name":"preData","type":"tuple"}],"name":"postExecCheck","outputs":[{"components":[{"internalType":"enum AuthResult","name":"result","type":"uint8"},{"internalType":"string","name":"message","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AuthorizerReturnData","name":"authData","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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"}],"internalType":"struct TransactionData","name":"transaction","type":"tuple"},{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"hint","type":"bytes"}],"internalType":"struct TransactionResult","name":"callResult","type":"tuple"}],"name":"postExecProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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"}],"internalType":"struct TransactionData","name":"transaction","type":"tuple"}],"name":"preExecCheck","outputs":[{"components":[{"internalType":"enum AuthResult","name":"result","type":"uint8"},{"internalType":"string","name":"message","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AuthorizerReturnData","name":"authData","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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"}],"internalType":"struct TransactionData","name":"transaction","type":"tuple"}],"name":"preExecProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isDelegateCall","type":"bool"},{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"authorizer","type":"address"}],"name":"removeAuthorizer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"setAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_caller","type":"address"}],"name":"setCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"setPendingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_tag","type":"bytes32"}],"name":"setTag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tag","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080346100ff57601f6131ad38819003918201601f19168301916001600160401b03831184841017610103578084926060946040528339810103126100ff5761004781610117565b90610060604061005960208401610117565b9201610117565b6001545f80546001600160a01b0319166001600160a01b03909516948517815560405194929392907f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b9080a26001600160b01b031916600160a01b176001555f600255600380546001600160a01b03199081166001600160a01b03938416179091556004805490911692909116919091179055613081908161012c8239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036100ff5756fe6080806040526004361015610012575f80fd5b5f3560e01c90816308dbebf61461105c5750806316c38b3c14610feb57806328562c6a14610f9257806329f6d57c14610ee4578063485cc95514610eba57806351f9106614610e9d5780635c975abb14610e785780635dab242014610e505780636000cfbb14610ccd5780636bdc489e14610c7d5780636f6a565914610bfb578063715018a614610b8b5780637c4c833b14610b02578063890eba6814610ae25780638da5cb5b14610abb5780639d5228e8146109f45780639dfd2019146109b7578063a192897c1461089e578063a3f4df7e1461086d578063a5314988146107ea578063b695e2ef14610794578063bb24fe8a1461076f578063beb92f55146106c2578063c0c53b8b14610649578063c42069ec146105d4578063c4d66de8146105b3578063d58c3fc314610574578063e30c39781461054c578063ebbc49651461051f578063f26600271461049f578063f2bcac3d146103e9578063f2fde38b14610368578063f974cf09146101e4578063fc9c8d39146101bc5763ffa1ad741461019d575f80fd5b346101b8575f3660031901126101b857602060405160018152f35b5f80fd5b346101b8575f3660031901126101b8576003546040516001600160a01b039091168152602090f35b346101b8576101f23661114f565b5f54610211906001600160a01b03166102096112c2565b9033146112e3565b604051631121d74d60e31b81526001600160a01b039190911692602082600481875afa91821561035d575f92610329575b5061024c83612dc6565b50151591825f52600860205260405f20815f5260205261026f8460405f20612e1b565b61027557005b8390837fd46106481e77b634fbbb2df03a3e15989faf5dfcd556c94702ca66dc5106e3495f80a4806005541760055560048116159081159161031c575b506102ba575b005b805f5260096020526102f66102d28360405f20612e1b565b604051906102e1604083611286565b6003825262229a9b60e91b60208301526112e3565b7fffd4c7f6ab86aa2243a178e9634bb19f4b1f3821e2b401f08fa6f4d862b593815f80a3005b60089150161515836102b2565b9091506020813d602011610355575b8161034560209383611286565b810103126101b857519084610242565b3d9150610338565b6040513d5f823e3d90fd5b346101b85760203660031901126101b85761038161110f565b5f54610398906001600160a01b03166102096112c2565b6001600160a01b038116156103b0576102b8906114dc565b60405162461bcd60e51b81526020600482015260116024820152704e6577204f776e6572206973207a65726f60781b6044820152606490fd5b346101b8575f3660031901126101b8576040518060206006549283815201809260065f527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f905f5b8181106104895750505081610447910382611286565b604051918291602083019060208452518091526040830191905f5b818110610470575050500390f35b8251845285945060209384019390920191600101610462565b8254845260209093019260019283019201610431565b346101b85761050c6104b036611223565b6104b86113f7565b6104d660018060a01b036003541633146104d06113d6565b906112e3565b9060ff60015460a81c165f1461051057505f81526104f2611416565b60208201525b6040519182916020835260208301906111a3565b0390f35b61051a9150611d1d565b6104f8565b346101b8575f3660031901126101b8576001546001600160a01b0316338190036101b8576102b8906114dc565b346101b8575f3660031901126101b8576001546040516001600160a01b039091168152602090f35b346101b85761058236611223565b61059a60018060a01b036003541633146104d06113d6565b60ff60015460a81c16156105aa57005b6102b890611b7d565b346101b85760203660031901126101b8576102b86105cf61110f565b611476565b346101b85760203660031901126101b8576105ed61110f565b5f54610604906001600160a01b03166102096112c2565b600180546001600160a01b0319166001600160a01b039290921691821790557f68f49b346b94582a8b5f9d10e3fe3365318fe8f191ff8dce7c59c6cad06b02f55f80a2005b346101b85760603660031901126101b85761066261110f565b61066a611125565b6044356001600160a01b0381169291908390036101b85761068a91611313565b600480546001600160a01b031916821790557f195359283029fbdb9a24519b1ec07caf1677655529bf99dc1634c1e8b28811805f80a2005b346101b85760203660031901126101b8576106db61110f565b5f546106f2906001600160a01b03166102096112c2565b6001600160a01b0316801561073957600380546001600160a01b031916821790557fac431eb831269b53b41991f6cbfbfc93f4baa395996a8170abac93962b5a358e5f80a2005b60405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21031b0b63632b960911b6044820152606490fd5b346101b8575f3660031901126101b857604051665365745479706560c81b8152602090f35b346101b85760203660031901126101b8575f54600435906107c0906001600160a01b03166102096112c2565b806002557fef711e3eb06966d227e22eb4fa0302550dcd7257cf69b537cf4d37af53ea9cda5f80a2005b346101b85760403660031901126101b857610803611100565b15155f52600860205260405f206024355f5260205260405f206040519081602082549182815201915f5260205f20905f5b8181106108575761050c8561084b81870382611286565b604051918291826111e1565b8254845260209093019260019283019201610834565b346101b8575f3660031901126101b8576040517220b933bab9a937b7ba20baba3437b934bd32b960691b8152602090f35b346101b85760803660031901126101b8576108b7611100565b602435906044359160643591151590815f52600860205260405f20815f5260205260405f20548084116109af575b506108f08484611361565b916108fa83611437565b926109086040519485611286565b808452610917601f1991611437565b013660208501375f5b61092a8686611361565b8110156109a157815f52600860205260405f20835f5260205260405f2081870180881161098d5761092a926109626001928a946124e3565b838060a01b0391549060031b1c1661097a828961144e565b90838060a01b0316905201915050610920565b634e487b7160e01b5f52601160045260245ffd5b6040518061050c86826111e1565b9250846108e5565b346101b85760403660031901126101b8576109d0611100565b15155f52600860205260405f206024355f52602052602060405f2054604051908152f35b346101b85760603660031901126101b8576004356001600160401b0381116101b85761010060031982360301126101b8576024356001600160401b0381116101b857606060031982360301126101b857604435906001600160401b0382116101b857606060031983360301126101b85761050c92610a706113f7565b610a8860018060a01b036003541633146104d06113d6565b9260ff60015460a81c165f14610aa6575050505f81526104f2611416565b61051a93506004019160040190600401611810565b346101b8575f3660031901126101b8575f546040516001600160a01b039091168152602090f35b346101b8575f3660031901126101b8576020604060055417604051908152f35b346101b85760403660031901126101b8576004356001600160401b0381116101b85761010060031982360301126101b857602435906001600160401b0382116101b857606060031983360301126101b857610b6b60018060a01b036003541633146104d06113d6565b60ff60015460a81c1615610b7b57005b6102b8916004019060040161168d565b346101b8575f3660031901126101b8575f54610bb2906001600160a01b03166102096112c2565b6001600160601b0360a01b5f54165f556001600160601b0360a01b600154166001555f7f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b8180a2005b346101b85760403660031901126101b8576004356001600160401b0381116101b85760609060031990360301126101b8576024356001600160401b0381116101b857606060031982360301126101b857610c69610c6282604461050c94019060040161136e565b36916113a0565b6040519182916020835260208301906110dc565b346101b8576020610cc3610c903661114f565b9115155f526008845260405f20905f52835260405f209060018060a01b0316906001915f520160205260405f2054151590565b6040519015158152f35b346101b857610cdb3661114f565b5f54610cf2906001600160a01b03166102096112c2565b604051631121d74d60e31b8152926001600160a01b039190911690602084600481855afa93841561035d575f94610e1c575b501592831592835f52600860205260405f20815f52602052610d498360405f206124f8565b610d4f57005b8290847f3fdc8e65a2b0db08501fd5ab951fb7e7be8f9fa0accec197cb4becf3183cd1e45f80a4600481161590811591610e0f575b50610d8b57005b815f526009602052610da08160405f206124f8565b156102b857817f839797155acceec9b78c2cda9190a51b8c4dbcaa8b72a6ea1793043fff1271935f80a35f52600960205260405f2054159081610dfa575b50610de557005b610df5600554600c811690611361565b600555005b90505f52600960205260405f20541581610dde565b6008915016151584610d84565b9093506020813d602011610e48575b81610e3860209383611286565b810103126101b857519284610d24565b3d9150610e2b565b346101b8575f3660031901126101b8576004546040516001600160a01b039091168152602090f35b346101b8575f3660031901126101b857602060ff60015460a81c166040519015158152f35b346101b8575f3660031901126101b8576020600254604051908152f35b346101b85760403660031901126101b8576102b8610ed661110f565b610ede611125565b90611313565b346101b85760203660031901126101b857610efd61110f565b5f54610f14906001600160a01b03166102096112c2565b6001600160a01b03168015610f5b57600480546001600160a01b031916821790557f195359283029fbdb9a24519b1ec07caf1677655529bf99dc1634c1e8b28811805f80a2005b60405162461bcd60e51b815260206004820152600f60248201526e125b9d985b1a59081858d8dbdd5b9d608a1b6044820152606490fd5b346101b85760603660031901126101b857610fab611100565b15155f52600860205260405f206024355f526020526020610fd260405f20604435906124e3565b905460405160039290921b1c6001600160a01b03168152f35b346101b85760203660031901126101b857611004611100565b5f5461101b906001600160a01b03166102096112c2565b151560015460ff60a81b8260a81b169060ff60a81b1916176001557f40db37ff5c0bdc2c427fbb2078c8f24afea940abac0e3c23bb4ea3bf2da2b2125f80a2005b346101b8575f3660031901126101b8576351fa6fbf60e11b8152602081600481305afa801561035d575f906110a8575b61050c9060405190602082015260208152610c69604082611286565b506020813d6020116110d4575b816110c260209383611286565b810103126101b85761050c905161108c565b3d91506110b5565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b6004359081151582036101b857565b600435906001600160a01b03821682036101b857565b602435906001600160a01b03821682036101b857565b35906001600160a01b03821682036101b857565b60609060031901126101b85760043580151581036101b85790602435906044356001600160a01b03811681036101b85790565b90600282101561118f5752565b634e487b7160e01b5f52602160045260245ffd5b6111de916111b2818351611182565b60406111cd60208401516060602085015260608401906110dc565b9201519060408184039101526110dc565b90565b60206040818301928281528451809452019201905f5b8181106112045750505090565b82516001600160a01b03168452602093840193909201916001016111f7565b60206003198201126101b857600435906001600160401b0382116101b8576101009082900360031901126101b85760040190565b606081019081106001600160401b0382111761127257604052565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b0382111761127257604052565b6001600160401b03811161127257601f01601f191660200190565b604051906112d1604083611286565b600382526245333560e81b6020830152565b156112eb5750565b60405162461bcd60e51b81526020600482015290819061130f9060248301906110dc565b0390fd5b61131c90611476565b600380546001600160a01b0319166001600160a01b039290921691821790557fac431eb831269b53b41991f6cbfbfc93f4baa395996a8170abac93962b5a358e5f80a2565b9190820391821161098d57565b903590601e19813603018212156101b857018035906001600160401b0382116101b8576020019181360383136101b857565b9291926113ac826112a7565b916113ba6040519384611286565b8294818452818301116101b8578281602093845f960137010152565b604051906113e5604083611286565b600382526245323760e81b6020830152565b6040519061140482611257565b60606040835f81528260208201520152565b60405190611425604083611286565b6003825262229a1b60e91b6020830152565b6001600160401b0381116112725760051b60200190565b80518210156114625760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b60ff60015460a01c166114a15761148c906114dc565b6001805460ff60a01b1916600160a01b179055565b60405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606490fd5b60018060a01b0316806001600160601b0360a01b5f5416175f556001600160601b0360a01b600154166001557f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b5f80a2565b9035601e19823603018112156101b85701602081359101916001600160401b0382116101b85781360383136101b857565b908060209392818452848401375f828201840152601f01601f1916010190565b6111de916001600160a01b036115948361113b565b1681526001600160a01b036115ab6020840161113b565b166020820152604082810135908201526001600160a01b036115cf6060840161113b565b1660608201526080820135608082015261162e6116236116086115f560a086018661152e565b61010060a087015261010086019161155f565b61161560c086018661152e565b9085830360c087015261155f565b9260e081019061152e565b9160e081850391015261155f565b80359182151583036101b8576111de921515815261167f611674611663602085018561152e565b60606020860152606085019161155f565b92604081019061152e565b91604081850391015261155f565b600860055416156117af57600160408201351615155f52600960205260405f20908154915f5b8381106116c1575050505050565b6116cb81836124e3565b9054604051631121d74d60e31b815260039290921b1c6001600160a01b03169190602081600481865afa801561035d575f9061177d575b6008915016611716575b60019150016116b3565b813b156101b8576001915f6040518092637c4c833b60e01b82526040600483015281838161175e8d61174c8d604485019061157f565b8381036003190160248501529061163c565b03925af161176d575b5061170c565b5f61177791611286565b5f611767565b506020813d82116117a7575b8161179660209383611286565b810103126101b85760089051611702565b3d9150611789565b5050565b9080601f830112156101b8578160206111de933591016113a0565b604051906117dd604083611286565b600382526204535360ec1b6020830152565b604051906117fe604083611286565b600382526208a68760eb1b6020830152565b92919261181b6113f7565b9361182960c083018361136e565b9050611b705780604061183d92019061136e565b8101906020818303126101b8578035906001600160401b0382116101b857019080601f830112156101b85781359161187483611437565b926118826040519485611286565b80845260208085019160051b830101918383116101b85760208101915b838310611a8057505050505090918151916118c36118bb6117ce565b8415156112e3565b60016040850135161515915f945b8486106118f0575050505050505f82526118e96117ef565b6020830152565b90919293949650611901878461144e565b5151966001600160a01b036020611918838761144e565b5101511697855f52600860205260405f20815f5260205261195561194d8a60405f206001915f520160205260405f2054151590565b6104d06117ce565b6040611961838761144e565b5101516119708186868d612ad8565b998a51600281101561118f576001146119935750505060010194939291906118d1565b604051631121d74d60e31b8152999a9992985060609750955090935091506020905082600481865afa801561035d5786925f91611a49575b509360209283926040611a2f9716611a37575b5050604051938285019687526040850152604084526119fe606085611286565b6040519586945180918487015e8401908282015f8152815193849201905e01015f815203601f198101835282611286565b604082015290565b611a42925085612bb7565b865f6119de565b9250506020823d8211611a78575b81611a6460209383611286565b810103126101b857905185919060206119cb565b3d9150611a57565b82356001600160401b0381116101b8578201906060828703601f1901126101b85760405191611aae83611257565b60208101358352611ac16040820161113b565b602084015260608101356001600160401b0381116101b8576020910101906060828803126101b85760405192611af684611257565b823560028110156101b857845260208301356001600160401b0381116101b857830188601f820112156101b85788816020611b33933591016113a0565b60208501526040830135936001600160401b0385116101b857611b5b896020968796016117b3565b6040820152604082015281520192019161189f565b91906111de93945061285e565b60046005541615611c8757600160408201351615155f52600960205260405f208054905f5b828110611baf5750505050565b611bb981836124e3565b9054604051631121d74d60e31b815260039290921b1c6001600160a01b03169190602081600481865afa801561035d575f90611c55575b6004915016611c04575b6001915001611ba2565b813b156101b85760405163d58c3fc360e01b8152602060048201526001925f908290818381611c36602482018d61157f565b03925af1611c45575b50611bfa565b5f611c4f91611286565b5f611c3f565b506020813d8211611c7f575b81611c6e60209383611286565b810103126101b85760049051611bf0565b3d9150611c61565b50565b90600182811c92168015611cb8575b6020831014611ca457565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611c99565b818110611ccd575050565b5f8155600101611cc2565b9190601f8111611ce757505050565b611d11925f5260205f20906020601f840160051c83019310611d13575b601f0160051c0190611cc2565b565b9091508190611d04565b90611d266113f7565b91611d3460c082018261136e565b90506124d8575f83526001600160a01b03611d4d612f51565b16905f611d5c60208301612d7c565b60405163ce6ccfaf60e01b81526001600160a01b03909116600482015292839060249082905afa91821561035d575f92612446575b50815191821561241c5760016040830135161515905f5b8481106120c85750505050508151600281101561118f576001036120b65760405160408101602080830152600a54809152816060810160608360051b83010190600a5f525f8051602061302c833981519152935f915b818310611f3557505050611e1b925003601f198101835282611286565b60408301525b600a545f600a5580611e305750565b8060050290600582040361098d57600a5f525f8051602061302c833981519152015f8051602061302c8339815191525b818110611e6b575050565b6005905f81555f60018201555f600282015560038101611e8b8154611c8a565b9081611ef3575b505060048101611ea28154611c8a565b9081611eb1575b505001611e60565b81601f5f9311600114611ec85750555b5f80611ea9565b81835260208320611ee391601f01861c810190600101611cc2565b8082528160208120915555611ec1565b81601f5f9311600114611f0a5750555b5f80611e92565b81835260208320611f2591601f01861c810190600101611cc2565b8082528160208120915555611f03565b91935091605f198682030182528454815260018060a01b03600186015416602082015260606040820152611f736060820160ff600288015416611182565b606060808201526003850180545f9291611f8c82611c8a565b918260c08501526001811690815f14612096575060011461205c575b5050600486019060a0605f19828503019101525f91815491611fc983611c8a565b80835292600181169081156120385750600114611ffb575b505050602060056001929601920193019093918593611dfe565b909192505f5260205f20915f925b8184106120225750500160209081019060056001611fe1565b6001816020925483878701015201930192612009565b6001955060209490859350600594925060ff1916838301521515831b010192611fe1565b5f90815260208120929350915b81831061207f575050810160e001905f80611fa8565b6001816020925460e0868801015201920191612069565b91505060e092935060ff191682840152151560051b820101905f80611fa8565b6120be6117ef565b6020830152611e21565b6120d2818361144e565b51835f52600860205260405f20815f5260205260405f20908154915f5b8381106121025750505050600101611da8565b61210c81836124e3565b905460039190911b1c6001600160a01b03166121288982612d90565b908151600281101561118f57600114612146575b50506001016120ef565b60018d526040519061215782611257565b8582526020820190815260408201928352600a54600160401b811015611272576001810180600a5581101561146257600590600a5f52029151825f8051602061302c83398151915201557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a982019060018060a01b039051166001600160601b0360a01b8254161790557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2aa81019151918251600281101561118f5760ff801983541691161790557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ab810160208301518051906001600160401b0382116112725761226a826122648554611c8a565b85611cd8565b602090601f83116001146123945782604095937fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ac95936122bf935f92612322575b50508160011b915f199060031b1c19161790565b90555b019101518051906001600160401b038211611272576122e5826122648554611c8a565b602090601f831160011461232d5791806123189260019695945f926123225750508160011b915f199060031b1c19161790565b90555b905f61213c565b015190505f806122ab565b90601f19831691845f52815f20925f5b81811061237c575091600196959492918388959310612364575b505050811b01905561231b565b01515f1960f88460031b161c191690555f8080612357565b9293602060018192878601518155019501930161233d565b90601f19831691845f52815f20925f5b8181106124045750926001928592604098967fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ac9896106123ec575b505050811b0190556122c2565b01515f1960f88460031b161c191690555f80806123df565b929360206001819287860151815501950193016123a4565b5050509060405161242e604082611286565b600381526245353360e81b6020820152602082015290565b9091503d805f833e6124588183611286565b8101906020818303126101b8578051906001600160401b0382116101b857019080601f830112156101b857815161248e81611437565b9261249c6040519485611286565b81845260208085019260051b8201019283116101b857602001905b8282106124c857505050905f611d91565b81518152602091820191016124b7565b6111de919250612c5d565b8054821015611462575f5260205f2001905f90565b906001820191815f528260205260405f20548015155f146125cb575f19810181811161098d5782545f1981019190821161098d57818103612580575b5050508054801561256c575f19019061254d82826124e3565b8154905f199060031b1b19169055555f526020525f6040812055600190565b634e487b7160e01b5f52603160045260245ffd5b6125b66125906125a093866124e3565b90549060031b1c928392866124e3565b819391549060031b91821b915f19901b19161790565b90555f528360205260405f20555f8080612534565b505050505f90565b604051906125e2604083611286565b600382526245343560e81b6020830152565b60405190612603604083611286565b600382526245343760e81b6020830152565b9190610100838203126101b8576040519061010082018281106001600160401b0382111761127257604052819361264b8161113b565b83526126596020820161113b565b6020840152604081013560408401526126746060820161113b565b60608401526080810135608084015260a08101356001600160401b0381116101b857826126a29183016117b3565b60a084015260c08101356001600160401b0381116101b857826126c69183016117b3565b60c084015260e0810135916001600160401b0383116101b85760e0926126ec92016117b3565b910152565b9291926126fd826112a7565b9161270b6040519384611286565b8294818452818301116101b8578281602093845f96015e010152565b9080601f830112156101b85781516111de926020016126f1565b6020818303126101b8578051906001600160401b0382116101b857016060818303126101b8576040519161277483611257565b815160028110156101b857835260208201516001600160401b0381116101b857820181601f820112156101b857818160206127b1935191016126f1565b602084015260408201516001600160401b0381116101b857611a2f9201612727565b6111de9160018060a01b03825116815260018060a01b0360208301511660208201526040820151604082015260018060a01b0360608301511660608201526080820151608082015260e061284d61283b60a085015161010060a08601526101008501906110dc565b60c085015184820360c08601526110dc565b9201519060e08184039101526110dc565b91906128686113f7565b9061287f61287960c086018661136e565b90612e6e565b604051631121d74d60e31b815290966001600160a01b039092169491929190602081600481895afa801561035d575f906129e9575b600291506128cc6128c482612ea5565b6104d06125d3565b16156129db575081816128f16128e96129319461296b9796612ec0565b6104d06125f4565b600160408301351615155f52600860205260405f20905f5260205261292a6128e98660405f206001915f520160205260405f2054151590565b3690612615565b9460c0860152612959604051956313aa451d60e31b87526060600488015260648701906127d3565b8581036003190160248701529061163c565b83810360031901604485015290823560028110156101b8575f856129aa82968661299784988597611182565b61167f611674611663602085018561152e565b03925af190811561035d575f916129bf575090565b6111de91503d805f833e6129d38183611286565b810190612741565b955050505050506001815290565b506020813d602011612a14575b81612a0360209383611286565b810103126101b857600290516128b4565b3d91506129f6565b5f9060033d11612a2857565b905060045f803e5f5160e01c90565b5f60443d106111de576040513d600319016004823e8051913d60248401116001600160401b03841117612aa357828201928351916001600160401b038311612a9b573d84016003190185840160200111612a9b57506111de92910160200190611286565b949350505050565b92915050565b3d15612ad3573d90612aba826112a7565b91612ac86040519384611286565b82523d5f602084013e565b606090565b91612b17926129595f8094979697612b29612af16113f7565b99604051988997889687956313aa451d60e31b875260606004880152606487019061157f565b838103600319016044850152906111a3565b03926001600160a01b03165af15f9181612b9b575b50612b9757506001612b4e612a1c565b6308c379a014612b71575b612b5f57565b612b67612aa9565b5f83526020830152565b612b79612a37565b80612b85575b50612b59565b90505f905f845260208401525f612b7f565b9150565b612bb09192503d805f833e6129d38183611286565b905f612b3e565b612bfb91925f91612be960609560405195869485938493636f6a565960e01b85526040600486015260448501906111a3565b838103600319016024850152906111a3565b03916001600160a01b03165afa5f9181612c1e575b50612c19575090565b905090565b9091503d805f833e612c308183611286565b81016020828203126101b85781516001600160401b0381116101b857612c569201612727565b905f612c10565b612c656113f7565b612c7561287960c084018461136e565b604051631121d74d60e31b815290946001600160a01b039092169391929190602081600481885afa801561035d575f90612d49575b60019150612cba6128c482612ea5565b1615612d3d5750915f93612d138385612cda6128e989986129aa98612ec0565b60016040830135161515875260086020526040872090875260205261292a6128e985604089206001915f520160205260405f2054151590565b9060c082015260405194858094819363f266002760e01b83526020600484015260248301906127d3565b93505050506001815290565b506020813d602011612d74575b81612d6360209383611286565b810103126101b85760019051612caa565b3d9150612d56565b356001600160a01b03811681036101b85790565b5f612b298192949394612da16113f7565b9560405194858094819363f266002760e01b835260206004840152602483019061157f565b805f52600760205260405f2054155f14612e1657600654600160401b81101561127257612dff6125a082600185940160065560066124e3565b9055600654905f52600760205260405f2055600190565b505f90565b5f828152600182016020526040902054612e6857805490600160401b8210156112725782612e536125a08460018096018555846124e3565b90558054925f520160205260405f2055600190565b50505f90565b91816040116101b85760208301356001600160a01b038116908190036101b8576111de909284359460403692603f190191016113a0565b600181161590811591612eb6575090565b6002915016151590565b906020906044612ee2836001600160a01b03612eda612f51565b169501612d7c565b604051948593849263ac4ab3fb60e01b845260018060a01b0316600484015260248301525afa90811561035d575f91612f19575090565b90506020813d602011612f49575b81612f3460209383611286565b810103126101b8575180151581036101b85790565b3d9150612f27565b60049060018060a01b038254166020604091612f898351612f728582611286565b600381526245353760e81b848201528215156112e3565b825162435da560e01b815294859182905afa928315613021575f93612fdb575b50611d119083612fbb82519283611286565b600382526208a6a760eb1b60208301526001600160a01b031615156112e3565b9092506020813d602011613019575b81612ff760209383611286565b810103126101b857516001600160a01b03811681036101b85791611d11612fa9565b3d9150612fea565b50513d5f823e3d90fdfec65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8a2646970667358221220043a5bbbd4e87b9f45dc76894ee19a6518d5a7735ceebd28f4b4bf5738dddb0f64736f6c634300081a0033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f3560e01c90816308dbebf61461105c5750806316c38b3c14610feb57806328562c6a14610f9257806329f6d57c14610ee4578063485cc95514610eba57806351f9106614610e9d5780635c975abb14610e785780635dab242014610e505780636000cfbb14610ccd5780636bdc489e14610c7d5780636f6a565914610bfb578063715018a614610b8b5780637c4c833b14610b02578063890eba6814610ae25780638da5cb5b14610abb5780639d5228e8146109f45780639dfd2019146109b7578063a192897c1461089e578063a3f4df7e1461086d578063a5314988146107ea578063b695e2ef14610794578063bb24fe8a1461076f578063beb92f55146106c2578063c0c53b8b14610649578063c42069ec146105d4578063c4d66de8146105b3578063d58c3fc314610574578063e30c39781461054c578063ebbc49651461051f578063f26600271461049f578063f2bcac3d146103e9578063f2fde38b14610368578063f974cf09146101e4578063fc9c8d39146101bc5763ffa1ad741461019d575f80fd5b346101b8575f3660031901126101b857602060405160018152f35b5f80fd5b346101b8575f3660031901126101b8576003546040516001600160a01b039091168152602090f35b346101b8576101f23661114f565b5f54610211906001600160a01b03166102096112c2565b9033146112e3565b604051631121d74d60e31b81526001600160a01b039190911692602082600481875afa91821561035d575f92610329575b5061024c83612dc6565b50151591825f52600860205260405f20815f5260205261026f8460405f20612e1b565b61027557005b8390837fd46106481e77b634fbbb2df03a3e15989faf5dfcd556c94702ca66dc5106e3495f80a4806005541760055560048116159081159161031c575b506102ba575b005b805f5260096020526102f66102d28360405f20612e1b565b604051906102e1604083611286565b6003825262229a9b60e91b60208301526112e3565b7fffd4c7f6ab86aa2243a178e9634bb19f4b1f3821e2b401f08fa6f4d862b593815f80a3005b60089150161515836102b2565b9091506020813d602011610355575b8161034560209383611286565b810103126101b857519084610242565b3d9150610338565b6040513d5f823e3d90fd5b346101b85760203660031901126101b85761038161110f565b5f54610398906001600160a01b03166102096112c2565b6001600160a01b038116156103b0576102b8906114dc565b60405162461bcd60e51b81526020600482015260116024820152704e6577204f776e6572206973207a65726f60781b6044820152606490fd5b346101b8575f3660031901126101b8576040518060206006549283815201809260065f527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f905f5b8181106104895750505081610447910382611286565b604051918291602083019060208452518091526040830191905f5b818110610470575050500390f35b8251845285945060209384019390920191600101610462565b8254845260209093019260019283019201610431565b346101b85761050c6104b036611223565b6104b86113f7565b6104d660018060a01b036003541633146104d06113d6565b906112e3565b9060ff60015460a81c165f1461051057505f81526104f2611416565b60208201525b6040519182916020835260208301906111a3565b0390f35b61051a9150611d1d565b6104f8565b346101b8575f3660031901126101b8576001546001600160a01b0316338190036101b8576102b8906114dc565b346101b8575f3660031901126101b8576001546040516001600160a01b039091168152602090f35b346101b85761058236611223565b61059a60018060a01b036003541633146104d06113d6565b60ff60015460a81c16156105aa57005b6102b890611b7d565b346101b85760203660031901126101b8576102b86105cf61110f565b611476565b346101b85760203660031901126101b8576105ed61110f565b5f54610604906001600160a01b03166102096112c2565b600180546001600160a01b0319166001600160a01b039290921691821790557f68f49b346b94582a8b5f9d10e3fe3365318fe8f191ff8dce7c59c6cad06b02f55f80a2005b346101b85760603660031901126101b85761066261110f565b61066a611125565b6044356001600160a01b0381169291908390036101b85761068a91611313565b600480546001600160a01b031916821790557f195359283029fbdb9a24519b1ec07caf1677655529bf99dc1634c1e8b28811805f80a2005b346101b85760203660031901126101b8576106db61110f565b5f546106f2906001600160a01b03166102096112c2565b6001600160a01b0316801561073957600380546001600160a01b031916821790557fac431eb831269b53b41991f6cbfbfc93f4baa395996a8170abac93962b5a358e5f80a2005b60405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21031b0b63632b960911b6044820152606490fd5b346101b8575f3660031901126101b857604051665365745479706560c81b8152602090f35b346101b85760203660031901126101b8575f54600435906107c0906001600160a01b03166102096112c2565b806002557fef711e3eb06966d227e22eb4fa0302550dcd7257cf69b537cf4d37af53ea9cda5f80a2005b346101b85760403660031901126101b857610803611100565b15155f52600860205260405f206024355f5260205260405f206040519081602082549182815201915f5260205f20905f5b8181106108575761050c8561084b81870382611286565b604051918291826111e1565b8254845260209093019260019283019201610834565b346101b8575f3660031901126101b8576040517220b933bab9a937b7ba20baba3437b934bd32b960691b8152602090f35b346101b85760803660031901126101b8576108b7611100565b602435906044359160643591151590815f52600860205260405f20815f5260205260405f20548084116109af575b506108f08484611361565b916108fa83611437565b926109086040519485611286565b808452610917601f1991611437565b013660208501375f5b61092a8686611361565b8110156109a157815f52600860205260405f20835f5260205260405f2081870180881161098d5761092a926109626001928a946124e3565b838060a01b0391549060031b1c1661097a828961144e565b90838060a01b0316905201915050610920565b634e487b7160e01b5f52601160045260245ffd5b6040518061050c86826111e1565b9250846108e5565b346101b85760403660031901126101b8576109d0611100565b15155f52600860205260405f206024355f52602052602060405f2054604051908152f35b346101b85760603660031901126101b8576004356001600160401b0381116101b85761010060031982360301126101b8576024356001600160401b0381116101b857606060031982360301126101b857604435906001600160401b0382116101b857606060031983360301126101b85761050c92610a706113f7565b610a8860018060a01b036003541633146104d06113d6565b9260ff60015460a81c165f14610aa6575050505f81526104f2611416565b61051a93506004019160040190600401611810565b346101b8575f3660031901126101b8575f546040516001600160a01b039091168152602090f35b346101b8575f3660031901126101b8576020604060055417604051908152f35b346101b85760403660031901126101b8576004356001600160401b0381116101b85761010060031982360301126101b857602435906001600160401b0382116101b857606060031983360301126101b857610b6b60018060a01b036003541633146104d06113d6565b60ff60015460a81c1615610b7b57005b6102b8916004019060040161168d565b346101b8575f3660031901126101b8575f54610bb2906001600160a01b03166102096112c2565b6001600160601b0360a01b5f54165f556001600160601b0360a01b600154166001555f7f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b8180a2005b346101b85760403660031901126101b8576004356001600160401b0381116101b85760609060031990360301126101b8576024356001600160401b0381116101b857606060031982360301126101b857610c69610c6282604461050c94019060040161136e565b36916113a0565b6040519182916020835260208301906110dc565b346101b8576020610cc3610c903661114f565b9115155f526008845260405f20905f52835260405f209060018060a01b0316906001915f520160205260405f2054151590565b6040519015158152f35b346101b857610cdb3661114f565b5f54610cf2906001600160a01b03166102096112c2565b604051631121d74d60e31b8152926001600160a01b039190911690602084600481855afa93841561035d575f94610e1c575b501592831592835f52600860205260405f20815f52602052610d498360405f206124f8565b610d4f57005b8290847f3fdc8e65a2b0db08501fd5ab951fb7e7be8f9fa0accec197cb4becf3183cd1e45f80a4600481161590811591610e0f575b50610d8b57005b815f526009602052610da08160405f206124f8565b156102b857817f839797155acceec9b78c2cda9190a51b8c4dbcaa8b72a6ea1793043fff1271935f80a35f52600960205260405f2054159081610dfa575b50610de557005b610df5600554600c811690611361565b600555005b90505f52600960205260405f20541581610dde565b6008915016151584610d84565b9093506020813d602011610e48575b81610e3860209383611286565b810103126101b857519284610d24565b3d9150610e2b565b346101b8575f3660031901126101b8576004546040516001600160a01b039091168152602090f35b346101b8575f3660031901126101b857602060ff60015460a81c166040519015158152f35b346101b8575f3660031901126101b8576020600254604051908152f35b346101b85760403660031901126101b8576102b8610ed661110f565b610ede611125565b90611313565b346101b85760203660031901126101b857610efd61110f565b5f54610f14906001600160a01b03166102096112c2565b6001600160a01b03168015610f5b57600480546001600160a01b031916821790557f195359283029fbdb9a24519b1ec07caf1677655529bf99dc1634c1e8b28811805f80a2005b60405162461bcd60e51b815260206004820152600f60248201526e125b9d985b1a59081858d8dbdd5b9d608a1b6044820152606490fd5b346101b85760603660031901126101b857610fab611100565b15155f52600860205260405f206024355f526020526020610fd260405f20604435906124e3565b905460405160039290921b1c6001600160a01b03168152f35b346101b85760203660031901126101b857611004611100565b5f5461101b906001600160a01b03166102096112c2565b151560015460ff60a81b8260a81b169060ff60a81b1916176001557f40db37ff5c0bdc2c427fbb2078c8f24afea940abac0e3c23bb4ea3bf2da2b2125f80a2005b346101b8575f3660031901126101b8576351fa6fbf60e11b8152602081600481305afa801561035d575f906110a8575b61050c9060405190602082015260208152610c69604082611286565b506020813d6020116110d4575b816110c260209383611286565b810103126101b85761050c905161108c565b3d91506110b5565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b6004359081151582036101b857565b600435906001600160a01b03821682036101b857565b602435906001600160a01b03821682036101b857565b35906001600160a01b03821682036101b857565b60609060031901126101b85760043580151581036101b85790602435906044356001600160a01b03811681036101b85790565b90600282101561118f5752565b634e487b7160e01b5f52602160045260245ffd5b6111de916111b2818351611182565b60406111cd60208401516060602085015260608401906110dc565b9201519060408184039101526110dc565b90565b60206040818301928281528451809452019201905f5b8181106112045750505090565b82516001600160a01b03168452602093840193909201916001016111f7565b60206003198201126101b857600435906001600160401b0382116101b8576101009082900360031901126101b85760040190565b606081019081106001600160401b0382111761127257604052565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b0382111761127257604052565b6001600160401b03811161127257601f01601f191660200190565b604051906112d1604083611286565b600382526245333560e81b6020830152565b156112eb5750565b60405162461bcd60e51b81526020600482015290819061130f9060248301906110dc565b0390fd5b61131c90611476565b600380546001600160a01b0319166001600160a01b039290921691821790557fac431eb831269b53b41991f6cbfbfc93f4baa395996a8170abac93962b5a358e5f80a2565b9190820391821161098d57565b903590601e19813603018212156101b857018035906001600160401b0382116101b8576020019181360383136101b857565b9291926113ac826112a7565b916113ba6040519384611286565b8294818452818301116101b8578281602093845f960137010152565b604051906113e5604083611286565b600382526245323760e81b6020830152565b6040519061140482611257565b60606040835f81528260208201520152565b60405190611425604083611286565b6003825262229a1b60e91b6020830152565b6001600160401b0381116112725760051b60200190565b80518210156114625760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b60ff60015460a01c166114a15761148c906114dc565b6001805460ff60a01b1916600160a01b179055565b60405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606490fd5b60018060a01b0316806001600160601b0360a01b5f5416175f556001600160601b0360a01b600154166001557f038720101b9ced74445432ced46c7e5e4c80202669153dd67d226c66a0aa477b5f80a2565b9035601e19823603018112156101b85701602081359101916001600160401b0382116101b85781360383136101b857565b908060209392818452848401375f828201840152601f01601f1916010190565b6111de916001600160a01b036115948361113b565b1681526001600160a01b036115ab6020840161113b565b166020820152604082810135908201526001600160a01b036115cf6060840161113b565b1660608201526080820135608082015261162e6116236116086115f560a086018661152e565b61010060a087015261010086019161155f565b61161560c086018661152e565b9085830360c087015261155f565b9260e081019061152e565b9160e081850391015261155f565b80359182151583036101b8576111de921515815261167f611674611663602085018561152e565b60606020860152606085019161155f565b92604081019061152e565b91604081850391015261155f565b600860055416156117af57600160408201351615155f52600960205260405f20908154915f5b8381106116c1575050505050565b6116cb81836124e3565b9054604051631121d74d60e31b815260039290921b1c6001600160a01b03169190602081600481865afa801561035d575f9061177d575b6008915016611716575b60019150016116b3565b813b156101b8576001915f6040518092637c4c833b60e01b82526040600483015281838161175e8d61174c8d604485019061157f565b8381036003190160248501529061163c565b03925af161176d575b5061170c565b5f61177791611286565b5f611767565b506020813d82116117a7575b8161179660209383611286565b810103126101b85760089051611702565b3d9150611789565b5050565b9080601f830112156101b8578160206111de933591016113a0565b604051906117dd604083611286565b600382526204535360ec1b6020830152565b604051906117fe604083611286565b600382526208a68760eb1b6020830152565b92919261181b6113f7565b9361182960c083018361136e565b9050611b705780604061183d92019061136e565b8101906020818303126101b8578035906001600160401b0382116101b857019080601f830112156101b85781359161187483611437565b926118826040519485611286565b80845260208085019160051b830101918383116101b85760208101915b838310611a8057505050505090918151916118c36118bb6117ce565b8415156112e3565b60016040850135161515915f945b8486106118f0575050505050505f82526118e96117ef565b6020830152565b90919293949650611901878461144e565b5151966001600160a01b036020611918838761144e565b5101511697855f52600860205260405f20815f5260205261195561194d8a60405f206001915f520160205260405f2054151590565b6104d06117ce565b6040611961838761144e565b5101516119708186868d612ad8565b998a51600281101561118f576001146119935750505060010194939291906118d1565b604051631121d74d60e31b8152999a9992985060609750955090935091506020905082600481865afa801561035d5786925f91611a49575b509360209283926040611a2f9716611a37575b5050604051938285019687526040850152604084526119fe606085611286565b6040519586945180918487015e8401908282015f8152815193849201905e01015f815203601f198101835282611286565b604082015290565b611a42925085612bb7565b865f6119de565b9250506020823d8211611a78575b81611a6460209383611286565b810103126101b857905185919060206119cb565b3d9150611a57565b82356001600160401b0381116101b8578201906060828703601f1901126101b85760405191611aae83611257565b60208101358352611ac16040820161113b565b602084015260608101356001600160401b0381116101b8576020910101906060828803126101b85760405192611af684611257565b823560028110156101b857845260208301356001600160401b0381116101b857830188601f820112156101b85788816020611b33933591016113a0565b60208501526040830135936001600160401b0385116101b857611b5b896020968796016117b3565b6040820152604082015281520192019161189f565b91906111de93945061285e565b60046005541615611c8757600160408201351615155f52600960205260405f208054905f5b828110611baf5750505050565b611bb981836124e3565b9054604051631121d74d60e31b815260039290921b1c6001600160a01b03169190602081600481865afa801561035d575f90611c55575b6004915016611c04575b6001915001611ba2565b813b156101b85760405163d58c3fc360e01b8152602060048201526001925f908290818381611c36602482018d61157f565b03925af1611c45575b50611bfa565b5f611c4f91611286565b5f611c3f565b506020813d8211611c7f575b81611c6e60209383611286565b810103126101b85760049051611bf0565b3d9150611c61565b50565b90600182811c92168015611cb8575b6020831014611ca457565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611c99565b818110611ccd575050565b5f8155600101611cc2565b9190601f8111611ce757505050565b611d11925f5260205f20906020601f840160051c83019310611d13575b601f0160051c0190611cc2565b565b9091508190611d04565b90611d266113f7565b91611d3460c082018261136e565b90506124d8575f83526001600160a01b03611d4d612f51565b16905f611d5c60208301612d7c565b60405163ce6ccfaf60e01b81526001600160a01b03909116600482015292839060249082905afa91821561035d575f92612446575b50815191821561241c5760016040830135161515905f5b8481106120c85750505050508151600281101561118f576001036120b65760405160408101602080830152600a54809152816060810160608360051b83010190600a5f525f8051602061302c833981519152935f915b818310611f3557505050611e1b925003601f198101835282611286565b60408301525b600a545f600a5580611e305750565b8060050290600582040361098d57600a5f525f8051602061302c833981519152015f8051602061302c8339815191525b818110611e6b575050565b6005905f81555f60018201555f600282015560038101611e8b8154611c8a565b9081611ef3575b505060048101611ea28154611c8a565b9081611eb1575b505001611e60565b81601f5f9311600114611ec85750555b5f80611ea9565b81835260208320611ee391601f01861c810190600101611cc2565b8082528160208120915555611ec1565b81601f5f9311600114611f0a5750555b5f80611e92565b81835260208320611f2591601f01861c810190600101611cc2565b8082528160208120915555611f03565b91935091605f198682030182528454815260018060a01b03600186015416602082015260606040820152611f736060820160ff600288015416611182565b606060808201526003850180545f9291611f8c82611c8a565b918260c08501526001811690815f14612096575060011461205c575b5050600486019060a0605f19828503019101525f91815491611fc983611c8a565b80835292600181169081156120385750600114611ffb575b505050602060056001929601920193019093918593611dfe565b909192505f5260205f20915f925b8184106120225750500160209081019060056001611fe1565b6001816020925483878701015201930192612009565b6001955060209490859350600594925060ff1916838301521515831b010192611fe1565b5f90815260208120929350915b81831061207f575050810160e001905f80611fa8565b6001816020925460e0868801015201920191612069565b91505060e092935060ff191682840152151560051b820101905f80611fa8565b6120be6117ef565b6020830152611e21565b6120d2818361144e565b51835f52600860205260405f20815f5260205260405f20908154915f5b8381106121025750505050600101611da8565b61210c81836124e3565b905460039190911b1c6001600160a01b03166121288982612d90565b908151600281101561118f57600114612146575b50506001016120ef565b60018d526040519061215782611257565b8582526020820190815260408201928352600a54600160401b811015611272576001810180600a5581101561146257600590600a5f52029151825f8051602061302c83398151915201557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a982019060018060a01b039051166001600160601b0360a01b8254161790557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2aa81019151918251600281101561118f5760ff801983541691161790557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ab810160208301518051906001600160401b0382116112725761226a826122648554611c8a565b85611cd8565b602090601f83116001146123945782604095937fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ac95936122bf935f92612322575b50508160011b915f199060031b1c19161790565b90555b019101518051906001600160401b038211611272576122e5826122648554611c8a565b602090601f831160011461232d5791806123189260019695945f926123225750508160011b915f199060031b1c19161790565b90555b905f61213c565b015190505f806122ab565b90601f19831691845f52815f20925f5b81811061237c575091600196959492918388959310612364575b505050811b01905561231b565b01515f1960f88460031b161c191690555f8080612357565b9293602060018192878601518155019501930161233d565b90601f19831691845f52815f20925f5b8181106124045750926001928592604098967fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ac9896106123ec575b505050811b0190556122c2565b01515f1960f88460031b161c191690555f80806123df565b929360206001819287860151815501950193016123a4565b5050509060405161242e604082611286565b600381526245353360e81b6020820152602082015290565b9091503d805f833e6124588183611286565b8101906020818303126101b8578051906001600160401b0382116101b857019080601f830112156101b857815161248e81611437565b9261249c6040519485611286565b81845260208085019260051b8201019283116101b857602001905b8282106124c857505050905f611d91565b81518152602091820191016124b7565b6111de919250612c5d565b8054821015611462575f5260205f2001905f90565b906001820191815f528260205260405f20548015155f146125cb575f19810181811161098d5782545f1981019190821161098d57818103612580575b5050508054801561256c575f19019061254d82826124e3565b8154905f199060031b1b19169055555f526020525f6040812055600190565b634e487b7160e01b5f52603160045260245ffd5b6125b66125906125a093866124e3565b90549060031b1c928392866124e3565b819391549060031b91821b915f19901b19161790565b90555f528360205260405f20555f8080612534565b505050505f90565b604051906125e2604083611286565b600382526245343560e81b6020830152565b60405190612603604083611286565b600382526245343760e81b6020830152565b9190610100838203126101b8576040519061010082018281106001600160401b0382111761127257604052819361264b8161113b565b83526126596020820161113b565b6020840152604081013560408401526126746060820161113b565b60608401526080810135608084015260a08101356001600160401b0381116101b857826126a29183016117b3565b60a084015260c08101356001600160401b0381116101b857826126c69183016117b3565b60c084015260e0810135916001600160401b0383116101b85760e0926126ec92016117b3565b910152565b9291926126fd826112a7565b9161270b6040519384611286565b8294818452818301116101b8578281602093845f96015e010152565b9080601f830112156101b85781516111de926020016126f1565b6020818303126101b8578051906001600160401b0382116101b857016060818303126101b8576040519161277483611257565b815160028110156101b857835260208201516001600160401b0381116101b857820181601f820112156101b857818160206127b1935191016126f1565b602084015260408201516001600160401b0381116101b857611a2f9201612727565b6111de9160018060a01b03825116815260018060a01b0360208301511660208201526040820151604082015260018060a01b0360608301511660608201526080820151608082015260e061284d61283b60a085015161010060a08601526101008501906110dc565b60c085015184820360c08601526110dc565b9201519060e08184039101526110dc565b91906128686113f7565b9061287f61287960c086018661136e565b90612e6e565b604051631121d74d60e31b815290966001600160a01b039092169491929190602081600481895afa801561035d575f906129e9575b600291506128cc6128c482612ea5565b6104d06125d3565b16156129db575081816128f16128e96129319461296b9796612ec0565b6104d06125f4565b600160408301351615155f52600860205260405f20905f5260205261292a6128e98660405f206001915f520160205260405f2054151590565b3690612615565b9460c0860152612959604051956313aa451d60e31b87526060600488015260648701906127d3565b8581036003190160248701529061163c565b83810360031901604485015290823560028110156101b8575f856129aa82968661299784988597611182565b61167f611674611663602085018561152e565b03925af190811561035d575f916129bf575090565b6111de91503d805f833e6129d38183611286565b810190612741565b955050505050506001815290565b506020813d602011612a14575b81612a0360209383611286565b810103126101b857600290516128b4565b3d91506129f6565b5f9060033d11612a2857565b905060045f803e5f5160e01c90565b5f60443d106111de576040513d600319016004823e8051913d60248401116001600160401b03841117612aa357828201928351916001600160401b038311612a9b573d84016003190185840160200111612a9b57506111de92910160200190611286565b949350505050565b92915050565b3d15612ad3573d90612aba826112a7565b91612ac86040519384611286565b82523d5f602084013e565b606090565b91612b17926129595f8094979697612b29612af16113f7565b99604051988997889687956313aa451d60e31b875260606004880152606487019061157f565b838103600319016044850152906111a3565b03926001600160a01b03165af15f9181612b9b575b50612b9757506001612b4e612a1c565b6308c379a014612b71575b612b5f57565b612b67612aa9565b5f83526020830152565b612b79612a37565b80612b85575b50612b59565b90505f905f845260208401525f612b7f565b9150565b612bb09192503d805f833e6129d38183611286565b905f612b3e565b612bfb91925f91612be960609560405195869485938493636f6a565960e01b85526040600486015260448501906111a3565b838103600319016024850152906111a3565b03916001600160a01b03165afa5f9181612c1e575b50612c19575090565b905090565b9091503d805f833e612c308183611286565b81016020828203126101b85781516001600160401b0381116101b857612c569201612727565b905f612c10565b612c656113f7565b612c7561287960c084018461136e565b604051631121d74d60e31b815290946001600160a01b039092169391929190602081600481885afa801561035d575f90612d49575b60019150612cba6128c482612ea5565b1615612d3d5750915f93612d138385612cda6128e989986129aa98612ec0565b60016040830135161515875260086020526040872090875260205261292a6128e985604089206001915f520160205260405f2054151590565b9060c082015260405194858094819363f266002760e01b83526020600484015260248301906127d3565b93505050506001815290565b506020813d602011612d74575b81612d6360209383611286565b810103126101b85760019051612caa565b3d9150612d56565b356001600160a01b03811681036101b85790565b5f612b298192949394612da16113f7565b9560405194858094819363f266002760e01b835260206004840152602483019061157f565b805f52600760205260405f2054155f14612e1657600654600160401b81101561127257612dff6125a082600185940160065560066124e3565b9055600654905f52600760205260405f2055600190565b505f90565b5f828152600182016020526040902054612e6857805490600160401b8210156112725782612e536125a08460018096018555846124e3565b90558054925f520160205260405f2055600190565b50505f90565b91816040116101b85760208301356001600160a01b038116908190036101b8576111de909284359460403692603f190191016113a0565b600181161590811591612eb6575090565b6002915016151590565b906020906044612ee2836001600160a01b03612eda612f51565b169501612d7c565b604051948593849263ac4ab3fb60e01b845260018060a01b0316600484015260248301525afa90811561035d575f91612f19575090565b90506020813d602011612f49575b81612f3460209383611286565b810103126101b8575180151581036101b85790565b3d9150612f27565b60049060018060a01b038254166020604091612f898351612f728582611286565b600381526245353760e81b848201528215156112e3565b825162435da560e01b815294859182905afa928315613021575f93612fdb575b50611d119083612fbb82519283611286565b600382526208a6a760eb1b60208301526001600160a01b031615156112e3565b9092506020813d602011613019575b81612ff760209383611286565b810103126101b857516001600160a01b03811681036101b85791611d11612fa9565b3d9150612fea565b50513d5f823e3d90fdfec65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8a2646970667358221220043a5bbbd4e87b9f45dc76894ee19a6518d5a7735ceebd28f4b4bf5738dddb0f64736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _owner (address): 0x0000000000000000000000000000000000000000
Arg [1] : _caller (address): 0x0000000000000000000000000000000000000000
Arg [2] : _account (address): 0x0000000000000000000000000000000000000000
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.