Source Code
Latest 25 from a total of 3,136 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Execute Blocks | 23064091 | 130 days ago | IN | 0 ETH | 0.00000969 | ||||
| Verify Blocks | 23064090 | 130 days ago | IN | 0 ETH | 0.00005222 | ||||
| Commit Blocks | 23064089 | 130 days ago | IN | 0 ETH | 0.00003502 | ||||
| Execute Blocks | 23056917 | 131 days ago | IN | 0 ETH | 0.00001422 | ||||
| Verify Blocks | 23056916 | 131 days ago | IN | 0 ETH | 0.00056357 | ||||
| Commit Blocks | 23056914 | 131 days ago | IN | 0 ETH | 0.00004966 | ||||
| Execute Blocks | 23052391 | 131 days ago | IN | 0 ETH | 0.00001366 | ||||
| Verify Blocks | 23052390 | 131 days ago | IN | 0 ETH | 0.00056334 | ||||
| Commit Blocks | 23052388 | 131 days ago | IN | 0 ETH | 0.00004875 | ||||
| Execute Blocks | 23047635 | 132 days ago | IN | 0 ETH | 0.0012325 | ||||
| Verify Blocks | 23047633 | 132 days ago | IN | 0 ETH | 0.00070427 | ||||
| Commit Blocks | 23047632 | 132 days ago | IN | 0 ETH | 0.00019656 | ||||
| Execute Blocks | 23042616 | 133 days ago | IN | 0 ETH | 0.00023462 | ||||
| Verify Blocks | 23042614 | 133 days ago | IN | 0 ETH | 0.00073589 | ||||
| Commit Blocks | 23042613 | 133 days ago | IN | 0 ETH | 0.00018003 | ||||
| Execute Blocks | 23035479 | 134 days ago | IN | 0 ETH | 0.00008705 | ||||
| Verify Blocks | 23035478 | 134 days ago | IN | 0 ETH | 0.00047039 | ||||
| Commit Blocks | 23035476 | 134 days ago | IN | 0 ETH | 0.00031795 | ||||
| Withdraw | 23030841 | 134 days ago | IN | 0 ETH | 0.00031356 | ||||
| Execute Blocks | 23028576 | 135 days ago | IN | 0 ETH | 0.00004535 | ||||
| Verify Blocks | 23028575 | 135 days ago | IN | 0 ETH | 0.00072641 | ||||
| Commit Blocks | 23028574 | 135 days ago | IN | 0 ETH | 0.0001624 | ||||
| Withdraw | 23022615 | 136 days ago | IN | 0 ETH | 0.00002437 | ||||
| Execute Blocks | 23021476 | 136 days ago | IN | 0 ETH | 0.00035395 | ||||
| Verify Blocks | 23021474 | 136 days ago | IN | 0 ETH | 0.00055933 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 23068383 | 129 days ago | 0.0026703 ETH | ||||
| Transfer | 23068383 | 129 days ago | 0.0026703 ETH | ||||
| Transfer | 23030841 | 134 days ago | 0.0144 ETH | ||||
| Transfer | 23030841 | 134 days ago | 0.0144 ETH | ||||
| Transfer | 23022615 | 136 days ago | 0.49946646 ETH | ||||
| Transfer | 23022615 | 136 days ago | 0.49946646 ETH | ||||
| Transfer | 23009272 | 137 days ago | 0.02946932 ETH | ||||
| Transfer | 23009272 | 137 days ago | 0.02946932 ETH | ||||
| Transfer | 22980707 | 141 days ago | 0.04945939 ETH | ||||
| Transfer | 22980707 | 141 days ago | 0.04945939 ETH | ||||
| Transfer | 22980345 | 141 days ago | 0.09946019 ETH | ||||
| Transfer | 22980345 | 141 days ago | 0.09946019 ETH | ||||
| Transfer | 22914371 | 151 days ago | 2.33032086 ETH | ||||
| Transfer | 22914371 | 151 days ago | 2.33032086 ETH | ||||
| Transfer | 22880713 | 155 days ago | 0.00545095 ETH | ||||
| Transfer | 22880713 | 155 days ago | 0.00545095 ETH | ||||
| Transfer | 22880387 | 155 days ago | 0.01409965 ETH | ||||
| Transfer | 22880387 | 155 days ago | 0.01409965 ETH | ||||
| Transfer | 22880383 | 155 days ago | 0.01403921 ETH | ||||
| Transfer | 22880383 | 155 days ago | 0.01403921 ETH | ||||
| Transfer | 22880382 | 155 days ago | 0.19923822 ETH | ||||
| Transfer | 22880382 | 155 days ago | 0.19923822 ETH | ||||
| Transfer | 22880375 | 155 days ago | 0.01401589 ETH | ||||
| Transfer | 22880375 | 155 days ago | 0.01401589 ETH | ||||
| Transfer | 22880362 | 155 days ago | 0.01420713 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
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
Contract ABI
API[{"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
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.