Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
SimpleVaultDiamond
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; import { SolidStateDiamond } from '@solidstate/contracts/proxy/diamond/SolidStateDiamond.sol'; /** * @title Diamond proxy used as centrally controlled SimpleVault implementation * @dev deployed standalone and passed to SimpleVaultManager constructor */ contract SimpleVaultDiamond is SolidStateDiamond { }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173 } from '../../interfaces/IERC173.sol'; interface IOwnable is 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'; interface ISafeOwnable is 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 set nominee owner, granting permission to call acceptOwnership */ function _transferOwnership(address account) internal virtual override { 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; 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; import { IERC165Internal } from './IERC165Internal.sol'; /** * @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 conrtact 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 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 { 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 }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"DiamondWritable__InvalidInitializationParameters","type":"error"},{"inputs":[],"name":"DiamondWritable__RemoveTargetNotZeroAddress","type":"error"},{"inputs":[],"name":"DiamondWritable__ReplaceTargetIsIdentical","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorAlreadyAdded","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorIsImmutable","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotFound","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotSpecified","type":"error"},{"inputs":[],"name":"DiamondWritable__TargetHasNoCode","type":"error"},{"inputs":[],"name":"ERC165Base__InvalidInterfaceId","type":"error"},{"inputs":[],"name":"Ownable__NotOwner","type":"error"},{"inputs":[],"name":"Ownable__NotTransitiveOwner","type":"error"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"inputs":[],"name":"SafeOwnable__NotNomineeOwner","type":"error"},{"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"},{"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":[],"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":"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
60806040523462000337576200031c6200001862000378565b620000336200002782620003bc565b632c40805960e01b9052565b6200004e6200004282620003d0565b639142376560e01b9052565b632f40adcf60e21b600052600080516020620025738339815191526020527fea929569903c3e19530358310fcaf1a971b387fd41008d81b0a7f1275e915a5c805460ff19166001179055620000b3620000a782620003e1565b6307e4c70760e21b9052565b6307e4c70760e21b600052600080516020620025738339815191526020527ffd29538739e576e7ec1eb8c7e901cca011aae0deb8fb2c6280a4c2300add457d805460ff19166001179055620001186200010c82620003f2565b637a0ed62760e01b9052565b62000133620001278262000403565b6356fe50af60e11b9052565b6200014e620001428262000414565b6314bbdacb60e21b9052565b620001696200015d8262000425565b6366ffd66360e11b9052565b6348e2b09360e01b600052600080516020620025738339815191526020527fb36cab0dec645683c2d905d6b41349479e1d7f665c3cff144fecc78944a31d5b805460ff19166001179055620001ce620001c28262000436565b6301ffc9a760e01b9052565b6301ffc9a760e01b600052600080516020620025738339815191526020527f3df35b507c5de77f483b4e9b5c258409299a2e6dc816fa76a389e598628b08a5805460ff1916600117905562000233620002278262000448565b638da5cb5b60e01b9052565b6200024e62000242826200045a565b63455a8a8560e11b9052565b620002696200025d826200046c565b63f2fde38b60e01b9052565b6200028462000278826200047e565b6379ba509760e01b9052565b6307f5828d60e41b600052600080516020620025738339815191526020527fa9832637661075437d81882814f92cc614421ae9c04c71ce67957179f7086c18805460ff19166001179055620002d8620004a5565b90620002e362000352565b30815290600060208301526040820152620002fe82620003bc565b526200030a81620003bc565b50620003156200052c565b90620006ed565b620003273362000550565b6040516116fe908162000e758239f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b60405190606082016001600160401b038111838210176200037257604052565b6200033c565b604051906101a082016001600160401b038111838210176200037257604052600c8252610180366020840137565b634e487b7160e01b600052603260045260246000fd5b805115620003ca5760200190565b620003a6565b805160011015620003ca5760400190565b805160021015620003ca5760600190565b805160031015620003ca5760800190565b805160041015620003ca5760a00190565b805160051015620003ca5760c00190565b805160061015620003ca5760e00190565b805160071015620003ca576101000190565b805160081015620003ca576101200190565b805160091015620003ca576101400190565b8051600a1015620003ca576101600190565b8051600b1015620003ca576101800190565b8051821015620003ca5760209160051b010190565b6040805191908281016001600160401b0381118482101762000372578152600183528291600091825b602080821015620005025790602091620004e762000352565b908682528681830152606085830152828901015201620004ce565b50505091925050565b600311156200051657565b634e487b7160e01b600052602160045260246000fd5b60405190602082016001600160401b03811183821017620003725760405260008252565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f671680460805490916001600160a01b039081169190829082167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a36001600160a01b031916179055565b919082519283825260005b848110620005e7575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201620005c5565b919091606092838201848352815180915260809485840191868160051b860101966020809501936000915b8383106200065357505050505050906000620006509493928201526040818403910152620005ba565b90565b909192939498607f198882030183528951908681019060018060a01b038351168152888301516003811015620005165784828b9594939286809401528a604080960151958201528451809452019201906000905b808210620006c85750505090806001929b0193019301919493929062000627565b82516001600160e01b03191684528a94938401939092019160019190910190620006a7565b9190916200071762000710600080516020620025938339815191525461ffff1690565b61ffff1690565b90819260009460078416620008b5575b6000935b8351851015620008035762000741858562000490565b5190602082015162000753816200050b565b6040808401515115620007f357506200076c816200050b565b806200078e5750906001976200078292620008e5565b9690945b01936200072b565b6200079d81979392976200050b565b60018103620007bb575090620007b560019262000d3d565b62000786565b80620007c96002926200050b565b14620007da575b5060019062000786565b600197620007e9929662000a98565b96909490620007d0565b5163eb6c3aeb60e01b8152600490fd5b819450957f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673939192966200085f96810362000890575b6007811662000861575b50506200085660405192839283620005fc565b0390a162000e56565b565b620008879060031c600052600080516020620025d3833981519152602052604060002090565b55388062000843565b60008051602062002593833981519152805461ffff191661ffff831617905562000839565b9450620008dd8360031c600052600080516020620025d3833981519152602052604060002090565b549462000727565b82519091906001600160a01b03166001600160a01b038116301415908162000a8d575b5062000a7b5760009384925b604080860151805186101562000a6f576200093486620009429262000490565b516001600160e01b03191690565b906200099b6200098f620009896200097b8563ffffffff60e01b16600052600080516020620025b3833981519152602052604060002090565b546001600160601b03191690565b60601c90565b6001600160a01b031690565b62000a5f5750855182906001600160601b031990620009ce906001600160a01b03165b60601b6001600160601b03191690565b1617620009fc8263ffffffff60e01b16600052600080516020620025b3833981519152602052604060002090565b5560e090818360051b169463ffffffff60e01b809216861c91861c191617931462000a2f575b6001938401930162000914565b9162000a568360031c600052600080516020620025d3833981519152602052604060002090565b55849162000a22565b51634923a77160e11b8152600490fd5b50509250925092509190565b604051633ddc5cab60e21b8152600490fd5b3b1590503862000908565b82519293929091906001600160a01b031662000d2b5790600780821691600390600090821c5b60409586890151805184101562000d1c57620009348462000adf9262000490565b9562000b0c8763ffffffff60e01b16600052600080516020620025b3833981519152602052604060002090565b54978860601c801562000d0b57301462000cfb57508162000ce8575050600019019062000b5182600052600080516020620025d3833981519152602052604060002090565b5494849687915b60e063ffffffff811b92600062000ba3858c600598891b1b1694868116860362000c645763ffffffff60e01b16600052600080516020620025b3833981519152602052604060002090565b5580881c611fff16941b169185841462000c51579062000c09929162000be185600052600080516020620025d3833981519152602052604060002090565b5491831c921c19161791600052600080516020620025d3833981519152602052604060002090565b555b851562000c20575b6001019094939462000abe565b9350600062000c4782600052600080516020620025d3833981519152602052604060002090565b5560009362000c13565b9180949893501c921c1916179362000c0b565b62000ca562000c986200097b8863ffffffff60e01b16600052600080516020620025b3833981519152602052604060002090565b6001600160601b03191690565b6001600160e01b03198781166000908152600080516020620025b383398151915260205260408082206001600160601b0389169490941790935592168252902090565b6000190196909591929187919062000b58565b5163e983573160e01b8152600490fd5b81516337e25a9760e11b8152600490fd5b5097509394505090501b179190565b604051633ab3490960e21b8152600490fd5b80516001600160a01b03163b1562000a7b5760005b604080830151805183101562000e5057620009348362000d729262000490565b9062000d9f8263ffffffff60e01b16600052600080516020620025b3833981519152602052604060002090565b54908160601c801562000d0b5730811462000e3f57855162000dca906001600160a01b03166200098f565b1462000e2f57508351600193929162000e279162000df69062000c98906001600160a01b0316620009be565b90858060601b0316179163ffffffff60e01b16600052600080516020620025b3833981519152602052604060002090565b550162000d52565b516330baabf360e11b8152600490fd5b815163e983573160e01b8152600490fd5b50505050565b511560010362000e6257565b6040516326df4ccd60e01b8152600490fdfe60806040526004361015610015575b36610ba657005b60003560e01c806301ffc9a7146100d55780631f931c1c146100d05780632c408059146100cb57806352ef6b2c146100c657806379ba5097146100c15780637a0ed627146100bc5780638ab5150a146100b75780638da5cb5b146100b257806391423765146100ad578063adfca15e146100a8578063cdffacc6146100a35763f2fde38b0361000e57610afe565b610aa1565b61098f565b6108c8565b610892565b61084a565b6105cd565b61046a565b6102e0565b610254565b6101d8565b61010b565b600435906001600160e01b0319821682036100f157565b600080fd5b35906001600160e01b0319821682036100f157565b346100f15760203660031901126100f1576001600160e01b031961012d6100da565b166000527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052602060ff604060002054166040519015158152f35b602435906001600160a01b03821682036100f157565b600435906001600160a01b03821682036100f157565b35906001600160a01b03821682036100f157565b9181601f840112156100f15782359167ffffffffffffffff83116100f157602083818601950101116100f157565b346100f15760603660031901126100f15760043567ffffffffffffffff8082116100f157366023830112156100f1578160040135918183116100f1573660248460051b830101116100f15761022b61016a565b6044359283116100f1576102529361024960249436906004016101aa565b94909301610e0b565b005b346100f15760003660031901126100f1577f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546040516001600160a01b039091168152602090f35b6020908160408183019282815285518094520193019160005b8281106102c3575050505090565b83516001600160a01b0316855293810193928101926001016102b5565b346100f1576000806003193601126104675761031661030f6000805160206116898339815191525461ffff1690565b61ffff1690565b9061032082610d36565b908080815b858210610341578385526040518061033d878261029c565b0390f35b61034a81610d88565b5483905b60088210610367575b505061036290610d74565b610325565b91959396909261037690610d74565b9481861161045a576103af6103a961039b63ffffffff60e01b868860051b1b16610b6e565b546001600160601b03191690565b60601c90565b886001600160a01b038216815b848110610411575b505061040657816103ee6103f3926103df6103f9958a610ddf565b6001600160a01b039091169052565b610d74565b93610d74565b909693959194929461034e565b50926103f990610d74565b61043a61042e610421838c610ddf565b516001600160a01b031690565b6001600160a01b031690565b821461044e5761044990610d74565b6103bc565b505050600138806103c4565b9492819794969250610357565b80fd5b346100f157600080600319360112610467577f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b03908181163303610501576000805160206116a9833981519152805492339084167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08780a36001600160a01b03199283163317905516905580f35b60405163efd1052d60e01b8152600490fd5b90815180825260208080930193019160005b828110610533575050505090565b83516001600160e01b03191685529381019392810192600101610525565b602080820190808352835180925260409283810182858560051b8401019601946000925b858410610586575050505050505090565b9091929394959685806105bc600193603f1986820301885286838d51878060a01b03815116845201519181858201520190610513565b990194019401929594939190610575565b346100f157600080600319360112610467576105fc61030f6000805160206116898339815191525461ffff1690565b61060581610ccd565b9061060f81610d36565b92809181825b828210610673575050505b818110610638578183526040518061033d8582610551565b8061065961065361064c61066e9488610ddf565b5160ff1690565b60ff1690565b60206106658387610ddf565b51015152610d74565b610620565b61067c81610d88565b5484905b60088210610699575b505061069490610d74565b610615565b90939196926106aa90989598610d74565b9582871161083d5763ffffffff60e01b828660051b1b166106d06103a961039b83610b6e565b8a6001600160a01b038216815b858110610787575b505061077b57916107536107669261071461076c95610704858b610ddf565b516001600160a01b039091169052565b61074361072088610d36565b6020908161072e878d610ddf565b51015261073b858b610ddf565b510151610dcd565b6001600160e01b03199091169052565b6103ee610760828a610ddf565b60019052565b94610d74565b90979497969193959296610680565b50509361076c90610d74565b8a858a846107a961042e61079b8785610ddf565b51516001600160a01b031690565b146107bf575050506107ba90610d74565b6106dd565b610834955083809550610825936108016108209461074360206107e861082c9a61064c98610ddf565b5101516107fb61065361064c8888610ddf565b90610ddf565b61081b60ff8061081461064c8686610ddf565b1610610df3565b610ddf565b610dfa565b918b610ddf565b9060ff169052565b600138806106e5565b9592969193979497610689565b346100f15760003660031901126100f1577f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890546040516001600160a01b039091168152602090f35b346100f15760003660031901126100f1576000805160206116a9833981519152546040516001600160a01b039091168152602090f35b346100f15760203660031901126100f1576108e1610180565b6000805160206116a9833981519152546001600160a01b039081163303610938577f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680546001600160a01b03191691909216179055005b604051632f7a8ee160e01b8152600490fd5b6020908160408183019282815285518094520193019160005b828110610971575050505090565b83516001600160e01b03191685529381019392810192600101610963565b346100f15760203660031901126100f1576109a8610180565b6109c561030f6000805160206116898339815191525461ffff1690565b906109cf82610d36565b9060009081906001600160a01b0316815b8583106109f8578385526040518061033d878261094a565b610a0181610d88565b546000905b60088210610a1f575b5050610a1a90610d74565b6109e0565b91969095929493610a2f90610d74565b95818711610a935763ffffffff60e01b838260051b1b16610a5861042e6103a961039b84610b6e565b8714610a76575b50610a6990610d74565b9096919593949295610a06565b856103ee610a8c92610743610a69959989610ddf565b9490610a5f565b819792509593949295610a0f565b346100f15760203660031901126100f1576001600160e01b0319610ac36100da565b166000527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052602060406000205460601c604051908152f35b346100f15760203660031901126100f157610b17610180565b6000805160206116a9833981519152546001600160a01b039081163303610938577f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b03191691909216179055005b63ffffffff60e01b166000527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604060002090565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c8015610c23575b803b15610c115760008091368280378136915af43d6000803e15610c0c573d6000f35b3d6000fd5b6040516321f27f0d60e21b8152600490fd5b507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b0316610be9565b634e487b7160e01b600052604160045260246000fd5b604051906060820182811067ffffffffffffffff821117610c8a57604052565b610c54565b6040519190601f01601f1916820167ffffffffffffffff811183821017610c8a57604052565b67ffffffffffffffff8111610c8a5760051b60200190565b90610cdf610cda83610cb5565b610c8f565b8281528092610cf0601f1991610cb5565b016000805b828110610d025750505050565b604090815182810181811067ffffffffffffffff821117610c8a576020935283815282606081830152828701015201610cf5565b90610d43610cda83610cb5565b8281528092610d54601f1991610cb5565b0190602036910137565b634e487b7160e01b600052601160045260246000fd5b6000198114610d835760010190565b610d5e565b6000527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc95602052604060002090565b634e487b7160e01b600052603260045260246000fd5b805115610dda5760200190565b610db7565b8051821015610dda5760209160051b010190565b156100f157565b60ff1660ff8114610d835760010190565b6000805160206116a98339815191525493959491936001600160a01b0316330361093857610e3b610cda85610cb5565b9081948083526020809301600591821b8301923684116100f15780915b848310610e7d57505050505050610e7b9394610e75913691610f64565b916110c1565b565b67ffffffffffffffff83358181116100f15783016060813603126100f157610ea3610c6a565b91610ead82610196565b83528882013560038110156100f15789840152604091828101359182116100f157019036601f830112156100f157813591610eea610cda84610cb5565b928a808583815201918a1b830101913683116100f157918b80969492979593015b818110610f25575050849550820152815201920191610e58565b9193958091939597610f36846100f6565b8152019101918b959391969492610f0b565b67ffffffffffffffff8111610c8a57601f01601f191660200190565b929192610f73610cda83610f48565b93828552828201116100f157816000926020928387013784010152565b60031115610f9a57565b634e487b7160e01b600052602160045260246000fd5b919082519283825260005b848110610fdc575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201610fbb565b93929091936060928382019380835281518095526080830160808660051b85010195602080940192600080915b8383106110525750505050505061104f94956110429183019060018060a01b03169052565b6040818403910152610fb0565b90565b909192939498607f1988820301865289519060018060a01b0382511681528782015160038110156110ad5761109f60019385848c9594868096015281604080940151938201520190610513565b9b019601949301919061101d565b634e487b7160e01b85526021600452602485fd5b9290926110e161030f6000805160206116898339815191525461ffff1690565b91829360009560078516611242575b6000945b84518610156111b3576111078686610ddf565b5190602082015161111781610f90565b60408084015151156111a3575061112d81610f90565b8061114b57509060019861114092611257565b9790955b01946110f4565b6111588198939298610f90565b6001810361117257509061116d60019261151a565b611144565b8061117e600292610f90565b1461118d575b50600190611144565b60019861119a929761137b565b97909590611184565b5163eb6c3aeb60e01b8152600490fd5b819491929550967f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6739397610e7b97810361121f575b6007811661120b575b50506112038560405193849384610ff0565b0390a161160d565b6112179060031c610d88565b5538806111f1565b600080516020611689833981519152805461ffff191661ffff83161790556111e8565b95506112508460031c610d88565b54956110f0565b82519091906001600160a01b03166001600160a01b0381163014159081611371575b5061135f5760009384925b6040808601518051861015611353576112a0866112ae92610ddf565b516001600160e01b03191690565b906112c161042e6103a961039b85610b6e565b6113435750855182906001600160601b0319906112f2906001600160a01b03165b60601b6001600160601b03191690565b16176112fd82610b6e565b5560e090818360051b169463ffffffff60e01b809216861c91861c191617931461132e575b60019384019301611284565b9161133b8360031c610d88565b558491611322565b51634923a77160e11b8152600490fd5b50509250925092509190565b604051633ddc5cab60e21b8152600490fd5b3b15905038611279565b82519293929091906001600160a01b03166115085790600780821691600390600090821c5b6040958689015180518410156114f9576112a0846113bd92610ddf565b956113c787610b6e565b54978860601c80156114e85730146114d85750816114c657505060001901906113ef82610d88565b5494849687915b60e063ffffffff811b92600061141d858c600598891b1b1694868116860361148b57610b6e565b5580881c611fff16941b1691858414611479579061144e929161143f85610d88565b5491831c921c19161791610d88565b555b8515611463575b600101909493946113a0565b9350600061147082610d88565b55600093611457565b9180949893501c921c19161793611450565b6114a761149a61039b88610b6e565b6001600160601b03191690565b6bffffffffffffffffffffffff8516176114c087610b6e565b55610b6e565b600019019690959192918791906113f6565b5163e983573160e01b8152600490fd5b81516337e25a9760e11b8152600490fd5b5097509394505090501b179190565b604051633ab3490960e21b8152600490fd5b80516001600160a01b03163b1561135f5760005b60408083015180518310156115e1576112a08361154a92610ddf565b9061155482610b6e565b54908160601c80156114e8573081146115d057855161157b906001600160a01b031661042e565b146115c05750835160019392916115b9916bffffffffffffffffffffffff906115b09061149a906001600160a01b03166112e2565b91161791610b6e565b550161152e565b516330baabf360e11b8152600490fd5b815163e983573160e01b8152600490fd5b50505050565b3d15611608573d906115fb610cda83610f48565b9182523d6000602084013e565b606090565b81516001600160a01b03821690811590158103611676571561162e57505050565b300361165e575b816000929160208493519201905af461164c6115e7565b501561165457565b3d6000803e3d6000fd5b803b61163557604051633ddc5cab60e21b8152600490fd5b6040516326df4ccd60e01b8152600490fdfe177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc948a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f671680460a2646970667358221220a3324a0079e3f96bb5533932d74a842f70577ec0a6f22accf665f046991f1f0c64736f6c63430008120033fc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc95
Deployed Bytecode
0x60806040526004361015610015575b36610ba657005b60003560e01c806301ffc9a7146100d55780631f931c1c146100d05780632c408059146100cb57806352ef6b2c146100c657806379ba5097146100c15780637a0ed627146100bc5780638ab5150a146100b75780638da5cb5b146100b257806391423765146100ad578063adfca15e146100a8578063cdffacc6146100a35763f2fde38b0361000e57610afe565b610aa1565b61098f565b6108c8565b610892565b61084a565b6105cd565b61046a565b6102e0565b610254565b6101d8565b61010b565b600435906001600160e01b0319821682036100f157565b600080fd5b35906001600160e01b0319821682036100f157565b346100f15760203660031901126100f1576001600160e01b031961012d6100da565b166000527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052602060ff604060002054166040519015158152f35b602435906001600160a01b03821682036100f157565b600435906001600160a01b03821682036100f157565b35906001600160a01b03821682036100f157565b9181601f840112156100f15782359167ffffffffffffffff83116100f157602083818601950101116100f157565b346100f15760603660031901126100f15760043567ffffffffffffffff8082116100f157366023830112156100f1578160040135918183116100f1573660248460051b830101116100f15761022b61016a565b6044359283116100f1576102529361024960249436906004016101aa565b94909301610e0b565b005b346100f15760003660031901126100f1577f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546040516001600160a01b039091168152602090f35b6020908160408183019282815285518094520193019160005b8281106102c3575050505090565b83516001600160a01b0316855293810193928101926001016102b5565b346100f1576000806003193601126104675761031661030f6000805160206116898339815191525461ffff1690565b61ffff1690565b9061032082610d36565b908080815b858210610341578385526040518061033d878261029c565b0390f35b61034a81610d88565b5483905b60088210610367575b505061036290610d74565b610325565b91959396909261037690610d74565b9481861161045a576103af6103a961039b63ffffffff60e01b868860051b1b16610b6e565b546001600160601b03191690565b60601c90565b886001600160a01b038216815b848110610411575b505061040657816103ee6103f3926103df6103f9958a610ddf565b6001600160a01b039091169052565b610d74565b93610d74565b909693959194929461034e565b50926103f990610d74565b61043a61042e610421838c610ddf565b516001600160a01b031690565b6001600160a01b031690565b821461044e5761044990610d74565b6103bc565b505050600138806103c4565b9492819794969250610357565b80fd5b346100f157600080600319360112610467577f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b03908181163303610501576000805160206116a9833981519152805492339084167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08780a36001600160a01b03199283163317905516905580f35b60405163efd1052d60e01b8152600490fd5b90815180825260208080930193019160005b828110610533575050505090565b83516001600160e01b03191685529381019392810192600101610525565b602080820190808352835180925260409283810182858560051b8401019601946000925b858410610586575050505050505090565b9091929394959685806105bc600193603f1986820301885286838d51878060a01b03815116845201519181858201520190610513565b990194019401929594939190610575565b346100f157600080600319360112610467576105fc61030f6000805160206116898339815191525461ffff1690565b61060581610ccd565b9061060f81610d36565b92809181825b828210610673575050505b818110610638578183526040518061033d8582610551565b8061065961065361064c61066e9488610ddf565b5160ff1690565b60ff1690565b60206106658387610ddf565b51015152610d74565b610620565b61067c81610d88565b5484905b60088210610699575b505061069490610d74565b610615565b90939196926106aa90989598610d74565b9582871161083d5763ffffffff60e01b828660051b1b166106d06103a961039b83610b6e565b8a6001600160a01b038216815b858110610787575b505061077b57916107536107669261071461076c95610704858b610ddf565b516001600160a01b039091169052565b61074361072088610d36565b6020908161072e878d610ddf565b51015261073b858b610ddf565b510151610dcd565b6001600160e01b03199091169052565b6103ee610760828a610ddf565b60019052565b94610d74565b90979497969193959296610680565b50509361076c90610d74565b8a858a846107a961042e61079b8785610ddf565b51516001600160a01b031690565b146107bf575050506107ba90610d74565b6106dd565b610834955083809550610825936108016108209461074360206107e861082c9a61064c98610ddf565b5101516107fb61065361064c8888610ddf565b90610ddf565b61081b60ff8061081461064c8686610ddf565b1610610df3565b610ddf565b610dfa565b918b610ddf565b9060ff169052565b600138806106e5565b9592969193979497610689565b346100f15760003660031901126100f1577f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890546040516001600160a01b039091168152602090f35b346100f15760003660031901126100f1576000805160206116a9833981519152546040516001600160a01b039091168152602090f35b346100f15760203660031901126100f1576108e1610180565b6000805160206116a9833981519152546001600160a01b039081163303610938577f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680546001600160a01b03191691909216179055005b604051632f7a8ee160e01b8152600490fd5b6020908160408183019282815285518094520193019160005b828110610971575050505090565b83516001600160e01b03191685529381019392810192600101610963565b346100f15760203660031901126100f1576109a8610180565b6109c561030f6000805160206116898339815191525461ffff1690565b906109cf82610d36565b9060009081906001600160a01b0316815b8583106109f8578385526040518061033d878261094a565b610a0181610d88565b546000905b60088210610a1f575b5050610a1a90610d74565b6109e0565b91969095929493610a2f90610d74565b95818711610a935763ffffffff60e01b838260051b1b16610a5861042e6103a961039b84610b6e565b8714610a76575b50610a6990610d74565b9096919593949295610a06565b856103ee610a8c92610743610a69959989610ddf565b9490610a5f565b819792509593949295610a0f565b346100f15760203660031901126100f1576001600160e01b0319610ac36100da565b166000527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052602060406000205460601c604051908152f35b346100f15760203660031901126100f157610b17610180565b6000805160206116a9833981519152546001600160a01b039081163303610938577f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b03191691909216179055005b63ffffffff60e01b166000527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604060002090565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c8015610c23575b803b15610c115760008091368280378136915af43d6000803e15610c0c573d6000f35b3d6000fd5b6040516321f27f0d60e21b8152600490fd5b507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b0316610be9565b634e487b7160e01b600052604160045260246000fd5b604051906060820182811067ffffffffffffffff821117610c8a57604052565b610c54565b6040519190601f01601f1916820167ffffffffffffffff811183821017610c8a57604052565b67ffffffffffffffff8111610c8a5760051b60200190565b90610cdf610cda83610cb5565b610c8f565b8281528092610cf0601f1991610cb5565b016000805b828110610d025750505050565b604090815182810181811067ffffffffffffffff821117610c8a576020935283815282606081830152828701015201610cf5565b90610d43610cda83610cb5565b8281528092610d54601f1991610cb5565b0190602036910137565b634e487b7160e01b600052601160045260246000fd5b6000198114610d835760010190565b610d5e565b6000527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc95602052604060002090565b634e487b7160e01b600052603260045260246000fd5b805115610dda5760200190565b610db7565b8051821015610dda5760209160051b010190565b156100f157565b60ff1660ff8114610d835760010190565b6000805160206116a98339815191525493959491936001600160a01b0316330361093857610e3b610cda85610cb5565b9081948083526020809301600591821b8301923684116100f15780915b848310610e7d57505050505050610e7b9394610e75913691610f64565b916110c1565b565b67ffffffffffffffff83358181116100f15783016060813603126100f157610ea3610c6a565b91610ead82610196565b83528882013560038110156100f15789840152604091828101359182116100f157019036601f830112156100f157813591610eea610cda84610cb5565b928a808583815201918a1b830101913683116100f157918b80969492979593015b818110610f25575050849550820152815201920191610e58565b9193958091939597610f36846100f6565b8152019101918b959391969492610f0b565b67ffffffffffffffff8111610c8a57601f01601f191660200190565b929192610f73610cda83610f48565b93828552828201116100f157816000926020928387013784010152565b60031115610f9a57565b634e487b7160e01b600052602160045260246000fd5b919082519283825260005b848110610fdc575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201610fbb565b93929091936060928382019380835281518095526080830160808660051b85010195602080940192600080915b8383106110525750505050505061104f94956110429183019060018060a01b03169052565b6040818403910152610fb0565b90565b909192939498607f1988820301865289519060018060a01b0382511681528782015160038110156110ad5761109f60019385848c9594868096015281604080940151938201520190610513565b9b019601949301919061101d565b634e487b7160e01b85526021600452602485fd5b9290926110e161030f6000805160206116898339815191525461ffff1690565b91829360009560078516611242575b6000945b84518610156111b3576111078686610ddf565b5190602082015161111781610f90565b60408084015151156111a3575061112d81610f90565b8061114b57509060019861114092611257565b9790955b01946110f4565b6111588198939298610f90565b6001810361117257509061116d60019261151a565b611144565b8061117e600292610f90565b1461118d575b50600190611144565b60019861119a929761137b565b97909590611184565b5163eb6c3aeb60e01b8152600490fd5b819491929550967f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6739397610e7b97810361121f575b6007811661120b575b50506112038560405193849384610ff0565b0390a161160d565b6112179060031c610d88565b5538806111f1565b600080516020611689833981519152805461ffff191661ffff83161790556111e8565b95506112508460031c610d88565b54956110f0565b82519091906001600160a01b03166001600160a01b0381163014159081611371575b5061135f5760009384925b6040808601518051861015611353576112a0866112ae92610ddf565b516001600160e01b03191690565b906112c161042e6103a961039b85610b6e565b6113435750855182906001600160601b0319906112f2906001600160a01b03165b60601b6001600160601b03191690565b16176112fd82610b6e565b5560e090818360051b169463ffffffff60e01b809216861c91861c191617931461132e575b60019384019301611284565b9161133b8360031c610d88565b558491611322565b51634923a77160e11b8152600490fd5b50509250925092509190565b604051633ddc5cab60e21b8152600490fd5b3b15905038611279565b82519293929091906001600160a01b03166115085790600780821691600390600090821c5b6040958689015180518410156114f9576112a0846113bd92610ddf565b956113c787610b6e565b54978860601c80156114e85730146114d85750816114c657505060001901906113ef82610d88565b5494849687915b60e063ffffffff811b92600061141d858c600598891b1b1694868116860361148b57610b6e565b5580881c611fff16941b1691858414611479579061144e929161143f85610d88565b5491831c921c19161791610d88565b555b8515611463575b600101909493946113a0565b9350600061147082610d88565b55600093611457565b9180949893501c921c19161793611450565b6114a761149a61039b88610b6e565b6001600160601b03191690565b6bffffffffffffffffffffffff8516176114c087610b6e565b55610b6e565b600019019690959192918791906113f6565b5163e983573160e01b8152600490fd5b81516337e25a9760e11b8152600490fd5b5097509394505090501b179190565b604051633ab3490960e21b8152600490fd5b80516001600160a01b03163b1561135f5760005b60408083015180518310156115e1576112a08361154a92610ddf565b9061155482610b6e565b54908160601c80156114e8573081146115d057855161157b906001600160a01b031661042e565b146115c05750835160019392916115b9916bffffffffffffffffffffffff906115b09061149a906001600160a01b03166112e2565b91161791610b6e565b550161152e565b516330baabf360e11b8152600490fd5b815163e983573160e01b8152600490fd5b50505050565b3d15611608573d906115fb610cda83610f48565b9182523d6000602084013e565b606090565b81516001600160a01b03821690811590158103611676571561162e57505050565b300361165e575b816000929160208493519201905af461164c6115e7565b501561165457565b3d6000803e3d6000fd5b803b61163557604051633ddc5cab60e21b8152600490fd5b6040516326df4ccd60e01b8152600490fdfe177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc948a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f671680460a2646970667358221220a3324a0079e3f96bb5533932d74a842f70577ec0a6f22accf665f046991f1f0c64736f6c63430008120033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.