编译器
0.8.19+commit.7dd6d404
文件 1 的 8:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 8: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;
}
}
文件 3 的 8: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);
}
文件 4 的 8:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 5 的 8: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);
}
}
文件 6 的 8:PROPCStaking.sol
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
interface IPropcToken {
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function transfer(address to, uint256 amount) external returns (bool);
}
contract PROPCStaking is Ownable {
using SafeMath for uint256;
using SafeERC20 for IERC20;
struct UserInfo {
uint256 amount;
uint256 totalRedeemed;
uint256 lastClaimTimestamp;
uint256 depositTimestamp;
}
struct APYInfo {
uint256 apyPercent;
uint256 startTime;
uint256 stopTime;
}
struct PoolInfo {
uint256 startTime;
IERC20 rewardsToken;
uint256 totalStaked;
bool active;
uint256 claimTimeLimit;
uint256 penaltyFee;
uint256 penaltyTimeLimit;
address penaltyWallet;
bool isVIPPool;
mapping (address => bool) isVIPAddress;
mapping (uint256 => APYInfo) apyInfo;
uint256 lastAPYIndex;
}
IPropcToken public propcToken;
address public rewardsWallet;
uint256 public totalPools;
mapping(uint256 => PoolInfo) private poolInfo;
mapping (uint256 => mapping (address => UserInfo)) private userInfo;
event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
event Redeem(address indexed user, uint256 indexed pid, uint256 amount);
constructor(
IPropcToken _propc,
address _rewardsWallet
) {
propcToken = _propc;
rewardsWallet = _rewardsWallet;
}
function updateRewardsWallet(address _wallet) external onlyOwner {
require(_wallet != address(0x0), "invalid rewards wallet address");
rewardsWallet = _wallet;
}
function poolLength() public view returns (uint256) {
return totalPools;
}
function setPool(
uint256 _pid,
uint256 _startTime,
IERC20 _rewardsToken,
uint256 _apyPercent,
uint256 _claimTimeLimit,
uint256 _penaltyFee,
uint256 _penaltyTimeLimit,
bool _active,
address _penaltyWallet,
bool _isVIPPool
) public onlyOwner {
uint256 pid = _pid == 0 ? ++totalPools : _pid;
PoolInfo storage pool = poolInfo[pid];
require(_pid == 0 || pool.lastAPYIndex > 0, "pid is not exist");
require(_pid > 0 || _apyPercent > 0, "APY should be bigger than zero when adding a new pool");
require(_penaltyFee <= 3500, "penalty fee can not be more than 35%");
if (_pid == 0) {
pool.startTime = _startTime;
}
if (_apyPercent != pool.apyInfo[pool.lastAPYIndex].apyPercent) {
pool.apyInfo[pool.lastAPYIndex].stopTime = block.timestamp;
pool.lastAPYIndex ++;
APYInfo storage apyInfo = pool.apyInfo[pool.lastAPYIndex];
apyInfo.apyPercent = _apyPercent;
apyInfo.startTime = block.timestamp;
}
pool.rewardsToken = _rewardsToken;
pool.claimTimeLimit = _claimTimeLimit;
pool.penaltyFee = _penaltyFee;
pool.penaltyTimeLimit = _penaltyTimeLimit;
pool.active = _active;
pool.penaltyWallet = _penaltyWallet;
pool.isVIPPool = _isVIPPool;
}
function addVIPAddress(uint256 _pid, address _vipAddress) external onlyOwner {
PoolInfo storage pool = poolInfo[_pid];
require(pool.isVIPPool, "not vip pool");
pool.isVIPAddress[_vipAddress] = true;
}
function addVIPAddresses(uint256 _pid, address[] memory _vipAddresses) external onlyOwner {
PoolInfo storage pool = poolInfo[_pid];
require(pool.isVIPPool, "not vip pool");
for (uint256 i = 0; i < _vipAddresses.length; i++) {
pool.isVIPAddress[_vipAddresses[i]] = true;
}
}
function removeVIPAddress(uint256 _pid, address _vipAddress) external onlyOwner {
PoolInfo storage pool = poolInfo[_pid];
require(pool.isVIPPool, "not vip pool");
pool.isVIPAddress[_vipAddress] = false;
}
function removeVIPAddresses(uint256 _pid, address[] memory _vipAddresses) external onlyOwner {
PoolInfo storage pool = poolInfo[_pid];
require(pool.isVIPPool, "not vip pool");
for (uint256 i = 0; i < _vipAddresses.length; i++) {
pool.isVIPAddress[_vipAddresses[i]] = false;
}
}
function getMultiplier(uint256 _from, uint256 _to) public pure returns (uint256) {
return _to.sub(_from);
}
function _max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function _min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function pendingRewardsToken(uint256 _pid, address _user) public view returns (uint256) {
PoolInfo storage pool = poolInfo[_pid];
UserInfo memory user = userInfo[_pid][_user];
uint256 pendingRewards = 0;
for (uint256 apyIndex = pool.lastAPYIndex; apyIndex > 0; apyIndex--) {
if (pool.apyInfo[apyIndex].stopTime > 0 && user.lastClaimTimestamp >= pool.apyInfo[apyIndex].stopTime) {
break;
}
if (pool.apyInfo[apyIndex].apyPercent == 0) {
continue;
}
uint256 _fromTime = _max(user.lastClaimTimestamp, pool.apyInfo[apyIndex].startTime);
uint256 _toTime = block.timestamp;
if (pool.apyInfo[apyIndex].stopTime > 0 && block.timestamp > pool.apyInfo[apyIndex].stopTime) {
_toTime = pool.apyInfo[apyIndex].stopTime;
}
if (_fromTime >= _toTime) {
continue;
}
uint256 multiplier = getMultiplier(_fromTime, _toTime);
uint256 rewardsPerAPYBlock = multiplier.mul(pool.apyInfo[apyIndex].apyPercent).mul(user.amount).div(365 days).div(10000);
pendingRewards = pendingRewards.add(rewardsPerAPYBlock);
}
return pendingRewards;
}
function allPendingRewardsToken(address _user) public view returns (uint256[] memory) {
uint256 length = poolLength();
uint256[] memory pendingRewards = new uint256[](length);
for(uint256 _pid = 1; _pid <= length; _pid++) {
pendingRewards[_pid - 1] = pendingRewardsToken(_pid, _user);
}
return pendingRewards;
}
function joinPool(uint256 _pid, uint256 _amount) external {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(pool.startTime < block.timestamp, "mining is not started yet");
require(pool.active, "pool not active");
require(!pool.isVIPPool || pool.isVIPAddress[msg.sender] == true, "not vip address");
if (user.amount > 0) {
uint256 pendingRewards = pendingRewardsToken(_pid, msg.sender);
if(pendingRewards > 0) {
safeRewardTransfer(_pid, msg.sender, pendingRewards);
user.totalRedeemed = user.totalRedeemed.add(pendingRewards);
}
}
propcToken.transferFrom(msg.sender, address(this), _amount);
user.amount = user.amount.add(_amount);
user.lastClaimTimestamp = block.timestamp;
user.depositTimestamp = block.timestamp;
pool.totalStaked = pool.totalStaked.add(_amount);
emit Deposit(msg.sender, _pid, _amount);
}
function leavePool(uint256 _pid, uint256 _amount) external {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
uint256 pendingRewards = pendingRewardsToken(_pid, msg.sender);
if(pendingRewards > 0) {
safeRewardTransfer(_pid, msg.sender, pendingRewards);
user.totalRedeemed = user.totalRedeemed.add(pendingRewards);
}
uint256 penaltyAmount = 0;
if (user.depositTimestamp + pool.penaltyTimeLimit > block.timestamp) {
penaltyAmount = _amount.mul(pool.penaltyFee).div(10000);
}
propcToken.transfer(msg.sender, _amount.sub(penaltyAmount));
propcToken.transfer(pool.penaltyWallet, penaltyAmount);
user.amount = user.amount.sub(_amount);
user.lastClaimTimestamp = block.timestamp;
user.depositTimestamp = block.timestamp;
pool.totalStaked = pool.totalStaked.sub(_amount);
emit Withdraw(msg.sender, _pid, _amount);
}
function _redeem(uint256 _pid, bool _require) private {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.lastClaimTimestamp + pool.claimTimeLimit < block.timestamp, "doesn't meet the claim time limit");
uint256 pendingRewards = pendingRewardsToken(_pid, msg.sender);
if (_require) {
require(pendingRewards > 0, "no pending rewards");
}
user.lastClaimTimestamp = block.timestamp;
if (pendingRewards > 0) {
user.totalRedeemed += pendingRewards;
safeRewardTransfer(_pid, msg.sender, pendingRewards);
emit Redeem(msg.sender, _pid, pendingRewards);
}
}
function redeem(uint256 _pid) public {
_redeem(_pid, true);
}
function redeemAll() public {
uint256[] memory pendingRewards = allPendingRewardsToken(msg.sender);
uint256 allPendingRewards = 0;
for (uint256 i = 0; i < pendingRewards.length; i++) {
allPendingRewards = allPendingRewards.add(pendingRewards[i]);
}
require(allPendingRewards > 0, "no pending rewards");
for(uint _pid = 1; _pid <= poolLength(); _pid++) {
_redeem(_pid, false);
}
}
function safeRewardTransfer(uint256 _pid, address _to, uint256 _amount) internal {
IERC20(poolInfo[_pid].rewardsToken).safeTransferFrom(rewardsWallet, _to, _amount);
}
function getUserInfo(uint256 _pid, address _account) public view returns(
uint256 amount,
uint256 totalRedeemed,
uint256 lastClaimTimestamp,
uint256 depositTimestamp
) {
UserInfo memory user = userInfo[_pid][_account];
return (
user.amount,
user.totalRedeemed,
user.lastClaimTimestamp,
user.depositTimestamp
);
}
function getPoolInfo(uint256 _pid) public view returns(
uint256 startTime,
address rewardsToken,
address penaltyWallet,
uint256 apyPercent,
uint256 totalStaked,
bool active,
uint256 claimTimeLimit,
uint256 penaltyFee,
uint256 penaltyTimeLimit,
bool isVIPPool
) {
PoolInfo storage pool = poolInfo[_pid];
startTime = pool.startTime;
penaltyWallet = pool.penaltyWallet;
isVIPPool = pool.isVIPPool;
rewardsToken = address(pool.rewardsToken);
apyPercent = pool.apyInfo[pool.lastAPYIndex].apyPercent;
totalStaked = pool.totalStaked;
active = pool.active;
claimTimeLimit = pool.claimTimeLimit;
penaltyFee = pool.penaltyFee;
penaltyTimeLimit = pool.penaltyTimeLimit;
}
}
文件 7 的 8:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 8 的 8:SafeMath.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
{
"compilationTarget": {
"contracts/platform/staking/PROPCStaking.sol": "PROPCStaking"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 4000
},
"remappings": [],
"viaIR": true
}
[{"inputs":[{"internalType":"contract IPropcToken","name":"_propc","type":"address"},{"internalType":"address","name":"_rewardsWallet","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","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":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_vipAddress","type":"address"}],"name":"addVIPAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address[]","name":"_vipAddresses","type":"address[]"}],"name":"addVIPAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"allPendingRewardsToken","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"getMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getPoolInfo","outputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"address","name":"rewardsToken","type":"address"},{"internalType":"address","name":"penaltyWallet","type":"address"},{"internalType":"uint256","name":"apyPercent","type":"uint256"},{"internalType":"uint256","name":"totalStaked","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"claimTimeLimit","type":"uint256"},{"internalType":"uint256","name":"penaltyFee","type":"uint256"},{"internalType":"uint256","name":"penaltyTimeLimit","type":"uint256"},{"internalType":"bool","name":"isVIPPool","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_account","type":"address"}],"name":"getUserInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"totalRedeemed","type":"uint256"},{"internalType":"uint256","name":"lastClaimTimestamp","type":"uint256"},{"internalType":"uint256","name":"depositTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"joinPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"leavePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingRewardsToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"propcToken","outputs":[{"internalType":"contract IPropcToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_vipAddress","type":"address"}],"name":"removeVIPAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address[]","name":"_vipAddresses","type":"address[]"}],"name":"removeVIPAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardsWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"contract IERC20","name":"_rewardsToken","type":"address"},{"internalType":"uint256","name":"_apyPercent","type":"uint256"},{"internalType":"uint256","name":"_claimTimeLimit","type":"uint256"},{"internalType":"uint256","name":"_penaltyFee","type":"uint256"},{"internalType":"uint256","name":"_penaltyTimeLimit","type":"uint256"},{"internalType":"bool","name":"_active","type":"bool"},{"internalType":"address","name":"_penaltyWallet","type":"address"},{"internalType":"bool","name":"_isVIPPool","type":"bool"}],"name":"setPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalPools","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"updateRewardsWallet","outputs":[],"stateMutability":"nonpayable","type":"function"}]