编译器
0.8.21+commit.d9974bed
文件 1 的 10:AppStorage.sol
pragma solidity 0.8.21;
import {STypes, F, SR} from "contracts/libraries/DataTypes.sol";
import {LibDiamond} from "contracts/libraries/LibDiamond.sol";
import {Errors} from "contracts/libraries/Errors.sol";
import {Constants} from "contracts/libraries/Constants.sol";
struct AppStorage {
address admin;
address ownerCandidate;
address baseOracle;
uint24 flaggerIdCounter;
uint40 tokenIdCounter;
uint8 reentrantStatus;
mapping(address deth => uint256 vault) dethVault;
mapping(address bridge => STypes.Bridge) bridge;
mapping(uint256 vault => STypes.Vault) vault;
mapping(uint256 vault => address[]) vaultBridges;
mapping(uint256 vault => mapping(address account => STypes.VaultUser)) vaultUser;
mapping(address asset => STypes.Asset) asset;
mapping(address asset => mapping(address account => STypes.AssetUser)) assetUser;
mapping(address asset => mapping(uint16 id => STypes.Order)) bids;
mapping(address asset => mapping(uint16 id => STypes.Order)) asks;
mapping(address asset => mapping(uint16 id => STypes.Order)) shorts;
mapping(
address asset
=> mapping(address account => mapping(uint8 id => STypes.ShortRecord))
) shortRecords;
mapping(uint24 flaggerId => address flagger) flagMapping;
mapping(uint256 tokenId => STypes.NFT) nftMapping;
mapping(uint256 tokenId => address) getApproved;
mapping(address owner => mapping(address operator => bool)) isApprovedForAll;
address[] assets;
mapping(uint256 assetId => address) assetMapping;
string name;
string symbol;
}
function appStorage() pure returns (AppStorage storage s) {
assembly {
s.slot := 0
}
}
contract Modifiers {
AppStorage internal s;
modifier onlyDAO() {
LibDiamond.enforceIsContractOwner();
_;
}
modifier onlyAdminOrDAO() {
if (msg.sender != LibDiamond.contractOwner() && msg.sender != s.admin) {
revert Errors.NotOwnerOrAdmin();
}
_;
}
modifier onlyDiamond() {
if (msg.sender != address(this)) revert Errors.NotDiamond();
_;
}
modifier onlyValidAsset(address asset) {
if (s.asset[asset].vault == 0) revert Errors.InvalidAsset();
_;
}
modifier isNotFrozen(address asset) {
if (s.asset[asset].frozen != F.Unfrozen) revert Errors.AssetIsFrozen();
_;
}
modifier isPermanentlyFrozen(address asset) {
if (s.asset[asset].frozen != F.Permanent) {
revert Errors.AssetIsNotPermanentlyFrozen();
}
_;
}
function _onlyValidShortRecord(address asset, address shorter, uint8 id)
internal
view
{
uint8 maxId = s.assetUser[asset][shorter].shortRecordIdCounter;
if (id >= maxId) revert Errors.InvalidShortId();
if (id < Constants.SHORT_STARTING_ID) revert Errors.InvalidShortId();
if (s.shortRecords[asset][shorter][id].status == SR.Closed) {
revert Errors.InvalidShortId();
}
}
modifier onlyValidShortRecord(address asset, address shorter, uint8 id) {
_onlyValidShortRecord(asset, shorter, id);
_;
}
modifier nonReentrant() {
if (s.reentrantStatus == Constants.ENTERED) revert Errors.ReentrantCall();
s.reentrantStatus = Constants.ENTERED;
_;
s.reentrantStatus = Constants.NOT_ENTERED;
}
modifier nonReentrantView() {
if (s.reentrantStatus == Constants.ENTERED) revert Errors.ReentrantCallView();
_;
}
modifier onlyValidBridge(address bridge) {
if (s.bridge[bridge].vault == 0) revert Errors.InvalidBridge();
_;
}
}
文件 2 的 10:Constants.sol
pragma solidity 0.8.21;
library Constants {
uint8 internal constant HEAD = 1;
uint8 internal constant TAIL = 1;
uint8 internal constant STARTING_ID = 100;
uint8 internal constant SHORT_MAX_ID = 254;
uint8 internal constant SHORT_STARTING_ID = 2;
uint256 internal constant DUST_FACTOR = 0.5 ether;
uint256 internal constant MIN_DURATION = 14 days;
uint256 internal constant CRATIO_MAX = 15 ether;
uint256 internal constant YIELD_DELAY_SECONDS = 60;
uint256 internal constant BRIDGE_YIELD_UPDATE_THRESHOLD = 1000 ether;
uint256 internal constant BRIDGE_YIELD_PERCENT_THRESHOLD = 0.01 ether;
uint88 internal constant MIN_DEPOSIT = 0.01 ether;
uint8 internal constant NOT_ENTERED = 1;
uint8 internal constant ENTERED = 2;
uint256 internal constant ONE_DECIMAL_PLACES = 10;
uint256 internal constant TWO_DECIMAL_PLACES = 100;
uint256 internal constant THREE_DECIMAL_PLACES = 1000;
uint256 internal constant FOUR_DECIMAL_PLACES = 10000;
uint256 internal constant FIVE_DECIMAL_PLACES = 100000;
uint256 internal constant SIX_DECIMAL_PLACES = 1000000;
uint256 internal constant STARTING_TIME = 1660353637;
int256 internal constant PREV = -1;
int256 internal constant EXACT = 0;
int256 internal constant NEXT = 1;
bool internal constant MARKET_ORDER = true;
bool internal constant LIMIT_ORDER = false;
int256 internal constant BASE_ORACLE_DECIMALS = 10 ** 10;
address internal constant USDC_WETH =
address(0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640);
address internal constant USDC = address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
address internal constant WETH = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
uint128 internal constant UNISWAP_WETH_BASE_AMT = 1 ether;
uint256 internal constant DECIMAL_USDC = 10 ** 6;
}
library Vault {
uint256 internal constant ONE = 1;
}
文件 3 的 10:DataTypes.sol
pragma solidity 0.8.21;
enum F {
Unfrozen,
Permanent
}
enum O {
Uninitialized,
LimitBid,
LimitAsk,
MarketBid,
MarketAsk,
LimitShort,
Cancelled,
Matched
}
enum SR {
PartialFill,
FullyFilled,
Closed
}
enum OF {
OneHour,
FifteenMinutes
}
library STypes {
struct Order {
uint88 ercAmount;
uint80 price;
uint16 prevId;
uint16 id;
uint16 nextId;
O orderType;
uint32 creationTime;
address addr;
O prevOrderType;
uint16 initialCR;
uint8 shortRecordId;
uint64 filler;
}
struct ShortRecord {
uint88 collateral;
uint88 ercDebt;
uint80 dethYieldRate;
SR status;
uint8 prevId;
uint8 id;
uint8 nextId;
uint64 ercDebtRate;
uint32 updatedAt;
uint32 flaggedAt;
uint24 flaggerId;
uint40 tokenId;
}
struct NFT {
address owner;
uint8 assetId;
uint8 shortRecordId;
}
struct Asset {
uint104 ercDebt;
uint88 dethCollateral;
uint16 startingShortId;
uint16 orderIdCounter;
uint16 initialCR;
F frozen;
uint8 vault;
uint8 minBidEth;
uint8 minAskEth;
uint16 minShortErc;
uint8 minimumCR;
uint8 tappFeePct;
uint8 callerFeePct;
uint8 forcedBidPriceBuffer;
uint8 assetId;
uint64 ercDebtRate;
uint16 primaryLiquidationCR;
uint16 secondaryLiquidationCR;
uint8 resetLiquidationTime;
uint8 secondLiquidationTime;
uint8 firstLiquidationTime;
uint64 filler;
address oracle;
}
struct Vault {
uint88 dethCollateral;
uint88 dethTotal;
uint80 dethYieldRate;
uint88 dethCollateralReward;
uint16 dethTithePercent;
uint16 dittoShorterRate;
uint128 filler2;
uint128 dittoMatchedShares;
uint96 dittoMatchedReward;
uint16 dittoMatchedRate;
uint16 dittoMatchedTime;
}
struct AssetUser {
uint104 ercEscrowed;
uint24 g_flaggerId;
uint32 g_flaggedAt;
uint8 shortRecordIdCounter;
uint96 filler;
}
struct VaultUser {
uint88 ethEscrowed;
uint88 dittoMatchedShares;
uint80 dittoReward;
}
struct Bridge {
uint8 vault;
uint16 withdrawalFee;
uint8 unstakeFee;
}
}
library MTypes {
struct OrderHint {
uint16 hintId;
uint256 creationTime;
}
struct BatchLiquidation {
address shorter;
uint8 shortId;
}
struct Match {
uint88 fillEth;
uint88 fillErc;
uint88 colUsed;
uint88 dittoMatchedShares;
uint88 shortFillEth;
uint96 askFillErc;
bool ratesQueried;
uint80 dethYieldRate;
uint64 ercDebtRate;
}
struct ExitShort {
address asset;
uint256 ercDebt;
uint88 collateral;
uint88 ethFilled;
uint88 ercAmountLeft;
uint88 ercFilled;
uint256 beforeExitCR;
}
struct CombineShorts {
bool shortFlagExists;
uint32 shortUpdatedAt;
}
struct PrimaryLiquidation {
address asset;
uint256 vault;
STypes.ShortRecord short;
address shorter;
uint256 cRatio;
uint80 oraclePrice;
uint256 forcedBidPriceBuffer;
uint256 ethDebt;
uint88 ethFilled;
uint88 ercDebtMatched;
bool loseCollateral;
uint256 tappFeePct;
uint256 callerFeePct;
uint88 gasFee;
uint88 totalFee;
uint256 minimumCR;
}
struct SecondaryLiquidation {
address asset;
uint256 vault;
STypes.ShortRecord short;
address shorter;
uint256 cRatio;
uint256 minimumCR;
uint88 liquidatorCollateral;
uint256 oraclePrice;
}
struct BidMatchAlgo {
uint16 askId;
uint16 shortHintId;
uint16 shortId;
uint16 prevShortId;
uint16 firstShortIdBelowOracle;
uint16 matchedAskId;
uint16 matchedShortId;
bool isMovingBack;
bool isMovingFwd;
uint256 oraclePrice;
uint16 dustAskId;
uint16 dustShortId;
}
struct CreateVaultParams {
uint16 dethTithePercent;
uint16 dittoMatchedRate;
uint16 dittoShorterRate;
}
struct CreateLimitShortParam {
address asset;
uint256 eth;
uint256 minShortErc;
uint256 minAskEth;
uint16 startingId;
uint256 oraclePrice;
}
}
文件 4 的 10:Diamond.sol
pragma solidity 0.8.21;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {LibDiamond} from "contracts/libraries/LibDiamond.sol";
import {IDiamondLoupe} from "contracts/interfaces/IDiamondLoupe.sol";
import {IDiamondCut} from "contracts/interfaces/IDiamondCut.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {AppStorage} from "contracts/libraries/AppStorage.sol";
import {Errors} from "contracts/libraries/Errors.sol";
import {Constants} from "contracts/libraries/Constants.sol";
contract Diamond {
AppStorage internal s;
constructor(address _contractOwner, address _diamondCutFacet, address _baseOracle)
payable
{
require(_contractOwner != address(0), "Diamond: owner can't be address(0)");
LibDiamond.setContractOwner(_contractOwner);
s.admin = _contractOwner;
IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);
bytes4[] memory functionSelectors = new bytes4[](1);
functionSelectors[0] = IDiamondCut.diamondCut.selector;
cut[0] = IDiamondCut.FacetCut({
facetAddress: _diamondCutFacet,
action: IDiamondCut.FacetCutAction.Add,
functionSelectors: functionSelectors
});
LibDiamond.diamondCut(cut, address(0), "");
LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
ds.supportedInterfaces[type(IERC165).interfaceId] = true;
ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true;
ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;
ds.supportedInterfaces[type(IERC721).interfaceId] = true;
s.reentrantStatus = Constants.NOT_ENTERED;
s.tokenIdCounter = s.flaggerIdCounter = Constants.HEAD;
s.name = "DITTO_NFT";
s.symbol = "DNFT";
require(_baseOracle != address(0), "Base oracle can't be address(0)");
s.baseOracle = _baseOracle;
}
fallback() external payable {
LibDiamond.DiamondStorage storage ds;
bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
assembly {
ds.slot := position
}
address facet = address(bytes20(ds.facets[msg.sig]));
if (facet == address(0)) revert Errors.FunctionNotFound(msg.sig);
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
receive() external payable {
revert("Diamond: Does not accept ether");
}
}
文件 5 的 10:Errors.sol
pragma solidity 0.8.21;
library Errors {
error AlreadyMinted();
error AssetIsFrozen();
error AssetIsNotPermanentlyFrozen();
error BadHintIdArray();
error BadShortHint();
error BridgeAlreadyCreated();
error CannotCancelMoreThan1000Orders();
error CannotExitPartialFillSR();
error CannotFlagSelf();
error CannotLeaveDustAmount();
error CannotLiquidateSelf();
error CannotMintAnymoreNFTs();
error CannotMintLastShortRecord();
error CannotSocializeDebt();
error CannotTransferFlaggableShort();
error CannotTransferFlaggedShort();
error CollateralHigherThanMax();
error CRLowerThanMin();
error DifferentVaults();
error ExitShortPriceTooLow();
error FirstShortDeleted();
error FirstShortMustBeNFT();
error FunctionNotFound(bytes4 _functionSelector);
error AlreadyLiquidatable();
error InvalidAmount();
error InvalidAsset();
error InvalidBridge();
error InvalidBuyback();
error InvalidFlaggerHint();
error InvalidInitialCR();
error InvalidMsgValue();
error InvalidPrice();
error InvalidShortId();
error InvalidTithe();
error InvalidTokenId();
error InvalidTwapPrice();
error InvalidTWAPSecondsAgo();
error InvalidVault();
error InvalidDeth();
error InsufficientWalletBalance();
error InsufficientCollateral();
error InsufficientERCEscrowed();
error InsufficientETHEscrowed();
error InsufficientEthInLiquidityPool();
error InsufficientNumberOfShorts();
error IsNotNFT();
error LiquidationAlreadyFlagged();
error LiquidationIneligibleWindow();
error SecondaryLiquidationNoValidShorts();
error MarketAlreadyCreated();
error NoDittoReward();
error NoSells();
error NoShares();
error NotActiveOrder();
error NotBridgeForBaseCollateral();
error NotDiamond();
error NotLastOrder();
error NotMinted();
error NotOwner();
error NotOwnerOrAdmin();
error NotOwnerCandidate();
error NoYield();
error OrderIdCountTooLow();
error OrderUnderMinimumSize();
error OriginalShortRecordCancelled();
error ParameterIsZero();
error PostExitCRLtPreExitCR();
error PriceOrAmountIs0();
error ReceiverExceededShortRecordLimit();
error ReentrantCall();
error ReentrantCallView();
error ShortNotFlagged();
error ShortRecordIdOverflow();
error ShortRecordIdsNotSorted();
error SufficientCollateral();
error TooManyHints();
error UnderMinimum();
error UnderMinimumDeposit();
error VaultAlreadyCreated();
error ERC721InvalidOwner(address owner);
error ERC721NonexistentToken(uint256 tokenId);
error ERC721InvalidOperator(address operator);
error ERC721InsufficientApproval(address operator, uint256 tokenId);
error ERC721InvalidApprover(address approver);
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
error ERC721InvalidReceiver(address receiver);
}
文件 6 的 10:IDiamondCut.sol
pragma solidity 0.8.21;
interface IDiamondCut {
enum FacetCutAction {
Add,
Replace,
Remove
}
struct FacetCut {
address facetAddress;
FacetCutAction action;
bytes4[] functionSelectors;
}
function diamondCut(
FacetCut[] calldata _diamondCut,
address _init,
bytes calldata _calldata
) external;
event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}
文件 7 的 10:IDiamondLoupe.sol
pragma solidity 0.8.21;
interface IDiamondLoupe {
struct Facet {
address facetAddress;
bytes4[] functionSelectors;
}
function facets() external view returns (Facet[] memory facets_);
function facetFunctionSelectors(address _facet)
external
view
returns (bytes4[] memory facetFunctionSelectors_);
function facetAddresses() external view returns (address[] memory facetAddresses_);
function facetAddress(bytes4 _functionSelector)
external
view
returns (address facetAddress_);
}
文件 8 的 10:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 9 的 10:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 10 的 10:LibDiamond.sol
pragma solidity 0.8.21;
import {IDiamondCut} from "contracts/interfaces/IDiamondCut.sol";
library LibDiamond {
bytes32 constant DIAMOND_STORAGE_POSITION =
keccak256("diamond.standard.diamond.storage");
struct DiamondStorage {
mapping(bytes4 => bytes32) facets;
mapping(uint256 => bytes32) selectorSlots;
mapping(bytes4 => bool) supportedInterfaces;
uint16 selectorCount;
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 {
require(
msg.sender == diamondStorage().contractOwner,
"LibDiamond: Must be contract owner"
);
}
event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);
bytes32 constant CLEAR_ADDRESS_MASK = bytes32(uint256(0xffffffffffffffffffffffff));
bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));
function diamondCut(
IDiamondCut.FacetCut[] memory _diamondCut,
address _init,
bytes memory _calldata
) internal {
DiamondStorage storage ds = diamondStorage();
uint256 originalSelectorCount = ds.selectorCount;
uint256 selectorCount = originalSelectorCount;
bytes32 selectorSlot;
if (selectorCount % 8 > 0) {
selectorSlot = ds.selectorSlots[selectorCount / 8];
}
for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
(selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(
selectorCount,
selectorSlot,
_diamondCut[facetIndex].facetAddress,
_diamondCut[facetIndex].action,
_diamondCut[facetIndex].functionSelectors
);
}
if (selectorCount != originalSelectorCount) {
ds.selectorCount = uint16(selectorCount);
}
if (selectorCount % 8 > 0) {
ds.selectorSlots[selectorCount / 8] = selectorSlot;
}
emit DiamondCut(_diamondCut, _init, _calldata);
initializeDiamondCut(_init, _calldata);
}
function addReplaceRemoveFacetSelectors(
uint256 _selectorCount,
bytes32 _selectorSlot,
address _newFacetAddress,
IDiamondCut.FacetCutAction _action,
bytes4[] memory _selectors
) internal returns (uint256, bytes32) {
DiamondStorage storage ds = diamondStorage();
require(_selectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
if (_action == IDiamondCut.FacetCutAction.Add) {
require(
_newFacetAddress != address(0),
"LibDiamondCut: Add facet can't be address(0)"
);
enforceHasContractCode(
_newFacetAddress, "LibDiamondCut: Add facet has no code"
);
for (
uint256 selectorIndex; selectorIndex < _selectors.length; selectorIndex++
) {
bytes4 selector = _selectors[selectorIndex];
bytes32 oldFacet = ds.facets[selector];
require(
address(bytes20(oldFacet)) == address(0),
"LibDiamondCut: Can't add function that already exists"
);
ds.facets[selector] = bytes20(_newFacetAddress) | bytes32(_selectorCount);
uint256 selectorInSlotPosition = (_selectorCount % 8) * 32;
_selectorSlot = (
_selectorSlot & ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)
) | (bytes32(selector) >> selectorInSlotPosition);
if (selectorInSlotPosition == 224) {
ds.selectorSlots[_selectorCount / 8] = _selectorSlot;
_selectorSlot = 0;
}
_selectorCount++;
}
} else if (_action == IDiamondCut.FacetCutAction.Replace) {
require(
_newFacetAddress != address(0),
"LibDiamondCut: Replace facet can't be address(0)"
);
enforceHasContractCode(
_newFacetAddress, "LibDiamondCut: Replace facet has no code"
);
for (
uint256 selectorIndex; selectorIndex < _selectors.length; selectorIndex++
) {
bytes4 selector = _selectors[selectorIndex];
bytes32 oldFacet = ds.facets[selector];
address oldFacetAddress = address(bytes20(oldFacet));
require(
oldFacetAddress != address(this),
"LibDiamondCut: Can't replace immutable function"
);
require(
oldFacetAddress != _newFacetAddress,
"LibDiamondCut: Can't replace function with same function"
);
require(
oldFacetAddress != address(0),
"LibDiamondCut: Can't replace function that doesn't exist"
);
ds.facets[selector] =
(oldFacet & CLEAR_ADDRESS_MASK) | bytes20(_newFacetAddress);
}
} else if (_action == IDiamondCut.FacetCutAction.Remove) {
require(
_newFacetAddress == address(0),
"LibDiamondCut: Remove facet address must be address(0)"
);
uint256 selectorSlotCount = _selectorCount / 8;
uint256 selectorInSlotIndex = (_selectorCount % 8) - 1;
for (
uint256 selectorIndex; selectorIndex < _selectors.length; selectorIndex++
) {
if (_selectorSlot == 0) {
selectorSlotCount--;
_selectorSlot = ds.selectorSlots[selectorSlotCount];
selectorInSlotIndex = 7;
}
bytes4 lastSelector;
uint256 oldSelectorsSlotCount;
uint256 oldSelectorInSlotPosition;
{
bytes4 selector = _selectors[selectorIndex];
bytes32 oldFacet = ds.facets[selector];
require(
address(bytes20(oldFacet)) != address(0),
"LibDiamondCut: Can't remove function that doesn't exist"
);
require(
address(bytes20(oldFacet)) != address(this),
"LibDiamondCut: Can't remove immutable function"
);
lastSelector = bytes4(_selectorSlot << (selectorInSlotIndex * 32));
if (lastSelector != selector) {
ds.facets[lastSelector] = (oldFacet & CLEAR_ADDRESS_MASK)
| bytes20(ds.facets[lastSelector]);
}
delete ds.facets[selector];
uint256 oldSelectorCount = uint16(uint256(oldFacet));
oldSelectorsSlotCount = oldSelectorCount / 8;
oldSelectorInSlotPosition = (oldSelectorCount % 8) * 32;
}
if (oldSelectorsSlotCount != selectorSlotCount) {
bytes32 oldSelectorSlot = ds.selectorSlots[oldSelectorsSlotCount];
oldSelectorSlot = (
oldSelectorSlot
& ~(CLEAR_SELECTOR_MASK >> oldSelectorInSlotPosition)
) | (bytes32(lastSelector) >> oldSelectorInSlotPosition);
ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;
} else {
_selectorSlot = (
_selectorSlot
& ~(CLEAR_SELECTOR_MASK >> oldSelectorInSlotPosition)
) | (bytes32(lastSelector) >> oldSelectorInSlotPosition);
}
if (selectorInSlotIndex == 0) {
delete ds.selectorSlots[selectorSlotCount];
_selectorSlot = 0;
}
selectorInSlotIndex--;
}
_selectorCount = selectorSlotCount * 8 + selectorInSlotIndex + 1;
} else {
revert("LibDiamondCut: Incorrect FacetCutAction");
}
return (_selectorCount, _selectorSlot);
}
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 == false) {
if (error.length > 0) {
revert(string(error));
} 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);
}
}
{
"compilationTarget": {
"contracts/Diamond.sol": "Diamond"
},
"evmVersion": "shanghai",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1000000
},
"remappings": [
":@chainlink/=node_modules/@chainlink/",
":@eth-optimism/=node_modules/@eth-optimism/",
":@openzeppelin/=node_modules/@openzeppelin/",
":@prb/=node_modules/@prb/",
":contracts/=contracts/",
":deploy/=deploy/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/",
":interfaces/=interfaces/",
":test-gas/=test-gas/",
":test/=test/"
]
}
[{"inputs":[{"internalType":"address","name":"_contractOwner","type":"address"},{"internalType":"address","name":"_diamondCutFacet","type":"address"},{"internalType":"address","name":"_baseOracle","type":"address"}],"stateMutability":"payable","type":"constructor"},{"inputs":[{"internalType":"bytes4","name":"_functionSelector","type":"bytes4"}],"name":"FunctionNotFound","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"_init","type":"address"},{"indexed":false,"internalType":"bytes","name":"_calldata","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"},{"stateMutability":"payable","type":"receive"}]