编译器
0.8.17+commit.8df45f5f
文件 1 的 9:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 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 functionCall(target, data, "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");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(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) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(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) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 9: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 的 9:FreqAIStaking.sol
pragma solidity ^0.8.17;
import "Context.sol";
import "Ownable.sol";
import "IERC20.sol";
import "SafeERC20.sol";
import "ReentrancyGuard.sol";
import "IUniswapV2Router02.sol";
import "IFreqAI.sol";
contract FreqAIStaking is Ownable, ReentrancyGuard {
using SafeERC20 for IERC20;
struct UserInfo {
uint16 lockTimeBoost;
uint32 lockedUntil;
uint96 claimableETH;
uint112 amount;
uint112 weightedBalance;
uint256 withdrawn;
uint112 ETHRewardDebt;
}
struct PoolInfo {
IERC20 lpToken;
uint64 allocPoint;
uint64 lastRewardBlock;
uint112 accETHPerShare;
uint112 weightedBalance;
}
uint256 constant ONE_DAY = 86400;
IFreqAI public FreqAI;
address public router;
address public WETH;
address public TaxDistributor;
uint256 public ETHPerBlock;
uint256 public ETHLeftUnshared;
uint256 public ETHLeftUnclaimed;
uint256 public numDays;
uint256 public boostMultiplier;
uint256 public blocksPerDay = 7200;
PoolInfo[] public poolInfo;
mapping(uint256 => mapping(address => UserInfo)) public userInfo;
uint256 public totalAllocPoint;
uint256 public startBlock;
bool public isEmergency;
event Deposit(address indexed user, uint256 indexed pid, uint256 amount, uint256 lockTime);
event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
event EmergencyWithdraw(
address indexed user,
uint256 indexed pid,
uint256 amount
);
event TokensLocked(
address indexed user,
uint256 timestamp,
uint256 lockTime
);
event Emergency(uint256 timestamp, bool ifEmergency);
mapping(IERC20 => bool) public poolExistence;
modifier nonDuplicated(IERC20 _lpToken) {
require(poolExistence[_lpToken] == false, "nonDuplicated: LP Token already added");
_;
}
modifier onlyEmergency() {
require(isEmergency == true, "onlyEmergency: Emergency use only!");
_;
}
mapping(address => bool) public authorized;
modifier onlyAuthorized() {
require(authorized[msg.sender] == true, "onlyAuthorized: address not authorized");
_;
}
constructor(IFreqAI _freqAI, address _router) {
FreqAI = _freqAI;
router = _router;
WETH = IUniswapV2Router02(router).WETH();
startBlock = type(uint256).max;
FreqAI.approve(router, FreqAI.totalSupply());
numDays = 30;
}
function poolLength() external view returns (uint256) {
return poolInfo.length;
}
function getMultiplier(uint256 _from, uint256 _to)
public
pure
returns (uint256)
{
return (_to - _from);
}
function pendingRewards(uint256 _pid, address _user) external view returns (uint256)
{
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 userWeightedAmount = user.weightedBalance;
uint256 accETHPerShare = pool.accETHPerShare;
uint256 weightedBalance = pool.weightedBalance;
uint256 PendingETH;
if (block.number > pool.lastRewardBlock && weightedBalance != 0) {
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 ETHReward = multiplier * ETHPerBlock * pool.allocPoint / totalAllocPoint;
accETHPerShare = accETHPerShare + ETHReward * 1e12 / weightedBalance;
PendingETH = (userWeightedAmount * accETHPerShare / 1e12) - user.ETHRewardDebt + user.claimableETH;
}
return (PendingETH);
}
function massUpdatePools() public {
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
updatePool(pid);
}
}
fallback() external payable {
ETHLeftUnshared += msg.value;
updateETHRewards();
}
receive() external payable {
require(msg.sender != TaxDistributor);
}
function updatePool(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
if (block.number <= pool.lastRewardBlock) {
return;
}
uint256 lpSupply = pool.weightedBalance;
if (lpSupply == 0 || pool.allocPoint == 0) {
pool.lastRewardBlock = uint64(block.number);
return;
}
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 ETHReward = multiplier * ETHPerBlock * pool.allocPoint / totalAllocPoint;
ETHLeftUnclaimed = ETHLeftUnclaimed + ETHReward;
ETHLeftUnshared = ETHLeftUnshared - ETHReward;
pool.accETHPerShare = uint112(pool.accETHPerShare + ETHReward * 1e12 / lpSupply);
pool.lastRewardBlock = uint64(block.number);
}
function deposit(uint256 _pid, uint256 _amount, uint256 lockTime) public nonReentrant {
_deposit(msg.sender, _pid, _amount, lockTime);
}
function withdraw(uint32 _pid, uint256 _amount) public nonReentrant {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.lockedUntil < block.timestamp, "withdraw: Tokens locked, if you're trying to claim your rewards use the deposit function");
require(user.amount >= _amount && _amount > 0, "withdraw: not good");
updatePool(_pid);
if (user.weightedBalance > 0) {
_addToClaimable(_pid, msg.sender);
if (user.claimableETH > 0) {
safeETHTransfer(msg.sender, user.claimableETH);
user.withdrawn += user.claimableETH;
user.claimableETH = 0;
}
}
user.amount = uint112(user.amount - _amount);
pool.lpToken.safeTransfer(address(msg.sender), _amount);
updateUserWeightedBalance(_pid, msg.sender);
emit Withdraw(msg.sender, _pid, _amount);
}
function emergencyWithdraw(uint256 _pid) public nonReentrant onlyEmergency {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
uint256 amount = user.amount;
pool.weightedBalance -= user.weightedBalance;
user.amount = 0;
user.weightedBalance = 0;
user.ETHRewardDebt = 0;
user.claimableETH = 0;
pool.lpToken.safeTransfer(address(msg.sender), amount);
emit EmergencyWithdraw(msg.sender, _pid, amount);
}
function addLiquidityNoFeeAndStake(uint256 amountTokensIn, uint256 amountETHMin, uint256 amountTokenMin, uint256 lockTime) public payable nonReentrant {
IFreqAI.LiquidityETHParams memory params;
UserInfo storage user = userInfo[0][msg.sender];
require(msg.value > 0);
require((lockTime >= 0 && lockTime <= 90 * ONE_DAY && user.lockedUntil <= lockTime + block.timestamp), "addLiquidityNoFeeAndStake : Lock out of range");
updatePool(0);
if (user.weightedBalance > 0) {
_addToClaimable(0, msg.sender);
}
FreqAI.transferFrom(msg.sender, address(this), amountTokensIn);
params.pair = address(poolInfo[0].lpToken);
params.to = address(this);
params.amountTokenMin = amountTokenMin;
params.amountETHMin = amountETHMin;
params.amountTokenOrLP = amountTokensIn;
params.deadline = block.timestamp;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(router);
(, uint256 ETHUsed, uint256 numLiquidityAdded) = _uniswapV2Router.addLiquidityETH{value : msg.value}(
address(FreqAI),
params.amountTokenOrLP,
params.amountTokenMin,
params.amountETHMin,
params.to,
block.timestamp
);
payable(msg.sender).transfer(msg.value - ETHUsed);
user.amount += uint112(numLiquidityAdded);
if (lockTime > 0) {
lockTokens(msg.sender, 0, lockTime);
} else {
updateUserWeightedBalance(0, msg.sender);
}
emit Deposit(msg.sender, 0, numLiquidityAdded, lockTime);
}
function reinvestETHRewards(uint256 amountOutMin) public nonReentrant {
UserInfo storage user = userInfo[1][msg.sender];
updatePool(1);
uint256 ETHPending = (user.weightedBalance * poolInfo[1].accETHPerShare / 1e12) - user.ETHRewardDebt + user.claimableETH;
require(ETHPending > 0);
address[] memory path = new address[](2);
path[0] = WETH;
path[1] = address(FreqAI);
if (ETHPending > ETHLeftUnclaimed) {
ETHPending = ETHLeftUnclaimed;
}
uint256 balanceBefore = FreqAI.balanceOf(address(this));
IUniswapV2Router02(router).swapExactETHForTokensSupportingFeeOnTransferTokens{value: ETHPending}(
amountOutMin,
path,
address(this),
block.timestamp
);
uint256 amountSwapped = FreqAI.balanceOf(address(this)) - balanceBefore;
user.amount += uint112(amountSwapped);
user.claimableETH = 0;
user.withdrawn += ETHPending;
updateUserWeightedBalance(1, msg.sender);
emit Deposit(msg.sender, 1, amountSwapped, 0);
}
function addToClaimable(uint256 _pid, address sender) public nonReentrant {
require(userInfo[_pid][sender].weightedBalance > 0);
updatePool(_pid);
_addToClaimable(_pid, sender);
}
function depositFor(address sender, uint256 _pid, uint256 amount, uint256 lockTime) public onlyAuthorized {
_deposit(sender, _pid, amount, lockTime);
}
function add(uint64 _allocPoint, IERC20 _lpToken, bool _withUpdate) public onlyOwner nonDuplicated(_lpToken) {
if (_withUpdate) {
massUpdatePools();
}
uint64 lastRewardBlock = uint64(block.number > startBlock ? block.number : startBlock);
totalAllocPoint = totalAllocPoint + _allocPoint;
poolExistence[_lpToken] = true;
poolInfo.push(
PoolInfo({
lpToken : _lpToken,
allocPoint : _allocPoint,
lastRewardBlock : lastRewardBlock,
accETHPerShare : 0,
weightedBalance : 0
}));
}
function setTaxDistributor(address _TaxDistributor) public onlyOwner {
TaxDistributor = _TaxDistributor;
}
function setRouter(address _router) public onlyOwner {
router = _router;
}
function rescueToken(address tokenAddress) public onlyOwner {
require(!poolExistence[IERC20(tokenAddress)], "rescueToken : wrong token address");
uint256 bal = IERC20(tokenAddress).balanceOf(address(this));
IERC20(tokenAddress).transfer(msg.sender, bal);
}
function set(uint256 _pid, uint64 _allocPoint, bool _withUpdate) public onlyOwner {
if (_withUpdate) {
massUpdatePools();
}
totalAllocPoint = totalAllocPoint - poolInfo[_pid].allocPoint + _allocPoint;
poolInfo[_pid].allocPoint = _allocPoint;
}
function startRewards() public onlyOwner {
require(startBlock > block.number, "startRewards: rewards already started");
startBlock = block.number;
for (uint256 i; i < poolInfo.length; i++) {
poolInfo[i].lastRewardBlock = uint64(block.number);
}
}
function emergency(bool _isEmergency) public onlyOwner {
isEmergency = _isEmergency;
emit Emergency(block.timestamp, _isEmergency);
}
function authorize(address _address) public onlyOwner {
authorized[_address] = true;
}
function unauthorize(address _address) public onlyOwner {
authorized[_address] = false;
}
function setNumDays(uint256 _days) public onlyOwner {
require(_days > 0 && _days < 180);
numDays = _days;
}
function setBoostMultiplier(uint256 _boostMultiplier) public onlyOwner {
require(_boostMultiplier < 10);
boostMultiplier = _boostMultiplier;
}
function setBlocksPerDay(uint256 _blocks) public onlyOwner {
blocksPerDay = _blocks;
}
function _deposit(address sender, uint256 _pid, uint256 _amount, uint256 lockTime) internal {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][sender];
updatePool(_pid);
if (user.weightedBalance > 0) {
if (_amount == 0 && lockTime == 0) {
uint256 ETHPending = (user.weightedBalance * pool.accETHPerShare / 1e12) - user.ETHRewardDebt + user.claimableETH;
if (ETHPending > 0) {
safeETHTransfer(sender, ETHPending);
user.withdrawn += ETHPending;
user.ETHRewardDebt = user.weightedBalance * pool.accETHPerShare / 1e12;
}
user.claimableETH = 0;
} else {
_addToClaimable(_pid, sender);
}
}
if (_amount > 0) {
require(
(lockTime >= 0 && lockTime <= 90 * ONE_DAY && user.lockedUntil <= lockTime + block.timestamp),
"deposit : Lock out of range or previously locked tokens are locked longer than new desired lock"
);
pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
user.amount = uint112(user.amount + _amount);
if (lockTime == 0) {
updateUserWeightedBalance(_pid, sender);
}
}
if (lockTime > 0) {
lockTokens(sender, _pid, lockTime);
}
if (user.lockedUntil < block.timestamp) {
updateUserWeightedBalance(_pid, sender);
}
emit Deposit(sender, _pid, _amount, lockTime);
}
function lockTokens(address sender, uint256 _pid, uint256 lockTime) internal {
UserInfo storage user = userInfo[_pid][sender];
require(user.amount > 0, "lockTokens: No tokens to lock");
require(user.lockedUntil <= block.timestamp + lockTime, "lockTokens: Tokens already locked");
require(lockTime >= ONE_DAY, "lockTokens: Lock time too short");
require(lockTime <= 90 * ONE_DAY, "lockTokens: Lock time too long");
user.lockedUntil = uint32(block.timestamp + lockTime);
user.lockTimeBoost = uint16((boostMultiplier * 1000 * lockTime) / (90 * ONE_DAY));
updateUserWeightedBalance(_pid, sender);
emit TokensLocked(sender, block.timestamp, lockTime);
}
function updateUserWeightedBalance(uint256 _pid, address _user) public {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 poolBalance = pool.weightedBalance - user.weightedBalance;
if (user.lockedUntil < block.timestamp) {
user.lockTimeBoost = 0;
}
user.weightedBalance = (user.amount * (1000 + user.lockTimeBoost) / 1000);
pool.weightedBalance = uint112(poolBalance + user.weightedBalance);
user.ETHRewardDebt = user.weightedBalance * pool.accETHPerShare / 1e12;
}
function updateETHRewards() internal {
massUpdatePools();
ETHPerBlock = ETHLeftUnshared / (blocksPerDay * numDays);
}
function _addToClaimable(uint256 _pid, address sender) internal {
UserInfo storage user = userInfo[_pid][sender];
PoolInfo storage pool = poolInfo[_pid];
uint256 ETHPending = (user.weightedBalance * pool.accETHPerShare / 1e12) - user.ETHRewardDebt;
if (ETHPending > 0) {
user.claimableETH += uint96(ETHPending);
user.ETHRewardDebt = user.weightedBalance * pool.accETHPerShare / 1e12;
}
}
function safeETHTransfer(address _to, uint256 _amount) internal {
if (_amount > ETHLeftUnclaimed) {
_amount = ETHLeftUnclaimed;
}
payable(_to).transfer(_amount);
ETHLeftUnclaimed -= _amount;
}
}
文件 4 的 9:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, 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 sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 5 的 9:IFreqAI.sol
pragma solidity 0.8.17;
import "IERC20.sol";
interface IFreqAI is IERC20 {
struct LiquidityETHParams {
address pair;
address to;
uint256 amountTokenOrLP;
uint256 amountTokenMin;
uint256 amountETHMin;
uint256 deadline;
}
}
文件 6 的 9:IUniswapV2Router02.sol
pragma solidity ^0.8.10;
pragma experimental ABIEncoderV2;
interface IUniswapV2Router02 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
)
external
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (
uint256 amountToken,
uint256 amountETH,
uint256 liquidity
);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
}
文件 7 的 9:Ownable.sol
pragma solidity ^0.8.0;
import "Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
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);
}
}
文件 8 的 9:ReentrancyGuard.sol
pragma solidity ^0.8.17;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 9 的 9:SafeERC20.sol
pragma solidity ^0.8.0;
import "IERC20.sol";
import "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 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
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");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
{
"compilationTarget": {
"FreqAIStaking.sol": "FreqAIStaking"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IFreqAI","name":"_freqAI","type":"address"},{"internalType":"address","name":"_router","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"},{"indexed":false,"internalType":"uint256","name":"lockTime","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"bool","name":"ifEmergency","type":"bool"}],"name":"Emergency","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":"EmergencyWithdraw","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":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lockTime","type":"uint256"}],"name":"TokensLocked","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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ETHLeftUnclaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETHLeftUnshared","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETHPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FreqAI","outputs":[{"internalType":"contract IFreqAI","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TaxDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_allocPoint","type":"uint64"},{"internalType":"contract IERC20","name":"_lpToken","type":"address"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountTokensIn","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"lockTime","type":"uint256"}],"name":"addLiquidityNoFeeAndStake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"sender","type":"address"}],"name":"addToClaimable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"authorize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksPerDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boostMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"lockTime","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"lockTime","type":"uint256"}],"name":"depositFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isEmergency","type":"bool"}],"name":"emergency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","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":[],"name":"isEmergency","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"numDays","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"name":"poolExistence","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"uint64","name":"allocPoint","type":"uint64"},{"internalType":"uint64","name":"lastRewardBlock","type":"uint64"},{"internalType":"uint112","name":"accETHPerShare","type":"uint112"},{"internalType":"uint112","name":"weightedBalance","type":"uint112"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"}],"name":"reinvestETHRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"rescueToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint64","name":"_allocPoint","type":"uint64"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blocks","type":"uint256"}],"name":"setBlocksPerDay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_boostMultiplier","type":"uint256"}],"name":"setBoostMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_days","type":"uint256"}],"name":"setNumDays","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_TaxDistributor","type":"address"}],"name":"setTaxDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAllocPoint","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":"_address","type":"address"}],"name":"unauthorize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"updateUserWeightedBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint16","name":"lockTimeBoost","type":"uint16"},{"internalType":"uint32","name":"lockedUntil","type":"uint32"},{"internalType":"uint96","name":"claimableETH","type":"uint96"},{"internalType":"uint112","name":"amount","type":"uint112"},{"internalType":"uint112","name":"weightedBalance","type":"uint112"},{"internalType":"uint256","name":"withdrawn","type":"uint256"},{"internalType":"uint112","name":"ETHRewardDebt","type":"uint112"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_pid","type":"uint32"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]