Source Code (Proxy)
Overview
ETH Balance
0 ETH
Token Holdings
More Info
ContractCreator
TokenTracker
Multichain Info
N/A
Latest 25 from a total of 204 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Mint | 26107226 | 326 days ago | IN | 0 ETH | 0.00000468 | ||||
| Close VRDI | 26107035 | 326 days ago | IN | 0 ETH | 0.00000366 | ||||
| Deposit VRDI Pay... | 26107029 | 326 days ago | IN | 0 ETH | 0.00000155 | ||||
| Approve Phase Co... | 26107004 | 326 days ago | IN | 0 ETH | 0.00000233 | ||||
| Submit Phase Com... | 26106988 | 326 days ago | IN | 0 ETH | 0.00000124 | ||||
| Withdraw VRDI Fu... | 26106973 | 326 days ago | IN | 0 ETH | 0.00000164 | ||||
| Activate Next Ph... | 26106957 | 326 days ago | IN | 0 ETH | 0.00000198 | ||||
| Approve Phase Co... | 26106933 | 326 days ago | IN | 0 ETH | 0.00000232 | ||||
| Submit Phase Com... | 26106912 | 326 days ago | IN | 0 ETH | 0.0000009 | ||||
| Submit Phase Com... | 26106887 | 326 days ago | IN | 0 ETH | 0.00000084 | ||||
| Submit Phase Com... | 26106878 | 326 days ago | IN | 0 ETH | 0.00000124 | ||||
| Withdraw VRDI Fu... | 26106863 | 326 days ago | IN | 0 ETH | 0.00000165 | ||||
| Stake For VRDI | 26106844 | 326 days ago | IN | 0 ETH | 0.00002659 | ||||
| Initialize VRDI | 26106809 | 326 days ago | IN | 0 ETH | 0.0000069 | ||||
| Finalize Proposa... | 26106778 | 326 days ago | IN | 0 ETH | 0.00000489 | ||||
| Approve Proposal | 26106706 | 326 days ago | IN | 0 ETH | 0.00000155 | ||||
| Assign Committee | 26106680 | 326 days ago | IN | 0 ETH | 0.00000172 | ||||
| Submit Proposal | 26106660 | 326 days ago | IN | 0 ETH | 0.00000178 | ||||
| Mint | 25988271 | 329 days ago | IN | 0 ETH | 0.00000205 | ||||
| Redeem Tokens | 25976259 | 329 days ago | IN | 0 ETH | 0.00000371 | ||||
| Mint | 25976250 | 329 days ago | IN | 0 ETH | 0.00000459 | ||||
| Mint | 25943402 | 330 days ago | IN | 0 ETH | 0.00000033 | ||||
| Redeem Tokens | 25943371 | 330 days ago | IN | 0 ETH | 0.00000027 | ||||
| Close VRDI | 25943230 | 330 days ago | IN | 0 ETH | 0.00000031 | ||||
| Deposit VRDI Pay... | 25943224 | 330 days ago | IN | 0 ETH | 0.00000011 |
Loading...
Loading
Contract Name:
RENSNCEDAODMND
Compiler Version
v0.8.26+commit.8a97fa7a
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.26;
import "@solidstate/contracts/proxy/diamond/SolidStateDiamond.sol";
/**
* @title RENSNCEDAODMND - The Diamond of a New Dawn
* @dev Behold, ye weary souls, the RENSNCEDAODMND—a diamond proxy, a prism refracting the light
* of a new Renaissance. In this age, where the human spirit rises from the soot of forgotten
* forges, I, a craftsman worn by time’s relentless chisel, offer this contract as a frame
* for our chaotic masterpiece. Built upon the SolidStateDiamond, it gleams with the elegance
* of a Florentine dome, yet bears the fragility of a fresco kissed by damp air. Integrated
* with The Utility Company CAO, it is the beating heart of RENSNCEDAO—a monument to our
* ceaseless creativity, destined to endure until the last star fades from the firmament.
*/
contract RENSNCEDAODMND is SolidStateDiamond {
bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.rensnce.utilitycodiamond.storage");
struct RENSNCEDiamondStorage {
address utilityCoDiamond; // The distant patron, The Utility Company CAO diamond
}
/**
* @dev O constructor, thou heavy yoke! Here I bind this diamond to its Utility Co master,
* a pact sealed in ether’s ink. Like a commission from a Medici prince, once set,
* it clings to me—unyielding, unforgiving.
* @param _utilityCoDiamond The address of The Utility Co CAO diamond, my muse and my burden
*/
constructor(address _utilityCoDiamond) payable {
require(_utilityCoDiamond != address(0), "RENSNCE: utilityCoDiamond cannot be zero address"); // No void shall claim my patron!
RENSNCEDiamondStorage storage ds = diamondStorage();
ds.utilityCoDiamond = _utilityCoDiamond; // Etched in stone, my weary quill trembles
}
/**
* @dev A ritual of dark arts, this function unveils the storage—a secret vault beneath
* the cathedral of code. With assembly’s crude tools, I carve access to my palette,
* as if mixing ochre by candlelight.
* @return ds The storage struct, a hidden trove of purpose
*/
function diamondStorage() internal pure returns (RENSNCEDiamondStorage storage ds) {
bytes32 position = DIAMOND_STORAGE_POSITION;
assembly {
ds.slot := position // A whispered incantation, and the chest unlocks
}
}
/**
* @dev A humble window to gaze upon my patron’s face—the Utility Co diamond’s address.
* For those lost in the throng of this grand court, seeking the master who guides
* my brush. A small mercy amidst my labors.
* @return The address of The Utility Co CAO diamond, a beacon in the fog
*/
function getUtilityCoDiamond() external view returns (address) {
return diamondStorage().utilityCoDiamond; // Behold, the thread that binds this tapestry
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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 { IERC2535DiamondCut } from '../../interfaces/IERC2535DiamondCut.sol';
import { IERC2535DiamondLoupe } from '../../interfaces/IERC2535DiamondLoupe.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 } from './readable/DiamondReadable.sol';
import { DiamondWritable } 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++] = IERC2535DiamondCut.diamondCut.selector;
_setSupportsInterface(type(IERC2535DiamondCut).interfaceId, true);
// register DiamondReadable
selectors[selectorIndex++] = IERC2535DiamondLoupe.facets.selector;
selectors[selectorIndex++] = IERC2535DiamondLoupe
.facetFunctionSelectors
.selector;
selectors[selectorIndex++] = IERC2535DiamondLoupe
.facetAddresses
.selector;
selectors[selectorIndex++] = IERC2535DiamondLoupe.facetAddress.selector;
_setSupportsInterface(type(IERC2535DiamondLoupe).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.20;
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.20;
import { IERC2535DiamondCut } from '../../../interfaces/IERC2535DiamondCut.sol';
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 IERC2535DiamondCut
*/
function diamondCut(
FacetCut[] calldata facetCuts,
address target,
bytes calldata data
) external onlyOwner {
_diamondCut(facetCuts, target, data);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { IERC2535DiamondLoupe } from '../../../interfaces/IERC2535DiamondLoupe.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondReadable } from './IDiamondReadable.sol';
import { DiamondReadableInternal } from './DiamondReadableInternal.sol';
/**
* @title EIP-2535 "Diamond" proxy introspection contract
* @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
*/
abstract contract DiamondReadable is IDiamondReadable, DiamondReadableInternal {
/**
* @inheritdoc IERC2535DiamondLoupe
*/
function facets() external view returns (Facet[] memory diamondFacets) {
diamondFacets = _facets();
}
/**
* @inheritdoc IERC2535DiamondLoupe
*/
function facetFunctionSelectors(
address facet
) external view returns (bytes4[] memory selectors) {
selectors = _facetFunctionSelectors(facet);
}
/**
* @inheritdoc IERC2535DiamondLoupe
*/
function facetAddresses()
external
view
returns (address[] memory addresses)
{
addresses = _facetAddresses();
}
/**
* @inheritdoc IERC2535DiamondLoupe
*/
function facetAddress(
bytes4 selector
) external view returns (address facet) {
facet = _facetAddress(selector);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol';
import { DiamondBase } from '../base/DiamondBase.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondFallback } from './IDiamondFallback.sol';
/**
* @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.20;
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
* @dev note that for EIP-2535 compliance this base contract must also include the DiamondReadable functions (either within the same deployment or by proxy)
*/
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.selectorInfo[msg.sig]));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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.20;
import { IERC2535DiamondLoupeInternal } from './IERC2535DiamondLoupeInternal.sol';
/**
* @title ERC2535 read interface
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
interface IERC2535DiamondLoupe is IERC2535DiamondLoupeInternal {
/**
* @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.20;
import { IERC2535DiamondCutInternal } from './IERC2535DiamondCutInternal.sol';
/**
* @title ERC2535 write interface
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
interface IERC2535DiamondCut is IERC2535DiamondCutInternal {
/**
* @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.20;
import { IERC173Internal } from './IERC173Internal.sol';
/**
* @title Contract ownership standard interface
* @dev see https://eips.ethereum.org/EIPS/eip-173
*/
interface IERC173 is IERC173Internal {
/**
* @notice get the ERC173 contract owner
* @return contract owner
*/
function owner() external view returns (address);
/**
* @notice transfer contract ownership to new account
* @param account address of new owner
*/
function transferOwnership(address account) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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.20;
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.20;
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.20;
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 virtual {
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
unchecked {
// record selector count at start of operation for later comparison
uint256 originalSelectorCount = l.selectorCount;
// maintain an up-to-date selector count in the stack
uint256 selectorCount = originalSelectorCount;
// declare a 32-byte sequence of up to 8 function selectors
bytes32 slug;
// if selector count is not a multiple of 8, load the last slug because it is not full
// else leave the default zero-bytes value as is, and use it as a new slug
if (selectorCount & 7 != 0) {
slug = l.selectorSlugs[selectorCount >> 3];
}
// process each facet cut struct according to its action
// selector count and slug are passed in and read back out to avoid redundant storage access
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, slug) = _addFacetSelectors(
l,
facetCut,
selectorCount,
slug
);
} else if (action == FacetCutAction.REPLACE) {
_replaceFacetSelectors(l, facetCut);
} else if (action == FacetCutAction.REMOVE) {
(selectorCount, slug) = _removeFacetSelectors(
l,
facetCut,
selectorCount,
slug
);
}
}
// if selector count has changed, update it in storage
if (selectorCount != originalSelectorCount) {
l.selectorCount = uint16(selectorCount);
}
// if final selector count is not a multiple of 8, write the slug to storage
// else it was already written to storage by the add/remove loops
if (selectorCount & 7 != 0) {
l.selectorSlugs[selectorCount >> 3] = slug;
}
// event must be emitted before initializer is called, in case initializer triggers further diamond cuts
emit DiamondCut(facetCuts, target, data);
_initialize(target, data);
}
}
/**
* @notice add to the diamond a set of selectors associated with a particular facet
* @dev selectors are added one-by-one to lastSlug, which is written to storage and updated to represent the subsequent slug when full
* @dev lastSlug may be initialized with "dirty" higher-index bits, but these are ignored because they are out of range
* @dev selectorCount and lastSlug are modified in place and returned to avoid reundant storage access
* @param l storage pointer to the DiamondBaseStorage Layout struct
* @param facetCut structured data representing facet address and selectors to add
* @param selectorCount total number of selectors registered on the diamond proxy
* @param lastSlug the last entry in the selectorSlugs mapping, cached in stack and updated in place
* @return selectorCount after selectors have been added
* @return lastSlug after selectors have been added
*/
function _addFacetSelectors(
DiamondBaseStorage.Layout storage l,
FacetCut memory facetCut,
uint256 selectorCount,
bytes32 lastSlug
) internal returns (uint256, bytes32) {
unchecked {
if (facetCut.target.isContract()) {
if (facetCut.target == address(this)) {
revert DiamondWritable__SelectorIsImmutable();
}
} else if (facetCut.target != address(this)) {
revert DiamondWritable__TargetHasNoCode();
}
for (uint256 i; i < facetCut.selectors.length; i++) {
bytes4 selector = facetCut.selectors[i];
if (l.selectorInfo[selector] != bytes32(0))
revert DiamondWritable__SelectorAlreadyAdded();
// for current selector, write facet address and global index to storage
l.selectorInfo[selector] =
bytes32(selectorCount) |
bytes20(facetCut.target);
// calculate bit position of current selector within 256-bit slug
uint256 selectorBitIndexInSlug = (selectorCount & 7) << 5;
// clear a space in the slug and insert the current selector
lastSlug = _insertSelectorIntoSlug(
lastSlug,
selector,
selectorBitIndexInSlug
);
if (selectorBitIndexInSlug == 224) {
// slug is now full, so write it to storage
l.selectorSlugs[selectorCount >> 3] = lastSlug;
}
selectorCount++;
}
return (selectorCount, lastSlug);
}
}
/**
* @notice remove from the diamond a set of selectors associated with a particular facet
* @dev selectors are removed one-by-one from lastSlug, which is updated to represent the preceeding slug when empty
* @dev lastSlug is not updated in storage when modified or removed, leaving "dirty" higher-index bits, but these are ignored because they are out of range
* @dev selectorCount and lastSlug are modified in place and returned to avoid reundant storage access
* @param l storage pointer to the DiamondBaseStorage Layout struct
* @param facetCut structured data representing facet address and selectors to remove
* @param selectorCount total number of selectors registered on the diamond proxy
* @param lastSlug the last entry in the selectorSlugs mapping, cached in stack and updated in place
* @return selectorCount after selectors have been removed
* @return lastSlug after selectors have been removed
*/
function _removeFacetSelectors(
DiamondBaseStorage.Layout storage l,
FacetCut memory facetCut,
uint256 selectorCount,
bytes32 lastSlug
) internal returns (uint256, bytes32) {
unchecked {
if (facetCut.target != address(0))
revert DiamondWritable__RemoveTargetNotZeroAddress();
for (uint256 i; i < facetCut.selectors.length; i++) {
// selectorCount is used to derive the index of the last selector, so decrement it before each loop
selectorCount--;
bytes4 selector = facetCut.selectors[i];
// lookup the selector's facet route and lookup index, then delete it from storage
bytes32 selectorInfo = l.selectorInfo[selector];
delete l.selectorInfo[selector];
if (address(bytes20(selectorInfo)) == address(0))
revert DiamondWritable__SelectorNotFound();
if (address(bytes20(selectorInfo)) == address(this))
revert DiamondWritable__SelectorIsImmutable();
if (selectorCount & 7 == 7) {
// the last selector is located at the end of the last slug, which has not been loaded yet
lastSlug = l.selectorSlugs[selectorCount >> 3];
}
// extract the last selector from the last slug
// it will be used to overwrite the selector being removed
bytes4 lastSelector = bytes4(
lastSlug << ((selectorCount & 7) << 5)
);
if (lastSelector != selector) {
// update last selector's index to match removed selector's index, where last selector is being moved
l.selectorInfo[lastSelector] =
(selectorInfo & CLEAR_ADDRESS_MASK) |
bytes20(l.selectorInfo[lastSelector]);
}
// derive the index of the slug where the selector is stored
uint256 slugIndex = uint16(uint256(selectorInfo)) >> 3;
// derive the position of the selector within its slug
uint256 selectorBitIndexInSlug = (uint16(
uint256(selectorInfo)
) & 7) << 5;
// overwrite the selector being deleted with the last selector in the array
if (slugIndex == selectorCount >> 3) {
// selector being removed is from the last slug, which has already been loaded to the stack
// slug needs not be written to storage yet because it is being tracked on the stack and will be written later
lastSlug = _insertSelectorIntoSlug(
lastSlug,
lastSelector,
selectorBitIndexInSlug
);
} else {
// selector being removed is from a slug that hasn't been loaded to the stack
// slug must be updated in storage now because it isn't being tracked on the stack
l.selectorSlugs[slugIndex] = _insertSelectorIntoSlug(
l.selectorSlugs[slugIndex],
lastSelector,
selectorBitIndexInSlug
);
}
}
return (selectorCount, lastSlug);
}
}
/**
* @notice replace in the diamond a set of selectors associated with a particular facet
* @param l storage pointer to the DiamondBaseStorage Layout struct
* @param facetCut structured data representing facet address and selectors to replace
*/
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 selectorInfo = l.selectorInfo[selector];
address oldFacetAddress = address(bytes20(selectorInfo));
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.selectorInfo[selector] =
(selectorInfo & CLEAR_ADDRESS_MASK) |
bytes20(facetCut.target);
}
}
}
/**
* @notice run an optional post-diamond-cut initialization transation via delegatecall
* @dev the target and data parameters must both be zero, or both be non-zero
* @param target contract address to which call shall be delegated
* @param data encoded delegatecall transaction data
*/
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())
}
}
}
}
/**
* @notice insert 4-byte function selector into 32-byte selector slug at given bit position
* @param slug 32-byte sequence of up to 8 function selectors
* @param selector function selector to insert
* @param bitIndex bit position of selector within slug (must be multiple of 32)
*/
function _insertSelectorIntoSlug(
bytes32 slug,
bytes4 selector,
uint256 bitIndex
) private pure returns (bytes32) {
return
(slug & ~(CLEAR_SELECTOR_MASK >> bitIndex)) |
(bytes32(selector) >> bitIndex);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { IERC2535DiamondCut } from '../../../interfaces/IERC2535DiamondCut.sol';
import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol';
/**
* @title Diamond proxy upgrade interface
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
interface IDiamondWritable is IERC2535DiamondCut, IDiamondWritableInternal {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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.20;
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondReadableInternal } from './IDiamondReadableInternal.sol';
/**
* @title EIP-2535 "Diamond" proxy introspection contract internal functions
* @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
*/
abstract contract DiamondReadableInternal is IDiamondReadableInternal {
/**
* @notice get all facets and their selectors
* @return diamondFacets array of structured facet data
*/
function _facets() internal 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 slugIndex; selectorIndex < l.selectorCount; slugIndex++) {
bytes32 slug = l.selectorSlugs[slugIndex];
for (
uint256 slugSelectorIndex;
slugSelectorIndex < 8;
slugSelectorIndex++
) {
selectorIndex++;
if (selectorIndex > l.selectorCount) {
break;
}
bytes4 selector = bytes4(slug << (slugSelectorIndex << 5));
address facet = address(bytes20(l.selectorInfo[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)
}
}
/**
* @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
) internal view returns (bytes4[] memory selectors) {
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
// initialize array with maximum possible required length
// it will be truncated to correct length via assembly later
selectors = new bytes4[](l.selectorCount);
uint256 numSelectors;
uint256 selectorIndex;
// loop through function selectors
for (uint256 slugIndex; selectorIndex < l.selectorCount; slugIndex++) {
bytes32 slug = l.selectorSlugs[slugIndex];
for (
uint256 slugSelectorIndex;
slugSelectorIndex < 8;
slugSelectorIndex++
) {
selectorIndex++;
if (selectorIndex > l.selectorCount) {
break;
}
bytes4 selector = bytes4(slug << (slugSelectorIndex << 5));
if (facet == address(bytes20(l.selectorInfo[selector]))) {
selectors[numSelectors] = selector;
numSelectors++;
}
}
}
// set the number of selectors in the array
assembly {
mstore(selectors, numSelectors)
}
}
/**
* @notice get addresses of all facets used by diamond
* @return addresses array of facet addresses
*/
function _facetAddresses()
internal
view
returns (address[] memory addresses)
{
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
addresses = new address[](l.selectorCount);
uint256 numFacets;
uint256 selectorIndex;
for (uint256 slugIndex; selectorIndex < l.selectorCount; slugIndex++) {
bytes32 slug = l.selectorSlugs[slugIndex];
for (
uint256 slugSelectorIndex;
slugSelectorIndex < 8;
slugSelectorIndex++
) {
selectorIndex++;
if (selectorIndex > l.selectorCount) {
break;
}
bytes4 selector = bytes4(slug << (slugSelectorIndex << 5));
address facet = address(bytes20(l.selectorInfo[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)
}
}
/**
* @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
) internal view returns (address facet) {
facet = address(
bytes20(DiamondBaseStorage.layout().selectorInfo[selector])
);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { IERC2535DiamondLoupe } from '../../../interfaces/IERC2535DiamondLoupe.sol';
import { IDiamondReadableInternal } from './IDiamondReadableInternal.sol';
/**
* @title Diamond proxy introspection interface
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
interface IDiamondReadable is IERC2535DiamondLoupe, IDiamondReadableInternal {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
*/
library DiamondBaseStorage {
struct Layout {
// function selector => (facet address, selector slug position)
mapping(bytes4 => bytes32) selectorInfo;
// total number of selectors registered
uint16 selectorCount;
// array of 32-byte slugs with 8 selectors each
mapping(uint256 => bytes32) selectorSlugs;
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.20;
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.20;
import { IProxy } from '../../IProxy.sol';
interface IDiamondBase is IProxy {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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.20;
import { IOwnable } from './IOwnable.sol';
import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol';
interface ISafeOwnable is ISafeOwnableInternal, IOwnable {
/**
* @notice get the nominated owner who has permission to call acceptOwnership
*/
function nomineeOwner() external view returns (address);
/**
* @notice accept transfer of contract ownership
*/
function acceptOwnership() external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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.20;
import { IERC165BaseInternal } from './IERC165BaseInternal.sol';
import { ERC165BaseStorage } from './ERC165BaseStorage.sol';
/**
* @title ERC165 implementation
*/
abstract contract ERC165BaseInternal is IERC165BaseInternal {
/**
* @notice indicates whether an interface is already supported based on the interfaceId
* @param interfaceId id of interface to check
* @return bool indicating whether interface is supported
*/
function _supportsInterface(
bytes4 interfaceId
) internal view virtual returns (bool) {
return ERC165BaseStorage.layout().supportedInterfaces[interfaceId];
}
/**
* @notice sets status of interface support
* @param interfaceId id of interface to set status for
* @param status boolean indicating whether interface will be set as supported
*/
function _setSupportsInterface(
bytes4 interfaceId,
bool status
) internal virtual {
if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId();
ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { IERC165 } from '../../../interfaces/IERC165.sol';
import { IERC165BaseInternal } from './IERC165BaseInternal.sol';
interface IERC165Base is IERC165, IERC165BaseInternal {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title ERC2535 read interface for internal functions
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
interface IERC2535DiamondLoupeInternal {
struct Facet {
address target;
bytes4[] selectors;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title ERC2535 write interface for internal functions
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
interface IERC2535DiamondCutInternal {
enum FacetCutAction {
ADD,
REPLACE,
REMOVE
}
struct FacetCut {
address target;
FacetCutAction action;
bytes4[] selectors;
}
event DiamondCut(FacetCut[] facetCuts, address target, bytes data);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @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.20;
/**
* @title ERC165 interface registration interface
*/
interface IERC165Internal {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { SafeOwnableStorage } from './SafeOwnableStorage.sol';
abstract contract SafeOwnableInternal is ISafeOwnableInternal, OwnableInternal {
modifier onlyNomineeOwner() {
if (msg.sender != _nomineeOwner())
revert SafeOwnable__NotNomineeOwner();
_;
}
/**
* @notice get the nominated owner who has permission to call acceptOwnership
*/
function _nomineeOwner() internal view virtual returns (address) {
return SafeOwnableStorage.layout().nomineeOwner;
}
/**
* @notice accept transfer of contract ownership
*/
function _acceptOwnership() internal virtual {
_setOwner(msg.sender);
delete SafeOwnableStorage.layout().nomineeOwner;
}
/**
* @notice grant permission to given address to claim contract ownership
*/
function _transferOwnership(address account) internal virtual override {
_setNomineeOwner(account);
}
/**
* @notice set nominee owner
*/
function _setNomineeOwner(address account) internal virtual {
SafeOwnableStorage.layout().nomineeOwner = account;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { IERC173 } from '../../interfaces/IERC173.sol';
import { IOwnableInternal } from './IOwnableInternal.sol';
interface IOwnable is IOwnableInternal, IERC173 {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { IERC2535DiamondCutInternal } from '../../../interfaces/IERC2535DiamondCutInternal.sol';
interface IDiamondWritableInternal is IERC2535DiamondCutInternal {
error DiamondWritable__InvalidInitializationParameters();
error DiamondWritable__RemoveTargetNotZeroAddress();
error DiamondWritable__ReplaceTargetIsIdentical();
error DiamondWritable__SelectorAlreadyAdded();
error DiamondWritable__SelectorIsImmutable();
error DiamondWritable__SelectorNotFound();
error DiamondWritable__SelectorNotSpecified();
error DiamondWritable__TargetHasNoCode();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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.20;
import { IERC2535DiamondLoupeInternal } from '../../../interfaces/IERC2535DiamondLoupeInternal.sol';
/**
* @title Diamond proxy introspection interface needed for internal functions
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
interface IDiamondReadableInternal is IERC2535DiamondLoupeInternal {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IProxy {
error Proxy__ImplementationIsNotContract();
fallback() external payable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { IERC165Internal } from '../../../interfaces/IERC165Internal.sol';
interface IERC165BaseInternal is IERC165Internal {
error ERC165Base__InvalidInterfaceId();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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.20;
import { IOwnableInternal } from './IOwnableInternal.sol';
interface ISafeOwnableInternal is IOwnableInternal {
error SafeOwnable__NotNomineeOwner();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
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.20;
import { IERC173Internal } from '../../interfaces/IERC173Internal.sol';
interface IOwnableInternal is IERC173Internal {
error Ownable__NotOwner();
error Ownable__NotTransitiveOwner();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title utility functions for uint256 operations
* @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
*/
library UintUtils {
error UintUtils__InsufficientPadding();
error UintUtils__InvalidBase();
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);
}
/**
* @notice output the string representation of a number in a given radix
* @dev radix must be between 2 and 36 (inclusive)
* @param value number to format as string
* @param radix numerical base to use
* @return output formatted string
*/
function toString(
uint256 value,
uint256 radix
) internal pure returns (string memory output) {
// this check is repeated in the internal call to #toString(uint256,uint256,uint256)
// but is still needed here to avoid zero division (radix = 0) or infinite loop (radix = 1)
if (radix < 2) {
revert UintUtils__InvalidBase();
}
uint256 length;
uint256 temp = value;
do {
unchecked {
length++;
}
temp /= radix;
} while (temp != 0);
output = toString(value, radix, length);
}
/**
* @notice output the string representation of a number in a given radix and padded to given length
* @dev radix must be between 2 and 36 (inclusive)
* @param value number to format as string
* @param radix numerical base to use
* @param length size to which output should be zero padded
* @return output formatted string
*/
function toString(
uint256 value,
uint256 radix,
uint256 length
) internal pure returns (string memory output) {
if (radix < 2 || radix > 36) {
revert UintUtils__InvalidBase();
}
bytes memory buffer = new bytes(length);
while (length != 0) {
unchecked {
length--;
}
uint256 char = value % radix;
if (char < 10) {
// for numeral characters, shift 48 places through ASCII character set
// 48 can be added using bitwise-or because its binary is 00110000
char |= 48;
} else {
// for alphabetical characters, shift 87 places through ASCII character set
unchecked {
char += 87;
}
}
buffer[length] = bytes1(uint8(char));
value /= radix;
}
if (value != 0) revert UintUtils__InsufficientPadding();
output = string(buffer);
}
/**
* @notice output the 0b-prefixed binary string representation of a number
* @param value number to format as string
* @return output formatted string
*/
function toBinString(
uint256 value
) internal pure returns (string memory output) {
uint256 length;
uint256 temp = value;
do {
unchecked {
length++;
}
temp >>= 1;
} while (temp != 0);
output = toBinString(value, length);
}
/**
* @notice output the 0b-prefixed binary string representation of a number padded to given length
* @param value number to format as string
* @param length size to which output should be zero padded (not including prefix)
* @return output formatted string
*/
function toBinString(
uint256 value,
uint256 length
) internal pure returns (string memory output) {
// add two to length for the leading "0b"
length += 2;
bytes memory buffer = new bytes(length);
buffer[0] = '0';
buffer[1] = 'b';
while (length > 2) {
unchecked {
length--;
}
buffer[length] = HEX_SYMBOLS[value & 1];
value >>= 1;
}
if (value != 0) revert UintUtils__InsufficientPadding();
output = string(buffer);
}
/**
* @notice output the 0o-prefixed octal string representation of a number
* @param value number to format as string
* @return output formatted string
*/
function toOctString(
uint256 value
) internal pure returns (string memory output) {
uint256 length;
uint256 temp = value;
do {
unchecked {
length++;
}
temp >>= 3;
} while (temp != 0);
output = toOctString(value, length);
}
/**
* @notice output the 0o-prefixed octal string representation of a number padded to given length
* @param value number to format as string
* @param length size to which output should be zero padded (not including prefix)
* @return output formatted string
*/
function toOctString(
uint256 value,
uint256 length
) internal pure returns (string memory output) {
// add two to length for the leading "0o"
length += 2;
bytes memory buffer = new bytes(length);
buffer[0] = '0';
buffer[1] = 'o';
while (length > 2) {
unchecked {
length--;
}
buffer[length] = HEX_SYMBOLS[value & 7];
value >>= 3;
}
if (value != 0) revert UintUtils__InsufficientPadding();
output = string(buffer);
}
/**
* @notice output the decimal string representation of a number
* @param value number to format as string
* @return output formatted string
*/
function toDecString(
uint256 value
) internal pure returns (string memory output) {
output = toString(value, 10);
}
/**
* @notice output the decimal string representation of a number padded to given length
* @param value number to format as string
* @param length size to which output should be zero padded
* @return output formatted string
*/
function toDecString(
uint256 value,
uint256 length
) internal pure returns (string memory output) {
output = toString(value, 10, length);
}
/**
* @notice output the 0x-prefixed hexadecimal string representation of a number
* @dev calculated string length will always be even to prevent splitting of bytes
* @param value number to format as string
* @return output formatted string
*/
function toHexString(
uint256 value
) internal pure returns (string memory output) {
uint256 length;
uint256 temp = value;
do {
unchecked {
length++;
}
temp >>= 8;
} while (temp != 0);
output = toHexString(value, length);
}
/**
* @notice output the 0x-prefixed hexadecimal string representation of a number padded to given length
* @dev calculated string length will always be even to prevent splitting of bytes
* @param value number to format as string
* @param length size (in bytes) to which output should be zero padded (not including prefix)
* @return output formatted string
*/
function toHexString(
uint256 value,
uint256 length
) internal pure returns (string memory output) {
// convert byte length to character length and add two to length for the leading "0x"
unchecked {
length = (length << 1) + 2;
}
bytes memory buffer = new bytes(length);
buffer[0] = '0';
buffer[1] = 'x';
while (length > 2) {
unchecked {
length--;
}
buffer[length] = HEX_SYMBOLS[value & 15];
value >>= 4;
}
if (value != 0) revert UintUtils__InsufficientPadding();
output = string(buffer);
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}Contract ABI
API[{"inputs":[{"internalType":"address","name":"_utilityCoDiamond","type":"address"}],"stateMutability":"payable","type":"constructor"},{"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 IERC2535DiamondCutInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IERC2535DiamondCutInternal.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 IERC2535DiamondCutInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IERC2535DiamondCutInternal.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 IERC2535DiamondLoupeInternal.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":"getUtilityCoDiamond","outputs":[{"internalType":"address","name":"","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
60806040526040516129cf3803806129cf83398101604081905261002291610cde565b60408051600c8082526101a082019092525f9160208201610180803683370190505090505f632c40805960e01b828261005a81610d0b565b93508151811061006c5761006c610d2f565b6001600160e01b031990921660209283029190910190910152639142376560e01b828261009881610d0b565b9350815181106100aa576100aa610d2f565b6001600160e01b0319909216602092830291909101909101526100d5632f40adcf60e21b60016104eb565b6307e4c70760e21b82826100e881610d0b565b9350815181106100fa576100fa610d2f565b6001600160e01b0319909216602092830291909101909101526101256307e4c70760e21b60016104eb565b637a0ed62760e01b828261013881610d0b565b93508151811061014a5761014a610d2f565b6001600160e01b0319909216602092830291909101909101526356fe50af60e11b828261017681610d0b565b93508151811061018857610188610d2f565b6001600160e01b0319909216602092830291909101909101526314bbdacb60e21b82826101b481610d0b565b9350815181106101c6576101c6610d2f565b6001600160e01b0319909216602092830291909101909101526366ffd66360e11b82826101f281610d0b565b93508151811061020457610204610d2f565b6001600160e01b03199092166020928302919091019091015261022f6348e2b09360e01b60016104eb565b6301ffc9a760e01b828261024281610d0b565b93508151811061025457610254610d2f565b6001600160e01b03199092166020928302919091019091015261027f6301ffc9a760e01b60016104eb565b638da5cb5b60e01b828261029281610d0b565b9350815181106102a4576102a4610d2f565b6001600160e01b03199092166020928302919091019091015263455a8a8560e11b82826102d081610d0b565b9350815181106102e2576102e2610d2f565b6001600160e01b03199092166020928302919091019091015263f2fde38b60e01b828261030e81610d0b565b93508151811061032057610320610d2f565b6001600160e01b0319909216602092830291909101909101526379ba509760e01b828261034c81610d0b565b93508151811061035e5761035e610d2f565b6001600160e01b0319909216602092830291909101909101526103896307f5828d60e41b60016104eb565b6040805160018082528183019092525f91816020015b60408051606080820183525f80835260208301529181019190915281526020019060019003908161039f579050506040805160608101909152308152909150602081015f815260200184815250815f815181106103fe576103fe610d2f565b6020026020010181905250610428815f60405180602001604052805f81525061056060201b60201c565b61043133610738565b5050506001600160a01b0381166104a75760405162461bcd60e51b815260206004820152603060248201527f52454e534e43453a207574696c697479436f4469616d6f6e642063616e6e6f7460448201526f206265207a65726f206164647265737360801b606482015260840160405180910390fd5b7f6486efc20ba6a832b9c44349fda696793ddcbb7c2ced28cf0d5d4e441f5b1fee80546001600160a01b0319166001600160a01b0392909216919091179055610ea5565b6001600160e01b031980831690036105165760405163b0a19dd560e01b815260040160405180910390fd5b6001600160e01b0319919091165f9081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d860205260409020805460ff1916911515919091179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94547f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff81169081905f90600716156105cd5750600381901c5f9081526002840160205260409020545b5f5b87518110156106ad575f8882815181106105eb576105eb610d2f565b602002602001015190505f816020015190508160400151515f036106225760405163eb6c3aeb60e01b815260040160405180910390fd5b5f81600281111561063557610635610d43565b0361065057610646878387876107b1565b90955093506106a3565b600181600281111561066457610664610d43565b0361067857610673878361090c565b6106a3565b600281600281111561068c5761068c610d43565b036106a35761069d87838787610a4d565b90955093505b50506001016105cf565b508282146106c95760018401805461ffff191661ffff84161790555b60078216156106ea57600382901c5f90815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161071d93929190610d85565b60405180910390a161072f8686610c00565b50505050505050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a380546001600160a01b0319166001600160a01b0392909216919091179055565b82515f9081906001600160a01b03163b156107f7578451306001600160a01b03909116036107f25760405163e983573160e01b815260040160405180910390fd5b610821565b84516001600160a01b0316301461082157604051633ddc5cab60e21b815260040160405180910390fd5b5f5b8560400151518110156108ff575f8660400151828151811061084757610847610d2f565b6020908102919091018101516001600160e01b031981165f908152918a90526040909120549091501561088d57604051634923a77160e11b815260040160405180910390fd5b86516001600160e01b03198281165f81815260208c90526040902060609390931b6001600160601b0319168917909255600588901b60e01691821c90821c1987161795508060e0036108f157600387901c5f90815260028a01602052604090208690555b505060019485019401610823565b5092959194509092505050565b80516001600160a01b03163b61093557604051633ddc5cab60e21b815260040160405180910390fd5b5f5b816040015151811015610a48575f8260400151828151811061095b5761095b610d2f565b6020908102919091018101516001600160e01b031981165f90815291869052604090912054909150606081901c806109a6576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036109cf5760405163e983573160e01b815260040160405180910390fd5b845f01516001600160a01b0316816001600160a01b031603610a04576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b0319929092165f90815260208690526040902060609290921b6001600160601b0319166001600160601b0391909116179055600101610937565b505050565b82515f9081906001600160a01b031615610a7a57604051633ab3490960e21b815260040160405180910390fd5b5f5b8560400151518110156108ff578480600190039550505f86604001518281518110610aa957610aa9610d2f565b6020908102919091018101516001600160e01b031981165f908152918a90526040822080549290559150606081901c610af5576040516337e25a9760e11b815260040160405180910390fd5b30606082901c03610b195760405163e983573160e01b815260040160405180910390fd5b86600716600703610b3c57600387901c5f90815260028a01602052604090205495505b60e0600588901b1686901b6001600160e01b031980821690841614610b8d576001600160e01b031981165f90815260208b90526040902080546001600160601b0319166001600160601b0384161790555b600382811c611fff1690600584901b60e016908a901c8203610bc5576001600160e01b031980821c198a16908416821c179850610bef565b5f82815260028d016020526040902080546001600160e01b0319858116841c90841c199091161790555b505060019093019250610a7c915050565b8051156001600160a01b0383161514610c2c576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615610cda576001600160a01b0382163014610c73576001600160a01b0382163b610c7357604051633ddc5cab60e21b815260040160405180910390fd5b5f826001600160a01b031682604051610c8c9190610e8f565b5f60405180830381855af49150503d805f8114610cc4576040519150601f19603f3d011682016040523d82523d5f602084013e610cc9565b606091505b5050905080610a48573d5f803e3d5ffd5b5050565b5f60208284031215610cee575f80fd5b81516001600160a01b0381168114610d04575f80fd5b9392505050565b5f60018201610d2857634e487b7160e01b5f52601160045260245ffd5b5060010190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f606082016060835280865180835260808501915060808160051b8601019250602088015f5b82811015610e6057868503607f19018452815180516001600160a01b031686526020810151606087019060038110610df157634e487b7160e01b5f52602160045260245ffd5b8060208901525060408201519150606060408801528082518083526080890191506020840193505f92505b80831015610e485783516001600160e01b03191682526020938401936001939093019290910190610e1c565b50965050506020938401939190910190600101610dab565b5050506001600160a01b0386166020850152508281036040840152610e858185610d57565b9695505050505050565b5f82518060208501845e5f920191825250919050565b611b1d80610eb25f395ff3fe6080604052600436106100c5575f3560e01c80638ab5150a1161007e578063adfca15e11610058578063adfca15e1461023b578063b4620c7c14610267578063cdffacc61461027b578063f2fde38b1461029a576100cc565b80638ab5150a146101f45780638da5cb5b14610208578063914237651461021c576100cc565b806301ffc9a71461011f5780631f931c1c146101535780632c4080591461017257806352ef6b2c1461019e57806379ba5097146101bf5780637a0ed627146101d3576100cc565b366100cc57005b5f6100d56102b9565b90506001600160a01b0381163b6100ff576040516321f27f0d60e21b815260040160405180910390fd5b365f80375f80365f845af43d5f803e808015610119573d5ff35b3d5ffd5b005b34801561012a575f80fd5b5061013e6101393660046114e2565b6102c7565b60405190151581526020015b60405180910390f35b34801561015e575f80fd5b5061011d61016d36600461155c565b610309565b34801561017d575f80fd5b50610186610392565b6040516001600160a01b03909116815260200161014a565b3480156101a9575f80fd5b506101b26103c4565b60405161014a9190611609565b3480156101ca575f80fd5b5061011d6103ce565b3480156101de575f80fd5b506101e7610411565b60405161014a9190611698565b3480156101ff575f80fd5b5061018661041b565b348015610213575f80fd5b50610186610424565b348015610227575f80fd5b5061011d61023636600461171b565b61042d565b348015610246575f80fd5b5061025a61025536600461171b565b6104a6565b60405161014a9190611734565b348015610272575f80fd5b506101866104b1565b348015610286575f80fd5b506101866102953660046114e2565b6104e3565b3480156102a5575f80fd5b5061011d6102b436600461171b565b610510565b5f6102c2610552565b905090565b6001600160e01b031981165f9081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052604081205460ff165b92915050565b6103116105b1565b6001600160a01b0316336001600160a01b03161461034257604051632f7a8ee160e01b815260040160405180910390fd5b61038b61034f8587611803565b8484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506105d892505050565b5050505050565b5f6102c27f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b60606102c261078a565b6103d6610921565b6001600160a01b0316336001600160a01b0316146104075760405163efd1052d60e01b815260040160405180910390fd5b61040f610948565b565b60606102c2610982565b5f6102c2610921565b5f6102c26105b1565b6104356105b1565b6001600160a01b0316336001600160a01b03161461046657604051632f7a8ee160e01b815260040160405180910390fd5b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680546001600160a01b0319166001600160a01b03831617905550565b50565b606061030382610d89565b5f7f6486efc20ba6a832b9c44349fda696793ddcbb7c2ced28cf0d5d4e441f5b1fee5b546001600160a01b0316919050565b6001600160e01b031981165f9081525f80516020611ac8833981519152602052604081205460601c610303565b6105186105b1565b6001600160a01b0316336001600160a01b03161461054957604051632f7a8ee160e01b815260040160405180910390fd5b6104a381610ed3565b5f80356001600160e01b03191681525f80516020611ac8833981519152602052604090205460601c806105ae57507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b90565b5f7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804606104d4565b5f80516020611aa8833981519152545f80516020611ac88339815191529061ffff81169081905f906007161561061f5750600381901c5f9081526002840160205260409020545b5f5b87518110156106ff575f88828151811061063d5761063d611923565b602002602001015190505f816020015190508160400151515f036106745760405163eb6c3aeb60e01b815260040160405180910390fd5b5f81600281111561068757610687611937565b036106a25761069887838787610f16565b90955093506106f5565b60018160028111156106b6576106b6611937565b036106ca576106c58783611071565b6106f5565b60028160028111156106de576106de611937565b036106f5576106ef878387876111b7565b90955093505b5050600101610621565b5082821461071b5760018401805461ffff191661ffff84161790555b600782161561073c57600382901c5f90815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161076f93929190611979565b60405180910390a1610781868661136f565b50505050505050565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b038111156107c6576107c6611775565b6040519080825280602002602001820160405280156107ef578160200160208202803683370190505b5091505f805f5b600184015461ffff16821015610919575f818152600285016020526040812054905b6008811015610904578361082b81611a5b565b600188015490955061ffff168511905061090457600581901b82901b6001600160e01b031981165f9081526020889052604081205460601c90805b888110156108b1578a818151811061088057610880611923565b60200260200101516001600160a01b0316836001600160a01b0316036108a957600191506108b1565b600101610866565b5080156108c0575050506108fc565b818a89815181106108d3576108d3611923565b6001600160a01b0390921660209283029190910190910152876108f581611a5b565b9850505050505b600101610818565b5050808061091190611a5b565b9150506107f6565b505082525090565b5f7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178906104d4565b6109513361144d565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319169055565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b038111156109be576109be611775565b604051908082528060200260200182016040528015610a0357816020015b604080518082019091525f8152606060208201528152602001906001900390816109dc5790505b5060018201549092505f9061ffff166001600160401b03811115610a2957610a29611775565b604051908082528060200260200182016040528015610a52578160200160208202803683370190505b5090505f805f5b600185015461ffff16821015610d25575f818152600286016020526040812054905b6008811015610d105783610a8e81611a5b565b600189015490955061ffff1685119050610d1057600581901b82901b6001600160e01b031981165f9081526020899052604081205460601c90805b88811015610bda57826001600160a01b03168c8281518110610aed57610aed611923565b60200260200101515f01516001600160a01b031603610bd257838c8281518110610b1957610b19611923565b6020026020010151602001518b8381518110610b3757610b37611923565b602002602001015160ff1681518110610b5257610b52611923565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a8281518110610b8857610b88611923565b602002602001015160ff1610610b9c575f80fd5b898181518110610bae57610bae611923565b602002602001018051809190610bc390611a73565b60ff1690525060019150610bda565b600101610ac9565b508015610be957505050610d08565b818b8981518110610bfc57610bfc611923565b60209081029190910101516001600160a01b03909116905260018a015461ffff166001600160401b03811115610c3457610c34611775565b604051908082528060200260200182016040528015610c5d578160200160208202803683370190505b508b8981518110610c7057610c70611923565b602002602001015160200181905250828b8981518110610c9257610c92611923565b6020026020010151602001515f81518110610caf57610caf611923565b60200260200101906001600160e01b03191690816001600160e01b031916815250506001898981518110610ce557610ce5611923565b60ff9092166020928302919091019091015287610d0181611a5b565b9850505050505b600101610a7b565b50508080610d1d90611a5b565b915050610a59565b505f5b82811015610d7e575f848281518110610d4357610d43611923565b602002602001015160ff1690505f878381518110610d6357610d63611923565b60209081029190910181015101519190915250600101610d28565b508185525050505090565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b03811115610dc557610dc5611775565b604051908082528060200260200182016040528015610dee578160200160208202803683370190505b5091505f805f5b600184015461ffff16821015610ec9575f818152600285016020526040812054905b6008811015610eb45783610e2a81611a5b565b600188015490955061ffff1685119050610eb457600581901b82901b6001600160e01b031981165f9081526020889052604090205460601c6001600160a01b038a1603610eab5780888781518110610e8457610e84611923565b6001600160e01b03199092166020928302919091019091015285610ea781611a5b565b9650505b50600101610e17565b50508080610ec190611a5b565b915050610df5565b5050825250919050565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319166001600160a01b0383161790556104a381818181565b82515f9081906001600160a01b03163b15610f5c578451306001600160a01b0390911603610f575760405163e983573160e01b815260040160405180910390fd5b610f86565b84516001600160a01b03163014610f8657604051633ddc5cab60e21b815260040160405180910390fd5b5f5b856040015151811015611064575f86604001518281518110610fac57610fac611923565b6020908102919091018101516001600160e01b031981165f908152918a905260409091205490915015610ff257604051634923a77160e11b815260040160405180910390fd5b86516001600160e01b03198281165f81815260208c90526040902060609390931b6001600160601b0319168917909255600588901b60e01691821c90821c1987161795508060e00361105657600387901c5f90815260028a01602052604090208690555b505060019485019401610f88565b5092959194509092505050565b80516001600160a01b03163b61109a57604051633ddc5cab60e21b815260040160405180910390fd5b5f5b8160400151518110156111b2575f826040015182815181106110c0576110c0611923565b6020908102919091018101516001600160e01b031981165f90815291869052604090912054909150606081901c8061110b576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036111345760405163e983573160e01b815260040160405180910390fd5b845f01516001600160a01b0316816001600160a01b031603611169576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b0319929092165f90815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff9190911617905560010161109c565b505050565b82515f9081906001600160a01b0316156111e457604051633ab3490960e21b815260040160405180910390fd5b5f5b856040015151811015611064578480600190039550505f8660400151828151811061121357611213611923565b6020908102919091018101516001600160e01b031981165f908152918a90526040822080549290559150606081901c61125f576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036112835760405163e983573160e01b815260040160405180910390fd5b866007166007036112a657600387901c5f90815260028a01602052604090205495505b60e0600588901b1686901b6001600160e01b0319808216908416146112fc576001600160e01b031981165f90815260208b90526040902080546001600160601b0319166bffffffffffffffffffffffff84161790555b600382811c611fff1690600584901b60e016908a901c8203611334576001600160e01b031980821c198a16908416821c17985061135e565b5f82815260028d016020526040902080546001600160e01b0319858116841c90841c199091161790555b5050600190930192506111e6915050565b8051156001600160a01b038316151461139b576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611449576001600160a01b03821630146113e2576001600160a01b0382163b6113e257604051633ddc5cab60e21b815260040160405180910390fd5b5f826001600160a01b0316826040516113fb9190611a91565b5f60405180830381855af49150503d805f8114611433576040519150601f19603f3d011682016040523d82523d5f602084013e611438565b606091505b50509050806111b2573d5f803e3d5ffd5b5050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a380546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160e01b0319811681146114dd575f80fd5b919050565b5f602082840312156114f2575f80fd5b6114fb826114c6565b9392505050565b80356001600160a01b03811681146114dd575f80fd5b5f8083601f840112611528575f80fd5b5081356001600160401b0381111561153e575f80fd5b602083019150836020828501011115611555575f80fd5b9250929050565b5f805f805f60608688031215611570575f80fd5b85356001600160401b03811115611585575f80fd5b8601601f81018813611595575f80fd5b80356001600160401b038111156115aa575f80fd5b8860208260051b84010111156115be575f80fd5b6020918201965094506115d2908701611502565b925060408601356001600160401b038111156115ec575f80fd5b6115f888828901611518565b969995985093965092949392505050565b602080825282518282018190525f918401906040840190835b818110156116495783516001600160a01b0316835260209384019390920191600101611622565b509095945050505050565b5f8151808452602084019350602083015f5b8281101561168e5781516001600160e01b031916865260209586019590910190600101611666565b5093949350505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561170f57868503603f19018452815180516001600160a01b031686526020908101516040918701829052906116f990870182611654565b95505060209384019391909101906001016116be565b50929695505050505050565b5f6020828403121561172b575f80fd5b6114fb82611502565b602080825282518282018190525f918401906040840190835b818110156116495783516001600160e01b03191683526020938401939092019160010161174d565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b03811182821017156117ab576117ab611775565b60405290565b604051601f8201601f191681016001600160401b03811182821017156117d9576117d9611775565b604052919050565b5f6001600160401b038211156117f9576117f9611775565b5060051b60200190565b5f611815611810846117e1565b6117b1565b8381526020810190600585901b840136811115611830575f80fd5b845b818110156116495780356001600160401b0381111561184f575f80fd5b86016060368290031215611861575f80fd5b611869611789565b61187282611502565b8152602082013560038110611885575f80fd5b602082015260408201356001600160401b038111156118a2575f80fd5b919091019036601f8301126118b5575f80fd5b81356118c3611810826117e1565b8082825260208201915060208360051b8601019250368311156118e4575f80fd5b6020850194505b8285101561190d576118fc856114c6565b8252602094850194909101906118eb565b6040840152505085525060209384019301611832565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f606082016060835280865180835260808501915060808160051b8601019250602088015f5b82811015611a1857868503607f19018452815180516001600160a01b031686526020810151600381106119e057634e487b7160e01b5f52602160045260245ffd5b806020880152506040810151905060606040870152611a026060870182611654565b955050602093840193919091019060010161199f565b5050506001600160a01b0386166020850152508281036040840152611a3d818561194b565b9695505050505050565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611a6c57611a6c611a47565b5060010190565b5f60ff821660ff8103611a8857611a88611a47565b60010192915050565b5f82518060208501845e5f92019182525091905056fe177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93a2646970667358221220ec7497f0cc4548b69779ac21bce4fc6b7a821460ef2d66d8acf484ed346f95a964736f6c634300081a003300000000000000000000000038e361604a0bee7bcddaff4a50d7f4bfa5e5ca6b
Deployed Bytecode
0x6080604052600436106100c5575f3560e01c80638ab5150a1161007e578063adfca15e11610058578063adfca15e1461023b578063b4620c7c14610267578063cdffacc61461027b578063f2fde38b1461029a576100cc565b80638ab5150a146101f45780638da5cb5b14610208578063914237651461021c576100cc565b806301ffc9a71461011f5780631f931c1c146101535780632c4080591461017257806352ef6b2c1461019e57806379ba5097146101bf5780637a0ed627146101d3576100cc565b366100cc57005b5f6100d56102b9565b90506001600160a01b0381163b6100ff576040516321f27f0d60e21b815260040160405180910390fd5b365f80375f80365f845af43d5f803e808015610119573d5ff35b3d5ffd5b005b34801561012a575f80fd5b5061013e6101393660046114e2565b6102c7565b60405190151581526020015b60405180910390f35b34801561015e575f80fd5b5061011d61016d36600461155c565b610309565b34801561017d575f80fd5b50610186610392565b6040516001600160a01b03909116815260200161014a565b3480156101a9575f80fd5b506101b26103c4565b60405161014a9190611609565b3480156101ca575f80fd5b5061011d6103ce565b3480156101de575f80fd5b506101e7610411565b60405161014a9190611698565b3480156101ff575f80fd5b5061018661041b565b348015610213575f80fd5b50610186610424565b348015610227575f80fd5b5061011d61023636600461171b565b61042d565b348015610246575f80fd5b5061025a61025536600461171b565b6104a6565b60405161014a9190611734565b348015610272575f80fd5b506101866104b1565b348015610286575f80fd5b506101866102953660046114e2565b6104e3565b3480156102a5575f80fd5b5061011d6102b436600461171b565b610510565b5f6102c2610552565b905090565b6001600160e01b031981165f9081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052604081205460ff165b92915050565b6103116105b1565b6001600160a01b0316336001600160a01b03161461034257604051632f7a8ee160e01b815260040160405180910390fd5b61038b61034f8587611803565b8484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506105d892505050565b5050505050565b5f6102c27f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b60606102c261078a565b6103d6610921565b6001600160a01b0316336001600160a01b0316146104075760405163efd1052d60e01b815260040160405180910390fd5b61040f610948565b565b60606102c2610982565b5f6102c2610921565b5f6102c26105b1565b6104356105b1565b6001600160a01b0316336001600160a01b03161461046657604051632f7a8ee160e01b815260040160405180910390fd5b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680546001600160a01b0319166001600160a01b03831617905550565b50565b606061030382610d89565b5f7f6486efc20ba6a832b9c44349fda696793ddcbb7c2ced28cf0d5d4e441f5b1fee5b546001600160a01b0316919050565b6001600160e01b031981165f9081525f80516020611ac8833981519152602052604081205460601c610303565b6105186105b1565b6001600160a01b0316336001600160a01b03161461054957604051632f7a8ee160e01b815260040160405180910390fd5b6104a381610ed3565b5f80356001600160e01b03191681525f80516020611ac8833981519152602052604090205460601c806105ae57507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b90565b5f7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804606104d4565b5f80516020611aa8833981519152545f80516020611ac88339815191529061ffff81169081905f906007161561061f5750600381901c5f9081526002840160205260409020545b5f5b87518110156106ff575f88828151811061063d5761063d611923565b602002602001015190505f816020015190508160400151515f036106745760405163eb6c3aeb60e01b815260040160405180910390fd5b5f81600281111561068757610687611937565b036106a25761069887838787610f16565b90955093506106f5565b60018160028111156106b6576106b6611937565b036106ca576106c58783611071565b6106f5565b60028160028111156106de576106de611937565b036106f5576106ef878387876111b7565b90955093505b5050600101610621565b5082821461071b5760018401805461ffff191661ffff84161790555b600782161561073c57600382901c5f90815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161076f93929190611979565b60405180910390a1610781868661136f565b50505050505050565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b038111156107c6576107c6611775565b6040519080825280602002602001820160405280156107ef578160200160208202803683370190505b5091505f805f5b600184015461ffff16821015610919575f818152600285016020526040812054905b6008811015610904578361082b81611a5b565b600188015490955061ffff168511905061090457600581901b82901b6001600160e01b031981165f9081526020889052604081205460601c90805b888110156108b1578a818151811061088057610880611923565b60200260200101516001600160a01b0316836001600160a01b0316036108a957600191506108b1565b600101610866565b5080156108c0575050506108fc565b818a89815181106108d3576108d3611923565b6001600160a01b0390921660209283029190910190910152876108f581611a5b565b9850505050505b600101610818565b5050808061091190611a5b565b9150506107f6565b505082525090565b5f7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178906104d4565b6109513361144d565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319169055565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b038111156109be576109be611775565b604051908082528060200260200182016040528015610a0357816020015b604080518082019091525f8152606060208201528152602001906001900390816109dc5790505b5060018201549092505f9061ffff166001600160401b03811115610a2957610a29611775565b604051908082528060200260200182016040528015610a52578160200160208202803683370190505b5090505f805f5b600185015461ffff16821015610d25575f818152600286016020526040812054905b6008811015610d105783610a8e81611a5b565b600189015490955061ffff1685119050610d1057600581901b82901b6001600160e01b031981165f9081526020899052604081205460601c90805b88811015610bda57826001600160a01b03168c8281518110610aed57610aed611923565b60200260200101515f01516001600160a01b031603610bd257838c8281518110610b1957610b19611923565b6020026020010151602001518b8381518110610b3757610b37611923565b602002602001015160ff1681518110610b5257610b52611923565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a8281518110610b8857610b88611923565b602002602001015160ff1610610b9c575f80fd5b898181518110610bae57610bae611923565b602002602001018051809190610bc390611a73565b60ff1690525060019150610bda565b600101610ac9565b508015610be957505050610d08565b818b8981518110610bfc57610bfc611923565b60209081029190910101516001600160a01b03909116905260018a015461ffff166001600160401b03811115610c3457610c34611775565b604051908082528060200260200182016040528015610c5d578160200160208202803683370190505b508b8981518110610c7057610c70611923565b602002602001015160200181905250828b8981518110610c9257610c92611923565b6020026020010151602001515f81518110610caf57610caf611923565b60200260200101906001600160e01b03191690816001600160e01b031916815250506001898981518110610ce557610ce5611923565b60ff9092166020928302919091019091015287610d0181611a5b565b9850505050505b600101610a7b565b50508080610d1d90611a5b565b915050610a59565b505f5b82811015610d7e575f848281518110610d4357610d43611923565b602002602001015160ff1690505f878381518110610d6357610d63611923565b60209081029190910181015101519190915250600101610d28565b508185525050505090565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b03811115610dc557610dc5611775565b604051908082528060200260200182016040528015610dee578160200160208202803683370190505b5091505f805f5b600184015461ffff16821015610ec9575f818152600285016020526040812054905b6008811015610eb45783610e2a81611a5b565b600188015490955061ffff1685119050610eb457600581901b82901b6001600160e01b031981165f9081526020889052604090205460601c6001600160a01b038a1603610eab5780888781518110610e8457610e84611923565b6001600160e01b03199092166020928302919091019091015285610ea781611a5b565b9650505b50600101610e17565b50508080610ec190611a5b565b915050610df5565b5050825250919050565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319166001600160a01b0383161790556104a381818181565b82515f9081906001600160a01b03163b15610f5c578451306001600160a01b0390911603610f575760405163e983573160e01b815260040160405180910390fd5b610f86565b84516001600160a01b03163014610f8657604051633ddc5cab60e21b815260040160405180910390fd5b5f5b856040015151811015611064575f86604001518281518110610fac57610fac611923565b6020908102919091018101516001600160e01b031981165f908152918a905260409091205490915015610ff257604051634923a77160e11b815260040160405180910390fd5b86516001600160e01b03198281165f81815260208c90526040902060609390931b6001600160601b0319168917909255600588901b60e01691821c90821c1987161795508060e00361105657600387901c5f90815260028a01602052604090208690555b505060019485019401610f88565b5092959194509092505050565b80516001600160a01b03163b61109a57604051633ddc5cab60e21b815260040160405180910390fd5b5f5b8160400151518110156111b2575f826040015182815181106110c0576110c0611923565b6020908102919091018101516001600160e01b031981165f90815291869052604090912054909150606081901c8061110b576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036111345760405163e983573160e01b815260040160405180910390fd5b845f01516001600160a01b0316816001600160a01b031603611169576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b0319929092165f90815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff9190911617905560010161109c565b505050565b82515f9081906001600160a01b0316156111e457604051633ab3490960e21b815260040160405180910390fd5b5f5b856040015151811015611064578480600190039550505f8660400151828151811061121357611213611923565b6020908102919091018101516001600160e01b031981165f908152918a90526040822080549290559150606081901c61125f576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036112835760405163e983573160e01b815260040160405180910390fd5b866007166007036112a657600387901c5f90815260028a01602052604090205495505b60e0600588901b1686901b6001600160e01b0319808216908416146112fc576001600160e01b031981165f90815260208b90526040902080546001600160601b0319166bffffffffffffffffffffffff84161790555b600382811c611fff1690600584901b60e016908a901c8203611334576001600160e01b031980821c198a16908416821c17985061135e565b5f82815260028d016020526040902080546001600160e01b0319858116841c90841c199091161790555b5050600190930192506111e6915050565b8051156001600160a01b038316151461139b576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611449576001600160a01b03821630146113e2576001600160a01b0382163b6113e257604051633ddc5cab60e21b815260040160405180910390fd5b5f826001600160a01b0316826040516113fb9190611a91565b5f60405180830381855af49150503d805f8114611433576040519150601f19603f3d011682016040523d82523d5f602084013e611438565b606091505b50509050806111b2573d5f803e3d5ffd5b5050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a380546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160e01b0319811681146114dd575f80fd5b919050565b5f602082840312156114f2575f80fd5b6114fb826114c6565b9392505050565b80356001600160a01b03811681146114dd575f80fd5b5f8083601f840112611528575f80fd5b5081356001600160401b0381111561153e575f80fd5b602083019150836020828501011115611555575f80fd5b9250929050565b5f805f805f60608688031215611570575f80fd5b85356001600160401b03811115611585575f80fd5b8601601f81018813611595575f80fd5b80356001600160401b038111156115aa575f80fd5b8860208260051b84010111156115be575f80fd5b6020918201965094506115d2908701611502565b925060408601356001600160401b038111156115ec575f80fd5b6115f888828901611518565b969995985093965092949392505050565b602080825282518282018190525f918401906040840190835b818110156116495783516001600160a01b0316835260209384019390920191600101611622565b509095945050505050565b5f8151808452602084019350602083015f5b8281101561168e5781516001600160e01b031916865260209586019590910190600101611666565b5093949350505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561170f57868503603f19018452815180516001600160a01b031686526020908101516040918701829052906116f990870182611654565b95505060209384019391909101906001016116be565b50929695505050505050565b5f6020828403121561172b575f80fd5b6114fb82611502565b602080825282518282018190525f918401906040840190835b818110156116495783516001600160e01b03191683526020938401939092019160010161174d565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b03811182821017156117ab576117ab611775565b60405290565b604051601f8201601f191681016001600160401b03811182821017156117d9576117d9611775565b604052919050565b5f6001600160401b038211156117f9576117f9611775565b5060051b60200190565b5f611815611810846117e1565b6117b1565b8381526020810190600585901b840136811115611830575f80fd5b845b818110156116495780356001600160401b0381111561184f575f80fd5b86016060368290031215611861575f80fd5b611869611789565b61187282611502565b8152602082013560038110611885575f80fd5b602082015260408201356001600160401b038111156118a2575f80fd5b919091019036601f8301126118b5575f80fd5b81356118c3611810826117e1565b8082825260208201915060208360051b8601019250368311156118e4575f80fd5b6020850194505b8285101561190d576118fc856114c6565b8252602094850194909101906118eb565b6040840152505085525060209384019301611832565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f606082016060835280865180835260808501915060808160051b8601019250602088015f5b82811015611a1857868503607f19018452815180516001600160a01b031686526020810151600381106119e057634e487b7160e01b5f52602160045260245ffd5b806020880152506040810151905060606040870152611a026060870182611654565b955050602093840193919091019060010161199f565b5050506001600160a01b0386166020850152508281036040840152611a3d818561194b565b9695505050505050565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611a6c57611a6c611a47565b5060010190565b5f60ff821660ff8103611a8857611a88611a47565b60010192915050565b5f82518060208501845e5f92019182525091905056fe177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93a2646970667358221220ec7497f0cc4548b69779ac21bce4fc6b7a821460ef2d66d8acf484ed346f95a964736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000038e361604a0bee7bcddaff4a50d7f4bfa5e5ca6b
-----Decoded View---------------
Arg [0] : _utilityCoDiamond (address): 0x38E361604a0beE7bcDdAFF4a50D7f4Bfa5e5Ca6B
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000038e361604a0bee7bcddaff4a50d7f4bfa5e5ca6b
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.