Address Contract Verified
Address
0x2FADC853eCC103ecdC61877017Fb72D711789c95
Balance
0 ETH
Nonce
1
Code Size
4163 bytes
Creator
0x8645E1bd...E2Cd at tx 0x89dea36b...addd81
Indexed Transactions
0
Contract Bytecode
4163 bytes
0x608060405234801561000f575f5ffd5b506004361061004a575f3560e01c806352ef6b2c1461004e5780637a0ed6271461006c578063adfca15e1461008a578063cdffacc6146100ba575b5f5ffd5b6100566100ea565b6040516100639190610b8a565b60405180910390f35b610074610183565b6040516100819190610d81565b60405180910390f35b6100a4600480360381019061009f9190610dcf565b6106d7565b6040516100b19190610e66565b60405180910390f35b6100d460048036038101906100cf9190610eb0565b6109b2565b6040516100e19190610eea565b60405180910390f35b60605f6100f5610a38565b90508060030180548060200260200160405190810160405280929190818152602001828054801561017857602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161012f575b505050505091505090565b60605f61018e610a38565b90505f816001018054905090505f826003018054905067ffffffffffffffff8111156101bd576101bc610f03565b5b6040519080825280602002602001820160405280156101eb5781602001602082028036833780820191505090505b5090505f5b82811015610376575f84600101828154811061020f5761020e610f30565b5b905f5260205f2090600891828204019190066004029054906101000a900460e01b90505f855f015f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f5b8660030180549050811015610366578173ffffffffffffffffffffffffffffffffffffffff168760030182815481106102e5576102e4610f30565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036103595784818151811061033b5761033a610f30565b5b60200260200101805180919061035090610f93565b81525050610366565b80806001019150506102a9565b50505080806001019150506101f0565b50826003018054905067ffffffffffffffff81111561039857610397610f03565b5b6040519080825280602002602001820160405280156103d157816020015b6103be610a74565b8152602001906001900390816103b65790505b5093505f5b83600301805490508110156106d0578360030181815481106103fb576103fa610f30565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685828151811061043657610435610f30565b5b60200260200101515f019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505081818151811061048657610485610f30565b5b602002602001015167ffffffffffffffff8111156104a7576104a6610f03565b5b6040519080825280602002602001820160405280156104d55781602001602082028036833780820191505090505b508582815181106104e9576104e8610f30565b5b6020026020010151602001819052505f5f90505f5b848110156106c1575f86600101828154811061051d5761051c610f30565b5b905f5260205f2090600891828204019190066004029054906101000a900460e01b90505f875f015f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508760030185815481106105cb576105ca610f30565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036106b2578189868151811061063957610638610f30565b5b602002602001015160200151858151811061065757610656610f30565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505083806106ae90610f93565b9450505b505080806001019150506104fe565b505080806001019150506103d6565b5050505090565b60605f6106e2610a38565b90505f816001018054905090505f5f90505f5b828110156107f357835f015f85600101838154811061071757610716610f30565b5b905f5260205f2090600891828204019190066004029054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036107e65781806107e290610f93565b9250505b80806001019150506106f5565b508067ffffffffffffffff81111561080e5761080d610f03565b5b60405190808252806020026020018201604052801561083c5781602001602082028036833780820191505090505b5093505f5f90505f5b838110156109a8575f85600101828154811061086457610863610f30565b5b905f5260205f2090600891828204019190066004029054906101000a900460e01b9050855f015f827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff160361099a578087848151811061093f5761093e610f30565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050828061099690610f93565b9350505b508080600101915050610845565b5050505050919050565b5f5f6109bc610a38565b9050805f015f847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b5f5f60017fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c5f1c610a699190610fda565b5f1b90508091505090565b60405180604001604052805f73ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610af582610acc565b9050919050565b610b0581610aeb565b82525050565b5f610b168383610afc565b60208301905092915050565b5f602082019050919050565b5f610b3882610aa3565b610b428185610aad565b9350610b4d83610abd565b805f5b83811015610b7d578151610b648882610b0b565b9750610b6f83610b22565b925050600181019050610b50565b5085935050505092915050565b5f6020820190508181035f830152610ba28184610b2e565b905092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610c3081610bfc565b82525050565b5f610c418383610c27565b60208301905092915050565b5f602082019050919050565b5f610c6382610bd3565b610c6d8185610bdd565b9350610c7883610bed565b805f5b83811015610ca8578151610c8f8882610c36565b9750610c9a83610c4d565b925050600181019050610c7b565b5085935050505092915050565b5f604083015f830151610cca5f860182610afc565b5060208301518482036020860152610ce28282610c59565b9150508091505092915050565b5f610cfa8383610cb5565b905092915050565b5f602082019050919050565b5f610d1882610baa565b610d228185610bb4565b935083602082028501610d3485610bc4565b805f5b85811015610d6f5784840389528151610d508582610cef565b9450610d5b83610d02565b925060208a01995050600181019050610d37565b50829750879550505050505092915050565b5f6020820190508181035f830152610d998184610d0e565b905092915050565b5f5ffd5b610dae81610aeb565b8114610db8575f5ffd5b50565b5f81359050610dc981610da5565b92915050565b5f60208284031215610de457610de3610da1565b5b5f610df184828501610dbb565b91505092915050565b5f82825260208201905092915050565b5f610e1482610bd3565b610e1e8185610dfa565b9350610e2983610bed565b805f5b83811015610e59578151610e408882610c36565b9750610e4b83610c4d565b925050600181019050610e2c565b5085935050505092915050565b5f6020820190508181035f830152610e7e8184610e0a565b905092915050565b610e8f81610bfc565b8114610e99575f5ffd5b50565b5f81359050610eaa81610e86565b92915050565b5f60208284031215610ec557610ec4610da1565b5b5f610ed284828501610e9c565b91505092915050565b610ee481610aeb565b82525050565b5f602082019050610efd5f830184610edb565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f819050919050565b5f610f9d82610f8a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610fcf57610fce610f5d565b5b600182019050919050565b5f610fe482610f8a565b9150610fef83610f8a565b925082820390508181111561100757611006610f5d565b5b9291505056fea26469706673582212209bcbe652a6e339ba5970d0e190c8df9e52154ffa09e105e7e690e9cb2b3c541e64736f6c634300081c0033
Verified Source Code Full Match
Compiler: v0.8.28+commit.7893614a
EVM: prague
Optimization: No
DiamondLoupeFacet.sol 102 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "../interfaces/IDiamondLoupe.sol";
import "../libraries/DiamondLib.sol";
/**
* @title DiamondLoupeFacet
* @notice Facet for diamond loupe functionality
* @dev Implements EIP-2535 Diamond Standard loupe operations
*/
contract DiamondLoupeFacet is IDiamondLoupe {
/**
* @notice Gets all facet addresses and their four byte function selectors
* @return facets_ Array of Facet structs
*/
function facets() external view override returns (Facet[] memory facets_) {
DiamondLib.DiamondStorage storage ds = DiamondLib.diamondStorage();
uint256 selectorCount = ds.selectors.length;
// Create an array to store facet selector counts
uint256[] memory facetSelectorCounts = new uint256[](ds.facetAddresses.length);
// Count selectors for each facet
for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) {
bytes4 selector = ds.selectors[selectorIndex];
address facet = ds.facetAddressAndSelectorPosition[selector].facetAddress;
for (uint256 facetIndex; facetIndex < ds.facetAddresses.length; facetIndex++) {
if (ds.facetAddresses[facetIndex] == facet) {
facetSelectorCounts[facetIndex]++;
break;
}
}
}
// Create facets array
facets_ = new Facet[](ds.facetAddresses.length);
for (uint256 facetIndex; facetIndex < ds.facetAddresses.length; facetIndex++) {
facets_[facetIndex].facetAddress = ds.facetAddresses[facetIndex];
facets_[facetIndex].functionSelectors = new bytes4[](facetSelectorCounts[facetIndex]);
uint256 currentSelectorIndex = 0;
for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) {
bytes4 selector = ds.selectors[selectorIndex];
address facet = ds.facetAddressAndSelectorPosition[selector].facetAddress;
if (facet == ds.facetAddresses[facetIndex]) {
facets_[facetIndex].functionSelectors[currentSelectorIndex] = selector;
currentSelectorIndex++;
}
}
}
}
/**
* @notice Gets all the function selectors supported by a specific facet
* @param facet_ The facet address
* @return facetFunctionSelectors_ Array of function selectors
*/
function facetFunctionSelectors(
address facet_
) external view override returns (bytes4[] memory facetFunctionSelectors_) {
DiamondLib.DiamondStorage storage ds = DiamondLib.diamondStorage();
uint256 selectorCount = ds.selectors.length;
uint256 facetSelectorCount = 0;
// Count selectors for this facet
for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) {
if (facet_ == ds.facetAddressAndSelectorPosition[ds.selectors[selectorIndex]].facetAddress) {
facetSelectorCount++;
}
}
// Create array and populate
facetFunctionSelectors_ = new bytes4[](facetSelectorCount);
uint256 currentIndex = 0;
for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) {
bytes4 selector = ds.selectors[selectorIndex];
if (facet_ == ds.facetAddressAndSelectorPosition[selector].facetAddress) {
facetFunctionSelectors_[currentIndex] = selector;
currentIndex++;
}
}
}
/**
* @notice Get all the facet addresses used by a diamond
* @return facetAddresses_ Array of facet addresses
*/
function facetAddresses() external view override returns (address[] memory facetAddresses_) {
DiamondLib.DiamondStorage storage ds = DiamondLib.diamondStorage();
facetAddresses_ = ds.facetAddresses;
}
/**
* @notice Gets the facet that supports the given selector
* @param functionSelector_ The function selector
* @return facetAddress_ The facet address that supports the selector
*/
function facetAddress(bytes4 functionSelector_) external view override returns (address facetAddress_) {
DiamondLib.DiamondStorage storage ds = DiamondLib.diamondStorage();
facetAddress_ = ds.facetAddressAndSelectorPosition[functionSelector_].facetAddress;
}
}
IDiamondCut.sol 31 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/**
* @title IDiamondCut
* @notice Interface for diamond cut functionality
* @dev EIP-2535 Diamond Standard interface
*/
interface IDiamondCut {
enum FacetCutAction {
Add,
Replace,
Remove
}
struct FacetCut {
address facetAddress;
FacetCutAction action;
bytes4[] functionSelectors;
}
/**
* @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 initCalldata
* @param initCalldata A function call, including function selector and arguments executed with delegatecall on init
*/
function diamondCut(FacetCut[] calldata diamondCut, address init, bytes calldata initCalldata) external;
event DiamondCut(FacetCut[] diamondCut, address init, bytes initCalldata);
}
IDiamondLoupe.sol 40 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/**
* @title IDiamondLoupe
* @notice Interface for diamond loupe functionality
* @dev EIP-2535 Diamond Standard loupe interface
*/
interface IDiamondLoupe {
struct Facet {
address facetAddress;
bytes4[] functionSelectors;
}
/**
* @notice Gets all facet addresses and their four byte function selectors
* @return facets_ Array of Facet structs
*/
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_ Array of function selectors
*/
function facetFunctionSelectors(address facet) external view returns (bytes4[] memory facetFunctionSelectors_);
/**
* @notice Get all the facet addresses used by a diamond
* @return facetAddresses_ Array of facet addresses
*/
function facetAddresses() external view returns (address[] memory facetAddresses_);
/**
* @notice Gets the facet that supports the given selector
* @param functionSelector The function selector
* @return facetAddress_ The facet address that supports the selector
*/
function facetAddress(bytes4 functionSelector) external view returns (address facetAddress_);
}
DiamondLib.sol 184 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "../interfaces/IDiamondCut.sol";
/**
* @title DiamondLib
* @notice Core library for diamond functionality
* @dev Implements EIP-2535 Diamond Standard core logic
*/
library DiamondLib {
bytes32 constant DIAMOND_STORAGE_POSITION = bytes32(uint256(keccak256("diamond.standard.diamond.storage")) - 1);
struct FacetAddressAndSelectorPosition {
address facetAddress;
uint16 selectorPosition;
}
struct DiamondStorage {
// Maps function selectors to the facet that executes the functions
mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition;
bytes4[] selectors;
mapping(address => uint256) facetAddressToSelectorCount;
address[] facetAddresses;
// Owner of the diamond
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);
event DiamondCut(IDiamondCut.FacetCut[] diamondCut, address init, bytes initCalldata);
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 {
require(msg.sender == diamondStorage().contractOwner, "DiamondLib: Must be contract owner");
}
function diamondCut(IDiamondCut.FacetCut[] memory diamondCut_, address init, bytes memory initCalldata) internal {
for (uint256 facetIndex; facetIndex < diamondCut_.length; facetIndex++) {
IDiamondCut.FacetCutAction action = diamondCut_[facetIndex].action;
if (action == IDiamondCut.FacetCutAction.Add) {
addFunctions(diamondCut_[facetIndex].facetAddress, diamondCut_[facetIndex].functionSelectors);
} else if (action == IDiamondCut.FacetCutAction.Replace) {
replaceFunctions(diamondCut_[facetIndex].facetAddress, diamondCut_[facetIndex].functionSelectors);
} else if (action == IDiamondCut.FacetCutAction.Remove) {
removeFunctions(diamondCut_[facetIndex].facetAddress, diamondCut_[facetIndex].functionSelectors);
} else {
revert("DiamondCutFacet: Incorrect FacetCutAction");
}
}
emit DiamondCut(diamondCut_, init, initCalldata);
initializeDiamondCut(init, initCalldata);
}
function addFunctions(address facetAddress, bytes4[] memory functionSelectors) internal {
require(functionSelectors.length > 0, "DiamondLib: No selectors in facet to cut");
DiamondStorage storage ds = diamondStorage();
uint16 selectorCount = uint16(ds.selectors.length);
require(facetAddress != address(0), "DiamondLib: Add facet can't be address(0)");
enforceHasContractCode(facetAddress, "DiamondLib: Add facet has no code");
for (uint256 selectorIndex; selectorIndex < functionSelectors.length; selectorIndex++) {
bytes4 selector = functionSelectors[selectorIndex];
address oldFacetAddress = ds.facetAddressAndSelectorPosition[selector].facetAddress;
require(oldFacetAddress == address(0), "DiamondLib: Can't add function that already exists");
ds.facetAddressAndSelectorPosition[selector] = FacetAddressAndSelectorPosition(facetAddress, selectorCount);
ds.selectors.push(selector);
selectorCount++;
}
if (ds.facetAddressToSelectorCount[facetAddress] == 0) {
ds.facetAddresses.push(facetAddress);
}
ds.facetAddressToSelectorCount[facetAddress] += functionSelectors.length;
}
function replaceFunctions(address facetAddress, bytes4[] memory functionSelectors) internal {
require(functionSelectors.length > 0, "DiamondLib: No selectors in facet to cut");
DiamondStorage storage ds = diamondStorage();
require(facetAddress != address(0), "DiamondLib: Replace facet can't be address(0)");
enforceHasContractCode(facetAddress, "DiamondLib: Replace facet has no code");
for (uint256 selectorIndex; selectorIndex < functionSelectors.length; selectorIndex++) {
bytes4 selector = functionSelectors[selectorIndex];
address oldFacetAddress = ds.facetAddressAndSelectorPosition[selector].facetAddress;
require(oldFacetAddress != facetAddress, "DiamondLib: Can't replace function with same function");
require(oldFacetAddress != address(0), "DiamondLib: Can't replace function that doesn't exist");
// Replace old facet address
ds.facetAddressAndSelectorPosition[selector].facetAddress = facetAddress;
if (ds.facetAddressToSelectorCount[facetAddress] == 0) {
ds.facetAddresses.push(facetAddress);
}
ds.facetAddressToSelectorCount[facetAddress]++;
ds.facetAddressToSelectorCount[oldFacetAddress]--;
if (ds.facetAddressToSelectorCount[oldFacetAddress] == 0) {
removeFacetAddress(ds, oldFacetAddress);
}
}
}
function removeFunctions(address facetAddress, bytes4[] memory functionSelectors) internal {
require(functionSelectors.length > 0, "DiamondLib: No selectors in facet to cut");
DiamondStorage storage ds = diamondStorage();
require(facetAddress == address(0), "DiamondLib: Remove facet address must be address(0)");
for (uint256 selectorIndex; selectorIndex < functionSelectors.length; selectorIndex++) {
bytes4 selector = functionSelectors[selectorIndex];
FacetAddressAndSelectorPosition memory oldFacetAddressAndSelectorPosition = ds
.facetAddressAndSelectorPosition[selector];
require(
oldFacetAddressAndSelectorPosition.facetAddress != address(0),
"DiamondLib: Can't remove function that doesn't exist"
);
// Replace selector with last selector
uint256 selectorPosition = oldFacetAddressAndSelectorPosition.selectorPosition;
uint256 lastSelectorPosition = ds.selectors.length - 1;
// If not the same then replace selector with last selector
if (selectorPosition != lastSelectorPosition) {
bytes4 lastSelector = ds.selectors[lastSelectorPosition];
ds.selectors[selectorPosition] = lastSelector;
ds.facetAddressAndSelectorPosition[lastSelector].selectorPosition = uint16(selectorPosition);
}
// Delete the last selector
ds.selectors.pop();
delete ds.facetAddressAndSelectorPosition[selector];
address oldFacetAddress = oldFacetAddressAndSelectorPosition.facetAddress;
ds.facetAddressToSelectorCount[oldFacetAddress]--;
if (ds.facetAddressToSelectorCount[oldFacetAddress] == 0) {
removeFacetAddress(ds, oldFacetAddress);
}
}
}
function removeFacetAddress(DiamondStorage storage ds, address facetAddress) internal {
uint256 facetAddressCount = ds.facetAddresses.length;
for (uint256 i; i < facetAddressCount; i++) {
if (ds.facetAddresses[i] == facetAddress) {
ds.facetAddresses[i] = ds.facetAddresses[facetAddressCount - 1];
ds.facetAddresses.pop();
break;
}
}
}
function initializeDiamondCut(address init, bytes memory initCalldata) internal {
if (init == address(0)) {
require(initCalldata.length == 0, "DiamondLib: init is address(0) but initCalldata is not empty");
} else {
require(initCalldata.length > 0, "DiamondLib: initCalldata is empty but init is not address(0)");
if (init != address(this)) {
enforceHasContractCode(init, "DiamondLib: init address has no code");
}
(bool success, bytes memory error) = init.delegatecall(initCalldata);
if (!success) {
if (error.length > 0) {
// bubble up the error
revert(string(error));
} else {
revert("DiamondLib: initializeDiamondCut failed");
}
}
}
}
function enforceHasContractCode(address facet, string memory errorMessage) internal view {
uint256 contractSize;
assembly {
contractSize := extcodesize(facet)
}
require(contractSize > 0, errorMessage);
}
}
Read Contract
facetAddress 0xcdffacc6 → address
facetAddresses 0x52ef6b2c → address[]
facetFunctionSelectors 0xadfca15e → bytes4[]
facets 0x7a0ed627 → tuple[]
Recent Transactions
No transactions found for this address