编译器
0.8.23+commit.f704f362
文件 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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 2 的 5:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 3 的 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);
}
}
文件 4 的 5:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
文件 5 的 5:StakeManager.sol
pragma solidity ^0.8.23;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract StakeManager is Ownable, ReentrancyGuard {
IERC20 public maskToken;
struct Pool {
uint256 pointAccStartBlock;
uint256 pointAccEndBlock;
bool unlocked;
bool stakingEnabled;
}
struct UserInfo {
uint256 stakedAmount;
uint8 poolId;
}
Pool[] public pools;
mapping(address => UserInfo) public userInfos;
uint8 public currentPoolId = 0;
event Staked(address indexed account, uint8 indexed poolId, uint256 stakedAmount);
event StakeChanged(address indexed account, uint8 indexed fromPoolId, uint8 indexed toPoolId);
event unstaked(address indexed account, uint8 indexed poolId, uint256 unStakedAmount);
event PoolCreated(
uint8 indexed poolId, uint256 pointAccStartBlock, uint256 pointAccEndBlock, bool unlocked, bool stakingEnabled
);
event PoolUpdated(
uint8 indexed poolId, uint256 pointAccStartBlock, uint256 pointAccEndBlock, bool unlocked, bool stakingEnabled
);
event CurrentPoolIdChanged(uint8 indexed fromPoolId, uint8 indexed toPoolId);
constructor(address _maskToken) Ownable() {
maskToken = IERC20(_maskToken);
}
function depositAndLock(uint256 _amount) public nonReentrant {
Pool storage pool = pools[currentPoolId];
require(pool.stakingEnabled, "Staking is disabled for this pool");
require(maskToken.transferFrom(msg.sender, address(this), _amount), "Transfer failed");
userInfos[msg.sender].stakedAmount += _amount;
userInfos[msg.sender].poolId = currentPoolId;
emit Staked(msg.sender, currentPoolId, _amount);
}
function withdraw(uint256 _amount) public nonReentrant {
Pool storage pool = pools[userInfos[msg.sender].poolId];
require(pool.unlocked, "Pool is locked");
require(userInfos[msg.sender].stakedAmount >= _amount, "Insufficient balance");
userInfos[msg.sender].stakedAmount -= _amount;
require(maskToken.transfer(msg.sender, _amount), "Transfer failed");
emit unstaked(msg.sender, userInfos[msg.sender].poolId, _amount);
}
function changePool() public nonReentrant {
uint8 fromPoolId = userInfos[msg.sender].poolId;
Pool storage fromPool = pools[userInfos[msg.sender].poolId];
Pool storage toPool = pools[currentPoolId];
require(fromPoolId != currentPoolId, "No need to change");
require(toPool.stakingEnabled, "Staking is disabled for this pool");
require(fromPool.unlocked, "From pool is locked");
require(userInfos[msg.sender].stakedAmount > 0, "No staked amount");
userInfos[msg.sender].poolId = currentPoolId;
emit StakeChanged(msg.sender, fromPoolId, currentPoolId);
}
function createPool(Pool calldata _pool) public onlyOwner {
pools.push(_pool);
emit PoolCreated(
uint8(pools.length - 1),
_pool.pointAccStartBlock,
_pool.pointAccEndBlock,
_pool.unlocked,
_pool.stakingEnabled
);
}
function updatePool(uint8 _poolId, Pool calldata _pool) public onlyOwner {
Pool storage pool = pools[_poolId];
pool.pointAccStartBlock = _pool.pointAccStartBlock;
pool.pointAccEndBlock = _pool.pointAccEndBlock;
pool.unlocked = _pool.unlocked;
pool.stakingEnabled = _pool.stakingEnabled;
emit PoolUpdated(
_poolId, _pool.pointAccStartBlock, _pool.pointAccEndBlock, _pool.unlocked, _pool.stakingEnabled
);
}
function updateCurrentPoolId(uint8 _poolId) public onlyOwner {
uint8 fromPoolId = currentPoolId;
Pool storage fromPool = pools[fromPoolId];
require(fromPool.unlocked, "From pool is locked");
Pool storage pool = pools[_poolId];
require(pool.stakingEnabled, "Staking is disabled for this pool");
currentPoolId = _poolId;
emit CurrentPoolIdChanged(fromPoolId, _poolId);
}
}
{
"compilationTarget": {
"src/StakeManager.sol": "StakeManager"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 10000
},
"remappings": [
":@ensdomains/=node_modules/@ensdomains/",
":@nomiclabs/=node_modules/@nomiclabs/",
":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
":@solidity-parser/=node_modules/@solidity-parser/",
":ds-test/=node_modules/ds-test/src/",
":erc4626-tests/=lib/murky/lib/openzeppelin-contracts/lib/erc4626-tests/",
":eth-gas-reporter/=node_modules/eth-gas-reporter/",
":forge-std/=node_modules/forge-std/src/",
":hardhat-deploy/=node_modules/hardhat-deploy/",
":hardhat/=node_modules/hardhat/",
":murky/=lib/murky/src/",
":openzeppelin-contracts/=lib/murky/lib/openzeppelin-contracts/"
]
}
[{"inputs":[{"internalType":"address","name":"_maskToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"fromPoolId","type":"uint8"},{"indexed":true,"internalType":"uint8","name":"toPoolId","type":"uint8"}],"name":"CurrentPoolIdChanged","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"poolId","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"pointAccStartBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pointAccEndBlock","type":"uint256"},{"indexed":false,"internalType":"bool","name":"unlocked","type":"bool"},{"indexed":false,"internalType":"bool","name":"stakingEnabled","type":"bool"}],"name":"PoolCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"poolId","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"pointAccStartBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pointAccEndBlock","type":"uint256"},{"indexed":false,"internalType":"bool","name":"unlocked","type":"bool"},{"indexed":false,"internalType":"bool","name":"stakingEnabled","type":"bool"}],"name":"PoolUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint8","name":"fromPoolId","type":"uint8"},{"indexed":true,"internalType":"uint8","name":"toPoolId","type":"uint8"}],"name":"StakeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint8","name":"poolId","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"stakedAmount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint8","name":"poolId","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"unStakedAmount","type":"uint256"}],"name":"unstaked","type":"event"},{"inputs":[],"name":"changePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"pointAccStartBlock","type":"uint256"},{"internalType":"uint256","name":"pointAccEndBlock","type":"uint256"},{"internalType":"bool","name":"unlocked","type":"bool"},{"internalType":"bool","name":"stakingEnabled","type":"bool"}],"internalType":"struct StakeManager.Pool","name":"_pool","type":"tuple"}],"name":"createPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentPoolId","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositAndLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maskToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"uint256","name":"pointAccStartBlock","type":"uint256"},{"internalType":"uint256","name":"pointAccEndBlock","type":"uint256"},{"internalType":"bool","name":"unlocked","type":"bool"},{"internalType":"bool","name":"stakingEnabled","type":"bool"}],"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":"uint8","name":"_poolId","type":"uint8"}],"name":"updateCurrentPoolId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_poolId","type":"uint8"},{"components":[{"internalType":"uint256","name":"pointAccStartBlock","type":"uint256"},{"internalType":"uint256","name":"pointAccEndBlock","type":"uint256"},{"internalType":"bool","name":"unlocked","type":"bool"},{"internalType":"bool","name":"stakingEnabled","type":"bool"}],"internalType":"struct StakeManager.Pool","name":"_pool","type":"tuple"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfos","outputs":[{"internalType":"uint256","name":"stakedAmount","type":"uint256"},{"internalType":"uint8","name":"poolId","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]