编译器
0.8.23+commit.f704f362
文件 1 的 6:IDiamondCut.sol
pragma solidity ^0.8.23;
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);
}
文件 2 的 6:IDiamondLoupe.sol
pragma solidity ^0.8.23;
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_);
}
文件 3 的 6:IStaking.sol
pragma solidity ^0.8.23;
interface IStaking {
struct StakingParams {
address owner;
uint256 withdrawTimeout;
}
struct StakingDetails {
uint256 claimable;
uint256 withdrawable;
uint256 unstakedAmount;
uint256 totalRewards;
uint256 timeToWithdraw;
uint256 stakedAmount;
}
function transferOwnership(address _newOwner) external;
function owner() external view returns (address);
function rescueERC20(address _address) external;
function stake(uint256 _amount) external;
function unstake(uint256 _amount) external;
function restake() external;
function withdraw() external;
function claimRewards() external;
function getUserDetails(address) external view returns (StakingDetails memory);
}
文件 4 的 6:LibAppStorageStaking.sol
pragma solidity ^0.8.23;
import {LibDiamond} from "./LibDiamond.sol";
struct AppStorageStaking {
address token;
uint256 accRewardsPrecision;
uint256 totalStakedAmount;
uint256 withdrawTimeout;
uint256 unallocatedETH;
uint256 accRewardsPerShare;
uint256 totalETHCollected;
mapping(address => uint256) totalRewards;
mapping(address => uint256) rewardDebt;
mapping(address => uint256) stakedAmount;
mapping(address => uint256) claimedAmount;
mapping(address => uint256) claimableRewards;
mapping(address => uint256) lastUnstakeTime;
mapping(address => uint256) unstakedAmount;
}
contract Modifiers {
AppStorageStaking internal s;
}
文件 5 的 6:LibDiamond.sol
pragma solidity ^0.8.23;
import { IDiamondCut } from "../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, "l0");
}
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 & 7 > 0) {
selectorSlot = ds.selectorSlots[selectorCount >> 3];
}
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 & 7 > 0) {
ds.selectorSlots[selectorCount >> 3] = selectorSlot;
}
require(_init == address(0), "l1");
require(_calldata.length == 0, "l2");
}
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, "l3");
if (_action == IDiamondCut.FacetCutAction.Add) {
enforceHasContractCode(_newFacetAddress, "l4");
for (uint256 selectorIndex; selectorIndex < _selectors.length; selectorIndex++) {
bytes4 selector = _selectors[selectorIndex];
bytes32 oldFacet = ds.facets[selector];
require(address(bytes20(oldFacet)) == address(0), "l5");
ds.facets[selector] = bytes20(_newFacetAddress) | bytes32(_selectorCount);
uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;
_selectorSlot = (_selectorSlot & ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) | (bytes32(selector) >> selectorInSlotPosition);
if (selectorInSlotPosition == 224) {
ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;
_selectorSlot = 0;
}
_selectorCount++;
}
}
else {
revert("l6");
}
return (_selectorCount, _selectorSlot);
}
function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
uint256 contractSize;
assembly {
contractSize := extcodesize(_contract)
}
require(contractSize > 0, _errorMessage);
}
}
文件 6 的 6:StakingDiamond.sol
pragma solidity ^0.8.23;
import { LibDiamond } from "../libraries/LibDiamond.sol";
import { IDiamondCut } from "../interfaces/IDiamondCut.sol";
import "../interfaces/IDiamondLoupe.sol";
import "../interfaces/IDiamondCut.sol";
import {AppStorageStaking} from "../libraries/LibAppStorageStaking.sol";
import { IStaking } from "../interfaces/IStaking.sol";
contract StakingDiamond {
AppStorageStaking internal s;
event RewardsReceived(address indexed sender, uint256 amount, uint256 accRewardsPerShare);
constructor(IDiamondCut.FacetCut[] memory _diamondCut, IStaking.StakingParams memory params) {
require(params.owner != address(0));
LibDiamond.diamondCut(_diamondCut, address(0), new bytes(0));
LibDiamond.setContractOwner(params.owner);
LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;
s.accRewardsPrecision = 1e18;
s.token = msg.sender;
s.withdrawTimeout = params.withdrawTimeout;
}
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), "sd1");
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 {
uint256 amount = msg.value;
require(amount > 0, "sd2");
s.totalRewards[msg.sender] += amount;
s.totalETHCollected += amount;
if (s.totalStakedAmount == 0) {
s.unallocatedETH += amount;
} else {
s.accRewardsPerShare += ((amount+s.unallocatedETH) * s.accRewardsPrecision) / s.totalStakedAmount;
s.unallocatedETH = 0;
}
emit RewardsReceived(msg.sender, amount, s.accRewardsPerShare);
}
}
{
"compilationTarget": {
"contracts/facets/StakingDiamond.sol": "StakingDiamond"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"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[]"},{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"withdrawTimeout","type":"uint256"}],"internalType":"struct IStaking.StakingParams","name":"params","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accRewardsPerShare","type":"uint256"}],"name":"RewardsReceived","type":"event"},{"stateMutability":"payable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]