编译器
0.8.17+commit.8df45f5f
文件 1 的 5:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 5:IStaking.sol
pragma solidity ^0.8.0;
struct StakingArgs {
address token;
address aggregator;
uint32 subscribeStageFrom;
uint32 subscribeStagePeriod;
uint32 earnStagePeriod;
uint32 claimStagePeriod;
uint64 maxTotalStake;
uint64 maxUserStake;
uint64 earningsQuota;
}
struct StakingData {
address token;
address aggregator;
uint32 subscribeStageFrom;
uint32 subscribeStageTo;
uint32 earnStageTo;
uint32 claimStageTo;
uint64 currentTotalDeposit;
uint64 maxTotalStake;
uint64 maxUserStake;
uint64 earningsQuota;
uint64 earningPercent;
uint64 unusedQuota;
}
struct StakingBalance {
uint64 current;
uint64 max;
}
interface IStaking {
function increaseDeposit(address from, uint256 value) external;
function withdrawDeposit(address from) external;
function claim(address from) external;
function getData() external view returns (StakingData memory);
function getUserBalance(address caller) external view returns (StakingBalance memory);
}
contract StakingTypes {
event DepositIncreased(address indexed user, uint256 value);
event DepositWithdrawn(address indexed user);
event Claimed(address indexed user, uint256 total);
error TokenTotalSupplyExceedsUint64();
error DepositTooEarly();
error DepositTooLate();
error BalanceTooLow();
error MaxUserStakeExceeded();
error MaxTotalStakeExceeded();
error ZeroBalance();
error TooEarlyForClaimStage();
error ZeroValue();
error ZeroUnusedQuota();
error UnusedQuotaAlreadyTransferred();
error SubscribeStageNotFinished();
error ClaimStageNotFinished();
error CallerIsNotAggregator();
}
文件 3 的 5:IStakingAggregatorV2.sol
pragma solidity ^0.8.0;
import './IStaking.sol';
contract IStakingAggregatorV2 {
error StakingInvalidAggregatorAddress();
}
struct StakingInstanceData {
address addr;
StakingData data;
}
文件 4 的 5:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 5 的 5:StakingAggregatorV2.sol
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/access/Ownable.sol';
import './IStaking.sol';
import './IStakingAggregatorV2.sol';
contract StakingAggregatorV2 is IStakingAggregatorV2, Ownable {
IStaking[] public instances;
function addInstance(IStaking instance) external onlyOwner {
if (instance.getData().aggregator != address(this)) {
revert StakingInvalidAggregatorAddress();
}
instances.push(instance);
}
function increaseDeposit(uint256 index, uint256 value) external {
return instances[index].increaseDeposit(msg.sender, value);
}
function withdrawDeposit(uint256 index) external {
instances[index].withdrawDeposit(msg.sender);
}
function claim(uint256 index) external {
return instances[index].claim(msg.sender);
}
function getInstances() external view returns (StakingInstanceData[] memory) {
StakingInstanceData[] memory arr = new StakingInstanceData[](instances.length);
for (uint256 i = 0; i < instances.length; i++) {
arr[i] = StakingInstanceData({addr: address(instances[i]), data: instances[i].getData()});
}
return arr;
}
function getUserBalances(address caller) external view returns (StakingBalance[] memory) {
StakingBalance[] memory arr = new StakingBalance[](instances.length);
for (uint256 i = 0; i < instances.length; i++) {
arr[i] = instances[i].getUserBalance(caller);
}
return arr;
}
}
{
"compilationTarget": {
"contracts/StakingAggregatorV2.sol": "StakingAggregatorV2"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"name":"StakingInvalidAggregatorAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"contract IStaking","name":"instance","type":"address"}],"name":"addInstance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getInstances","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"aggregator","type":"address"},{"internalType":"uint32","name":"subscribeStageFrom","type":"uint32"},{"internalType":"uint32","name":"subscribeStageTo","type":"uint32"},{"internalType":"uint32","name":"earnStageTo","type":"uint32"},{"internalType":"uint32","name":"claimStageTo","type":"uint32"},{"internalType":"uint64","name":"currentTotalDeposit","type":"uint64"},{"internalType":"uint64","name":"maxTotalStake","type":"uint64"},{"internalType":"uint64","name":"maxUserStake","type":"uint64"},{"internalType":"uint64","name":"earningsQuota","type":"uint64"},{"internalType":"uint64","name":"earningPercent","type":"uint64"},{"internalType":"uint64","name":"unusedQuota","type":"uint64"}],"internalType":"struct StakingData","name":"data","type":"tuple"}],"internalType":"struct StakingInstanceData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"getUserBalances","outputs":[{"components":[{"internalType":"uint64","name":"current","type":"uint64"},{"internalType":"uint64","name":"max","type":"uint64"}],"internalType":"struct StakingBalance[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"increaseDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"instances","outputs":[{"internalType":"contract IStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"withdrawDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"}]