Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Contract Name:
SignerFacet
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {BFacetOwner} from "../facets/base/BFacetOwner.sol";
import {
_addExecutorSigner,
_removeExecutorSigner,
_isExecutorSigner,
_numberOfExecutorSigners,
_executorSigners,
_addCheckerSigner,
_removeCheckerSigner,
_isCheckerSigner,
_numberOfCheckerSigners,
_checkerSigners
} from "./storage/SignerStorage.sol";
import {LibDiamond} from "../libraries/diamond/standard/LibDiamond.sol";
contract SignerFacet is BFacetOwner {
using LibDiamond for address;
// EXECUTOR SIGNERS
// ################ Callable by Gov ################
function addExecutorSigners(
address[] calldata executorSigners_
) external onlyOwner {
for (uint256 i; i < executorSigners_.length; i++)
require(
_addExecutorSigner(executorSigners_[i]),
"SignerFacet.addExecutorSigners"
);
}
function removeExecutorSigners(
address[] calldata executorSigners_
) external onlyOwner {
for (uint256 i; i < executorSigners_.length; i++) {
require(
msg.sender == executorSigners_[i] ||
msg.sender.isContractOwner(),
"SignerFacet.removeExecutorSigners: msg.sender ! executorSigner || owner"
);
require(
_removeExecutorSigner(executorSigners_[i]),
"SignerFacet.removeExecutorSigners"
);
}
}
function isExecutorSigner(
address _executorSigner
) external view returns (bool) {
return _isExecutorSigner(_executorSigner);
}
function numberOfExecutorSigners() external view returns (uint256) {
return _numberOfExecutorSigners();
}
function executorSigners() external view returns (address[] memory) {
return _executorSigners();
}
// CHECKER SIGNERS
function addCheckerSigners(
address[] calldata checkerSigners_
) external onlyOwner {
for (uint256 i; i < checkerSigners_.length; i++)
require(
_addCheckerSigner(checkerSigners_[i]),
"SignerFacet.addCheckerSigners"
);
}
function removeCheckerSigners(address[] calldata checkerSigners_) external {
for (uint256 i; i < checkerSigners_.length; i++) {
require(
msg.sender == checkerSigners_[i] ||
msg.sender.isContractOwner(),
"SignerFacet.removeCheckerSigners: msg.sender ! checkerSigner || owner"
);
require(
_removeCheckerSigner(checkerSigners_[i]),
"SignerFacet.removeCheckerSigners"
);
}
}
function isCheckerSigner(
address checkerSigner_
) external view returns (bool) {
return _isCheckerSigner(checkerSigner_);
}
function numberOfCheckerSigners() external view returns (uint256) {
return _numberOfCheckerSigners();
}
function checkerSigners() external view returns (address[] memory) {
return _checkerSigners();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastValue;
// Update the index for the moved value
set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {LibDiamond} from "../../libraries/diamond/standard/LibDiamond.sol";
abstract contract BFacetOwner {
modifier onlyOwner() {
LibDiamond.enforceIsContractOwner();
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {
EnumerableSet
} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
using EnumerableSet for EnumerableSet.AddressSet;
struct SignerStorage {
EnumerableSet.AddressSet executorSigners;
EnumerableSet.AddressSet checkerSigners;
}
bytes32 constant _SIGNER_STORAGE_POSITION = keccak256(
"gelato.diamond.signer.storage"
);
function _addExecutorSigner(address _executor) returns (bool) {
return _signerStorage().executorSigners.add(_executor);
}
function _removeExecutorSigner(address _executor) returns (bool) {
return _signerStorage().executorSigners.remove(_executor);
}
function _isExecutorSigner(address _executorSigner) view returns (bool) {
return _signerStorage().executorSigners.contains(_executorSigner);
}
function _executorSignerAt(uint256 _index) view returns (address) {
return _signerStorage().executorSigners.at(_index);
}
function _executorSigners() view returns (address[] memory) {
return _signerStorage().executorSigners.values();
}
function _numberOfExecutorSigners() view returns (uint256) {
return _signerStorage().executorSigners.length();
}
function _addCheckerSigner(address _checker) returns (bool) {
return _signerStorage().checkerSigners.add(_checker);
}
function _removeCheckerSigner(address _checker) returns (bool) {
return _signerStorage().checkerSigners.remove(_checker);
}
function _isCheckerSigner(address _checker) view returns (bool) {
return _signerStorage().checkerSigners.contains(_checker);
}
function _checkerSignerAt(uint256 _index) view returns (address) {
return _signerStorage().checkerSigners.at(_index);
}
function _checkerSigners() view returns (address[] memory checkers) {
return _signerStorage().checkerSigners.values();
}
function _numberOfCheckerSigners() view returns (uint256) {
return _signerStorage().checkerSigners.length();
}
function _signerStorage() pure returns (SignerStorage storage ess) {
bytes32 position = _SIGNER_STORAGE_POSITION;
assembly {
ess.slot := position
}
}// SPDX-License-Identifier: MIT pragma solidity 0.8.23; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamond Standard: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ interface IDiamondCut { 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); /// @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; }
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
library GelatoBytes {
function calldataSliceSelector(
bytes calldata _bytes
) internal pure returns (bytes4 selector) {
selector =
_bytes[0] |
(bytes4(_bytes[1]) >> 8) |
(bytes4(_bytes[2]) >> 16) |
(bytes4(_bytes[3]) >> 24);
}
function memorySliceSelector(
bytes memory _bytes
) internal pure returns (bytes4 selector) {
selector =
_bytes[0] |
(bytes4(_bytes[1]) >> 8) |
(bytes4(_bytes[2]) >> 16) |
(bytes4(_bytes[3]) >> 24);
}
function revertWithError(
bytes memory _bytes,
string memory _tracingInfo
) internal pure {
// 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err
if (_bytes.length % 32 == 4) {
bytes4 selector;
assembly {
selector := mload(add(0x20, _bytes))
}
if (selector == 0x08c379a0) {
// Function selector for Error(string)
assembly {
_bytes := add(_bytes, 68)
}
revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));
} else {
revert(
string(abi.encodePacked(_tracingInfo, "NoErrorSelector"))
);
}
} else {
revert(
string(abi.encodePacked(_tracingInfo, "UnexpectedReturndata"))
);
}
}
function returnError(
bytes memory _bytes,
string memory _tracingInfo
) internal pure returns (string memory) {
// 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err
if (_bytes.length % 32 == 4) {
bytes4 selector;
assembly {
selector := mload(add(0x20, _bytes))
}
if (selector == 0x08c379a0) {
// Function selector for Error(string)
assembly {
_bytes := add(_bytes, 68)
}
return string(abi.encodePacked(_tracingInfo, string(_bytes)));
} else {
return
string(abi.encodePacked(_tracingInfo, "NoErrorSelector"));
}
} else {
return
string(abi.encodePacked(_tracingInfo, "UnexpectedReturndata"));
}
}
}// SPDX-License-Identifier: MIT pragma solidity 0.8.23; // solhint-disable max-line-length // https://github.com/mudgen/diamond-3/blob/b009cd08b7822bad727bbcc47aa1b50d8b50f7f0/contracts/libraries/LibDiamond.sol#L1 /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamond Standard: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ import "../../../interfaces/diamond/standard/IDiamondCut.sol"; // Custom due to incorrect string casting (non UTF-8 formatted) import {GelatoBytes} from "../../../libraries/GelatoBytes.sol"; library LibDiamond { bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage"); struct FacetAddressAndPosition { address facetAddress; uint16 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array } struct FacetFunctionSelectors { bytes4[] functionSelectors; uint16 facetAddressPosition; // position of facetAddress in facetAddresses array } struct DiamondStorage { // maps function selector to the facet address and // the position of the selector in the facetFunctionSelectors.selectors array mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition; // maps facet addresses to function selectors mapping(address => FacetFunctionSelectors) facetFunctionSelectors; // facet addresses address[] facetAddresses; // Used to query if a contract implements an interface. // Used to implement ERC-165. 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 isContractOwner(address _guy) internal view returns (bool) { return _guy == contractOwner(); } function enforceIsContractOwner() internal view { require( msg.sender == diamondStorage().contractOwner, "LibDiamond: Must be contract owner" ); } 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++ ) { 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("LibDiamondCut: Incorrect FacetCutAction"); } } emit DiamondCut(_diamondCut, _init, _calldata); initializeDiamondCut(_init, _calldata); } function addFunctions( address _facetAddress, bytes4[] memory _functionSelectors ) internal { require( _functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut" ); DiamondStorage storage ds = diamondStorage(); // uint16 selectorCount = uint16(diamondStorage().selectors.length); require( _facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)" ); uint16 selectorPosition = uint16( ds.facetFunctionSelectors[_facetAddress].functionSelectors.length ); // add new facet address if it does not exist if (selectorPosition == 0) { enforceHasContractCode( _facetAddress, "LibDiamondCut: New facet has no code" ); ds .facetFunctionSelectors[_facetAddress] .facetAddressPosition = uint16(ds.facetAddresses.length); ds.facetAddresses.push(_facetAddress); } for ( uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++ ) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds .selectorToFacetAndPosition[selector] .facetAddress; require( oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists" ); ds.facetFunctionSelectors[_facetAddress].functionSelectors.push( selector ); ds .selectorToFacetAndPosition[selector] .facetAddress = _facetAddress; ds .selectorToFacetAndPosition[selector] .functionSelectorPosition = selectorPosition; selectorPosition++; } } function replaceFunctions( address _facetAddress, bytes4[] memory _functionSelectors ) internal { require( _functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut" ); DiamondStorage storage ds = diamondStorage(); require( _facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)" ); uint16 selectorPosition = uint16( ds.facetFunctionSelectors[_facetAddress].functionSelectors.length ); // add new facet address if it does not exist if (selectorPosition == 0) { enforceHasContractCode( _facetAddress, "LibDiamondCut: New facet has no code" ); ds .facetFunctionSelectors[_facetAddress] .facetAddressPosition = uint16(ds.facetAddresses.length); ds.facetAddresses.push(_facetAddress); } for ( uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++ ) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds .selectorToFacetAndPosition[selector] .facetAddress; require( oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function" ); removeFunction(oldFacetAddress, selector); // add function ds .selectorToFacetAndPosition[selector] .functionSelectorPosition = selectorPosition; ds.facetFunctionSelectors[_facetAddress].functionSelectors.push( selector ); ds .selectorToFacetAndPosition[selector] .facetAddress = _facetAddress; selectorPosition++; } } function removeFunctions( address _facetAddress, bytes4[] memory _functionSelectors ) internal { require( _functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut" ); DiamondStorage storage ds = diamondStorage(); // if function does not exist then do nothing and return require( _facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)" ); for ( uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++ ) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds .selectorToFacetAndPosition[selector] .facetAddress; removeFunction(oldFacetAddress, selector); } } function removeFunction(address _facetAddress, bytes4 _selector) internal { DiamondStorage storage ds = diamondStorage(); require( _facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist" ); // an immutable function is a function defined directly in a diamond require( _facetAddress != address(this), "LibDiamondCut: Can't remove immutable function" ); // replace selector with last selector, then delete last selector uint256 selectorPosition = ds .selectorToFacetAndPosition[_selector] .functionSelectorPosition; uint256 lastSelectorPosition = ds .facetFunctionSelectors[_facetAddress] .functionSelectors .length - 1; // if not the same then replace _selector with lastSelector if (selectorPosition != lastSelectorPosition) { bytes4 lastSelector = ds .facetFunctionSelectors[_facetAddress] .functionSelectors[lastSelectorPosition]; ds.facetFunctionSelectors[_facetAddress].functionSelectors[ selectorPosition ] = lastSelector; ds .selectorToFacetAndPosition[lastSelector] .functionSelectorPosition = uint16(selectorPosition); } // delete the last selector ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop(); delete ds.selectorToFacetAndPosition[_selector]; // if no more selectors for facet address then delete the facet address if (lastSelectorPosition == 0) { // replace facet address with last facet address and delete last facet address uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1; uint256 facetAddressPosition = ds .facetFunctionSelectors[_facetAddress] .facetAddressPosition; if (facetAddressPosition != lastFacetAddressPosition) { address lastFacetAddress = ds.facetAddresses[ lastFacetAddressPosition ]; ds.facetAddresses[facetAddressPosition] = lastFacetAddress; ds .facetFunctionSelectors[lastFacetAddress] .facetAddressPosition = uint16(facetAddressPosition); } ds.facetAddresses.pop(); delete ds .facetFunctionSelectors[_facetAddress] .facetAddressPosition; } } function initializeDiamondCut( address _init, bytes memory _calldata ) internal { if (_init == address(0)) { require( _calldata.length == 0, "LibDiamondCut: _init is address(0) but_calldata is not empty" ); } else { require( _calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)" ); if (_init != address(this)) { enforceHasContractCode( _init, "LibDiamondCut: _init address has no code" ); } (bool success, bytes memory error) = _init.delegatecall(_calldata); if (!success) { if (error.length > 0) { // bubble up the error GelatoBytes.revertWithError(error, "LibDiamondCut:_init:"); } else { revert("LibDiamondCut: _init function reverted"); } } } } function enforceHasContractCode( address _contract, string memory _errorMessage ) internal view { uint256 contractSize; assembly { contractSize := extcodesize(_contract) } require(contractSize > 0, _errorMessage); } }
{
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"viaIR": true,
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract ABI
API[{"inputs":[{"internalType":"address[]","name":"checkerSigners_","type":"address[]"}],"name":"addCheckerSigners","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"executorSigners_","type":"address[]"}],"name":"addExecutorSigners","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkerSigners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"executorSigners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"checkerSigner_","type":"address"}],"name":"isCheckerSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_executorSigner","type":"address"}],"name":"isExecutorSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numberOfCheckerSigners","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numberOfExecutorSigners","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"checkerSigners_","type":"address[]"}],"name":"removeCheckerSigners","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"executorSigners_","type":"address[]"}],"name":"removeExecutorSigners","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080806040523461001657610c2f908161001c8239f35b600080fdfe6080604081815260048036101561001557600080fd5b600092833560e01c9081630a1d34de14610646575080630f4901f0146105ec5780633b96abfe1461049d5780633d21c94e146103dc5780638c40060f146103b05780639a8f05ac1461031b578063aeff94bd146102c1578063bcdfb2a614610291578063d807c58b146101fc5763fb2422f31461009157600080fd5b346101f85761009f36610733565b92906100a96107bf565b845b8481106100b6578580f35b6001600160a01b03806100d26100cd848987610785565b6107ab565b16331480156101cc575b15610153576100f9906100f36100cd848987610785565b166109f7565b15610106576001016100ab565b825162461bcd60e51b8152602081860152602160248201527f5369676e657246616365742e72656d6f76654578656375746f725369676e65726044820152607360f81b6064820152608490fd5b835162461bcd60e51b8152602081870152604760248201527f5369676e657246616365742e72656d6f76654578656375746f725369676e657260448201527f733a206d73672e73656e6465722021206578656375746f725369676e6572207c6064820152663e1037bbb732b960c91b608482015260a490fd5b50807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320541633146100dc565b8280fd5b50346101f85761020b36610733565b92906102156107bf565b845b848110610222578580f35b6102416001600160a01b0361023b6100cd848987610785565b16610b49565b1561024e57600101610217565b825162461bcd60e51b8152602081860152601d60248201527f5369676e657246616365742e616464436865636b65725369676e6572730000006044820152606490fd5b5050346102bd57816003193601126102bd57602090600080516020610bba833981519152549051908152f35b5080fd5b50346101f85760203660031901126101f857356001600160a01b038116908190036101f857828291602094527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d18452205415159051908152f35b50346101f85761032a36610733565b92906103346107bf565b845b848110610341578580f35b6103606001600160a01b0361035a6100cd848987610785565b16610ab0565b1561036d57600101610336565b825162461bcd60e51b8152602081860152601e60248201527f5369676e657246616365742e6164644578656375746f725369676e65727300006044820152606490fd5b5050346102bd57816003193601126102bd57602090600080516020610bda833981519152549051908152f35b509190346102bd57816003193601126102bd5780519081600080516020610bba83398151915290815480825260208092019286527f01617e88a0a7a97f106ffe470e44c8e9ab79f4fc04ca7f28d2b62751aa5c7f2e9186905b8282106104865750505050829003601f01601f191682019267ffffffffffffffff841183851017610473575082918261046f9252826106ee565b0390f35b634e487b7160e01b815260418552602490fd5b835485529384019360019384019390910190610435565b50346101f8576104ac36610733565b9290845b8481106104bb578580f35b6001600160a01b03806104d26100cd848987610785565b16331480156105c0575b15610549576104f9906104f36100cd848987610785565b166108c8565b15610506576001016104b0565b825162461bcd60e51b8152602081860181905260248201527f5369676e657246616365742e72656d6f7665436865636b65725369676e6572736044820152606490fd5b835162461bcd60e51b8152602081870152604560248201527f5369676e657246616365742e72656d6f7665436865636b65725369676e65727360448201527f3a206d73672e73656e646572202120636865636b65725369676e6572207c7c2060648201526437bbb732b960d91b608482015260a490fd5b50807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320541633146104dc565b50346101f85760203660031901126101f857356001600160a01b038116908190036101f857828291602094527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d38452205415159051908152f35b84915083346101f857826003193601126101f857600080516020610bda8339815191528054808452602090602085019286527fcb0c7e8cb179341a64c662d8675ea35c483ffc7eab4acc92a255ccb1994cdd089186905b8282106106d75750505050829003601f01601f191682019267ffffffffffffffff841183851017610473575082918261046f9252826106ee565b83548552938401936001938401939091019061069d565b602090602060408183019282815285518094520193019160005b828110610716575050505090565b83516001600160a01b031685529381019392810192600101610708565b9060206003198301126107805760043567ffffffffffffffff9283821161078057806023830112156107805781600401359384116107805760248460051b83010111610780576024019190565b600080fd5b91908110156107955760051b0190565b634e487b7160e01b600052603260045260246000fd5b356001600160a01b03811681036107805790565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b031633036107f257565b60405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b6064820152608490fd5b600080516020610bba8339815191528054821015610795576000527f01617e88a0a7a97f106ffe470e44c8e9ab79f4fc04ca7f28d2b62751aa5c7f2e0190600090565b600080516020610bda8339815191528054821015610795576000527fcb0c7e8cb179341a64c662d8675ea35c483ffc7eab4acc92a255ccb1994cdd080190600090565b6000908082527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d3908160205260408320548015156000146109f15760001990808201908082116109dd57600080516020610bba833981519152918254908482019182116109c95780820361097f575b5050508054801561096b5782019161094e83610842565b909182549160031b1b191690555582526020526040812055600190565b634e487b7160e01b86526031600452602486fd5b6109b461098e61099d93610842565b90549060031b1c928392610842565b819391549060031b91821b91600019901b19161790565b90558652846020526040862055388080610937565b634e487b7160e01b88526011600452602488fd5b634e487b7160e01b86526011600452602486fd5b50505090565b6000908082527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d1908160205260408320548015156000146109f15760001990808201908082116109dd57600080516020610bda833981519152918254908482019182116109c957808203610a7d575b5050508054801561096b5782019161094e83610885565b610a9b610a8c61099d93610885565b90549060031b1c928392610885565b90558652846020526040862055388080610a66565b906000918083527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d19283602052604081205415600014610b4457600080516020610bda83398151915293845494600160401b861015610b305783610b2061099d886001604098999a018555610885565b9055549382526020522055600190565b634e487b7160e01b83526041600452602483fd5b925050565b906000918083527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d39283602052604081205415600014610b4457600080516020610bba83398151915293845494600160401b861015610b305783610b2061099d886001604098999a01855561084256fedee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d2dee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d0a2646970667358221220617f7511a1417739f0234fb166f2987b0a2f4679e7de635b98b4dd99d315ddb364736f6c63430008170033
Deployed Bytecode
0x6080604081815260048036101561001557600080fd5b600092833560e01c9081630a1d34de14610646575080630f4901f0146105ec5780633b96abfe1461049d5780633d21c94e146103dc5780638c40060f146103b05780639a8f05ac1461031b578063aeff94bd146102c1578063bcdfb2a614610291578063d807c58b146101fc5763fb2422f31461009157600080fd5b346101f85761009f36610733565b92906100a96107bf565b845b8481106100b6578580f35b6001600160a01b03806100d26100cd848987610785565b6107ab565b16331480156101cc575b15610153576100f9906100f36100cd848987610785565b166109f7565b15610106576001016100ab565b825162461bcd60e51b8152602081860152602160248201527f5369676e657246616365742e72656d6f76654578656375746f725369676e65726044820152607360f81b6064820152608490fd5b835162461bcd60e51b8152602081870152604760248201527f5369676e657246616365742e72656d6f76654578656375746f725369676e657260448201527f733a206d73672e73656e6465722021206578656375746f725369676e6572207c6064820152663e1037bbb732b960c91b608482015260a490fd5b50807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320541633146100dc565b8280fd5b50346101f85761020b36610733565b92906102156107bf565b845b848110610222578580f35b6102416001600160a01b0361023b6100cd848987610785565b16610b49565b1561024e57600101610217565b825162461bcd60e51b8152602081860152601d60248201527f5369676e657246616365742e616464436865636b65725369676e6572730000006044820152606490fd5b5050346102bd57816003193601126102bd57602090600080516020610bba833981519152549051908152f35b5080fd5b50346101f85760203660031901126101f857356001600160a01b038116908190036101f857828291602094527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d18452205415159051908152f35b50346101f85761032a36610733565b92906103346107bf565b845b848110610341578580f35b6103606001600160a01b0361035a6100cd848987610785565b16610ab0565b1561036d57600101610336565b825162461bcd60e51b8152602081860152601e60248201527f5369676e657246616365742e6164644578656375746f725369676e65727300006044820152606490fd5b5050346102bd57816003193601126102bd57602090600080516020610bda833981519152549051908152f35b509190346102bd57816003193601126102bd5780519081600080516020610bba83398151915290815480825260208092019286527f01617e88a0a7a97f106ffe470e44c8e9ab79f4fc04ca7f28d2b62751aa5c7f2e9186905b8282106104865750505050829003601f01601f191682019267ffffffffffffffff841183851017610473575082918261046f9252826106ee565b0390f35b634e487b7160e01b815260418552602490fd5b835485529384019360019384019390910190610435565b50346101f8576104ac36610733565b9290845b8481106104bb578580f35b6001600160a01b03806104d26100cd848987610785565b16331480156105c0575b15610549576104f9906104f36100cd848987610785565b166108c8565b15610506576001016104b0565b825162461bcd60e51b8152602081860181905260248201527f5369676e657246616365742e72656d6f7665436865636b65725369676e6572736044820152606490fd5b835162461bcd60e51b8152602081870152604560248201527f5369676e657246616365742e72656d6f7665436865636b65725369676e65727360448201527f3a206d73672e73656e646572202120636865636b65725369676e6572207c7c2060648201526437bbb732b960d91b608482015260a490fd5b50807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320541633146104dc565b50346101f85760203660031901126101f857356001600160a01b038116908190036101f857828291602094527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d38452205415159051908152f35b84915083346101f857826003193601126101f857600080516020610bda8339815191528054808452602090602085019286527fcb0c7e8cb179341a64c662d8675ea35c483ffc7eab4acc92a255ccb1994cdd089186905b8282106106d75750505050829003601f01601f191682019267ffffffffffffffff841183851017610473575082918261046f9252826106ee565b83548552938401936001938401939091019061069d565b602090602060408183019282815285518094520193019160005b828110610716575050505090565b83516001600160a01b031685529381019392810192600101610708565b9060206003198301126107805760043567ffffffffffffffff9283821161078057806023830112156107805781600401359384116107805760248460051b83010111610780576024019190565b600080fd5b91908110156107955760051b0190565b634e487b7160e01b600052603260045260246000fd5b356001600160a01b03811681036107805790565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b031633036107f257565b60405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b6064820152608490fd5b600080516020610bba8339815191528054821015610795576000527f01617e88a0a7a97f106ffe470e44c8e9ab79f4fc04ca7f28d2b62751aa5c7f2e0190600090565b600080516020610bda8339815191528054821015610795576000527fcb0c7e8cb179341a64c662d8675ea35c483ffc7eab4acc92a255ccb1994cdd080190600090565b6000908082527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d3908160205260408320548015156000146109f15760001990808201908082116109dd57600080516020610bba833981519152918254908482019182116109c95780820361097f575b5050508054801561096b5782019161094e83610842565b909182549160031b1b191690555582526020526040812055600190565b634e487b7160e01b86526031600452602486fd5b6109b461098e61099d93610842565b90549060031b1c928392610842565b819391549060031b91821b91600019901b19161790565b90558652846020526040862055388080610937565b634e487b7160e01b88526011600452602488fd5b634e487b7160e01b86526011600452602486fd5b50505090565b6000908082527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d1908160205260408320548015156000146109f15760001990808201908082116109dd57600080516020610bda833981519152918254908482019182116109c957808203610a7d575b5050508054801561096b5782019161094e83610885565b610a9b610a8c61099d93610885565b90549060031b1c928392610885565b90558652846020526040862055388080610a66565b906000918083527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d19283602052604081205415600014610b4457600080516020610bda83398151915293845494600160401b861015610b305783610b2061099d886001604098999a018555610885565b9055549382526020522055600190565b634e487b7160e01b83526041600452602483fd5b925050565b906000918083527fdee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d39283602052604081205415600014610b4457600080516020610bba83398151915293845494600160401b861015610b305783610b2061099d886001604098999a01855561084256fedee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d2dee078fadc21593590e9046d81e4518a7b3feb16bdee74b2d2488cd4455264d0a2646970667358221220617f7511a1417739f0234fb166f2987b0a2f4679e7de635b98b4dd99d315ddb364736f6c63430008170033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.