Address Contract Verified
Address
0xfa86aa141e45da5183B42792d99Dede3D26Ec515
Balance
0 ETH
Nonce
1
Code Size
3307 bytes
Creator
0x07dA2d30...bD0A at tx 0xe468b868...924652
Indexed Transactions
1 (24,428,441 → 24,428,441)
Gas Used (indexed)
759,287
Contract Bytecode
3307 bytes
0x60806040523661000b57005b600080356001600160e01b0319168152600080516020610c22833981519152602081905260409091205481906001600160a01b031680610075576000356001600160e01b031916604051630a82dd7360e31b815260040161006c9190610972565b60405180910390fd5b3660008037600080366000845af43d6000803e808015610094573d6000f35b3d6000fd5b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80546001600160a01b031981166001600160a01b03848116918217909355604051600080516020610c22833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60005b835181101561028557600084828151811061013c5761013c610987565b6020026020010151604001519050600085838151811061015e5761015e610987565b602002602001015160000151905081516000141561019a5760405163e767f91f60e01b81526001600160a01b038216600482015260240161006c565b60008684815181106101ae576101ae610987565b6020026020010151602001519050600060028111156101cf576101cf61099d565b8160028111156101e1576101e161099d565b14156101f6576101f182846102d0565b61026f565b600181600281111561020a5761020a61099d565b141561021a576101f1828461048b565b600281600281111561022e5761022e61099d565b141561023e576101f18284610602565b8060028111156102505761025061099d565b604051633ff4d20f60e11b815260ff909116600482015260240161006c565b505050808061027d906109c9565b91505061011f565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738383836040516102b993929190610a3c565b60405180910390a16102cb8282610888565b505050565b6001600160a01b0382166102f957806040516302b8da0760e21b815260040161006c9190610b3c565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d5460408051606081019091526024808252600080516020610c22833981519152929161035091869190610c42602083013961094e565b60005b835181101561048457600084828151811061037057610370610987565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b031680156103c3578160405163ebbf5d0760e01b815260040161006c9190610972565b6040805180820182526001600160a01b03808a16825261ffff80881660208085019182526001600160e01b0319881660009081528b8252958620945185549251909316600160a01b026001600160b01b0319909216929093169190911717909155600180880180549182018155835291206008820401805460e085901c60046007909416939093026101000a92830263ffffffff90930219169190911790558361046c81610b8a565b9450505050808061047c906109c9565b915050610353565b5050505050565b600080516020610c228339815191526001600160a01b0383166104c3578160405163cd98a96f60e01b815260040161006c9190610b3c565b6104e583604051806060016040528060288152602001610c8e6028913961094e565b60005b82518110156105fc57600083828151811061050557610505610987565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b03163081141561055a5781604051632901806d60e11b815260040161006c9190610972565b856001600160a01b0316816001600160a01b0316141561058f5781604051631ac6ce8d60e11b815260040161006c9190610972565b6001600160a01b0381166105b85781604051637479f93960e01b815260040161006c9190610972565b506001600160e01b031916600090815260208390526040902080546001600160a01b0319166001600160a01b038616179055806105f4816109c9565b9150506104e8565b50505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d54600080516020610c22833981519152906001600160a01b038416156106675760405163d091bc8160e01b81526001600160a01b038516600482015260240161006c565b60005b835181101561048457600084828151811061068757610687610987565b6020908102919091018101516001600160e01b0319811660009081528683526040908190208151808301909252546001600160a01b038116808352600160a01b90910461ffff1693820193909352909250906106f85781604051637a08a22d60e01b815260040161006c9190610972565b80516001600160a01b03163014156107255781604051630df5fd6160e31b815260040161006c9190610972565b8361072f81610bac565b94505083816020015161ffff161461080d57600085600101858154811061075857610758610987565b90600052602060002090600891828204019190066004029054906101000a900460e01b90508086600101836020015161ffff168154811061079b5761079b610987565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c92909202939093179055838201516001600160e01b03199390931681529087905260409020805461ffff60a01b1916600160a01b61ffff909316929092029190911790555b8460010180548061082057610820610bc3565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319909316815291859052506040902080546001600160b01b031916905580610880816109c9565b91505061066a565b6001600160a01b03821661089a575050565b6108bc82604051806060016040528060288152602001610c666028913961094e565b600080836001600160a01b0316836040516108d79190610bd9565b600060405180830381855af49150503d8060008114610912576040519150601f19603f3d011682016040523d82523d6000602084013e610917565b606091505b5091509150816105fc578051156109315780518082602001fd5b838360405163192105d760e01b815260040161006c929190610bf5565b813b806102cb57828260405163919834b960e01b815260040161006c929190610bf5565b6001600160e01b031991909116815260200190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156109dd576109dd6109b3565b5060010190565b60005b838110156109ff5781810151838201526020016109e7565b838111156105fc5750506000910152565b60008151808452610a288160208601602086016109e4565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b84811015610b0c57898403607f19018652815180516001600160a01b03168552838101518986019060038110610aab57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015610af75783516001600160e01b0319168252928601926001929092019190860190610acd565b50978501979550505090820190600101610a65565b50506001600160a01b038a16908801528681036040880152610b2e8189610a10565b9a9950505050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015610b7e5783516001600160e01b03191683529284019291840191600101610b58565b50909695505050505050565b600061ffff80831681811415610ba257610ba26109b3565b6001019392505050565b600081610bbb57610bbb6109b3565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60008251610beb8184602087016109e4565b9190910192915050565b6001600160a01b0383168152604060208201819052600090610c1990830184610a10565b94935050505056fec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a264697066735822122073e1ec3b192868777b4730f9a2ebe99976a57173d8d74976d7e2b8105522d82164736f6c634300080c0033
Verified Source Code Full Match
Compiler: v0.8.12+commit.f00d7308
EVM: london
Optimization: Yes (200 runs)
IERC165.sol 12 lines
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
interface IERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceId The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
IDiamondCut.sol 23 lines
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]>, Twitter/Github: @mudgen * EIP-2535 Diamonds /******************************************************************************/ import { IDiamond } from "./IDiamond.sol"; interface IDiamondCut is IDiamond { /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut( FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata ) external; }
IDiamond.sol 24 lines
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]>, Twitter/Github: @mudgen * EIP-2535 Diamonds /******************************************************************************/ interface IDiamond { enum FacetCutAction { Add, Replace, Remove } // Add=0, Replace=1, Remove=2 struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); }
Diamond.sol 75 lines
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]>, Twitter/Github: @mudgen * EIP-2535 Diamonds * * Implementation of a diamond. /******************************************************************************/ import { LibDiamond } from "./libraries/LibDiamond.sol"; import { IDiamondCut } from "./interfaces/IDiamondCut.sol"; import { IDiamondLoupe } from "./interfaces/IDiamondLoupe.sol"; import { IERC173 } from "./interfaces/IERC173.sol"; import { IERC165 } from "./interfaces/IERC165.sol"; // solhint-disable no-complex-fallback // solhint-disable no-inline-assembly // solhint-disable no-empty-blocks // When no function exists for function called error FunctionNotFound(bytes4 _functionSelector); // This is used in diamond constructor // more arguments are added to this struct // this avoids stack too deep errors struct DiamondArgs { address owner; address init; bytes initCalldata; } contract Diamond { constructor(IDiamondCut.FacetCut[] memory _diamondCut, DiamondArgs memory _args) payable { LibDiamond.setContractOwner(_args.owner); LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); // Code can be added here to perform actions and set state variables. } // Find facet for function that is called and execute the // function if a facet is found and return any value. fallback() external payable { LibDiamond.DiamondStorage storage ds; bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; // get diamond storage assembly { ds.slot := position } // get facet from function selector address facet = ds.facetAddressAndSelectorPosition[msg.sig].facetAddress; if (facet == address(0)) { revert FunctionNotFound(msg.sig); } // Execute external function from facet using delegatecall and return any value. assembly { // copy function selector and any arguments calldatacopy(0, 0, calldatasize()) // execute function call using the facet let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) // get any return value returndatacopy(0, 0, returndatasize()) // return any return value or error back to the caller switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } receive() external payable {} }
LibDiamond.sol 210 lines
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]>, Twitter/Github: @mudgen * EIP-2535 Diamonds /******************************************************************************/ import { IDiamond } from "../interfaces/IDiamond.sol"; import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; // solhint-disable avoid-low-level-calls // solhint-disable no-inline-assembly // Remember to add the loupe functions from DiamondLoupeFacet to the diamond. // The loupe functions are required by the EIP2535 Diamonds standard error NoSelectorsGivenToAdd(); error NotContractOwner(address _user, address _contractOwner); error NoSelectorsProvidedForFacetForCut(address _facetAddress); error CannotAddSelectorsToZeroAddress(bytes4[] _selectors); error NoBytecodeAtAddress(address _contractAddress, string _message); error IncorrectFacetCutAction(uint8 _action); error CannotAddFunctionToDiamondThatAlreadyExists(bytes4 _selector); error CannotReplaceFunctionsFromFacetWithZeroAddress(bytes4[] _selectors); error CannotReplaceImmutableFunction(bytes4 _selector); error CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet(bytes4 _selector); error CannotReplaceFunctionThatDoesNotExists(bytes4 _selector); error RemoveFacetAddressMustBeZeroAddress(address _facetAddress); error CannotRemoveFunctionThatDoesNotExist(bytes4 _selector); error CannotRemoveImmutableFunction(bytes4 _selector); error InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata); library LibDiamond { bytes32 internal constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage"); struct FacetAddressAndSelectorPosition { address facetAddress; uint16 selectorPosition; } struct DiamondStorage { // function selector => facet address and selector position in selectors array mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition; bytes4[] selectors; mapping(bytes4 => bool) supportedInterfaces; // owner of the contract address contractOwner; } function diamondStorage() internal pure returns (DiamondStorage storage ds) { bytes32 position = DIAMOND_STORAGE_POSITION; assembly { ds.slot := position } } event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function setContractOwner(address _newOwner) internal { DiamondStorage storage ds = diamondStorage(); address previousOwner = ds.contractOwner; ds.contractOwner = _newOwner; emit OwnershipTransferred(previousOwner, _newOwner); } function contractOwner() internal view returns (address contractOwner_) { contractOwner_ = diamondStorage().contractOwner; } function enforceIsContractOwner() internal view { if (msg.sender != diamondStorage().contractOwner) { revert NotContractOwner(msg.sender, diamondStorage().contractOwner); } } event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata); // Internal function version of diamondCut function diamondCut( IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata ) internal { for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) { bytes4[] memory functionSelectors = _diamondCut[facetIndex].functionSelectors; address facetAddress = _diamondCut[facetIndex].facetAddress; if (functionSelectors.length == 0) { revert NoSelectorsProvidedForFacetForCut(facetAddress); } IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action; if (action == IDiamond.FacetCutAction.Add) { addFunctions(facetAddress, functionSelectors); } else if (action == IDiamond.FacetCutAction.Replace) { replaceFunctions(facetAddress, functionSelectors); } else if (action == IDiamond.FacetCutAction.Remove) { removeFunctions(facetAddress, functionSelectors); } else { revert IncorrectFacetCutAction(uint8(action)); } } emit DiamondCut(_diamondCut, _init, _calldata); initializeDiamondCut(_init, _calldata); } function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { if (_facetAddress == address(0)) { revert CannotAddSelectorsToZeroAddress(_functionSelectors); } DiamondStorage storage ds = diamondStorage(); uint16 selectorCount = uint16(ds.selectors.length); enforceHasContractCode(_facetAddress, "LibDiamondCut: Add facet has no code"); for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.facetAddressAndSelectorPosition[selector].facetAddress; if (oldFacetAddress != address(0)) { revert CannotAddFunctionToDiamondThatAlreadyExists(selector); } ds.facetAddressAndSelectorPosition[selector] = FacetAddressAndSelectorPosition(_facetAddress, selectorCount); ds.selectors.push(selector); selectorCount++; } } function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { DiamondStorage storage ds = diamondStorage(); if (_facetAddress == address(0)) { revert CannotReplaceFunctionsFromFacetWithZeroAddress(_functionSelectors); } enforceHasContractCode(_facetAddress, "LibDiamondCut: Replace facet has no code"); for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.facetAddressAndSelectorPosition[selector].facetAddress; // can't replace immutable functions -- functions defined directly in the diamond in this case if (oldFacetAddress == address(this)) { revert CannotReplaceImmutableFunction(selector); } if (oldFacetAddress == _facetAddress) { revert CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet(selector); } if (oldFacetAddress == address(0)) { revert CannotReplaceFunctionThatDoesNotExists(selector); } // replace old facet address ds.facetAddressAndSelectorPosition[selector].facetAddress = _facetAddress; } } function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { DiamondStorage storage ds = diamondStorage(); uint256 selectorCount = ds.selectors.length; if (_facetAddress != address(0)) { revert RemoveFacetAddressMustBeZeroAddress(_facetAddress); } for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; FacetAddressAndSelectorPosition memory oldFacetAddressAndSelectorPosition = ds.facetAddressAndSelectorPosition[ selector ]; if (oldFacetAddressAndSelectorPosition.facetAddress == address(0)) { revert CannotRemoveFunctionThatDoesNotExist(selector); } // can't remove immutable functions -- functions defined directly in the diamond if (oldFacetAddressAndSelectorPosition.facetAddress == address(this)) { revert CannotRemoveImmutableFunction(selector); } // replace selector with last selector selectorCount--; if (oldFacetAddressAndSelectorPosition.selectorPosition != selectorCount) { bytes4 lastSelector = ds.selectors[selectorCount]; ds.selectors[oldFacetAddressAndSelectorPosition.selectorPosition] = lastSelector; ds.facetAddressAndSelectorPosition[lastSelector].selectorPosition = oldFacetAddressAndSelectorPosition .selectorPosition; } // delete last selector ds.selectors.pop(); delete ds.facetAddressAndSelectorPosition[selector]; } } function initializeDiamondCut(address _init, bytes memory _calldata) internal { if (_init == address(0)) { return; } enforceHasContractCode(_init, "LibDiamondCut: _init address has no code"); (bool success, bytes memory error) = _init.delegatecall(_calldata); if (!success) { if (error.length > 0) { // bubble up error /// @solidity memory-safe-assembly assembly { let returndata_size := mload(error) revert(add(32, error), returndata_size) } } else { revert InitializationFunctionReverted(_init, _calldata); } } } function enforceHasContractCode(address _contract, string memory _errorMessage) internal view { uint256 contractSize; assembly { contractSize := extcodesize(_contract) } if (contractSize == 0) { revert NoBytecodeAtAddress(_contract, _errorMessage); } } }
IERC173.sol 19 lines
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
/// @title ERC-173 Contract Ownership Standard
/// Note: the ERC-165 identifier for this interface is 0x7f5828d0
/* is ERC165 */
interface IERC173 {
/// @dev This emits when ownership of a contract changes.
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/// @notice Get the address of the owner
/// @return owner_ The address of the owner.
function owner() external view returns (address owner_);
/// @notice Set the address of the new owner of the contract
/// @dev Set _newOwner to address(0) to renounce any ownership.
/// @param _newOwner The address of the new owner of the contract
function transferOwnership(address _newOwner) external;
}
IDiamondLoupe.sol 38 lines
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]>, Twitter/Github: @mudgen * EIP-2535 Diamonds /******************************************************************************/ // A loupe is a small magnifying glass used to look at diamonds. // These functions look at diamonds interface IDiamondLoupe { /// These functions are expected to be called frequently /// by tools. struct Facet { address facetAddress; bytes4[] functionSelectors; } /// @notice Gets all facet addresses and their four byte function selectors. /// @return facets_ Facet function facets() external view returns (Facet[] memory facets_); /// @notice Gets all the function selectors supported by a specific facet. /// @param _facet The facet address. /// @return facetFunctionSelectors_ function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_); /// @notice Get all the facet addresses used by a diamond. /// @return facetAddresses_ function facetAddresses() external view returns (address[] memory facetAddresses_); /// @notice Gets the facet that supports the given selector. /// @dev If facet is not found return address(0). /// @param _functionSelector The function selector. /// @return facetAddress_ The facet address. function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_); }
Top Interactions
| Address | Txns | Sent | Received |
|---|---|---|---|
| 0xF88e4e3d...F805 | 1 | 1 |
Recent Transactions
|
| Hash | Block | Age | From/To | Value | |
|---|---|---|---|---|---|
| 0x1b1810e3...530868 | 24,428,441 | IN | 0xF88e4e3d...F805 | 0 ETH |