Overview
TokenID
2891
Transfers
-
0
Market
Onchain Market Cap
-
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
| # | Exchange | Pair | Price | 24H Volume | % Volume |
|---|
Contract Name:
Scapes
Compiler Version
v0.8.16+commit.07a7930e
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.16;
import {SolidStateDiamond} from "@solidstate/contracts/proxy/diamond/SolidStateDiamond.sol";
/**
* @title Scapes
* @notice Welcome home.
* @author akuti.eth, jalil.eth | scapes.eth
* @dev This is a Diamond Contract following EIP-2535.
* To view its ABI and interact with functions,
* use an EIP-2535 compatible explorer.
*/
contract Scapes is SolidStateDiamond {
/**
*
* ____ _____ ___ ___ ____ ____
* / __// ___// _ | / _ \ / __// __/
* _\ \ / /__ / __ | / ___// _/ _\ \
* /___/ \___//_/ |_|/_/ /___//___/
*
*
* This journey began on September 24th, 2021,
* when the original PunkScapes smart contract went live.
* The mission was simple: Create "10,000 homes for the CryptoPunks."
*
* But as we received more and more love from other communities,
* it became clear that we wanted to become a HOME FOR EVERYONE.
* From this realization, we embarked on a mission
* to build a world centered around that idea.
*
* The metadata and art of PunkScapes
* was originally hosted on the Interplanetary File System (IPFS).
* But we soon realized, in order to fulfill their true potential,
* they needed to go fully onchain.
*
* As time passed,
* we felt the weight of our old contract,
* and knew it was time to move on.
*
* So, on the 20th of December,
* we burned the old world to the ground,
* leaving behind only ashes and memories.
* From those ashes, we built a new world,
* one that would be our home for all time.
*
* And thus, the Scapes were created.
*
* Welcome home.
*/
}// 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';
import { OwnableStorage } from './OwnableStorage.sol';
/**
* @title Ownership access control based on ERC173
*/
abstract contract Ownable is IOwnable, OwnableInternal {
using OwnableStorage for OwnableStorage.Layout;
/**
* @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;
using OwnableStorage for OwnableStorage.Layout;
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) {
address owner = _owner();
while (owner.isContract()) {
try IERC173(owner).owner() returns (address transitiveOwner) {
owner = transitiveOwner;
} catch {
return owner;
}
}
return owner;
}
function _transferOwnership(address account) internal virtual {
OwnableStorage.layout().setOwner(account);
emit OwnershipTransferred(msg.sender, 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
}
}
function setOwner(Layout storage l, address owner) internal {
l.owner = owner;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { Ownable, OwnableStorage } 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 { OwnableStorage } from './OwnableStorage.sol';
import { SafeOwnableStorage } from './SafeOwnableStorage.sol';
abstract contract SafeOwnableInternal is ISafeOwnableInternal, OwnableInternal {
using OwnableStorage for OwnableStorage.Layout;
using SafeOwnableStorage for SafeOwnableStorage.Layout;
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 {
OwnableStorage.Layout storage l = OwnableStorage.layout();
emit OwnershipTransferred(l.owner, msg.sender);
l.setOwner(msg.sender);
SafeOwnableStorage.layout().setNomineeOwner(address(0));
}
/**
* @notice set nominee owner, granting permission to call acceptOwnership
*/
function _transferOwnership(address account) internal virtual override {
SafeOwnableStorage.layout().setNomineeOwner(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
}
}
function setNomineeOwner(Layout storage l, address nomineeOwner) internal {
l.nomineeOwner = nomineeOwner;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title ERC165 interface registration interface
* @dev see https://eips.ethereum.org/EIPS/eip-165
*/
interface IERC165 {
/**
* @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 { 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 { ERC165Storage } from './ERC165Storage.sol';
/**
* @title ERC165 implementation
*/
abstract contract ERC165 is IERC165 {
using ERC165Storage for ERC165Storage.Layout;
/**
* @inheritdoc IERC165
*/
function supportsInterface(bytes4 interfaceId) public view returns (bool) {
return ERC165Storage.layout().isSupportedInterface(interfaceId);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
library ERC165Storage {
error ERC165Storage__InvalidInterfaceId();
struct Layout {
mapping(bytes4 => bool) supportedInterfaces;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.ERC165');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
function isSupportedInterface(
Layout storage l,
bytes4 interfaceId
) internal view returns (bool) {
return l.supportedInterfaces[interfaceId];
}
function setSupportedInterface(
Layout storage l,
bytes4 interfaceId,
bool status
) internal {
if (interfaceId == 0xffffffff)
revert ERC165Storage__InvalidInterfaceId();
l.supportedInterfaces[interfaceId] = status;
}
}// 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, OwnableStorage } from '../../access/ownable/Ownable.sol';
import { ISafeOwnable, SafeOwnable } from '../../access/ownable/SafeOwnable.sol';
import { IERC173 } from '../../interfaces/IERC173.sol';
import { ERC165, IERC165, ERC165Storage } from '../../introspection/ERC165.sol';
import { DiamondBase, DiamondBaseStorage } 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,
ERC165
{
using DiamondBaseStorage for DiamondBaseStorage.Layout;
using ERC165Storage for ERC165Storage.Layout;
using OwnableStorage for OwnableStorage.Layout;
constructor() {
ERC165Storage.Layout storage erc165 = ERC165Storage.layout();
bytes4[] memory selectors = new bytes4[](12);
uint256 selectorIndex;
// register DiamondFallback
selectors[selectorIndex++] = IDiamondFallback
.getFallbackAddress
.selector;
selectors[selectorIndex++] = IDiamondFallback
.setFallbackAddress
.selector;
erc165.setSupportedInterface(type(IDiamondFallback).interfaceId, true);
// register DiamondWritable
selectors[selectorIndex++] = IDiamondWritable.diamondCut.selector;
erc165.setSupportedInterface(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;
erc165.setSupportedInterface(type(IDiamondReadable).interfaceId, true);
// register ERC165
selectors[selectorIndex++] = IERC165.supportsInterface.selector;
erc165.setSupportedInterface(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;
erc165.setSupportedInterface(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
OwnableStorage.layout().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 { DiamondBaseStorage } from '../base/DiamondBaseStorage.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
{
using DiamondBaseStorage for DiamondBaseStorage.Layout;
/**
* @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":"ERC165Storage__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
60806040523480156200001157600080fd5b506000620000296200050060201b62000b9e1760201c565b60408051600c8082526101a082019092529192506000919060208201610180803683370190505090506000632c40805960e01b8282620000698162000db7565b9350815181106200007e576200007e62000ddf565b6001600160e01b031990921660209283029190910190910152639142376560e01b8282620000ac8162000db7565b935081518110620000c157620000c162000ddf565b6001600160e01b0319909216602092830291909101820152620000fb908490632f40adcf60e21b9060019062000bc262000524821b17901c565b6307e4c70760e21b8282620001108162000db7565b93508151811062000125576200012562000ddf565b6001600160e01b03199092166020928302919091018201526200015f9084906307e4c70760e21b9060019062000bc262000524821b17901c565b637a0ed62760e01b8282620001748162000db7565b93508151811062000189576200018962000ddf565b6001600160e01b0319909216602092830291909101909101526356fe50af60e11b8282620001b78162000db7565b935081518110620001cc57620001cc62000ddf565b6001600160e01b0319909216602092830291909101909101526314bbdacb60e21b8282620001fa8162000db7565b9350815181106200020f576200020f62000ddf565b6001600160e01b0319909216602092830291909101909101526366ffd66360e11b82826200023d8162000db7565b93508151811062000252576200025262000ddf565b6001600160e01b03199092166020928302919091018201526200028c9084906348e2b09360e01b9060019062000bc262000524821b17901c565b6301ffc9a760e01b8282620002a18162000db7565b935081518110620002b657620002b662000ddf565b6001600160e01b0319909216602092830291909101820152620002f09084906301ffc9a760e01b9060019062000bc262000524821b17901c565b638da5cb5b60e01b8282620003058162000db7565b9350815181106200031a576200031a62000ddf565b6001600160e01b03199092166020928302919091019091015263455a8a8560e11b8282620003488162000db7565b9350815181106200035d576200035d62000ddf565b6001600160e01b03199092166020928302919091019091015263f2fde38b60e01b82826200038b8162000db7565b935081518110620003a057620003a062000ddf565b6001600160e01b0319909216602092830291909101909101526379ba509760e01b8282620003ce8162000db7565b935081518110620003e357620003e362000ddf565b6001600160e01b03199092166020928302919091018201526200041d9084906307f5828d60e41b9060019062000bc262000524821b17901c565b604080516001808252818301909252600091816020015b6040805160608082018352600080835260208301529181019190915281526020019060019003908162000434579050506040805160608101909152308152909150602081016000815260200184815250816000815181106200049a576200049a62000ddf565b6020026020010181905250620004c8816000604051806020016040528060008152506200057e60201b60201c565b620004f633620004e26200075a60201b62000c1b1760201c565b6200077e60201b62000c3f1790919060201c565b5050505062000f84565b7f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e70590565b6001600160e01b03198083169003620005505760405163f31e8ca960e01b815260040160405180910390fd5b6001600160e01b03199190911660009081526020929092526040909120805460ff1916911515919091179055565b6000620005956200079b60201b62000c5c1760201c565b600181015490915061ffff811690819060009060071615620005c95750600381901c60009081526002840160205260409020545b60005b8751811015620006c8576000888281518110620005ed57620005ed62000ddf565b60200260200101519050600081602001519050816040015151600003620006275760405163eb6c3aeb60e01b815260040160405180910390fd5b60008160028111156200063e576200063e62000df5565b036200065d576200065287868685620007bf565b9095509350620006bd565b600181600281111562000674576200067462000df5565b036200068c576200068687836200091e565b620006bd565b6002816002811115620006a357620006a362000df5565b03620006bd57620006b78786868562000a84565b90955093505b5050600101620005cc565b50828214620006e55760018401805461ffff191661ffff84161790555b60078216156200070857600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516200073d9392919062000e5f565b60405180910390a162000751868662000cb0565b50505050505050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b81546001600160a01b0319166001600160a01b0391909116179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b805160009081906001600160a01b03163014801590620007ff5750620007fd83600001516001600160a01b031662000db160201b620002ad1760201c565b155b156200081e57604051633ddc5cab60e21b815260040160405180910390fd5b60005b83604001515181101562000911576000846040015182815181106200084a576200084a62000ddf565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c156200089757604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c199990991617978190036200090157600389901c600090815260028b0160205260408120989098555b5050506001958601950162000821565b5093959294509192505050565b6200094181600001516001600160a01b031662000db160201b620002ad1760201c565b6200095f57604051633ddc5cab60e21b815260040160405180910390fd5b60005b81604001515181101562000a7f576000826040015182815181106200098b576200098b62000ddf565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c80620009d8576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b0382160362000a025760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b03160362000a39576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166001600160601b039190911617905560010162000962565b505050565b805160009081906001600160a01b03161562000ab357604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b85604001515181101562000c9c5760008660400151828151811062000ae85762000ae862000ddf565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c62000b34576040516337e25a9760e11b815260040160405180910390fd5b30606082901c0362000b595760405163e983573160e01b815260040160405180910390fd5b600089900362000b8757600019909401600081815260028c0160205260409020549850936007935062000b8f565b600019909301925b600584901b89901b6000806001600160e01b03198084169086161462000be2576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166001600160601b0386161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b1687821462000c4757600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c17905562000c6b565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000362000c8a57600088815260028f01602052604081208190559b505b50506001909301925062000abf915050565b5060039190911b1796939550929350505050565b8051156001600160a01b038316151462000cdd576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b0382161562000dad576001600160a01b038216301462000d3b5762000d1d826001600160a01b031662000db160201b620002ad1760201c565b62000d3b57604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b03168260405162000d57919062000f66565b600060405180830381855af49150503d806000811462000d94576040519150601f19603f3d011682016040523d82523d6000602084013e62000d99565b606091505b505090508062000a7f573d6000803e3d6000fd5b5050565b3b151590565b60006001820162000dd857634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60005b8381101562000e2857818101518382015260200162000e0e565b50506000910152565b6000815180845262000e4b81602086016020860162000e0b565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101562000f3457898403607f19018652815180516001600160a01b0316855283810151898601906003811062000ed057634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b8083101562000f1e5783516001600160e01b031916825292860192600192909201919086019062000ef2565b5097850197955050509082019060010162000e88565b50506001600160a01b038a1690880152868103604088015262000f58818962000e31565b9a9950505050505050505050565b6000825162000f7a81846020870162000e0b565b9190910192915050565b611bb38062000f946000396000f3fe6080604052600436106100ab5760003560e01c80638ab5150a116100645780638ab5150a146101e75780638da5cb5b146101fc5780639142376514610211578063adfca15e14610231578063cdffacc61461025e578063f2fde38b1461027e576100b2565b806301ffc9a71461010c5780631f931c1c146101415780632c4080591461016157806352ef6b2c1461018e57806379ba5097146101b05780637a0ed627146101c5576100b2565b366100b257005b60006100bc61029e565b90506001600160a01b0381163b6100e6576040516321f27f0d60e21b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610105573d6000f35b3d6000fd5b005b34801561011857600080fd5b5061012c610127366004611566565b6102b3565b60405190151581526020015b60405180910390f35b34801561014d57600080fd5b5061010a61015c3660046115e8565b6102e8565b34801561016d57600080fd5b50610176610372565b6040516001600160a01b039091168152602001610138565b34801561019a57600080fd5b506101a361037c565b604051610138919061169a565b3480156101bc57600080fd5b5061010a61051f565b3480156101d157600080fd5b506101da610562565b604051610138919061172c565b3480156101f357600080fd5b5061017661098a565b34801561020857600080fd5b50610176610994565b34801561021d57600080fd5b5061010a61022c3660046117a9565b61099e565b34801561023d57600080fd5b5061025161024c3660046117a9565b6109e3565b60405161013891906117c4565b34801561026a57600080fd5b50610176610279366004611566565b610b2f565b34801561028a57600080fd5b5061010a6102993660046117a9565b610b5c565b60006102a8610c80565b905090565b3b151590565b60006102e2826102c1610b9e565b906001600160e01b0319166000908152602091909152604090205460ff1690565b92915050565b6102f0610ccc565b6001600160a01b0316336001600160a01b03161461032157604051632f7a8ee160e01b815260040160405180910390fd5b61036b61032e858761189a565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ce592505050565b5050505050565b60006102a8610e93565b60606000610388610c5c565b600181015490915061ffff1667ffffffffffffffff8111156103ac576103ac611806565b6040519080825280602002602001820160405280156103d5578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610517576000818152600285016020526040812054905b60088110156105025783610414816119e4565b600188015490955061ffff168511905061050257600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156104a5578a818151811061046a5761046a6119fd565b60200260200101516001600160a01b0316836001600160a01b03160361049357600191506104a5565b8061049d816119e4565b915050610450565b5080156104b4575050506104f0565b818a89815181106104c7576104c76119fd565b6001600160a01b0390921660209283029190910190910152876104e9816119e4565b9850505050505b806104fa816119e4565b915050610401565b5050808061050f906119e4565b9150506103de565b505082525090565b610527610eaf565b6001600160a01b0316336001600160a01b0316146105585760405163efd1052d60e01b815260040160405180910390fd5b610560610ed7565b565b6060600061056e610c5c565b600181015490915061ffff1667ffffffffffffffff81111561059257610592611806565b6040519080825280602002602001820160405280156105d857816020015b6040805180820190915260008152606060208201528152602001906001900390816105b05790505b50600182015490925060009061ffff1667ffffffffffffffff81111561060057610600611806565b604051908082528060200260200182016040528015610629578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610918576000818152600286016020526040812054905b60088110156109035783610668816119e4565b600189015490955061ffff168511905061090357600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b888110156107c157826001600160a01b03168c82815181106106c8576106c86119fd565b6020026020010151600001516001600160a01b0316036107af57838c82815181106106f5576106f56119fd565b6020026020010151602001518b8381518110610713576107136119fd565b602002602001015160ff168151811061072e5761072e6119fd565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a8281518110610764576107646119fd565b602002602001015160ff161061077957600080fd5b89818151811061078b5761078b6119fd565b6020026020010180518091906107a090611a13565b60ff16905250600191506107c1565b806107b9816119e4565b9150506106a4565b5080156107d0575050506108f1565b818b89815181106107e3576107e36119fd565b60209081029190910101516001600160a01b03909116905260018a015461ffff1667ffffffffffffffff81111561081c5761081c611806565b604051908082528060200260200182016040528015610845578160200160208202803683370190505b508b8981518110610858576108586119fd565b602002602001015160200181905250828b898151811061087a5761087a6119fd565b602002602001015160200151600081518110610898576108986119fd565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106108ce576108ce6119fd565b60ff90921660209283029190910190910152876108ea816119e4565b9850505050505b806108fb816119e4565b915050610655565b50508080610910906119e4565b915050610632565b5060005b8281101561097f576000848281518110610938576109386119fd565b602002602001015160ff1690506000878381518110610959576109596119fd565b602002602001015160200151905081815250508080610977906119e4565b91505061091c565b508185525050505090565b60006102a8610eaf565b60006102a8610ccc565b6109a6610ccc565b6001600160a01b0316336001600160a01b0316146109d757604051632f7a8ee160e01b815260040160405180910390fd5b6109e081610f54565b50565b606060006109ef610c5c565b600181015490915061ffff1667ffffffffffffffff811115610a1357610a13611806565b604051908082528060200260200182016040528015610a3c578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610b25576000818152600285016020526040812054905b6008811015610b105783610a7b816119e4565b600188015490955061ffff1685119050610b1057600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a1603610afd5780888781518110610ad657610ad66119fd565b6001600160e01b03199092166020928302919091019091015285610af9816119e4565b9650505b5080610b08816119e4565b915050610a68565b50508080610b1d906119e4565b915050610a45565b5050825250919050565b6000610b39610c5c565b6001600160e01b0319909216600090815260209290925250604090205460601c90565b610b64610ccc565b6001600160a01b0316336001600160a01b031614610b9557604051632f7a8ee160e01b815260040160405180910390fd5b6109e081610f81565b7f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e70590565b6001600160e01b03198083169003610bed5760405163f31e8ca960e01b815260040160405180910390fd5b6001600160e01b03199190911660009081526020929092526040909120805460ff1916911515919091179055565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b81546001600160a01b0319166001600160a01b0391909116179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c80610cc9576102a8610e93565b90565b6000610cd6610c1b565b546001600160a01b0316919050565b6000610cef610c5c565b600181015490915061ffff811690819060009060071615610d225750600381901c60009081526002840160205260409020545b60005b8751811015610e07576000888281518110610d4257610d426119fd565b60200260200101519050600081602001519050816040015151600003610d7b5760405163eb6c3aeb60e01b815260040160405180910390fd5b6000816002811115610d8f57610d8f611a32565b03610daa57610da087868685610f8a565b9095509350610dfd565b6001816002811115610dbe57610dbe611a32565b03610dd257610dcd87836110c9565b610dfd565b6002816002811115610de657610de6611a32565b03610dfd57610df787868685611214565b90955093505b5050600101610d25565b50828214610e235760018401805461ffff191661ffff84161790555b6007821615610e4557600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673878787604051610e7893929190611a98565b60405180910390a1610e8a8686611437565b50505050505050565b6000610e9d610c5c565b600301546001600160a01b0316919050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610cd6565b6000610ee1610c1b565b805460405191925033916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3610f278133610c3f565b6109e060007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178905b90610c3f565b80610f5d610c5c565b60030180546001600160a01b0319166001600160a01b039290921691909117905550565b6109e08161151b565b805160009081906001600160a01b03163014801590610fb2575082516001600160a01b03163b155b15610fd057604051633ddc5cab60e21b815260040160405180910390fd5b60005b8360400151518110156110bc57600084604001518281518110610ff857610ff86119fd565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1561104457604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c199990991617978190036110ad57600389901c600090815260028b0160205260408120989098555b50505060019586019501610fd3565b5093959294509192505050565b80516001600160a01b03163b6110f257604051633ddc5cab60e21b815260040160405180910390fd5b60005b81604001515181101561120f5760008260400151828151811061111a5761111a6119fd565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c80611166576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b0382160361118f5760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b0316036111c5576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff919091161790556001016110f5565b505050565b805160009081906001600160a01b03161561124257604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b85604001515181101561142357600086604001518281518110611273576112736119fd565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c6112be576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036112e25760405163e983573160e01b815260040160405180910390fd5b600089900361130e57600019909401600081815260028c01602052604090205498509360079350611316565b600019909301925b600584901b89901b6000806001600160e01b03198084169086161461136d576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166bffffffffffffffffffffffff86161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b168782146113d057600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c1790556113f4565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000361141257600088815260028f01602052604081208190559b505b50506001909301925061124e915050565b5060039190911b1796939550929350505050565b8051156001600160a01b0383161514611463576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611517576001600160a01b03821630146114aa576001600160a01b0382163b6114aa57604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b0316826040516114c49190611b61565b600060405180830381855af49150503d80600081146114ff576040519150601f19603f3d011682016040523d82523d6000602084013e611504565b606091505b505090508061120f573d6000803e3d6000fd5b5050565b6109e0816109e0817f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610f4e565b80356001600160e01b03198116811461156157600080fd5b919050565b60006020828403121561157857600080fd5b61158182611549565b9392505050565b80356001600160a01b038116811461156157600080fd5b60008083601f8401126115b157600080fd5b50813567ffffffffffffffff8111156115c957600080fd5b6020830191508360208285010111156115e157600080fd5b9250929050565b60008060008060006060868803121561160057600080fd5b853567ffffffffffffffff8082111561161857600080fd5b818801915088601f83011261162c57600080fd5b81358181111561163b57600080fd5b8960208260051b850101111561165057600080fd5b6020830197508096505061166660208901611588565b9450604088013591508082111561167c57600080fd5b506116898882890161159f565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b818110156116db5783516001600160a01b0316835292840192918401916001016116b6565b50909695505050505050565b600081518084526020808501945080840160005b838110156117215781516001600160e01b031916875295820195908201906001016116fb565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561179b57888303603f19018552815180516001600160a01b03168452870151878401879052611788878501826116e7565b9588019593505090860190600101611753565b509098975050505050505050565b6000602082840312156117bb57600080fd5b61158182611588565b6020808252825182820181905260009190848201906040850190845b818110156116db5783516001600160e01b031916835292840192918401916001016117e0565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561183f5761183f611806565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561186e5761186e611806565b604052919050565b600067ffffffffffffffff82111561189057611890611806565b5060051b60200190565b60006118ad6118a884611876565b611845565b83815260208082019190600586811b8601368111156118cb57600080fd5b865b818110156119c157803567ffffffffffffffff808211156118ee5760008081fd5b818a019150606082360312156119045760008081fd5b61190c61181c565b61191583611588565b815286830135600381106119295760008081fd5b81880152604083810135838111156119415760008081fd5b939093019236601f85011261195857600092508283fd5b833592506119686118a884611876565b83815292871b840188019288810190368511156119855760008081fd5b948901945b848610156119aa5761199b86611549565b8252948901949089019061198a565b9183019190915250885250509483019483016118cd565b5092979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016119f6576119f66119ce565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103611a2957611a296119ce565b60010192915050565b634e487b7160e01b600052602160045260246000fd5b60005b83811015611a63578181015183820152602001611a4b565b50506000910152565b60008151808452611a84816020860160208601611a48565b601f01601f19169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b84811015611b3157898703607f19018652825180516001600160a01b031688528481015160038110611b0257634e487b7160e01b84526021600452602484fd5b88860152604090810151908801899052611b1e898901826116e7565b9750509483019491830191600101611ac2565b5050506001600160a01b0389169087015250508381036040850152611b568186611a6c565b979650505050505050565b60008251611b73818460208701611a48565b919091019291505056fea2646970667358221220e6ba1a829f238e956234ed1df418dca0ea2a0c19e82b065a572653d163f5504264736f6c63430008100033
Deployed Bytecode
0x6080604052600436106100ab5760003560e01c80638ab5150a116100645780638ab5150a146101e75780638da5cb5b146101fc5780639142376514610211578063adfca15e14610231578063cdffacc61461025e578063f2fde38b1461027e576100b2565b806301ffc9a71461010c5780631f931c1c146101415780632c4080591461016157806352ef6b2c1461018e57806379ba5097146101b05780637a0ed627146101c5576100b2565b366100b257005b60006100bc61029e565b90506001600160a01b0381163b6100e6576040516321f27f0d60e21b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610105573d6000f35b3d6000fd5b005b34801561011857600080fd5b5061012c610127366004611566565b6102b3565b60405190151581526020015b60405180910390f35b34801561014d57600080fd5b5061010a61015c3660046115e8565b6102e8565b34801561016d57600080fd5b50610176610372565b6040516001600160a01b039091168152602001610138565b34801561019a57600080fd5b506101a361037c565b604051610138919061169a565b3480156101bc57600080fd5b5061010a61051f565b3480156101d157600080fd5b506101da610562565b604051610138919061172c565b3480156101f357600080fd5b5061017661098a565b34801561020857600080fd5b50610176610994565b34801561021d57600080fd5b5061010a61022c3660046117a9565b61099e565b34801561023d57600080fd5b5061025161024c3660046117a9565b6109e3565b60405161013891906117c4565b34801561026a57600080fd5b50610176610279366004611566565b610b2f565b34801561028a57600080fd5b5061010a6102993660046117a9565b610b5c565b60006102a8610c80565b905090565b3b151590565b60006102e2826102c1610b9e565b906001600160e01b0319166000908152602091909152604090205460ff1690565b92915050565b6102f0610ccc565b6001600160a01b0316336001600160a01b03161461032157604051632f7a8ee160e01b815260040160405180910390fd5b61036b61032e858761189a565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ce592505050565b5050505050565b60006102a8610e93565b60606000610388610c5c565b600181015490915061ffff1667ffffffffffffffff8111156103ac576103ac611806565b6040519080825280602002602001820160405280156103d5578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610517576000818152600285016020526040812054905b60088110156105025783610414816119e4565b600188015490955061ffff168511905061050257600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156104a5578a818151811061046a5761046a6119fd565b60200260200101516001600160a01b0316836001600160a01b03160361049357600191506104a5565b8061049d816119e4565b915050610450565b5080156104b4575050506104f0565b818a89815181106104c7576104c76119fd565b6001600160a01b0390921660209283029190910190910152876104e9816119e4565b9850505050505b806104fa816119e4565b915050610401565b5050808061050f906119e4565b9150506103de565b505082525090565b610527610eaf565b6001600160a01b0316336001600160a01b0316146105585760405163efd1052d60e01b815260040160405180910390fd5b610560610ed7565b565b6060600061056e610c5c565b600181015490915061ffff1667ffffffffffffffff81111561059257610592611806565b6040519080825280602002602001820160405280156105d857816020015b6040805180820190915260008152606060208201528152602001906001900390816105b05790505b50600182015490925060009061ffff1667ffffffffffffffff81111561060057610600611806565b604051908082528060200260200182016040528015610629578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610918576000818152600286016020526040812054905b60088110156109035783610668816119e4565b600189015490955061ffff168511905061090357600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b888110156107c157826001600160a01b03168c82815181106106c8576106c86119fd565b6020026020010151600001516001600160a01b0316036107af57838c82815181106106f5576106f56119fd565b6020026020010151602001518b8381518110610713576107136119fd565b602002602001015160ff168151811061072e5761072e6119fd565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a8281518110610764576107646119fd565b602002602001015160ff161061077957600080fd5b89818151811061078b5761078b6119fd565b6020026020010180518091906107a090611a13565b60ff16905250600191506107c1565b806107b9816119e4565b9150506106a4565b5080156107d0575050506108f1565b818b89815181106107e3576107e36119fd565b60209081029190910101516001600160a01b03909116905260018a015461ffff1667ffffffffffffffff81111561081c5761081c611806565b604051908082528060200260200182016040528015610845578160200160208202803683370190505b508b8981518110610858576108586119fd565b602002602001015160200181905250828b898151811061087a5761087a6119fd565b602002602001015160200151600081518110610898576108986119fd565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106108ce576108ce6119fd565b60ff90921660209283029190910190910152876108ea816119e4565b9850505050505b806108fb816119e4565b915050610655565b50508080610910906119e4565b915050610632565b5060005b8281101561097f576000848281518110610938576109386119fd565b602002602001015160ff1690506000878381518110610959576109596119fd565b602002602001015160200151905081815250508080610977906119e4565b91505061091c565b508185525050505090565b60006102a8610eaf565b60006102a8610ccc565b6109a6610ccc565b6001600160a01b0316336001600160a01b0316146109d757604051632f7a8ee160e01b815260040160405180910390fd5b6109e081610f54565b50565b606060006109ef610c5c565b600181015490915061ffff1667ffffffffffffffff811115610a1357610a13611806565b604051908082528060200260200182016040528015610a3c578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610b25576000818152600285016020526040812054905b6008811015610b105783610a7b816119e4565b600188015490955061ffff1685119050610b1057600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a1603610afd5780888781518110610ad657610ad66119fd565b6001600160e01b03199092166020928302919091019091015285610af9816119e4565b9650505b5080610b08816119e4565b915050610a68565b50508080610b1d906119e4565b915050610a45565b5050825250919050565b6000610b39610c5c565b6001600160e01b0319909216600090815260209290925250604090205460601c90565b610b64610ccc565b6001600160a01b0316336001600160a01b031614610b9557604051632f7a8ee160e01b815260040160405180910390fd5b6109e081610f81565b7f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e70590565b6001600160e01b03198083169003610bed5760405163f31e8ca960e01b815260040160405180910390fd5b6001600160e01b03199190911660009081526020929092526040909120805460ff1916911515919091179055565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b81546001600160a01b0319166001600160a01b0391909116179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c80610cc9576102a8610e93565b90565b6000610cd6610c1b565b546001600160a01b0316919050565b6000610cef610c5c565b600181015490915061ffff811690819060009060071615610d225750600381901c60009081526002840160205260409020545b60005b8751811015610e07576000888281518110610d4257610d426119fd565b60200260200101519050600081602001519050816040015151600003610d7b5760405163eb6c3aeb60e01b815260040160405180910390fd5b6000816002811115610d8f57610d8f611a32565b03610daa57610da087868685610f8a565b9095509350610dfd565b6001816002811115610dbe57610dbe611a32565b03610dd257610dcd87836110c9565b610dfd565b6002816002811115610de657610de6611a32565b03610dfd57610df787868685611214565b90955093505b5050600101610d25565b50828214610e235760018401805461ffff191661ffff84161790555b6007821615610e4557600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673878787604051610e7893929190611a98565b60405180910390a1610e8a8686611437565b50505050505050565b6000610e9d610c5c565b600301546001600160a01b0316919050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610cd6565b6000610ee1610c1b565b805460405191925033916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3610f278133610c3f565b6109e060007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178905b90610c3f565b80610f5d610c5c565b60030180546001600160a01b0319166001600160a01b039290921691909117905550565b6109e08161151b565b805160009081906001600160a01b03163014801590610fb2575082516001600160a01b03163b155b15610fd057604051633ddc5cab60e21b815260040160405180910390fd5b60005b8360400151518110156110bc57600084604001518281518110610ff857610ff86119fd565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1561104457604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c199990991617978190036110ad57600389901c600090815260028b0160205260408120989098555b50505060019586019501610fd3565b5093959294509192505050565b80516001600160a01b03163b6110f257604051633ddc5cab60e21b815260040160405180910390fd5b60005b81604001515181101561120f5760008260400151828151811061111a5761111a6119fd565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c80611166576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b0382160361118f5760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b0316036111c5576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff919091161790556001016110f5565b505050565b805160009081906001600160a01b03161561124257604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b85604001515181101561142357600086604001518281518110611273576112736119fd565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c6112be576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036112e25760405163e983573160e01b815260040160405180910390fd5b600089900361130e57600019909401600081815260028c01602052604090205498509360079350611316565b600019909301925b600584901b89901b6000806001600160e01b03198084169086161461136d576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166bffffffffffffffffffffffff86161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b168782146113d057600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c1790556113f4565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000361141257600088815260028f01602052604081208190559b505b50506001909301925061124e915050565b5060039190911b1796939550929350505050565b8051156001600160a01b0383161514611463576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611517576001600160a01b03821630146114aa576001600160a01b0382163b6114aa57604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b0316826040516114c49190611b61565b600060405180830381855af49150503d80600081146114ff576040519150601f19603f3d011682016040523d82523d6000602084013e611504565b606091505b505090508061120f573d6000803e3d6000fd5b5050565b6109e0816109e0817f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610f4e565b80356001600160e01b03198116811461156157600080fd5b919050565b60006020828403121561157857600080fd5b61158182611549565b9392505050565b80356001600160a01b038116811461156157600080fd5b60008083601f8401126115b157600080fd5b50813567ffffffffffffffff8111156115c957600080fd5b6020830191508360208285010111156115e157600080fd5b9250929050565b60008060008060006060868803121561160057600080fd5b853567ffffffffffffffff8082111561161857600080fd5b818801915088601f83011261162c57600080fd5b81358181111561163b57600080fd5b8960208260051b850101111561165057600080fd5b6020830197508096505061166660208901611588565b9450604088013591508082111561167c57600080fd5b506116898882890161159f565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b818110156116db5783516001600160a01b0316835292840192918401916001016116b6565b50909695505050505050565b600081518084526020808501945080840160005b838110156117215781516001600160e01b031916875295820195908201906001016116fb565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561179b57888303603f19018552815180516001600160a01b03168452870151878401879052611788878501826116e7565b9588019593505090860190600101611753565b509098975050505050505050565b6000602082840312156117bb57600080fd5b61158182611588565b6020808252825182820181905260009190848201906040850190845b818110156116db5783516001600160e01b031916835292840192918401916001016117e0565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561183f5761183f611806565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561186e5761186e611806565b604052919050565b600067ffffffffffffffff82111561189057611890611806565b5060051b60200190565b60006118ad6118a884611876565b611845565b83815260208082019190600586811b8601368111156118cb57600080fd5b865b818110156119c157803567ffffffffffffffff808211156118ee5760008081fd5b818a019150606082360312156119045760008081fd5b61190c61181c565b61191583611588565b815286830135600381106119295760008081fd5b81880152604083810135838111156119415760008081fd5b939093019236601f85011261195857600092508283fd5b833592506119686118a884611876565b83815292871b840188019288810190368511156119855760008081fd5b948901945b848610156119aa5761199b86611549565b8252948901949089019061198a565b9183019190915250885250509483019483016118cd565b5092979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016119f6576119f66119ce565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103611a2957611a296119ce565b60010192915050565b634e487b7160e01b600052602160045260246000fd5b60005b83811015611a63578181015183820152602001611a4b565b50506000910152565b60008151808452611a84816020860160208601611a48565b601f01601f19169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b84811015611b3157898703607f19018652825180516001600160a01b031688528481015160038110611b0257634e487b7160e01b84526021600452602484fd5b88860152604090810151908801899052611b1e898901826116e7565b9750509483019491830191600101611ac2565b5050506001600160a01b0389169087015250508381036040850152611b568186611a6c565b979650505050505050565b60008251611b73818460208701611a48565b919091019291505056fea2646970667358221220e6ba1a829f238e956234ed1df418dca0ea2a0c19e82b065a572653d163f5504264736f6c63430008100033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.