More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x48ad1678ada0af497078c888f87776e242a6409df38466ccc4b2d6150753dcb2 | Commit Blocks | (pending) | less than 1 sec ago | IN | 0 ETH | (Pending) | |||
Execute Blocks | 21697859 | 23 hrs ago | IN | 0 ETH | 0.00041819 | ||||
Verify Blocks | 21697857 | 23 hrs ago | IN | 0 ETH | 0.00214334 | ||||
Commit Blocks | 21697855 | 23 hrs ago | IN | 0 ETH | 0.00115121 | ||||
Execute Blocks | 21690691 | 47 hrs ago | IN | 0 ETH | 0.00037738 | ||||
Verify Blocks | 21690689 | 47 hrs ago | IN | 0 ETH | 0.00192068 | ||||
Commit Blocks | 21690687 | 47 hrs ago | IN | 0 ETH | 0.00095844 | ||||
Execute Blocks | 21683525 | 2 days ago | IN | 0 ETH | 0.00044075 | ||||
Verify Blocks | 21683523 | 2 days ago | IN | 0 ETH | 0.00175949 | ||||
Commit Blocks | 21683522 | 2 days ago | IN | 0 ETH | 0.00118908 | ||||
Execute Blocks | 21676359 | 3 days ago | IN | 0 ETH | 0.00054037 | ||||
Verify Blocks | 21676357 | 3 days ago | IN | 0 ETH | 0.00234055 | ||||
Commit Blocks | 21676356 | 3 days ago | IN | 0 ETH | 0.00164138 | ||||
Execute Blocks | 21669200 | 4 days ago | IN | 0 ETH | 0.00065233 | ||||
Verify Blocks | 21669199 | 4 days ago | IN | 0 ETH | 0.00393371 | ||||
Commit Blocks | 21669197 | 4 days ago | IN | 0 ETH | 0.00237436 | ||||
Execute Blocks | 21665756 | 5 days ago | IN | 0 ETH | 0.00125136 | ||||
Verify Blocks | 21665753 | 5 days ago | IN | 0 ETH | 0.00664794 | ||||
Commit Blocks | 21665710 | 5 days ago | IN | 0 ETH | 0.00466002 | ||||
Withdraw | 21658818 | 6 days ago | IN | 0 ETH | 0.00274268 | ||||
Execute Blocks | 21658794 | 6 days ago | IN | 0 ETH | 0.00231384 | ||||
Verify Blocks | 21658649 | 6 days ago | IN | 0 ETH | 0.00689292 | ||||
Commit Blocks | 21658642 | 6 days ago | IN | 0 ETH | 0.00492888 | ||||
Execute Blocks | 21654871 | 6 days ago | IN | 0 ETH | 0.00123383 | ||||
Verify Blocks | 21654869 | 6 days ago | IN | 0 ETH | 0.00701572 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21613952 | 12 days ago | 5.16276482 ETH | ||||
21613952 | 12 days ago | 5.16276482 ETH | ||||
21490189 | 29 days ago | 0.06088098 ETH | ||||
21490189 | 29 days ago | 0.00304404 ETH | ||||
21490189 | 29 days ago | 0.00304404 ETH | ||||
21490189 | 29 days ago | 0.06392502 ETH | ||||
21490189 | 29 days ago | 0.06392502 ETH | ||||
21490189 | 29 days ago | 0.06088098 ETH | ||||
21490189 | 29 days ago | 0.06088098 ETH | ||||
21471317 | 32 days ago | 0.01 ETH | ||||
21471317 | 32 days ago | 0.01 ETH | ||||
21471316 | 32 days ago | 0.01 ETH | ||||
21471316 | 32 days ago | 0.01 ETH | ||||
21471316 | 32 days ago | 0.01 ETH | ||||
21471316 | 32 days ago | 0.01 ETH | ||||
21471316 | 32 days ago | 0.01 ETH | ||||
21471316 | 32 days ago | 0.01 ETH | ||||
21471316 | 32 days ago | 0.01 ETH | ||||
21471315 | 32 days ago | 0.01 ETH | ||||
21471315 | 32 days ago | 0.01 ETH | ||||
21471315 | 32 days ago | 0.01 ETH | ||||
21471315 | 32 days ago | 0.01 ETH | ||||
21471315 | 32 days ago | 0.01 ETH | ||||
21471315 | 32 days ago | 0.01 ETH | ||||
21471314 | 32 days ago | 0.01 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ZkTrueUp
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import {SolidStateDiamond} from "@solidstate/contracts/proxy/diamond/SolidStateDiamond.sol"; import {AccessControl} from "@solidstate/contracts/access/access_control/AccessControl.sol"; /** * @title Zk-TrueUp Contract * @author Term Structure Labs * @notice The core contract of Term Structure Protocol, which implemented by * diamond proxy standard. */ // solhint-disable-next-line no-empty-blocks contract ZkTrueUp is SolidStateDiamond, AccessControl { // inherit from SolidStateDiamond and AccessControl, no additional logic }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAccessControl } from './IAccessControl.sol'; import { AccessControlInternal } from './AccessControlInternal.sol'; /** * @title Role-based access control system * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) */ abstract contract AccessControl is IAccessControl, AccessControlInternal { /** * @inheritdoc IAccessControl */ function grantRole( bytes32 role, address account ) external onlyRole(_getRoleAdmin(role)) { _grantRole(role, account); } /** * @inheritdoc IAccessControl */ function hasRole( bytes32 role, address account ) external view returns (bool) { return _hasRole(role, account); } /** * @inheritdoc IAccessControl */ function getRoleAdmin(bytes32 role) external view returns (bytes32) { return _getRoleAdmin(role); } /** * @inheritdoc IAccessControl */ function revokeRole( bytes32 role, address account ) external onlyRole(_getRoleAdmin(role)) { _revokeRole(role, account); } /** * @inheritdoc IAccessControl */ function renounceRole(bytes32 role) external { _renounceRole(role); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { EnumerableSet } from '../../data/EnumerableSet.sol'; import { AddressUtils } from '../../utils/AddressUtils.sol'; import { UintUtils } from '../../utils/UintUtils.sol'; import { IAccessControlInternal } from './IAccessControlInternal.sol'; import { AccessControlStorage } from './AccessControlStorage.sol'; /** * @title Role-based access control system * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) */ abstract contract AccessControlInternal is IAccessControlInternal { using AddressUtils for address; using EnumerableSet for EnumerableSet.AddressSet; using UintUtils for uint256; modifier onlyRole(bytes32 role) { _checkRole(role); _; } /* * @notice query whether role is assigned to account * @param role role to query * @param account account to query * @return whether role is assigned to account */ function _hasRole( bytes32 role, address account ) internal view virtual returns (bool) { return AccessControlStorage.layout().roles[role].members.contains(account); } /** * @notice revert if sender does not have given role * @param role role to query */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, msg.sender); } /** * @notice revert if given account does not have given role * @param role role to query * @param account to query */ function _checkRole(bytes32 role, address account) internal view virtual { if (!_hasRole(role, account)) { revert( string( abi.encodePacked( 'AccessControl: account ', account.toString(), ' is missing role ', uint256(role).toHexString(32) ) ) ); } } /* * @notice query admin role for given role * @param role role to query * @return admin role */ function _getRoleAdmin( bytes32 role ) internal view virtual returns (bytes32) { return AccessControlStorage.layout().roles[role].adminRole; } /** * @notice set role as admin role * @param role role to set * @param adminRole admin role to set */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = _getRoleAdmin(role); AccessControlStorage.layout().roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /* * @notice assign role to given account * @param role role to assign * @param account recipient of role assignment */ function _grantRole(bytes32 role, address account) internal virtual { AccessControlStorage.layout().roles[role].members.add(account); emit RoleGranted(role, account, msg.sender); } /* * @notice unassign role from given account * @param role role to unassign * @parm account */ function _revokeRole(bytes32 role, address account) internal virtual { AccessControlStorage.layout().roles[role].members.remove(account); emit RoleRevoked(role, account, msg.sender); } /** * @notice relinquish role * @param role role to relinquish */ function _renounceRole(bytes32 role) internal virtual { _revokeRole(role, msg.sender); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { EnumerableSet } from '../../data/EnumerableSet.sol'; library AccessControlStorage { struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } struct Layout { mapping(bytes32 => RoleData) roles; } bytes32 internal constant DEFAULT_ADMIN_ROLE = 0x00; bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.AccessControl'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAccessControlInternal } from './IAccessControlInternal.sol'; /** * @title AccessControl interface */ interface IAccessControl is IAccessControlInternal { /* * @notice query whether role is assigned to account * @param role role to query * @param account account to query * @return whether role is assigned to account */ function hasRole( bytes32 role, address account ) external view returns (bool); /* * @notice query admin role for given role * @param role role to query * @return admin role */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /* * @notice assign role to given account * @param role role to assign * @param account recipient of role assignment */ function grantRole(bytes32 role, address account) external; /* * @notice unassign role from given account * @param role role to unassign * @parm account */ function revokeRole(bytes32 role, address account) external; /** * @notice relinquish role * @param role role to relinquish */ function renounceRole(bytes32 role) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Partial AccessControl interface needed by internal functions */ interface IAccessControlInternal { event RoleAdminChanged( bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole ); event RoleGranted( bytes32 indexed role, address indexed account, address indexed sender ); event RoleRevoked( bytes32 indexed role, address indexed account, address indexed sender ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173 } from '../../interfaces/IERC173.sol'; import { IOwnableInternal } from './IOwnableInternal.sol'; interface IOwnable is IOwnableInternal, IERC173 {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173Internal } from '../../interfaces/IERC173Internal.sol'; interface IOwnableInternal is IERC173Internal { error Ownable__NotOwner(); error Ownable__NotTransitiveOwner(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IOwnable } from './IOwnable.sol'; import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol'; interface ISafeOwnable is ISafeOwnableInternal, IOwnable { /** * @notice get the nominated owner who has permission to call acceptOwnership */ function nomineeOwner() external view returns (address); /** * @notice accept transfer of contract ownership */ function acceptOwnership() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IOwnableInternal } from './IOwnableInternal.sol'; interface ISafeOwnableInternal is IOwnableInternal { error SafeOwnable__NotNomineeOwner(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173 } from '../../interfaces/IERC173.sol'; import { IOwnable } from './IOwnable.sol'; import { OwnableInternal } from './OwnableInternal.sol'; /** * @title Ownership access control based on ERC173 */ abstract contract Ownable is IOwnable, OwnableInternal { /** * @inheritdoc IERC173 */ function owner() public view virtual returns (address) { return _owner(); } /** * @inheritdoc IERC173 */ function transferOwnership(address account) public virtual onlyOwner { _transferOwnership(account); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173 } from '../../interfaces/IERC173.sol'; import { AddressUtils } from '../../utils/AddressUtils.sol'; import { IOwnableInternal } from './IOwnableInternal.sol'; import { OwnableStorage } from './OwnableStorage.sol'; abstract contract OwnableInternal is IOwnableInternal { using AddressUtils for address; modifier onlyOwner() { if (msg.sender != _owner()) revert Ownable__NotOwner(); _; } modifier onlyTransitiveOwner() { if (msg.sender != _transitiveOwner()) revert Ownable__NotTransitiveOwner(); _; } function _owner() internal view virtual returns (address) { return OwnableStorage.layout().owner; } function _transitiveOwner() internal view virtual returns (address owner) { owner = _owner(); while (owner.isContract()) { try IERC173(owner).owner() returns (address transitiveOwner) { owner = transitiveOwner; } catch { break; } } } function _transferOwnership(address account) internal virtual { _setOwner(account); } function _setOwner(address account) internal virtual { OwnableStorage.Layout storage l = OwnableStorage.layout(); emit OwnershipTransferred(l.owner, account); l.owner = account; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; library OwnableStorage { struct Layout { address owner; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.Ownable'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { Ownable } from './Ownable.sol'; import { ISafeOwnable } from './ISafeOwnable.sol'; import { OwnableInternal } from './OwnableInternal.sol'; import { SafeOwnableInternal } from './SafeOwnableInternal.sol'; /** * @title Ownership access control based on ERC173 with ownership transfer safety check */ abstract contract SafeOwnable is ISafeOwnable, Ownable, SafeOwnableInternal { /** * @inheritdoc ISafeOwnable */ function nomineeOwner() public view virtual returns (address) { return _nomineeOwner(); } /** * @inheritdoc ISafeOwnable */ function acceptOwnership() public virtual onlyNomineeOwner { _acceptOwnership(); } function _transferOwnership( address account ) internal virtual override(OwnableInternal, SafeOwnableInternal) { super._transferOwnership(account); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol'; import { OwnableInternal } from './OwnableInternal.sol'; import { SafeOwnableStorage } from './SafeOwnableStorage.sol'; abstract contract SafeOwnableInternal is ISafeOwnableInternal, OwnableInternal { modifier onlyNomineeOwner() { if (msg.sender != _nomineeOwner()) revert SafeOwnable__NotNomineeOwner(); _; } /** * @notice get the nominated owner who has permission to call acceptOwnership */ function _nomineeOwner() internal view virtual returns (address) { return SafeOwnableStorage.layout().nomineeOwner; } /** * @notice accept transfer of contract ownership */ function _acceptOwnership() internal virtual { _setOwner(msg.sender); delete SafeOwnableStorage.layout().nomineeOwner; } /** * @notice grant permission to given address to claim contract ownership */ function _transferOwnership(address account) internal virtual override { _setNomineeOwner(account); } /** * @notice set nominee owner */ function _setNomineeOwner(address account) internal virtual { SafeOwnableStorage.layout().nomineeOwner = account; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; library SafeOwnableStorage { struct Layout { address nomineeOwner; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.SafeOwnable'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title Set implementation with enumeration functions * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) */ library EnumerableSet { error EnumerableSet__IndexOutOfBounds(); struct Set { bytes32[] _values; // 1-indexed to allow 0 to signify nonexistence mapping(bytes32 => uint256) _indexes; } struct Bytes32Set { Set _inner; } struct AddressSet { Set _inner; } struct UintSet { Set _inner; } function at( Bytes32Set storage set, uint256 index ) internal view returns (bytes32) { return _at(set._inner, index); } function at( AddressSet storage set, uint256 index ) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } function at( UintSet storage set, uint256 index ) internal view returns (uint256) { return uint256(_at(set._inner, index)); } function contains( Bytes32Set storage set, bytes32 value ) internal view returns (bool) { return _contains(set._inner, value); } function contains( AddressSet storage set, address value ) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } function contains( UintSet storage set, uint256 value ) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } function indexOf( Bytes32Set storage set, bytes32 value ) internal view returns (uint256) { return _indexOf(set._inner, value); } function indexOf( AddressSet storage set, address value ) internal view returns (uint256) { return _indexOf(set._inner, bytes32(uint256(uint160(value)))); } function indexOf( UintSet storage set, uint256 value ) internal view returns (uint256) { return _indexOf(set._inner, bytes32(value)); } function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } function add( Bytes32Set storage set, bytes32 value ) internal returns (bool) { return _add(set._inner, value); } function add( AddressSet storage set, address value ) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } function remove( Bytes32Set storage set, bytes32 value ) internal returns (bool) { return _remove(set._inner, value); } function remove( AddressSet storage set, address value ) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } function remove( UintSet storage set, uint256 value ) internal returns (bool) { return _remove(set._inner, bytes32(value)); } function toArray( Bytes32Set storage set ) internal view returns (bytes32[] memory) { return set._inner._values; } function toArray( AddressSet storage set ) internal view returns (address[] memory) { bytes32[] storage values = set._inner._values; address[] storage array; assembly { array.slot := values.slot } return array; } function toArray( UintSet storage set ) internal view returns (uint256[] memory) { bytes32[] storage values = set._inner._values; uint256[] storage array; assembly { array.slot := values.slot } return array; } function _at( Set storage set, uint256 index ) private view returns (bytes32) { if (index >= set._values.length) revert EnumerableSet__IndexOutOfBounds(); return set._values[index]; } function _contains( Set storage set, bytes32 value ) private view returns (bool) { return set._indexes[value] != 0; } function _indexOf( Set storage set, bytes32 value ) private view returns (uint256) { unchecked { return set._indexes[value] - 1; } } function _length(Set storage set) private view returns (uint256) { return set._values.length; } function _add( Set storage set, bytes32 value ) private returns (bool status) { if (!_contains(set, value)) { set._values.push(value); set._indexes[value] = set._values.length; status = true; } } function _remove( Set storage set, bytes32 value ) private returns (bool status) { uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { unchecked { bytes32 last = set._values[set._values.length - 1]; // move last value to now-vacant index set._values[valueIndex - 1] = last; set._indexes[last] = valueIndex; } // clear last index set._values.pop(); delete set._indexes[value]; status = true; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC165Internal } from './IERC165Internal.sol'; /** * @title ERC165 interface registration interface * @dev see https://eips.ethereum.org/EIPS/eip-165 */ interface IERC165 is IERC165Internal { /** * @notice query whether contract has registered support for given interface * @param interfaceId interface id * @return bool whether interface is supported */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title ERC165 interface registration interface */ interface IERC165Internal { }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173Internal } from './IERC173Internal.sol'; /** * @title Contract ownership standard interface * @dev see https://eips.ethereum.org/EIPS/eip-173 */ interface IERC173 is IERC173Internal { /** * @notice get the ERC173 contract owner * @return contract owner */ function owner() external view returns (address); /** * @notice transfer contract ownership to new account * @param account address of new owner */ function transferOwnership(address account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title Partial ERC173 interface needed by internal functions */ interface IERC173Internal { event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC165 } from '../../../interfaces/IERC165.sol'; import { IERC165Base } from './IERC165Base.sol'; import { ERC165BaseInternal } from './ERC165BaseInternal.sol'; import { ERC165BaseStorage } from './ERC165BaseStorage.sol'; /** * @title ERC165 implementation */ abstract contract ERC165Base is IERC165Base, ERC165BaseInternal { /** * @inheritdoc IERC165 */ function supportsInterface(bytes4 interfaceId) public view returns (bool) { return _supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC165BaseInternal } from './IERC165BaseInternal.sol'; import { ERC165BaseStorage } from './ERC165BaseStorage.sol'; /** * @title ERC165 implementation */ abstract contract ERC165BaseInternal is IERC165BaseInternal { /** * @notice indicates whether an interface is already supported based on the interfaceId * @param interfaceId id of interface to check * @return bool indicating whether interface is supported */ function _supportsInterface( bytes4 interfaceId ) internal view virtual returns (bool) { return ERC165BaseStorage.layout().supportedInterfaces[interfaceId]; } /** * @notice sets status of interface support * @param interfaceId id of interface to set status for * @param status boolean indicating whether interface will be set as supported */ function _setSupportsInterface( bytes4 interfaceId, bool status ) internal virtual { if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId(); ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; library ERC165BaseStorage { struct Layout { mapping(bytes4 => bool) supportedInterfaces; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.ERC165Base'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC165 } from '../../../interfaces/IERC165.sol'; import { IERC165BaseInternal } from './IERC165BaseInternal.sol'; interface IERC165Base is IERC165, IERC165BaseInternal {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC165Internal } from '../../../interfaces/IERC165Internal.sol'; interface IERC165BaseInternal is IERC165Internal { error ERC165Base__InvalidInterfaceId(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { Proxy } from '../../Proxy.sol'; import { IDiamondBase } from './IDiamondBase.sol'; import { DiamondBaseStorage } from './DiamondBaseStorage.sol'; /** * @title EIP-2535 "Diamond" proxy base contract * @dev see https://eips.ethereum.org/EIPS/eip-2535 */ abstract contract DiamondBase is IDiamondBase, Proxy { /** * @inheritdoc Proxy */ function _getImplementation() internal view virtual override returns (address implementation) { // inline storage layout retrieval uses less gas DiamondBaseStorage.Layout storage l; bytes32 slot = DiamondBaseStorage.STORAGE_SLOT; assembly { l.slot := slot } implementation = address(bytes20(l.facets[msg.sig])); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @dev derived from https://github.com/mudgen/diamond-2 (MIT license) */ library DiamondBaseStorage { struct Layout { // function selector => (facet address, selector slot position) mapping(bytes4 => bytes32) facets; // total number of selectors registered uint16 selectorCount; // array of selector slots with 8 selectors per slot mapping(uint256 => bytes32) selectorSlots; address fallbackAddress; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.DiamondBase'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IProxy } from '../../IProxy.sol'; interface IDiamondBase is IProxy {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol'; import { DiamondBase } from '../base/DiamondBase.sol'; import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol'; import { IDiamondFallback } from './IDiamondFallback.sol'; // TODO: DiamondFallback interface /** * @title Fallback feature for EIP-2535 "Diamond" proxy */ abstract contract DiamondFallback is IDiamondFallback, OwnableInternal, DiamondBase { /** * @inheritdoc IDiamondFallback */ function getFallbackAddress() external view returns (address fallbackAddress) { fallbackAddress = _getFallbackAddress(); } /** * @inheritdoc IDiamondFallback */ function setFallbackAddress(address fallbackAddress) external onlyOwner { _setFallbackAddress(fallbackAddress); } /** * @inheritdoc DiamondBase * @notice query custom fallback address is no implementation is found */ function _getImplementation() internal view virtual override returns (address implementation) { implementation = super._getImplementation(); if (implementation == address(0)) { implementation = _getFallbackAddress(); } } /** * @notice query the address of the fallback implementation * @return fallbackAddress address of fallback implementation */ function _getFallbackAddress() internal view virtual returns (address fallbackAddress) { fallbackAddress = DiamondBaseStorage.layout().fallbackAddress; } /** * @notice set the address of the fallback implementation * @param fallbackAddress address of fallback implementation */ function _setFallbackAddress(address fallbackAddress) internal virtual { DiamondBaseStorage.layout().fallbackAddress = fallbackAddress; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IDiamondBase } from '../base/IDiamondBase.sol'; interface IDiamondFallback is IDiamondBase { /** * @notice query the address of the fallback implementation * @return fallbackAddress address of fallback implementation */ function getFallbackAddress() external view returns (address fallbackAddress); /** * @notice set the address of the fallback implementation * @param fallbackAddress address of fallback implementation */ function setFallbackAddress(address fallbackAddress) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { ISafeOwnable } from '../../access/ownable/ISafeOwnable.sol'; import { IERC165 } from '../../interfaces/IERC165.sol'; import { IDiamondBase } from './base/IDiamondBase.sol'; import { IDiamondFallback } from './fallback/IDiamondFallback.sol'; import { IDiamondReadable } from './readable/IDiamondReadable.sol'; import { IDiamondWritable } from './writable/IDiamondWritable.sol'; interface ISolidStateDiamond is IDiamondBase, IDiamondFallback, IDiamondReadable, IDiamondWritable, ISafeOwnable, IERC165 { receive() external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol'; import { IDiamondReadable } from './IDiamondReadable.sol'; /** * @title EIP-2535 "Diamond" proxy introspection contract * @dev derived from https://github.com/mudgen/diamond-2 (MIT license) */ abstract contract DiamondReadable is IDiamondReadable { /** * @inheritdoc IDiamondReadable */ function facets() external view returns (Facet[] memory diamondFacets) { DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout(); diamondFacets = new Facet[](l.selectorCount); uint8[] memory numFacetSelectors = new uint8[](l.selectorCount); uint256 numFacets; uint256 selectorIndex; // loop through function selectors for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) { bytes32 slot = l.selectorSlots[slotIndex]; for ( uint256 selectorSlotIndex; selectorSlotIndex < 8; selectorSlotIndex++ ) { selectorIndex++; if (selectorIndex > l.selectorCount) { break; } bytes4 selector = bytes4(slot << (selectorSlotIndex << 5)); address facet = address(bytes20(l.facets[selector])); bool continueLoop; for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { if (diamondFacets[facetIndex].target == facet) { diamondFacets[facetIndex].selectors[ numFacetSelectors[facetIndex] ] = selector; // probably will never have more than 256 functions from one facet contract require(numFacetSelectors[facetIndex] < 255); numFacetSelectors[facetIndex]++; continueLoop = true; break; } } if (continueLoop) { continue; } diamondFacets[numFacets].target = facet; diamondFacets[numFacets].selectors = new bytes4[]( l.selectorCount ); diamondFacets[numFacets].selectors[0] = selector; numFacetSelectors[numFacets] = 1; numFacets++; } } for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { uint256 numSelectors = numFacetSelectors[facetIndex]; bytes4[] memory selectors = diamondFacets[facetIndex].selectors; // setting the number of selectors assembly { mstore(selectors, numSelectors) } } // setting the number of facets assembly { mstore(diamondFacets, numFacets) } } /** * @inheritdoc IDiamondReadable */ function facetFunctionSelectors( address facet ) external view returns (bytes4[] memory selectors) { DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout(); selectors = new bytes4[](l.selectorCount); uint256 numSelectors; uint256 selectorIndex; // loop through function selectors for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) { bytes32 slot = l.selectorSlots[slotIndex]; for ( uint256 selectorSlotIndex; selectorSlotIndex < 8; selectorSlotIndex++ ) { selectorIndex++; if (selectorIndex > l.selectorCount) { break; } bytes4 selector = bytes4(slot << (selectorSlotIndex << 5)); if (facet == address(bytes20(l.facets[selector]))) { selectors[numSelectors] = selector; numSelectors++; } } } // set the number of selectors in the array assembly { mstore(selectors, numSelectors) } } /** * @inheritdoc IDiamondReadable */ function facetAddresses() external view returns (address[] memory addresses) { DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout(); addresses = new address[](l.selectorCount); uint256 numFacets; uint256 selectorIndex; for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) { bytes32 slot = l.selectorSlots[slotIndex]; for ( uint256 selectorSlotIndex; selectorSlotIndex < 8; selectorSlotIndex++ ) { selectorIndex++; if (selectorIndex > l.selectorCount) { break; } bytes4 selector = bytes4(slot << (selectorSlotIndex << 5)); address facet = address(bytes20(l.facets[selector])); bool continueLoop; for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { if (facet == addresses[facetIndex]) { continueLoop = true; break; } } if (continueLoop) { continue; } addresses[numFacets] = facet; numFacets++; } } // set the number of facet addresses in the array assembly { mstore(addresses, numFacets) } } /** * @inheritdoc IDiamondReadable */ function facetAddress( bytes4 selector ) external view returns (address facet) { facet = address(bytes20(DiamondBaseStorage.layout().facets[selector])); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title Diamond proxy introspection interface * @dev see https://eips.ethereum.org/EIPS/eip-2535 */ interface IDiamondReadable { struct Facet { address target; bytes4[] selectors; } /** * @notice get all facets and their selectors * @return diamondFacets array of structured facet data */ function facets() external view returns (Facet[] memory diamondFacets); /** * @notice get all selectors for given facet address * @param facet address of facet to query * @return selectors array of function selectors */ function facetFunctionSelectors( address facet ) external view returns (bytes4[] memory selectors); /** * @notice get addresses of all facets used by diamond * @return addresses array of facet addresses */ function facetAddresses() external view returns (address[] memory addresses); /** * @notice get the address of the facet associated with given selector * @param selector function selector to query * @return facet facet address (zero address if not found) */ function facetAddress( bytes4 selector ) external view returns (address facet); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IOwnable, Ownable, OwnableInternal } from '../../access/ownable/Ownable.sol'; import { ISafeOwnable, SafeOwnable } from '../../access/ownable/SafeOwnable.sol'; import { IERC165 } from '../../interfaces/IERC165.sol'; import { IERC173 } from '../../interfaces/IERC173.sol'; import { ERC165Base, ERC165BaseStorage } from '../../introspection/ERC165/base/ERC165Base.sol'; import { DiamondBase } from './base/DiamondBase.sol'; import { DiamondFallback, IDiamondFallback } from './fallback/DiamondFallback.sol'; import { DiamondReadable, IDiamondReadable } from './readable/DiamondReadable.sol'; import { DiamondWritable, IDiamondWritable } from './writable/DiamondWritable.sol'; import { ISolidStateDiamond } from './ISolidStateDiamond.sol'; /** * @title SolidState "Diamond" proxy reference implementation */ abstract contract SolidStateDiamond is ISolidStateDiamond, DiamondBase, DiamondFallback, DiamondReadable, DiamondWritable, SafeOwnable, ERC165Base { constructor() { bytes4[] memory selectors = new bytes4[](12); uint256 selectorIndex; // register DiamondFallback selectors[selectorIndex++] = IDiamondFallback .getFallbackAddress .selector; selectors[selectorIndex++] = IDiamondFallback .setFallbackAddress .selector; _setSupportsInterface(type(IDiamondFallback).interfaceId, true); // register DiamondWritable selectors[selectorIndex++] = IDiamondWritable.diamondCut.selector; _setSupportsInterface(type(IDiamondWritable).interfaceId, true); // register DiamondReadable selectors[selectorIndex++] = IDiamondReadable.facets.selector; selectors[selectorIndex++] = IDiamondReadable .facetFunctionSelectors .selector; selectors[selectorIndex++] = IDiamondReadable.facetAddresses.selector; selectors[selectorIndex++] = IDiamondReadable.facetAddress.selector; _setSupportsInterface(type(IDiamondReadable).interfaceId, true); // register ERC165 selectors[selectorIndex++] = IERC165.supportsInterface.selector; _setSupportsInterface(type(IERC165).interfaceId, true); // register SafeOwnable selectors[selectorIndex++] = Ownable.owner.selector; selectors[selectorIndex++] = SafeOwnable.nomineeOwner.selector; selectors[selectorIndex++] = Ownable.transferOwnership.selector; selectors[selectorIndex++] = SafeOwnable.acceptOwnership.selector; _setSupportsInterface(type(IERC173).interfaceId, true); // diamond cut FacetCut[] memory facetCuts = new FacetCut[](1); facetCuts[0] = FacetCut({ target: address(this), action: FacetCutAction.ADD, selectors: selectors }); _diamondCut(facetCuts, address(0), ''); // set owner _setOwner(msg.sender); } receive() external payable {} function _transferOwnership( address account ) internal virtual override(OwnableInternal, SafeOwnable) { super._transferOwnership(account); } /** * @inheritdoc DiamondFallback */ function _getImplementation() internal view override(DiamondBase, DiamondFallback) returns (address implementation) { implementation = super._getImplementation(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol'; import { IDiamondWritable } from './IDiamondWritable.sol'; import { DiamondWritableInternal } from './DiamondWritableInternal.sol'; /** * @title EIP-2535 "Diamond" proxy update contract */ abstract contract DiamondWritable is IDiamondWritable, DiamondWritableInternal, OwnableInternal { /** * @inheritdoc IDiamondWritable */ function diamondCut( FacetCut[] calldata facetCuts, address target, bytes calldata data ) external onlyOwner { _diamondCut(facetCuts, target, data); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { AddressUtils } from '../../../utils/AddressUtils.sol'; import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol'; import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol'; abstract contract DiamondWritableInternal is IDiamondWritableInternal { using AddressUtils for address; bytes32 private constant CLEAR_ADDRESS_MASK = bytes32(uint256(0xffffffffffffffffffffffff)); bytes32 private constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224)); /** * @notice update functions callable on Diamond proxy * @param facetCuts array of structured Diamond facet update data * @param target optional recipient of initialization delegatecall * @param data optional initialization call data */ function _diamondCut( FacetCut[] memory facetCuts, address target, bytes memory data ) internal { DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout(); unchecked { uint256 originalSelectorCount = l.selectorCount; uint256 selectorCount = originalSelectorCount; bytes32 selectorSlot; // Check if last selector slot is not full if (selectorCount & 7 > 0) { // get last selectorSlot selectorSlot = l.selectorSlots[selectorCount >> 3]; } for (uint256 i; i < facetCuts.length; i++) { FacetCut memory facetCut = facetCuts[i]; FacetCutAction action = facetCut.action; if (facetCut.selectors.length == 0) revert DiamondWritable__SelectorNotSpecified(); if (action == FacetCutAction.ADD) { (selectorCount, selectorSlot) = _addFacetSelectors( l, selectorCount, selectorSlot, facetCut ); } else if (action == FacetCutAction.REPLACE) { _replaceFacetSelectors(l, facetCut); } else if (action == FacetCutAction.REMOVE) { (selectorCount, selectorSlot) = _removeFacetSelectors( l, selectorCount, selectorSlot, facetCut ); } } if (selectorCount != originalSelectorCount) { l.selectorCount = uint16(selectorCount); } // If last selector slot is not full if (selectorCount & 7 > 0) { l.selectorSlots[selectorCount >> 3] = selectorSlot; } emit DiamondCut(facetCuts, target, data); _initialize(target, data); } } function _addFacetSelectors( DiamondBaseStorage.Layout storage l, uint256 selectorCount, bytes32 selectorSlot, FacetCut memory facetCut ) internal returns (uint256, bytes32) { unchecked { if ( facetCut.target != address(this) && !facetCut.target.isContract() ) revert DiamondWritable__TargetHasNoCode(); for (uint256 i; i < facetCut.selectors.length; i++) { bytes4 selector = facetCut.selectors[i]; bytes32 oldFacet = l.facets[selector]; if (address(bytes20(oldFacet)) != address(0)) revert DiamondWritable__SelectorAlreadyAdded(); // add facet for selector l.facets[selector] = bytes20(facetCut.target) | bytes32(selectorCount); uint256 selectorInSlotPosition = (selectorCount & 7) << 5; // clear selector position in slot and add selector selectorSlot = (selectorSlot & ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) | (bytes32(selector) >> selectorInSlotPosition); // if slot is full then write it to storage if (selectorInSlotPosition == 224) { l.selectorSlots[selectorCount >> 3] = selectorSlot; selectorSlot = 0; } selectorCount++; } return (selectorCount, selectorSlot); } } function _removeFacetSelectors( DiamondBaseStorage.Layout storage l, uint256 selectorCount, bytes32 selectorSlot, FacetCut memory facetCut ) internal returns (uint256, bytes32) { unchecked { if (facetCut.target != address(0)) revert DiamondWritable__RemoveTargetNotZeroAddress(); uint256 selectorSlotCount = selectorCount >> 3; uint256 selectorInSlotIndex = selectorCount & 7; for (uint256 i; i < facetCut.selectors.length; i++) { bytes4 selector = facetCut.selectors[i]; bytes32 oldFacet = l.facets[selector]; if (address(bytes20(oldFacet)) == address(0)) revert DiamondWritable__SelectorNotFound(); if (address(bytes20(oldFacet)) == address(this)) revert DiamondWritable__SelectorIsImmutable(); if (selectorSlot == 0) { selectorSlotCount--; selectorSlot = l.selectorSlots[selectorSlotCount]; selectorInSlotIndex = 7; } else { selectorInSlotIndex--; } bytes4 lastSelector; uint256 oldSelectorsSlotCount; uint256 oldSelectorInSlotPosition; // adding a block here prevents stack too deep error { // replace selector with last selector in l.facets lastSelector = bytes4( selectorSlot << (selectorInSlotIndex << 5) ); if (lastSelector != selector) { // update last selector slot position info l.facets[lastSelector] = (oldFacet & CLEAR_ADDRESS_MASK) | bytes20(l.facets[lastSelector]); } delete l.facets[selector]; uint256 oldSelectorCount = uint16(uint256(oldFacet)); oldSelectorsSlotCount = oldSelectorCount >> 3; oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5; } if (oldSelectorsSlotCount != selectorSlotCount) { bytes32 oldSelectorSlot = l.selectorSlots[ oldSelectorsSlotCount ]; // clears the selector we are deleting and puts the last selector in its place. oldSelectorSlot = (oldSelectorSlot & ~(CLEAR_SELECTOR_MASK >> oldSelectorInSlotPosition)) | (bytes32(lastSelector) >> oldSelectorInSlotPosition); // update storage with the modified slot l.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot; } else { // clears the selector we are deleting and puts the last selector in its place. selectorSlot = (selectorSlot & ~(CLEAR_SELECTOR_MASK >> oldSelectorInSlotPosition)) | (bytes32(lastSelector) >> oldSelectorInSlotPosition); } if (selectorInSlotIndex == 0) { delete l.selectorSlots[selectorSlotCount]; selectorSlot = 0; } } selectorCount = (selectorSlotCount << 3) | selectorInSlotIndex; return (selectorCount, selectorSlot); } } function _replaceFacetSelectors( DiamondBaseStorage.Layout storage l, FacetCut memory facetCut ) internal { unchecked { if (!facetCut.target.isContract()) revert DiamondWritable__TargetHasNoCode(); for (uint256 i; i < facetCut.selectors.length; i++) { bytes4 selector = facetCut.selectors[i]; bytes32 oldFacet = l.facets[selector]; address oldFacetAddress = address(bytes20(oldFacet)); if (oldFacetAddress == address(0)) revert DiamondWritable__SelectorNotFound(); if (oldFacetAddress == address(this)) revert DiamondWritable__SelectorIsImmutable(); if (oldFacetAddress == facetCut.target) revert DiamondWritable__ReplaceTargetIsIdentical(); // replace old facet address l.facets[selector] = (oldFacet & CLEAR_ADDRESS_MASK) | bytes20(facetCut.target); } } } function _initialize(address target, bytes memory data) private { if ((target == address(0)) != (data.length == 0)) revert DiamondWritable__InvalidInitializationParameters(); if (target != address(0)) { if (target != address(this)) { if (!target.isContract()) revert DiamondWritable__TargetHasNoCode(); } (bool success, ) = target.delegatecall(data); if (!success) { assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol'; /** * @title Diamond proxy upgrade interface * @dev see https://eips.ethereum.org/EIPS/eip-2535 */ interface IDiamondWritable is IDiamondWritableInternal { /** * @notice update diamond facets and optionally execute arbitrary initialization function * @param facetCuts array of structured Diamond facet update data * @param target optional target of initialization delegatecall * @param data optional initialization function call data */ function diamondCut( FacetCut[] calldata facetCuts, address target, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; interface IDiamondWritableInternal { enum FacetCutAction { ADD, REPLACE, REMOVE } event DiamondCut(FacetCut[] facetCuts, address target, bytes data); error DiamondWritable__InvalidInitializationParameters(); error DiamondWritable__RemoveTargetNotZeroAddress(); error DiamondWritable__ReplaceTargetIsIdentical(); error DiamondWritable__SelectorAlreadyAdded(); error DiamondWritable__SelectorIsImmutable(); error DiamondWritable__SelectorNotFound(); error DiamondWritable__SelectorNotSpecified(); error DiamondWritable__TargetHasNoCode(); struct FacetCut { address target; FacetCutAction action; bytes4[] selectors; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; interface IProxy { error Proxy__ImplementationIsNotContract(); fallback() external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { AddressUtils } from '../utils/AddressUtils.sol'; import { IProxy } from './IProxy.sol'; /** * @title Base proxy contract */ abstract contract Proxy is IProxy { using AddressUtils for address; /** * @notice delegate all calls to implementation contract * @dev reverts if implementation address contains no code, for compatibility with metamorphic contracts * @dev memory location in use by assembly may be unsafe in other contexts */ fallback() external payable virtual { address implementation = _getImplementation(); if (!implementation.isContract()) revert Proxy__ImplementationIsNotContract(); assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall( gas(), implementation, 0, calldatasize(), 0, 0 ) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @notice get logic implementation address * @return implementation address */ function _getImplementation() internal virtual returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { UintUtils } from './UintUtils.sol'; library AddressUtils { using UintUtils for uint256; error AddressUtils__InsufficientBalance(); error AddressUtils__NotContract(); error AddressUtils__SendValueFailed(); function toString(address account) internal pure returns (string memory) { return uint256(uint160(account)).toHexString(20); } function isContract(address account) internal view returns (bool) { uint256 size; assembly { size := extcodesize(account) } return size > 0; } function sendValue(address payable account, uint256 amount) internal { (bool success, ) = account.call{ value: amount }(''); if (!success) revert AddressUtils__SendValueFailed(); } function functionCall( address target, bytes memory data ) internal returns (bytes memory) { return functionCall(target, data, 'AddressUtils: failed low-level call'); } function functionCall( address target, bytes memory data, string memory error ) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, error); } function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, 'AddressUtils: failed low-level call with value' ); } function functionCallWithValue( address target, bytes memory data, uint256 value, string memory error ) internal returns (bytes memory) { if (value > address(this).balance) revert AddressUtils__InsufficientBalance(); return _functionCallWithValue(target, data, value, error); } /** * @notice execute arbitrary external call with limited gas usage and amount of copied return data * @dev derived from https://github.com/nomad-xyz/ExcessivelySafeCall (MIT License) * @param target recipient of call * @param gasAmount gas allowance for call * @param value native token value to include in call * @param maxCopy maximum number of bytes to copy from return data * @param data encoded call data * @return success whether call is successful * @return returnData copied return data */ function excessivelySafeCall( address target, uint256 gasAmount, uint256 value, uint16 maxCopy, bytes memory data ) internal returns (bool success, bytes memory returnData) { returnData = new bytes(maxCopy); assembly { // execute external call via assembly to avoid automatic copying of return data success := call( gasAmount, target, value, add(data, 0x20), mload(data), 0, 0 ) // determine whether to limit amount of data to copy let toCopy := returndatasize() if gt(toCopy, maxCopy) { toCopy := maxCopy } // store the length of the copied bytes mstore(returnData, toCopy) // copy the bytes from returndata[0:toCopy] returndatacopy(add(returnData, 0x20), 0, toCopy) } } function _functionCallWithValue( address target, bytes memory data, uint256 value, string memory error ) private returns (bytes memory) { if (!isContract(target)) revert AddressUtils__NotContract(); (bool success, bytes memory returnData) = target.call{ value: value }( data ); if (success) { return returnData; } else if (returnData.length > 0) { assembly { let returnData_size := mload(returnData) revert(add(32, returnData), returnData_size) } } else { revert(error); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title utility functions for uint256 operations * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license) */ library UintUtils { error UintUtils__InsufficientHexLength(); bytes16 private constant HEX_SYMBOLS = '0123456789abcdef'; function add(uint256 a, int256 b) internal pure returns (uint256) { return b < 0 ? sub(a, -b) : a + uint256(b); } function sub(uint256 a, int256 b) internal pure returns (uint256) { return b < 0 ? add(a, -b) : a - uint256(b); } function toString(uint256 value) internal pure returns (string memory) { if (value == 0) { return '0'; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return '0x00'; } uint256 length = 0; for (uint256 temp = value; temp != 0; temp >>= 8) { unchecked { length++; } } return toHexString(value, length); } function toHexString( uint256 value, uint256 length ) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = '0'; buffer[1] = 'x'; unchecked { for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_SYMBOLS[value & 0xf]; value >>= 4; } } if (value != 0) revert UintUtils__InsufficientHexLength(); return string(buffer); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"DiamondWritable__InvalidInitializationParameters","type":"error"},{"inputs":[],"name":"DiamondWritable__RemoveTargetNotZeroAddress","type":"error"},{"inputs":[],"name":"DiamondWritable__ReplaceTargetIsIdentical","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorAlreadyAdded","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorIsImmutable","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotFound","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotSpecified","type":"error"},{"inputs":[],"name":"DiamondWritable__TargetHasNoCode","type":"error"},{"inputs":[],"name":"ERC165Base__InvalidInterfaceId","type":"error"},{"inputs":[],"name":"Ownable__NotOwner","type":"error"},{"inputs":[],"name":"Ownable__NotTransitiveOwner","type":"error"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"inputs":[],"name":"SafeOwnable__NotNomineeOwner","type":"error"},{"inputs":[],"name":"UintUtils__InsufficientHexLength","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"DiamondCut","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facet","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondReadable.Facet[]","name":"diamondFacets","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackAddress","outputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nomineeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"name":"setFallbackAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060408051600c8082526101a0820190925260009160208201610180803683370190505090506000632c40805960e01b82826200004e8162000da6565b93508151811062000063576200006362000dce565b6001600160e01b031990921660209283029190910190910152639142376560e01b8282620000918162000da6565b935081518110620000a657620000a662000dce565b6001600160e01b031990921660209283029190910190910152620000d3632f40adcf60e21b600162000480565b6307e4c70760e21b8282620000e88162000da6565b935081518110620000fd57620000fd62000dce565b6001600160e01b0319909216602092830291909101909101526200012a6307e4c70760e21b600162000480565b637a0ed62760e01b82826200013f8162000da6565b93508151811062000154576200015462000dce565b6001600160e01b0319909216602092830291909101909101526356fe50af60e11b8282620001828162000da6565b93508151811062000197576200019762000dce565b6001600160e01b0319909216602092830291909101909101526314bbdacb60e21b8282620001c58162000da6565b935081518110620001da57620001da62000dce565b6001600160e01b0319909216602092830291909101909101526366ffd66360e11b8282620002088162000da6565b9350815181106200021d576200021d62000dce565b6001600160e01b0319909216602092830291909101909101526200024a6348e2b09360e01b600162000480565b6301ffc9a760e01b82826200025f8162000da6565b93508151811062000274576200027462000dce565b6001600160e01b031990921660209283029190910190910152620002a16301ffc9a760e01b600162000480565b638da5cb5b60e01b8282620002b68162000da6565b935081518110620002cb57620002cb62000dce565b6001600160e01b03199092166020928302919091019091015263455a8a8560e11b8282620002f98162000da6565b9350815181106200030e576200030e62000dce565b6001600160e01b03199092166020928302919091019091015263f2fde38b60e01b82826200033c8162000da6565b93508151811062000351576200035162000dce565b6001600160e01b0319909216602092830291909101909101526379ba509760e01b82826200037f8162000da6565b93508151811062000394576200039462000dce565b6001600160e01b031990921660209283029190910190910152620003c16307f5828d60e41b600162000480565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081620003d8579050506040805160608101909152308152909150602081016000815260200184815250816000815181106200043e576200043e62000dce565b60200260200101819052506200046c81600060405180602001604052806000815250620004f260201b60201c565b6200047733620006ce565b50505062000f73565b6001600160e01b03198083169003620004ac5760405163b0a19dd560e01b815260040160405180910390fd5b80620004c26200074260201b62000ce31760201c565b6001600160e01b03199390931660009081526020939093526040909220805460ff19169215159290921790915550565b6000620005096200076660201b62000d071760201c565b600181015490915061ffff8116908190600090600716156200053d5750600381901c60009081526002840160205260409020545b60005b87518110156200063c57600088828151811062000561576200056162000dce565b602002602001015190506000816020015190508160400151516000036200059b5760405163eb6c3aeb60e01b815260040160405180910390fd5b6000816002811115620005b257620005b262000de4565b03620005d157620005c6878686856200078a565b909550935062000631565b6001816002811115620005e857620005e862000de4565b036200060057620005fa8783620008e9565b62000631565b600281600281111562000617576200061762000de4565b0362000631576200062b8786868562000a4f565b90955093505b505060010162000540565b50828214620006595760018401805461ffff191661ffff84161790555b60078216156200067c57600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673878787604051620006b19392919062000e4e565b60405180910390a1620006c5868662000c7b565b50505050505050565b6000620006e562000d7c60201b62000d2b1760201c565b80546040519192506001600160a01b03808516929116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380546001600160a01b0319166001600160a01b0392909216919091179055565b7ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b805160009081906001600160a01b03163014801590620007ca5750620007c883600001516001600160a01b031662000da060201b620003b21760201c565b155b15620007e957604051633ddc5cab60e21b815260040160405180910390fd5b60005b836040015151811015620008dc5760008460400151828151811062000815576200081562000dce565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c156200086257604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c19999099161797819003620008cc57600389901c600090815260028b0160205260408120989098555b50505060019586019501620007ec565b5093959294509192505050565b6200090c81600001516001600160a01b031662000da060201b620003b21760201c565b6200092a57604051633ddc5cab60e21b815260040160405180910390fd5b60005b81604001515181101562000a4a5760008260400151828151811062000956576200095662000dce565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c80620009a3576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b03821603620009cd5760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b03160362000a04576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166001600160601b03919091161790556001016200092d565b505050565b805160009081906001600160a01b03161562000a7e57604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b85604001515181101562000c675760008660400151828151811062000ab35762000ab362000dce565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c62000aff576040516337e25a9760e11b815260040160405180910390fd5b30606082901c0362000b245760405163e983573160e01b815260040160405180910390fd5b600089900362000b5257600019909401600081815260028c0160205260409020549850936007935062000b5a565b600019909301925b600584901b89901b6000806001600160e01b03198084169086161462000bad576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166001600160601b0386161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b1687821462000c1257600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c17905562000c36565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000362000c5557600088815260028f01602052604081208190559b505b50506001909301925062000a8a915050565b5060039190911b1796939550929350505050565b8051156001600160a01b038316151462000ca8576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b0382161562000d78576001600160a01b038216301462000d065762000ce8826001600160a01b031662000da060201b620003b21760201c565b62000d0657604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b03168260405162000d22919062000f55565b600060405180830381855af49150503d806000811462000d5f576040519150601f19603f3d011682016040523d82523d6000602084013e62000d64565b606091505b505090508062000a4a573d6000803e3d6000fd5b5050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b3b151590565b60006001820162000dc757634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60005b8381101562000e1757818101518382015260200162000dfd565b50506000910152565b6000815180845262000e3a81602086016020860162000dfa565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101562000f2357898403607f19018652815180516001600160a01b0316855283810151898601906003811062000ebf57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b8083101562000f0d5783516001600160e01b031916825292860192600192909201919086019062000ee1565b5097850197955050509082019060010162000e77565b50506001600160a01b038a1690880152868103604088015262000f47818962000e20565b9a9950505050505050505050565b6000825162000f6981846020870162000dfa565b9190910192915050565b61224a8062000f836000396000f3fe6080604052600436106101025760003560e01c80638ab5150a1161009557806391d148541161006457806391d14854146102f6578063adfca15e14610316578063cdffacc614610343578063d547741f14610363578063f2fde38b1461038357610109565b80638ab5150a1461028c5780638bb9c5bf146102a15780638da5cb5b146102c157806391423765146102d657610109565b80632f2ff15d116100d15780632f2ff15d1461021357806352ef6b2c1461023357806379ba5097146102555780637a0ed6271461026a57610109565b806301ffc9a7146101635780631f931c1c14610198578063248a9ca3146101b85780632c408059146101e657610109565b3661010957005b60006101136103a3565b90506001600160a01b0381163b61013d576040516321f27f0d60e21b815260040160405180910390fd5b3660008037600080366000845af43d6000803e80801561015c573d6000f35b3d6000fd5b005b34801561016f57600080fd5b5061018361017e366004611ad7565b6103b8565b60405190151581526020015b60405180910390f35b3480156101a457600080fd5b506101616101b3366004611b52565b6103c9565b3480156101c457600080fd5b506101d86101d3366004611c04565b610453565b60405190815260200161018f565b3480156101f257600080fd5b506101fb61045e565b6040516001600160a01b03909116815260200161018f565b34801561021f57600080fd5b5061016161022e366004611c1d565b610468565b34801561023f57600080fd5b50610248610489565b60405161018f9190611c49565b34801561026157600080fd5b5061016161062c565b34801561027657600080fd5b5061027f61066f565b60405161018f9190611cdb565b34801561029857600080fd5b506101fb610a97565b3480156102ad57600080fd5b506101616102bc366004611c04565b610aa1565b3480156102cd57600080fd5b506101fb610aad565b3480156102e257600080fd5b506101616102f1366004611d58565b610ab7565b34801561030257600080fd5b50610183610311366004611c1d565b610af9565b34801561032257600080fd5b50610336610331366004611d58565b610b0c565b60405161018f9190611d73565b34801561034f57600080fd5b506101fb61035e366004611ad7565b610c58565b34801561036f57600080fd5b5061016161037e366004611c1d565b610c85565b34801561038f57600080fd5b5061016161039e366004611d58565b610ca1565b60006103ad610d4f565b905090565b3b151590565b60006103c382610d9b565b92915050565b6103d1610dc8565b6001600160a01b0316336001600160a01b03161461040257604051632f7a8ee160e01b815260040160405180910390fd5b61044c61040f8587611e49565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610de192505050565b5050505050565b60006103c382610f8f565b60006103ad610fb1565b61047182610f8f565b61047a81610fcd565b6104848383610fd7565b505050565b60606000610495610d07565b600181015490915061ffff1667ffffffffffffffff8111156104b9576104b9611db5565b6040519080825280602002602001820160405280156104e2578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610624576000818152600285016020526040812054905b600881101561060f578361052181611f93565b600188015490955061ffff168511905061060f57600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156105b2578a818151811061057757610577611fac565b60200260200101516001600160a01b0316836001600160a01b0316036105a057600191506105b2565b806105aa81611f93565b91505061055d565b5080156105c1575050506105fd565b818a89815181106105d4576105d4611fac565b6001600160a01b0390921660209283029190910190910152876105f681611f93565b9850505050505b8061060781611f93565b91505061050e565b5050808061061c90611f93565b9150506104eb565b505082525090565b610634611039565b6001600160a01b0316336001600160a01b0316146106655760405163efd1052d60e01b815260040160405180910390fd5b61066d611061565b565b6060600061067b610d07565b600181015490915061ffff1667ffffffffffffffff81111561069f5761069f611db5565b6040519080825280602002602001820160405280156106e557816020015b6040805180820190915260008152606060208201528152602001906001900390816106bd5790505b50600182015490925060009061ffff1667ffffffffffffffff81111561070d5761070d611db5565b604051908082528060200260200182016040528015610736578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610a25576000818152600286016020526040812054905b6008811015610a10578361077581611f93565b600189015490955061ffff1685119050610a1057600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b888110156108ce57826001600160a01b03168c82815181106107d5576107d5611fac565b6020026020010151600001516001600160a01b0316036108bc57838c828151811061080257610802611fac565b6020026020010151602001518b838151811061082057610820611fac565b602002602001015160ff168151811061083b5761083b611fac565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a828151811061087157610871611fac565b602002602001015160ff161061088657600080fd5b89818151811061089857610898611fac565b6020026020010180518091906108ad90611fc2565b60ff16905250600191506108ce565b806108c681611f93565b9150506107b1565b5080156108dd575050506109fe565b818b89815181106108f0576108f0611fac565b60209081029190910101516001600160a01b03909116905260018a015461ffff1667ffffffffffffffff81111561092957610929611db5565b604051908082528060200260200182016040528015610952578160200160208202803683370190505b508b898151811061096557610965611fac565b602002602001015160200181905250828b898151811061098757610987611fac565b6020026020010151602001516000815181106109a5576109a5611fac565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106109db576109db611fac565b60ff90921660209283029190910190910152876109f781611f93565b9850505050505b80610a0881611f93565b915050610762565b50508080610a1d90611f93565b91505061073f565b5060005b82811015610a8c576000848281518110610a4557610a45611fac565b602002602001015160ff1690506000878381518110610a6657610a66611fac565b602002602001015160200151905081815250508080610a8490611f93565b915050610a29565b508185525050505090565b60006103ad611039565b610aaa8161109b565b50565b60006103ad610dc8565b610abf610dc8565b6001600160a01b0316336001600160a01b031614610af057604051632f7a8ee160e01b815260040160405180910390fd5b610aaa816110a5565b6000610b0583836110d2565b9392505050565b60606000610b18610d07565b600181015490915061ffff1667ffffffffffffffff811115610b3c57610b3c611db5565b604051908082528060200260200182016040528015610b65578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610c4e576000818152600285016020526040812054905b6008811015610c395783610ba481611f93565b600188015490955061ffff1685119050610c3957600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a1603610c265780888781518110610bff57610bff611fac565b6001600160e01b03199092166020928302919091019091015285610c2281611f93565b9650505b5080610c3181611f93565b915050610b91565b50508080610c4690611f93565b915050610b6e565b5050825250919050565b6000610c62610d07565b6001600160e01b0319909216600090815260209290925250604090205460601c90565b610c8e82610f8f565b610c9781610fcd565b61048483836110f7565b610ca9610dc8565b6001600160a01b0316336001600160a01b031614610cda57604051632f7a8ee160e01b815260040160405180910390fd5b610aaa81611159565b7ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c80610d98576103ad610fb1565b90565b6000610da5610ce3565b6001600160e01b0319909216600090815260209290925250604090205460ff1690565b6000610dd2610d2b565b546001600160a01b0316919050565b6000610deb610d07565b600181015490915061ffff811690819060009060071615610e1e5750600381901c60009081526002840160205260409020545b60005b8751811015610f03576000888281518110610e3e57610e3e611fac565b60200260200101519050600081602001519050816040015151600003610e775760405163eb6c3aeb60e01b815260040160405180910390fd5b6000816002811115610e8b57610e8b611fe1565b03610ea657610e9c87868685611162565b9095509350610ef9565b6001816002811115610eba57610eba611fe1565b03610ece57610ec987836112a1565b610ef9565b6002816002811115610ee257610ee2611fe1565b03610ef957610ef3878686856113e7565b90955093505b5050600101610e21565b50828214610f1f5760018401805461ffff191661ffff84161790555b6007821615610f4157600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673878787604051610f7493929190612047565b60405180910390a1610f86868661160a565b50505050505050565b60009081526000805160206121f5833981519152602052604090206002015490565b6000610fbb610d07565b600301546001600160a01b0316919050565b610aaa81336116ee565b60008281526000805160206121f583398151915260205260409020610ffc9082611759565b5060405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610dd2565b61106a3361176e565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319169055565b610aaa81336110f7565b806110ae610d07565b60030180546001600160a01b0319166001600160a01b039290921691909117905550565b60008281526000805160206121f583398151915260205260408120610b0590836117d5565b60008281526000805160206121f58339815191526020526040902061111c90826117f7565b5060405133906001600160a01b0383169084907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b90600090a45050565b610aaa8161180c565b805160009081906001600160a01b0316301480159061118a575082516001600160a01b03163b155b156111a857604051633ddc5cab60e21b815260040160405180910390fd5b60005b836040015151811015611294576000846040015182815181106111d0576111d0611fac565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1561121c57604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c1999909916179781900361128557600389901c600090815260028b0160205260408120989098555b505050600195860195016111ab565b5093959294509192505050565b80516001600160a01b03163b6112ca57604051633ddc5cab60e21b815260040160405180910390fd5b60005b816040015151811015610484576000826040015182815181106112f2576112f2611fac565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c8061133e576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036113675760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b03160361139d576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff919091161790556001016112cd565b805160009081906001600160a01b03161561141557604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b8560400151518110156115f65760008660400151828151811061144657611446611fac565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c611491576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036114b55760405163e983573160e01b815260040160405180910390fd5b60008990036114e157600019909401600081815260028c016020526040902054985093600793506114e9565b600019909301925b600584901b89901b6000806001600160e01b031980841690861614611540576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166bffffffffffffffffffffffff86161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b168782146115a357600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c1790556115c7565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b866000036115e557600088815260028f01602052604081208190559b505b505060019093019250611421915050565b5060039190911b1796939550929350505050565b8051156001600160a01b0383161514611636576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b038216156116ea576001600160a01b038216301461167d576001600160a01b0382163b61167d57604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b0316826040516116979190612110565b600060405180830381855af49150503d80600081146116d2576040519150601f19603f3d011682016040523d82523d6000602084013e6116d7565b606091505b5050905080610484573d6000803e3d6000fd5b5050565b6116f882826110d2565b6116ea5761170e816001600160a01b031661184d565b61171983602061185f565b60405160200161172a92919061212c565b60408051601f198184030181529082905262461bcd60e51b8252611750916004016121a1565b60405180910390fd5b6000610b05836001600160a01b0384166119b2565b6000611778610d2b565b80546040519192506001600160a01b03808516929116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03811660009081526001830160205260408120541515610b05565b6000610b05836001600160a01b0384166119f5565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319166001600160a01b038316179055610aaa8181565b60606103c36001600160a01b03831660145b6060600061186e8360026121b4565b6118799060026121cb565b67ffffffffffffffff81111561189157611891611db5565b6040519080825280601f01601f1916602001820160405280156118bb576020820181803683370190505b509050600360fc1b816000815181106118d6576118d6611fac565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061190557611905611fac565b60200101906001600160f81b031916908160001a905350600160028402015b6001811115611992576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061195557611955611fac565b1a60f81b82828151811061196b5761196b611fac565b60200101906001600160f81b031916908160001a90535060049490941c9360001901611924565b508315610b055760405163c913478560e01b815260040160405180910390fd5b60008181526001830160205260408120546103c3575081546001808201845560008481526020808220909301849055845493815293810190915260409092205590565b60008181526001830160205260408120548015611ab357835460009085906000198101908110611a2757611a27611fac565b9060005260206000200154905080856000016001840381548110611a4d57611a4d611fac565b6000918252602080832090910192909255918252600186019052604090208190558354849080611a7f57611a7f6121de565b6001900381819060005260206000200160009055905583600101600084815260200190815260200160002060009055600191505b5092915050565b80356001600160e01b031981168114611ad257600080fd5b919050565b600060208284031215611ae957600080fd5b610b0582611aba565b80356001600160a01b0381168114611ad257600080fd5b60008083601f840112611b1b57600080fd5b50813567ffffffffffffffff811115611b3357600080fd5b602083019150836020828501011115611b4b57600080fd5b9250929050565b600080600080600060608688031215611b6a57600080fd5b853567ffffffffffffffff80821115611b8257600080fd5b818801915088601f830112611b9657600080fd5b813581811115611ba557600080fd5b8960208260051b8501011115611bba57600080fd5b60208301975080965050611bd060208901611af2565b94506040880135915080821115611be657600080fd5b50611bf388828901611b09565b969995985093965092949392505050565b600060208284031215611c1657600080fd5b5035919050565b60008060408385031215611c3057600080fd5b82359150611c4060208401611af2565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015611c8a5783516001600160a01b031683529284019291840191600101611c65565b50909695505050505050565b600081518084526020808501945080840160005b83811015611cd05781516001600160e01b03191687529582019590820190600101611caa565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611d4a57888303603f19018552815180516001600160a01b03168452870151878401879052611d3787850182611c96565b9588019593505090860190600101611d02565b509098975050505050505050565b600060208284031215611d6a57600080fd5b610b0582611af2565b6020808252825182820181905260009190848201906040850190845b81811015611c8a5783516001600160e01b03191683529284019291840191600101611d8f565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611dee57611dee611db5565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611e1d57611e1d611db5565b604052919050565b600067ffffffffffffffff821115611e3f57611e3f611db5565b5060051b60200190565b6000611e5c611e5784611e25565b611df4565b83815260208082019190600586811b860136811115611e7a57600080fd5b865b81811015611f7057803567ffffffffffffffff80821115611e9d5760008081fd5b818a01915060608236031215611eb35760008081fd5b611ebb611dcb565b611ec483611af2565b81528683013560038110611ed85760008081fd5b8188015260408381013583811115611ef05760008081fd5b939093019236601f850112611f0757600092508283fd5b83359250611f17611e5784611e25565b83815292871b84018801928881019036851115611f345760008081fd5b948901945b84861015611f5957611f4a86611aba565b82529489019490890190611f39565b918301919091525088525050948301948301611e7c565b5092979650505050505050565b634e487b7160e01b600052601160045260246000fd5b600060018201611fa557611fa5611f7d565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103611fd857611fd8611f7d565b60010192915050565b634e487b7160e01b600052602160045260246000fd5b60005b83811015612012578181015183820152602001611ffa565b50506000910152565b60008151808452612033816020860160208601611ff7565b601f01601f19169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b848110156120e057898703607f19018652825180516001600160a01b0316885284810151600381106120b157634e487b7160e01b84526021600452602484fd5b888601526040908101519088018990526120cd89890182611c96565b9750509483019491830191600101612071565b5050506001600160a01b0389169087015250508381036040850152612105818661201b565b979650505050505050565b60008251612122818460208701611ff7565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612164816017850160208801611ff7565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612195816028840160208801611ff7565b01602801949350505050565b602081526000610b05602083018461201b565b80820281158282048414176103c3576103c3611f7d565b808201808211156103c3576103c3611f7d565b634e487b7160e01b600052603160045260246000fdfed3889cc5458b268d0544e5534672df1296288ca3f93cbd39bd6f497a5c622811a2646970667358221220414b9b3bbd6fc714b587bfcf8b1cc621e20d5235de78bc17e9083a48412381cc64736f6c63430008110033
Deployed Bytecode
0x6080604052600436106101025760003560e01c80638ab5150a1161009557806391d148541161006457806391d14854146102f6578063adfca15e14610316578063cdffacc614610343578063d547741f14610363578063f2fde38b1461038357610109565b80638ab5150a1461028c5780638bb9c5bf146102a15780638da5cb5b146102c157806391423765146102d657610109565b80632f2ff15d116100d15780632f2ff15d1461021357806352ef6b2c1461023357806379ba5097146102555780637a0ed6271461026a57610109565b806301ffc9a7146101635780631f931c1c14610198578063248a9ca3146101b85780632c408059146101e657610109565b3661010957005b60006101136103a3565b90506001600160a01b0381163b61013d576040516321f27f0d60e21b815260040160405180910390fd5b3660008037600080366000845af43d6000803e80801561015c573d6000f35b3d6000fd5b005b34801561016f57600080fd5b5061018361017e366004611ad7565b6103b8565b60405190151581526020015b60405180910390f35b3480156101a457600080fd5b506101616101b3366004611b52565b6103c9565b3480156101c457600080fd5b506101d86101d3366004611c04565b610453565b60405190815260200161018f565b3480156101f257600080fd5b506101fb61045e565b6040516001600160a01b03909116815260200161018f565b34801561021f57600080fd5b5061016161022e366004611c1d565b610468565b34801561023f57600080fd5b50610248610489565b60405161018f9190611c49565b34801561026157600080fd5b5061016161062c565b34801561027657600080fd5b5061027f61066f565b60405161018f9190611cdb565b34801561029857600080fd5b506101fb610a97565b3480156102ad57600080fd5b506101616102bc366004611c04565b610aa1565b3480156102cd57600080fd5b506101fb610aad565b3480156102e257600080fd5b506101616102f1366004611d58565b610ab7565b34801561030257600080fd5b50610183610311366004611c1d565b610af9565b34801561032257600080fd5b50610336610331366004611d58565b610b0c565b60405161018f9190611d73565b34801561034f57600080fd5b506101fb61035e366004611ad7565b610c58565b34801561036f57600080fd5b5061016161037e366004611c1d565b610c85565b34801561038f57600080fd5b5061016161039e366004611d58565b610ca1565b60006103ad610d4f565b905090565b3b151590565b60006103c382610d9b565b92915050565b6103d1610dc8565b6001600160a01b0316336001600160a01b03161461040257604051632f7a8ee160e01b815260040160405180910390fd5b61044c61040f8587611e49565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610de192505050565b5050505050565b60006103c382610f8f565b60006103ad610fb1565b61047182610f8f565b61047a81610fcd565b6104848383610fd7565b505050565b60606000610495610d07565b600181015490915061ffff1667ffffffffffffffff8111156104b9576104b9611db5565b6040519080825280602002602001820160405280156104e2578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610624576000818152600285016020526040812054905b600881101561060f578361052181611f93565b600188015490955061ffff168511905061060f57600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156105b2578a818151811061057757610577611fac565b60200260200101516001600160a01b0316836001600160a01b0316036105a057600191506105b2565b806105aa81611f93565b91505061055d565b5080156105c1575050506105fd565b818a89815181106105d4576105d4611fac565b6001600160a01b0390921660209283029190910190910152876105f681611f93565b9850505050505b8061060781611f93565b91505061050e565b5050808061061c90611f93565b9150506104eb565b505082525090565b610634611039565b6001600160a01b0316336001600160a01b0316146106655760405163efd1052d60e01b815260040160405180910390fd5b61066d611061565b565b6060600061067b610d07565b600181015490915061ffff1667ffffffffffffffff81111561069f5761069f611db5565b6040519080825280602002602001820160405280156106e557816020015b6040805180820190915260008152606060208201528152602001906001900390816106bd5790505b50600182015490925060009061ffff1667ffffffffffffffff81111561070d5761070d611db5565b604051908082528060200260200182016040528015610736578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610a25576000818152600286016020526040812054905b6008811015610a10578361077581611f93565b600189015490955061ffff1685119050610a1057600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b888110156108ce57826001600160a01b03168c82815181106107d5576107d5611fac565b6020026020010151600001516001600160a01b0316036108bc57838c828151811061080257610802611fac565b6020026020010151602001518b838151811061082057610820611fac565b602002602001015160ff168151811061083b5761083b611fac565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a828151811061087157610871611fac565b602002602001015160ff161061088657600080fd5b89818151811061089857610898611fac565b6020026020010180518091906108ad90611fc2565b60ff16905250600191506108ce565b806108c681611f93565b9150506107b1565b5080156108dd575050506109fe565b818b89815181106108f0576108f0611fac565b60209081029190910101516001600160a01b03909116905260018a015461ffff1667ffffffffffffffff81111561092957610929611db5565b604051908082528060200260200182016040528015610952578160200160208202803683370190505b508b898151811061096557610965611fac565b602002602001015160200181905250828b898151811061098757610987611fac565b6020026020010151602001516000815181106109a5576109a5611fac565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106109db576109db611fac565b60ff90921660209283029190910190910152876109f781611f93565b9850505050505b80610a0881611f93565b915050610762565b50508080610a1d90611f93565b91505061073f565b5060005b82811015610a8c576000848281518110610a4557610a45611fac565b602002602001015160ff1690506000878381518110610a6657610a66611fac565b602002602001015160200151905081815250508080610a8490611f93565b915050610a29565b508185525050505090565b60006103ad611039565b610aaa8161109b565b50565b60006103ad610dc8565b610abf610dc8565b6001600160a01b0316336001600160a01b031614610af057604051632f7a8ee160e01b815260040160405180910390fd5b610aaa816110a5565b6000610b0583836110d2565b9392505050565b60606000610b18610d07565b600181015490915061ffff1667ffffffffffffffff811115610b3c57610b3c611db5565b604051908082528060200260200182016040528015610b65578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610c4e576000818152600285016020526040812054905b6008811015610c395783610ba481611f93565b600188015490955061ffff1685119050610c3957600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a1603610c265780888781518110610bff57610bff611fac565b6001600160e01b03199092166020928302919091019091015285610c2281611f93565b9650505b5080610c3181611f93565b915050610b91565b50508080610c4690611f93565b915050610b6e565b5050825250919050565b6000610c62610d07565b6001600160e01b0319909216600090815260209290925250604090205460601c90565b610c8e82610f8f565b610c9781610fcd565b61048483836110f7565b610ca9610dc8565b6001600160a01b0316336001600160a01b031614610cda57604051632f7a8ee160e01b815260040160405180910390fd5b610aaa81611159565b7ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c80610d98576103ad610fb1565b90565b6000610da5610ce3565b6001600160e01b0319909216600090815260209290925250604090205460ff1690565b6000610dd2610d2b565b546001600160a01b0316919050565b6000610deb610d07565b600181015490915061ffff811690819060009060071615610e1e5750600381901c60009081526002840160205260409020545b60005b8751811015610f03576000888281518110610e3e57610e3e611fac565b60200260200101519050600081602001519050816040015151600003610e775760405163eb6c3aeb60e01b815260040160405180910390fd5b6000816002811115610e8b57610e8b611fe1565b03610ea657610e9c87868685611162565b9095509350610ef9565b6001816002811115610eba57610eba611fe1565b03610ece57610ec987836112a1565b610ef9565b6002816002811115610ee257610ee2611fe1565b03610ef957610ef3878686856113e7565b90955093505b5050600101610e21565b50828214610f1f5760018401805461ffff191661ffff84161790555b6007821615610f4157600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673878787604051610f7493929190612047565b60405180910390a1610f86868661160a565b50505050505050565b60009081526000805160206121f5833981519152602052604090206002015490565b6000610fbb610d07565b600301546001600160a01b0316919050565b610aaa81336116ee565b60008281526000805160206121f583398151915260205260409020610ffc9082611759565b5060405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610dd2565b61106a3361176e565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319169055565b610aaa81336110f7565b806110ae610d07565b60030180546001600160a01b0319166001600160a01b039290921691909117905550565b60008281526000805160206121f583398151915260205260408120610b0590836117d5565b60008281526000805160206121f58339815191526020526040902061111c90826117f7565b5060405133906001600160a01b0383169084907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b90600090a45050565b610aaa8161180c565b805160009081906001600160a01b0316301480159061118a575082516001600160a01b03163b155b156111a857604051633ddc5cab60e21b815260040160405180910390fd5b60005b836040015151811015611294576000846040015182815181106111d0576111d0611fac565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1561121c57604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c1999909916179781900361128557600389901c600090815260028b0160205260408120989098555b505050600195860195016111ab565b5093959294509192505050565b80516001600160a01b03163b6112ca57604051633ddc5cab60e21b815260040160405180910390fd5b60005b816040015151811015610484576000826040015182815181106112f2576112f2611fac565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c8061133e576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036113675760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b03160361139d576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff919091161790556001016112cd565b805160009081906001600160a01b03161561141557604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b8560400151518110156115f65760008660400151828151811061144657611446611fac565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c611491576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036114b55760405163e983573160e01b815260040160405180910390fd5b60008990036114e157600019909401600081815260028c016020526040902054985093600793506114e9565b600019909301925b600584901b89901b6000806001600160e01b031980841690861614611540576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166bffffffffffffffffffffffff86161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b168782146115a357600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c1790556115c7565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b866000036115e557600088815260028f01602052604081208190559b505b505060019093019250611421915050565b5060039190911b1796939550929350505050565b8051156001600160a01b0383161514611636576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b038216156116ea576001600160a01b038216301461167d576001600160a01b0382163b61167d57604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b0316826040516116979190612110565b600060405180830381855af49150503d80600081146116d2576040519150601f19603f3d011682016040523d82523d6000602084013e6116d7565b606091505b5050905080610484573d6000803e3d6000fd5b5050565b6116f882826110d2565b6116ea5761170e816001600160a01b031661184d565b61171983602061185f565b60405160200161172a92919061212c565b60408051601f198184030181529082905262461bcd60e51b8252611750916004016121a1565b60405180910390fd5b6000610b05836001600160a01b0384166119b2565b6000611778610d2b565b80546040519192506001600160a01b03808516929116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03811660009081526001830160205260408120541515610b05565b6000610b05836001600160a01b0384166119f5565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319166001600160a01b038316179055610aaa8181565b60606103c36001600160a01b03831660145b6060600061186e8360026121b4565b6118799060026121cb565b67ffffffffffffffff81111561189157611891611db5565b6040519080825280601f01601f1916602001820160405280156118bb576020820181803683370190505b509050600360fc1b816000815181106118d6576118d6611fac565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061190557611905611fac565b60200101906001600160f81b031916908160001a905350600160028402015b6001811115611992576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061195557611955611fac565b1a60f81b82828151811061196b5761196b611fac565b60200101906001600160f81b031916908160001a90535060049490941c9360001901611924565b508315610b055760405163c913478560e01b815260040160405180910390fd5b60008181526001830160205260408120546103c3575081546001808201845560008481526020808220909301849055845493815293810190915260409092205590565b60008181526001830160205260408120548015611ab357835460009085906000198101908110611a2757611a27611fac565b9060005260206000200154905080856000016001840381548110611a4d57611a4d611fac565b6000918252602080832090910192909255918252600186019052604090208190558354849080611a7f57611a7f6121de565b6001900381819060005260206000200160009055905583600101600084815260200190815260200160002060009055600191505b5092915050565b80356001600160e01b031981168114611ad257600080fd5b919050565b600060208284031215611ae957600080fd5b610b0582611aba565b80356001600160a01b0381168114611ad257600080fd5b60008083601f840112611b1b57600080fd5b50813567ffffffffffffffff811115611b3357600080fd5b602083019150836020828501011115611b4b57600080fd5b9250929050565b600080600080600060608688031215611b6a57600080fd5b853567ffffffffffffffff80821115611b8257600080fd5b818801915088601f830112611b9657600080fd5b813581811115611ba557600080fd5b8960208260051b8501011115611bba57600080fd5b60208301975080965050611bd060208901611af2565b94506040880135915080821115611be657600080fd5b50611bf388828901611b09565b969995985093965092949392505050565b600060208284031215611c1657600080fd5b5035919050565b60008060408385031215611c3057600080fd5b82359150611c4060208401611af2565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015611c8a5783516001600160a01b031683529284019291840191600101611c65565b50909695505050505050565b600081518084526020808501945080840160005b83811015611cd05781516001600160e01b03191687529582019590820190600101611caa565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611d4a57888303603f19018552815180516001600160a01b03168452870151878401879052611d3787850182611c96565b9588019593505090860190600101611d02565b509098975050505050505050565b600060208284031215611d6a57600080fd5b610b0582611af2565b6020808252825182820181905260009190848201906040850190845b81811015611c8a5783516001600160e01b03191683529284019291840191600101611d8f565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611dee57611dee611db5565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611e1d57611e1d611db5565b604052919050565b600067ffffffffffffffff821115611e3f57611e3f611db5565b5060051b60200190565b6000611e5c611e5784611e25565b611df4565b83815260208082019190600586811b860136811115611e7a57600080fd5b865b81811015611f7057803567ffffffffffffffff80821115611e9d5760008081fd5b818a01915060608236031215611eb35760008081fd5b611ebb611dcb565b611ec483611af2565b81528683013560038110611ed85760008081fd5b8188015260408381013583811115611ef05760008081fd5b939093019236601f850112611f0757600092508283fd5b83359250611f17611e5784611e25565b83815292871b84018801928881019036851115611f345760008081fd5b948901945b84861015611f5957611f4a86611aba565b82529489019490890190611f39565b918301919091525088525050948301948301611e7c565b5092979650505050505050565b634e487b7160e01b600052601160045260246000fd5b600060018201611fa557611fa5611f7d565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103611fd857611fd8611f7d565b60010192915050565b634e487b7160e01b600052602160045260246000fd5b60005b83811015612012578181015183820152602001611ffa565b50506000910152565b60008151808452612033816020860160208601611ff7565b601f01601f19169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b848110156120e057898703607f19018652825180516001600160a01b0316885284810151600381106120b157634e487b7160e01b84526021600452602484fd5b888601526040908101519088018990526120cd89890182611c96565b9750509483019491830191600101612071565b5050506001600160a01b0389169087015250508381036040850152612105818661201b565b979650505050505050565b60008251612122818460208701611ff7565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612164816017850160208801611ff7565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612195816028840160208801611ff7565b01602801949350505050565b602081526000610b05602083018461201b565b80820281158282048414176103c3576103c3611f7d565b808201808211156103c3576103c3611f7d565b634e487b7160e01b600052603160045260246000fdfed3889cc5458b268d0544e5534672df1296288ca3f93cbd39bd6f497a5c622811a2646970667358221220414b9b3bbd6fc714b587bfcf8b1cc621e20d5235de78bc17e9083a48412381cc64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 31.51% | $104,599 | 1.3816 | $144,508.84 | |
ETH | 22.44% | $3,319.58 | 31.0009 | $102,910.03 | |
ETH | 18.00% | $0.999974 | 82,550.4153 | $82,548.27 | |
ETH | 15.21% | $0.999846 | 69,780.0771 | $69,769.33 | |
ETH | 9.64% | $1 | 44,140.6331 | $44,184.77 | |
ETH | 0.63% | $3,511.93 | 0.817 | $2,869.1 | |
ETH | 0.25% | $3,958.03 | 0.2845 | $1,126.13 | |
ETH | 0.16% | $1.14 | 644.5606 | $734.8 | |
BSC | 2.17% | $1.86 | 5,328.2404 | $9,932.13 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.