文件 1 的 8:AppStorage.sol
pragma solidity 0.7.3;
struct Account {
uint96 ghst;
uint96 uniV2PoolTokens;
uint40 lastUpdate;
uint104 frens;
}
struct Ticket {
mapping(address => uint256) accountBalances;
uint96 totalSupply;
}
struct AppStorage {
mapping(address => mapping(address => bool)) approved;
mapping(address => Account) accounts;
mapping(uint256 => Ticket) tickets;
address ghstContract;
address uniV2PoolContract;
string ticketsBaseUri;
}
文件 2 的 8:GHSTStakingDiamond.sol
pragma solidity 0.7.3;
pragma experimental ABIEncoderV2;
import "./libraries/LibDiamond.sol";
import "./interfaces/IDiamondLoupe.sol";
import "./interfaces/IDiamondCut.sol";
import "./interfaces/IERC173.sol";
import "./interfaces/IERC165.sol";
import "./libraries/AppStorage.sol";
import "./interfaces/IERC1155Metadata_URI.sol";
contract GHSTStakingDiamond {
AppStorage s;
event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value);
constructor(
IDiamondCut.FacetCut[] memory _diamondCut,
address _owner,
address _ghstContract,
address _uniV2PoolContract
) {
require(_owner != address(0), "GHSTStakingDiamond: _owner can't be address(0)");
require(_ghstContract != address(0), "GHSTStakingDiamond: _ghstContract can't be address(0)");
require(_uniV2PoolContract != address(0), "GHSTStakingDiamond: _uniV2PoolContract can't be address(0)");
LibDiamond.diamondCut(_diamondCut, address(0), new bytes(0));
LibDiamond.setContractOwner(_owner);
LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
s.ghstContract = _ghstContract;
s.uniV2PoolContract = _uniV2PoolContract;
s.ticketsBaseUri = "https://aavegotchi.com/metadata/";
ds.supportedInterfaces[type(IERC165).interfaceId] = true;
ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;
ds.supportedInterfaces[type(IERC173).interfaceId] = true;
ds.supportedInterfaces[0xd9b67a26] = true;
ds.supportedInterfaces[IERC1155Metadata_URI.uri.selector] = true;
emit TransferSingle(msg.sender, address(0), address(0), 0, 0);
emit TransferSingle(msg.sender, address(0), address(0), 1, 0);
emit TransferSingle(msg.sender, address(0), address(0), 2, 0);
emit TransferSingle(msg.sender, address(0), address(0), 3, 0);
emit TransferSingle(msg.sender, address(0), address(0), 4, 0);
emit TransferSingle(msg.sender, address(0), address(0), 5, 0);
}
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]));
require(facet != address(0), "GHSTSTaking: Function does not exist");
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("GHSTStaking: Does not accept ether");
}
}
文件 3 的 8:IDiamondCut.sol
pragma solidity 0.7.3;
pragma experimental ABIEncoderV2;
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);
}
文件 4 的 8:IDiamondLoupe.sol
pragma solidity 0.7.3;
pragma experimental ABIEncoderV2;
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_);
}
文件 5 的 8:IERC1155Metadata_URI.sol
pragma solidity 0.7.3;
interface IERC1155Metadata_URI {
function uri(uint256 _id) external view returns (string memory);
}
文件 6 的 8:IERC165.sol
pragma solidity 0.7.3;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 7 的 8:IERC173.sol
pragma solidity 0.7.3;
interface IERC173 {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function owner() external view returns (address owner_);
function transferOwnership(address _newOwner) external;
}
文件 8 的 8:LibDiamond.sol
pragma solidity 0.7.3;
pragma experimental ABIEncoderV2;
import "../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;
uint16 selectorCount;
mapping(bytes4 => bool) supportedInterfaces;
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");
}
modifier onlyOwner {
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) {
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/GHSTStakingDiamond.sol": "GHSTStakingDiamond"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 20000
},
"remappings": []
}
[{"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_ghstContract","type":"address"},{"internalType":"address","name":"_uniV2PoolContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"stateMutability":"payable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]