编译器
0.8.19+commit.7dd6d404
文件 1 的 22:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 22: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);
}
}
}
文件 3 的 22: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;
}
}
文件 4 的 22:DeFiChefV2.sol
pragma solidity 0.8.19;
import '@openzeppelin/contracts/access/AccessControl.sol';
import '@openzeppelin/contracts/security/Pausable.sol';
import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import '@openzeppelin/contracts/interfaces/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '../vesting/interfaces/DeFiMerkleVesting/IDeFiMerkleVestingActions.sol';
import '../vesting/interfaces/DeFiVestingV2/IDeFiVestingV2Actions.sol';
import './interfaces/IDeFiChefV2.sol';
contract DeFiChefV2 is AccessControl, Pausable, ReentrancyGuard, IDeFiChefV2 {
using SafeERC20 for IERC20;
bytes32 public constant PAUSER_ROLE = keccak256('PAUSER_ROLE');
bytes32 public constant EXTERNAL_SOURCE_ROLE = keccak256('EXTERNAL_SOURCE_ROLE');
bytes32 public constant OPERATOR_ROLE = keccak256('OPERATOR_ROLE');
uint256 public constant YEAR = 360 days;
uint256 public constant PRECISION = 10 ** 18;
IERC20 public immutable DEFI;
IERC20 public immutable STAKE;
IDeFiVestingV2Actions public VESTING;
uint256 private _cooldown = 1 days;
uint16 private _poolsIndex = 1;
uint256 private _totalStaked;
mapping(PoolType => uint16) private _customPools;
mapping(uint16 => Pool) private _pools;
mapping(address => mapping(uint16 => mapping(uint256 => Stake))) private _stakes;
mapping(address => mapping(uint16 => uint256)) private _positions;
uint256 private _referralCliff = 7 days;
uint256 private _referralDuration = 180 days;
mapping(address => Referral) private _referrals;
mapping(address => uint256) private _referralsBalances;
constructor(IERC20 DEFI_, IERC20 STAKE_, IDeFiVestingV2Actions VESTING_) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(OPERATOR_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
if (address(DEFI_) == address(0)) revert TokenNullAddressErr();
if (address(STAKE_) == address(0)) revert TokenNullAddressErr();
if (address(VESTING_) == address(0)) revert TokenNullAddressErr();
DEFI = DEFI_;
STAKE = STAKE_;
VESTING = VESTING_;
}
modifier whenReferralEnabled(address referral_) {
if (_referrals[referral_].defined && !_referrals[referral_].enabled) revert ReferralDisabledErr(referral_);
_;
}
modifier whenReferralLvlV1(address referral_) {
if (
!_referrals[referral_].defined ||
!_referrals[referral_].enabled ||
_referrals[referral_].lvl != Lvl.v1
) revert ReferralLvlV1Err(referral_);
_;
}
modifier whenValidSource(address source_) {
if (!hasRole(EXTERNAL_SOURCE_ROLE, source_)) revert ExternalSourceAuthErr();
_;
}
function pause()
external
onlyRole(PAUSER_ROLE)
{
_pause();
}
function unpause()
external
onlyRole(PAUSER_ROLE)
{
_unpause();
}
function setupVesting(address vesting_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
VESTING = IDeFiVestingV2Actions(vesting_);
emit VestingSetup(vesting_);
}
function setupCooldown(uint256 cooldown_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
_cooldown = cooldown_;
emit CooldownSetup(cooldown_);
}
function setupPool(
uint256 minAmount_,
uint256 baseRate_,
uint256 boostRate_,
uint256 affRate_,
uint256 refRate_,
uint256 duration_,
PoolType type_,
bool enabled_
)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
uint16 pid = _poolsIndex;
_poolsIndex++;
_pools[pid] = Pool({
defined: true,
enabled: enabled_,
minAmount: minAmount_,
baseRate: baseRate_,
boostRate: boostRate_,
affRate: affRate_,
refRate: refRate_,
duration: duration_,
closedAt: 0,
closed: false
});
if (type_ == PoolType.baseline) {
_customPools[type_] = pid;
}
emit PoolAdded(pid, minAmount_, baseRate_, boostRate_, affRate_, refRate_, duration_, enabled_);
}
function updatePool(
uint16 pid_,
uint256 minAmount_,
uint256 baseRate_,
uint256 boostRate_,
uint256 affRate_,
uint256 refRate_,
uint256 duration_,
bool enabled_
)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (pid_ == 0 || !_pools[pid_].defined) revert PoolUndefinedErr(pid_);
if (_pools[pid_].closed) revert PoolClosedErr(pid_);
_pools[pid_].minAmount = minAmount_;
_pools[pid_].baseRate = baseRate_;
_pools[pid_].boostRate = boostRate_;
_pools[pid_].affRate = affRate_;
_pools[pid_].refRate = refRate_;
_pools[pid_].duration = duration_;
_pools[pid_].enabled = enabled_;
emit PoolUpdated(pid_, minAmount_, baseRate_, boostRate_, affRate_, refRate_, duration_, enabled_);
}
function enablePool(uint16 pid_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (pid_ == 0 || !_pools[pid_].defined) revert PoolUndefinedErr(pid_);
if (_pools[pid_].closed) revert PoolClosedErr(pid_);
_pools[pid_].enabled = true;
emit PoolUpdated(
pid_,
_pools[pid_].minAmount,
_pools[pid_].baseRate,
_pools[pid_].boostRate,
_pools[pid_].affRate,
_pools[pid_].refRate,
_pools[pid_].duration,
true
);
}
function disablePool(uint16 pid_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (pid_ == 0 || !_pools[pid_].defined) revert PoolUndefinedErr(pid_);
if (_pools[pid_].closed) revert PoolClosedErr(pid_);
_pools[pid_].enabled = false;
emit PoolUpdated(
pid_,
_pools[pid_].minAmount,
_pools[pid_].baseRate,
_pools[pid_].boostRate,
_pools[pid_].affRate,
_pools[pid_].refRate,
_pools[pid_].duration,
false
);
}
function closePool(uint16 pid_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (pid_ == 0 || !_pools[pid_].defined) revert PoolUndefinedErr(pid_);
if (_pools[pid_].closed) revert PoolClosedErr(pid_);
_pools[pid_].enabled = false;
_pools[pid_].closedAt = block.timestamp;
_pools[pid_].closed = true;
emit PoolClosed(pid_);
}
function setupReferrals(
address[] calldata referrals_,
Lvl[] calldata lvls_,
uint16[] calldata pools_,
uint256[] calldata rates_
)
public
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (referrals_.length != lvls_.length) revert ArrayParamsInvalidLengthErr();
if (pools_.length != rates_.length) revert ArrayParamsInvalidLengthErr();
uint256 rlength = referrals_.length;
uint256 plength = pools_.length;
for (uint256 ri = 0; ri < rlength; ri++) {
address referral = referrals_[ri];
Lvl lvl = lvls_[ri];
if (_referrals[referral].defined) revert ReferralDefinedErr(referral);
_referrals[referral].defined = true;
_referrals[referral].enabled = true;
_referrals[referral].lvl = lvl;
if (lvl == Lvl.v2) {
_referrals[referral].cliffAt = block.timestamp + _referralCliff;
}
for (uint16 pi = 0; pi < plength; pi++) {
uint16 pid = pools_[pi];
uint256 rate = rates_[pi];
if (pid == 0 || !_pools[pid].defined) revert PoolUndefinedErr(pid);
_referrals[referral].rates[pid] = rate;
}
emit ReferralAdded(referral, lvl);
}
}
function updateReferrals(
address[] calldata referrals_,
uint16[] calldata pools_,
uint256[] calldata rates_
)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (pools_.length != rates_.length) revert ArrayParamsInvalidLengthErr();
uint256 rlength = referrals_.length;
uint256 plength = pools_.length;
for (uint256 ri = 0; ri < rlength; ri++) {
address referral = referrals_[ri];
if (!_referrals[referral].defined) revert ReferralUndefinedErr(referral);
for (uint16 pi = 0; pi < plength; pi++) {
uint16 pid = pools_[pi];
uint256 rate = rates_[pi];
if (pid == 0 || !_pools[pid].defined) revert PoolUndefinedErr(pid);
_referrals[referral].rates[pid] = rate;
}
emit ReferralUpdated(referral);
}
}
function updateReferralCliff(uint256 referralCliff_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
_referralCliff = referralCliff_;
emit ReferralCliffUpdated(_referralCliff);
}
function updateReferralDuration(uint256 referralDuration_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
_referralDuration = referralDuration_;
emit ReferralDurationUpdated(_referralDuration);
}
function enableReferral(address referral_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (_referrals[referral_].defined && _referrals[referral_].enabled) revert ReferralEnabledErr(referral_);
_referrals[referral_].defined = true;
_referrals[referral_].enabled = true;
emit ReferralEnabled(referral_);
}
function disableReferral(address referral_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (_referrals[referral_].defined && !_referrals[referral_].enabled) revert ReferralDisabledErr(referral_);
_referrals[referral_].defined = true;
_referrals[referral_].enabled = false;
emit ReferralDisabled(referral_);
}
function deposit(
uint16 pid_,
uint256 amount_,
address referral_
)
external
nonReentrant()
whenNotPaused()
whenReferralEnabled(referral_)
{
Pool memory pool = _pools[pid_];
if (amount_ == 0) revert AmountZeroErr();
if (_msgSender() == referral_) revert InvalidReferralErr();
if (!pool.enabled) revert PoolDisabledErr(pid_);
if (pid_ == _customPools[PoolType.baseline]) revert PoolBaselineErr(pid_);
uint256 before = STAKE.balanceOf(address(this));
STAKE.safeTransferFrom(_msgSender(), address(this), amount_);
amount_ = STAKE.balanceOf(address(this)) - before;
if (amount_ < pool.minAmount) revert PoolMinAmountErr(pid_);
uint256 rate = pool.baseRate + pool.boostRate;
uint256 refRate;
if (referral_ != address(0)) {
if (!_referrals[referral_].defined) {
_referrals[referral_].defined = true;
_referrals[referral_].enabled = true;
_referrals[referral_].lvl = Lvl.v1;
emit ReferralAdded(referral_, Lvl.v1);
}
rate = rate + pool.affRate;
refRate = getReferralRate(referral_, pid_);
if (_referrals[referral_].lvl == Lvl.v2) {
uint256 refReward = amount_ * refRate * pool.duration / YEAR / PRECISION;
_referralsBalances[referral_] += refReward;
emit ReferralBalanceUpdated(referral_, refReward);
}
}
uint256 position = _positions[_msgSender()][pid_];
Stake memory stake = Stake({
defined: true,
pid: pid_,
amount: amount_,
rate: rate,
referral: referral_,
refRate: refRate,
lockAt: block.timestamp,
duration: pool.duration,
unlockAt: 0,
closed: false
});
_stakes[_msgSender()][pid_][position] = stake;
_positions[_msgSender()][pid_] = position + 1;
_totalStaked += amount_;
emit Deposited(_msgSender(), pid_, position, amount_, rate);
}
function depositFrom(
address vesting_,
uint256 vid_,
uint16 pid_,
bytes calldata message_
)
external
nonReentrant()
whenNotPaused()
whenValidSource(vesting_)
{
Pool memory pool = _pools[pid_];
if (!pool.enabled) revert PoolDisabledErr(pid_);
if (pid_ == _customPools[PoolType.baseline]) revert PoolBaselineErr(pid_);
uint256 before = STAKE.balanceOf(address(this));
IDeFiMerkleVestingActions(vesting_).claimFrom(vid_, _msgSender(), address(this), message_);
uint256 amount_ = STAKE.balanceOf(address(this)) - before;
if (amount_ < pool.minAmount) revert PoolMinAmountErr(pid_);
uint256 rate = pool.baseRate + pool.boostRate + pool.refRate + pool.affRate;
uint256 position = _positions[_msgSender()][pid_];
Stake memory stake = Stake({
defined: true,
pid: pid_,
amount: amount_,
rate: rate,
referral: address(0),
refRate: 0,
lockAt: block.timestamp,
duration: pool.duration,
unlockAt: 0,
closed: false
});
_stakes[_msgSender()][pid_][position] = stake;
_positions[_msgSender()][pid_] = position + 1;
_totalStaked += amount_;
emit DepositedFrom(vesting_, _msgSender(), pid_, position, amount_, rate);
}
function withdraw(uint16 pid_, uint256 pos_)
external
nonReentrant()
whenNotPaused()
returns (uint256 amount, uint256 reward)
{
Stake memory stake = _stakes[_msgSender()][pid_][pos_];
if (!stake.defined) revert StakeUndefinedErr();
if (stake.closed) revert StakeClosedErr();
if (!isStakeUnlocked(_msgSender(), pid_, pos_)) revert StakeLockedErr();
amount = stake.amount;
_totalStaked -= amount;
uint256 baselineDuration = getBaselineDuration(_msgSender(), pid_, pos_);
_stakes[_msgSender()][pid_][pos_].closed = true;
reward = amount * stake.rate * stake.duration / YEAR / PRECISION;
if (baselineDuration > 0) {
Pool memory baselinePool = _pools[_customPools[PoolType.baseline]];
uint256 baselineRate = baselinePool.baseRate + baselinePool.boostRate;
reward += amount * baselineRate * baselineDuration / YEAR / PRECISION;
}
if (stake.referral != address(0) && _referrals[stake.referral].lvl == Lvl.v1) {
uint256 refReward = amount * stake.refRate * stake.duration / YEAR / PRECISION;
_referralsBalances[stake.referral] += refReward;
emit ReferralBalanceUpdated(stake.referral, refReward);
}
STAKE.safeTransfer(_msgSender(), amount);
if (reward > 0) {
DEFI.safeTransfer(_msgSender(), reward);
}
emit Withdrawn(_msgSender(), pid_, pos_, amount, reward);
}
function withdrawRequest(uint16 pid_, uint256 pos_)
external
nonReentrant()
whenNotPaused()
{
Stake memory stake = _stakes[_msgSender()][pid_][pos_];
if (!stake.defined) revert StakeUndefinedErr();
if (stake.closed) revert StakeClosedErr();
if (stake.lockAt + stake.duration > block.timestamp) revert StakeLockedErr();
uint256 unlockAt = block.timestamp + _cooldown;
_stakes[_msgSender()][pid_][pos_].unlockAt = unlockAt;
emit WithdrawRequested(_msgSender(), pid_, pos_, unlockAt);
}
function claim()
external
nonReentrant()
whenNotPaused()
whenReferralLvlV1(_msgSender())
returns (uint256 amount)
{
amount = _referralsBalances[_msgSender()];
if (amount == 0) revert ReferralZeroBalanceErr(_msgSender());
_referralsBalances[_msgSender()] = 0;
DEFI.safeTransfer(_msgSender(), amount);
emit Claimed(_msgSender(), amount);
}
function claimLvlV2(address[] calldata referrals_)
external
onlyRole(OPERATOR_ROLE)
{
uint256 length = referrals_.length;
uint256[] memory amounts = new uint256[](length);
for (uint256 i = 0; i < length; i++) {
address referral = referrals_[i];
if (!_referrals[referral].enabled || _referrals[referral].lvl != Lvl.v2 || _referrals[referral].cliffAt > block.timestamp) {
revert ReferralLvlV2Err(referral);
}
_referrals[referral].cliffAt = block.timestamp + _referralCliff;
amounts[i] = _referralsBalances[referral];
_referralsBalances[referral] = 0;
}
uint256 startTime = block.timestamp + 10;
uint256 endTime = startTime + _referralDuration;
uint256 pid = VESTING.setupPool(startTime, endTime, false, 0, 0);
VESTING.setupBeneficiaryBatches(pid, referrals_, amounts);
for (uint256 i = 0; i < length; i++) {
emit ClaimedLvlV2(referrals_[i], amounts[i], pid);
}
}
function recoverERC20(address token_, uint256 amount_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
IERC20(token_).safeTransfer(_msgSender(), amount_);
emit ERC20Recovered(token_, amount_);
}
function isStakeUnlocked(address beneficiary_, uint16 pid_, uint256 pos_)
public
view
returns (bool)
{
Stake memory stake = _stakes[beneficiary_][pid_][pos_];
if (!stake.defined || stake.closed) return false;
if (_cooldown == 0) {
uint256 mainlineTimestamp = stake.lockAt + stake.duration;
return mainlineTimestamp < block.timestamp;
}
return stake.unlockAt > 0 ? stake.unlockAt < block.timestamp : false;
}
function getBaselineDuration(address beneficiary_, uint16 pid_, uint256 pos_)
public
view
returns (uint256)
{
Pool memory baselinePool = _pools[_customPools[PoolType.baseline]];
if (!baselinePool.defined) return 0;
Stake memory stake = _stakes[beneficiary_][pid_][pos_];
if (!stake.defined || stake.closed) return 0;
uint256 mainlineTimestamp = stake.lockAt + stake.duration;
uint256 baselineTimestamp = baselinePool.closed ? baselinePool.closedAt : block.timestamp;
return baselineTimestamp > mainlineTimestamp ? baselineTimestamp - mainlineTimestamp : 0;
}
function getReferralLvl(address referral_)
external
view
returns (Lvl, uint256)
{
return (_referrals[referral_].lvl, _referrals[referral_].cliffAt);
}
function getReferralRate(address referral_, uint16 pid_)
public
view
returns (uint256)
{
Pool memory pool = _pools[pid_];
uint256 rate = pool.refRate;
if (_referrals[referral_].defined && _referrals[referral_].enabled) {
rate = Math.max(_referrals[referral_].rates[pid_], rate);
}
return rate;
}
function referralBalanceOf(address referral_)
public
view
returns (uint256)
{
return _referralsBalances[referral_];
}
function getStake(address beneficiary_, uint16 pid_, uint256 pos_)
external
view
returns (Stake memory stake)
{
stake = _stakes[beneficiary_][pid_][pos_];
}
function getTotalStakeAmount()
external
view
returns (uint256)
{
return _totalStaked;
}
function getTotalPoolsCount()
external
view
returns (uint256)
{
return _poolsIndex - 1;
}
function getPosCount(address beneficiary_, uint16 pid_)
external
view
returns (uint256)
{
return _positions[beneficiary_][pid_];
}
function getPool(uint16 pid_)
external
view
returns (Pool memory pool)
{
pool = _pools[pid_];
}
function getBaselinePoolId()
external
view
returns (uint256)
{
return _customPools[PoolType.baseline];
}
function getCooldown()
external
view
returns (uint256)
{
return _cooldown;
}
function getReferralCliff()
external
view
returns (uint256)
{
return _referralCliff;
}
function getReferralDuration()
external
view
returns (uint256)
{
return _referralDuration;
}
}
文件 5 的 22:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 22:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 7 的 22:IDeFiChefActionsV2.sol
pragma solidity 0.8.19;
import './IDeFiChefStateV2.sol';
interface IDeFiChefActionsV2 {
function setupVesting(address vesting_) external;
function setupCooldown(uint256 cooldown_) external;
function setupPool(
uint256 minAmount_,
uint256 baseRate_,
uint256 boostRate_,
uint256 affRate_,
uint256 refRate_,
uint256 duration_,
IDeFiChefStateV2.PoolType type_,
bool enabled_
) external;
function updatePool(
uint16 pid_,
uint256 minAmount_,
uint256 baseRate_,
uint256 boostRate_,
uint256 affRate_,
uint256 refRate_,
uint256 duration_,
bool enabled_
) external;
function closePool(uint16 pid_) external;
function enablePool(uint16 pid_) external;
function disablePool(uint16 pid_) external;
function setupReferrals(
address[] calldata referrals_,
IDeFiChefStateV2.Lvl[] calldata lvls_,
uint16[] calldata pools_,
uint256[] calldata rates_
) external;
function updateReferrals(
address[] calldata referrals_,
uint16[] calldata pools_,
uint256[] calldata rates_
) external;
function updateReferralCliff(uint256 referralCliff_) external;
function updateReferralDuration(uint256 referralDuration_) external;
function enableReferral(address referral_) external;
function disableReferral(address referral_) external;
function deposit(uint16 pid_, uint256 amount_, address referral_) external;
function depositFrom(address vesting_, uint256 vid_, uint16 pid_, bytes calldata message_) external;
function withdraw(uint16 pid_, uint256 pos_) external returns (uint256 amount, uint256 reward);
function withdrawRequest(uint16 pid_, uint256 pos_) external;
function claim() external returns (uint256 amount);
function recoverERC20(address token_, uint256 amount_) external;
function getStake(address beneficiary_, uint16 pid_, uint256 pos_) external view returns (IDeFiChefStateV2.Stake memory stake);
function isStakeUnlocked(address beneficiary_, uint16 pid_, uint256 pos_) external view returns (bool);
function getBaselineDuration(address beneficiary_, uint16 pid_, uint256 pos_) external view returns (uint256);
function getReferralLvl(address referral_) external view returns (IDeFiChefStateV2.Lvl, uint256);
function getReferralRate(address referral_, uint16 pid_) external view returns (uint256);
function referralBalanceOf(address referral_) external view returns (uint256);
function getTotalStakeAmount() external view returns (uint256);
function getTotalPoolsCount() external view returns (uint256);
function getPool(uint16 pid_) external view returns (IDeFiChefStateV2.Pool memory pool);
function getBaselinePoolId() external view returns (uint256);
function getCooldown() external view returns (uint256);
function getPosCount(address beneficiary_, uint16 pid_) external view returns (uint256);
function getReferralCliff() external view returns (uint256);
function getReferralDuration() external view returns (uint256);
}
文件 8 的 22:IDeFiChefErrorsV2.sol
pragma solidity 0.8.19;
interface IDeFiChefErrorsV2 {
error ArrayParamsInvalidLengthErr();
error AmountZeroErr();
error PoolDefinedErr(uint16 pid_);
error PoolUndefinedErr(uint16 pid_);
error PoolBaselineErr(uint16 pid_);
error PoolDisabledErr(uint16 pid_);
error PoolClosedErr(uint16 pid_);
error PoolMinAmountErr(uint16 pid_);
error StakeUndefinedErr();
error StakeEmergencyErr();
error StakeLockedErr();
error StakeClosedErr();
error InvalidReferralErr();
error ReferralDefinedErr(address referral_);
error ReferralUndefinedErr(address referral_);
error ReferralEnabledErr(address referral_);
error ReferralDisabledErr(address referral_);
error ReferralLvlV1Err(address referral_);
error ReferralLvlV2Err(address referral_);
error ReferralErr(address referral_);
error ReferralZeroBalanceErr(address referral_);
error ReferralEpochErr(address referral_);
error TokenNullAddressErr();
error ExternalSourceAuthErr();
}
文件 9 的 22:IDeFiChefEventsV2.sol
pragma solidity 0.8.19;
import './IDeFiChefStateV2.sol';
interface IDeFiChefEventsV2 {
event VestingSetup(address vesting);
event CooldownSetup(uint256 cooldown);
event PoolAdded(uint16 indexed pid, uint256 minAmount, uint256 baseRate, uint256 boostRate, uint256 affRate, uint256 refRate, uint256 duration, bool enabled);
event PoolUpdated(uint16 indexed pid, uint256 minAmount, uint256 baseRate, uint256 boostRate, uint256 affRate, uint256 refRate, uint256 duration, bool enabled);
event PoolClosed(uint16 indexed pid);
event ReferralAdded(address indexed referral, IDeFiChefStateV2.Lvl lvl);
event ReferralUpdated(address indexed referral);
event ReferralCliffUpdated(uint256 cliff);
event ReferralDurationUpdated(uint256 referralDuration);
event ReferralEnabled(address indexed referral);
event ReferralDisabled(address indexed referral);
event ReferralBalanceUpdated(address indexed referral, uint256 amount);
event ReferralVestingSetup(uint256 epoch, uint256 duration);
event Deposited(address indexed user, uint16 pool, uint256 pos, uint256 amount, uint256 rate);
event DepositedFrom(address indexed source, address indexed user, uint16 pool, uint256 pos, uint256 amount, uint256 rate);
event Withdrawn(address indexed user, uint16 pool, uint256 pos, uint256 amount, uint256 reward);
event WithdrawRequested(address indexed user, uint16 pool, uint256 pos, uint256 unlock);
event Claimed(address indexed referral, uint256 amount);
event ClaimedLvlV2(address indexed referral, uint256 amount, uint256 pid);
event ERC20Recovered(address token, uint256 amount);
}
文件 10 的 22:IDeFiChefStateV2.sol
pragma solidity 0.8.19;
interface IDeFiChefStateV2 {
struct Stake {
bool defined;
uint16 pid;
uint256 amount;
uint256 rate;
address referral;
uint256 refRate;
uint256 lockAt;
uint256 duration;
uint256 unlockAt;
bool closed;
}
enum PoolType {
none,
baseline
}
struct Pool {
bool defined;
bool enabled;
uint256 minAmount;
uint256 baseRate;
uint256 boostRate;
uint256 affRate;
uint256 refRate;
uint256 duration;
uint256 closedAt;
bool closed;
}
enum Lvl {
v1,
v2
}
struct Referral {
bool defined;
bool enabled;
Lvl lvl;
uint256 cliffAt;
mapping(uint16 => uint256) rates;
}
}
文件 11 的 22:IDeFiChefV2.sol
pragma solidity 0.8.19;
import './DeFiChefV2/IDeFiChefActionsV2.sol';
import './DeFiChefV2/IDeFiChefErrorsV2.sol';
import './DeFiChefV2/IDeFiChefEventsV2.sol';
import './DeFiChefV2/IDeFiChefStateV2.sol';
interface IDeFiChefV2 is IDeFiChefActionsV2, IDeFiChefErrorsV2, IDeFiChefEventsV2, IDeFiChefStateV2 {
}
文件 12 的 22:IDeFiMerkleVestingActions.sol
pragma solidity 0.8.19;
interface IDeFiMerkleVestingActions {
function setupPool(
uint256 startTime_,
uint256 endTime_,
bytes32 merkleRoot_,
bool lockable_,
uint256 baseRate_,
uint256 boostRate_
) external returns (uint256 pid);
function updatePoolTiming(uint256 pid_, uint256 startTime_, uint256 endTime_) external;
function updatePoolRoot(uint256 pid_, bytes32 merkleRoot_) external;
function updatePoolRate(uint256 pid_, bool lockable_, uint256 baseRate_, uint256 boostRate_) external;
function enableBeneficiary(uint256[] calldata pids_, address beneficiary_) external;
function disableBeneficiary(uint256[] calldata pids_, address beneficiary_) external;
function recoverBeneficiary(uint256 pid_, address beneficiary_, bool disabled_, uint256 withdrawn_, bool locked_, uint256 lockedAt_, uint256 rate_) external;
function claim(uint256 pid_, bytes calldata message_) external returns (uint256 amount);
function claimFrom(uint256 pid_, address from_, address to_, bytes calldata message_) external returns (uint256 amount);
function lock(uint256 pid_, bytes calldata message_) external;
function unlock(uint256 pid_, address[] calldata beneficiaries_) external;
function recoverERC20(address token_, uint256 amount_) external;
function getReleasableAmount(uint256 pid_, address beneficiary_, bytes calldata message_) external view returns (uint256);
function getVestedAmount(uint256 pid_, address beneficiary_, bytes calldata message_, uint256 time_) external view returns (uint256);
function getBeneficiary(uint256 pid_, address beneficiary_, bytes calldata message_)
external
view
returns (
bool disabled,
uint256 lockedAmount,
uint256 withdrawn,
uint256 releasableAmount,
uint256 currentTime,
bool locked,
uint256 lockedAt,
uint256 rate
);
function getPoolsCount() external view returns (uint256 poolsCount);
function getPool(uint256 pid_)
external
view
returns (
uint256 startTime,
uint256 endTime,
bytes32 merkleRoot,
bool lockable,
uint256 baseRate,
uint256 boostRate
);
}
文件 13 的 22:IDeFiVestingV2Actions.sol
pragma solidity 0.8.19;
interface IDeFiVestingV2Actions {
function setupPool(uint256 startTime_, uint256 endTime_, bool lockable_, uint256 baseRate_, uint256 boostRate_) external returns (uint256 pid);
function updatePoolTiming(uint256 pid_, uint256 startTime_, uint256 endTime_) external;
function updatePoolRate(uint256 pid_, bool lockable_, uint256 baseRate_, uint256 boostRate_) external;
function setupBeneficiary(uint256 pid_, address beneficiary_, uint256 lockedAmount_) external;
function setupBeneficiaryBatches(uint256 pid_, address[] calldata beneficiaries_, uint256[] calldata lockedAmounts_) external;
function disableBeneficiary(uint256[] calldata pids_, address beneficiary_) external;
function recoverBeneficiary(uint256[] calldata pids_, address beneficiary_, bool disabled_, uint256 withdrawn_, uint256 lockedAmount, bool locked_, uint256 lockedAt_, uint256 rate_) external;
function claim(uint256 pid_) external returns (uint256 amount);
function claimFrom(uint256 pid_, address from_, address to_) external returns (uint256 amount);
function lock(uint256 pid_) external;
function getReleasableAmount(uint256 pid_, address beneficiary_) external view returns (uint256);
function getVestedAmount(uint256 pid_, address beneficiary_, uint256 time_) external view returns (uint256);
function getBeneficiary(uint256 pid_, address beneficiary_)
external
view
returns (
bool defined,
bool disabled,
address beneficiary,
uint256 lockedAmount,
uint256 withdrawn,
uint256 releasableAmount,
uint256 currentTime,
bool locked,
uint256 lockedAt,
uint256 rate
);
function getPoolsCount() external view returns (uint256 poolsCount);
function getPool(uint256 pid_)
external
view
returns (
uint256 startTime,
uint256 endTime,
bool lockable,
uint256 baseRate,
uint256 boostRate
);
}
文件 14 的 22:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 15 的 22:IERC20.sol
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20.sol";
文件 16 的 22: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);
}
文件 17 的 22:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
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 average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 18 的 22:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 19 的 22: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;
}
}
文件 20 的 22: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));
}
}
文件 21 的 22:SignedMath.sol
pragma solidity ^0.8.0;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 22 的 22:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
{
"compilationTarget": {
"contracts/staking/DeFiChefV2.sol": "DeFiChefV2"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"viaIR": true
}
[{"inputs":[{"internalType":"contract IERC20","name":"DEFI_","type":"address"},{"internalType":"contract IERC20","name":"STAKE_","type":"address"},{"internalType":"contract IDeFiVestingV2Actions","name":"VESTING_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AmountZeroErr","type":"error"},{"inputs":[],"name":"ArrayParamsInvalidLengthErr","type":"error"},{"inputs":[],"name":"ExternalSourceAuthErr","type":"error"},{"inputs":[],"name":"InvalidReferralErr","type":"error"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"PoolBaselineErr","type":"error"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"PoolClosedErr","type":"error"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"PoolDefinedErr","type":"error"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"PoolDisabledErr","type":"error"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"PoolMinAmountErr","type":"error"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"PoolUndefinedErr","type":"error"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"ReferralDefinedErr","type":"error"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"ReferralDisabledErr","type":"error"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"ReferralEnabledErr","type":"error"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"ReferralEpochErr","type":"error"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"ReferralErr","type":"error"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"ReferralLvlV1Err","type":"error"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"ReferralLvlV2Err","type":"error"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"ReferralUndefinedErr","type":"error"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"ReferralZeroBalanceErr","type":"error"},{"inputs":[],"name":"StakeClosedErr","type":"error"},{"inputs":[],"name":"StakeEmergencyErr","type":"error"},{"inputs":[],"name":"StakeLockedErr","type":"error"},{"inputs":[],"name":"StakeUndefinedErr","type":"error"},{"inputs":[],"name":"TokenNullAddressErr","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referral","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referral","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"}],"name":"ClaimedLvlV2","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cooldown","type":"uint256"}],"name":"CooldownSetup","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint16","name":"pool","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"pos","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"source","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint16","name":"pool","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"pos","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"}],"name":"DepositedFrom","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"pid","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"minAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"affRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"refRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"PoolAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"pid","type":"uint16"}],"name":"PoolClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"pid","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"minAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"affRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"refRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"PoolUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referral","type":"address"},{"indexed":false,"internalType":"enum IDeFiChefStateV2.Lvl","name":"lvl","type":"uint8"}],"name":"ReferralAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referral","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReferralBalanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cliff","type":"uint256"}],"name":"ReferralCliffUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referral","type":"address"}],"name":"ReferralDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"referralDuration","type":"uint256"}],"name":"ReferralDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referral","type":"address"}],"name":"ReferralEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referral","type":"address"}],"name":"ReferralUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"ReferralVestingSetup","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vesting","type":"address"}],"name":"VestingSetup","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint16","name":"pool","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"pos","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unlock","type":"uint256"}],"name":"WithdrawRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint16","name":"pool","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"pos","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFI","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTERNAL_SOURCE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKE","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VESTING","outputs":[{"internalType":"contract IDeFiVestingV2Actions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"referrals_","type":"address[]"}],"name":"claimLvlV2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"closePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"address","name":"referral_","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vesting_","type":"address"},{"internalType":"uint256","name":"vid_","type":"uint256"},{"internalType":"uint16","name":"pid_","type":"uint16"},{"internalType":"bytes","name":"message_","type":"bytes"}],"name":"depositFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"disablePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"disableReferral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"enablePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"enableReferral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary_","type":"address"},{"internalType":"uint16","name":"pid_","type":"uint16"},{"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"getBaselineDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBaselinePoolId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"getPool","outputs":[{"components":[{"internalType":"bool","name":"defined","type":"bool"},{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"uint256","name":"baseRate","type":"uint256"},{"internalType":"uint256","name":"boostRate","type":"uint256"},{"internalType":"uint256","name":"affRate","type":"uint256"},{"internalType":"uint256","name":"refRate","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"closedAt","type":"uint256"},{"internalType":"bool","name":"closed","type":"bool"}],"internalType":"struct IDeFiChefStateV2.Pool","name":"pool","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary_","type":"address"},{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"getPosCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReferralCliff","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReferralDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"getReferralLvl","outputs":[{"internalType":"enum IDeFiChefStateV2.Lvl","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"},{"internalType":"uint16","name":"pid_","type":"uint16"}],"name":"getReferralRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary_","type":"address"},{"internalType":"uint16","name":"pid_","type":"uint16"},{"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"getStake","outputs":[{"components":[{"internalType":"bool","name":"defined","type":"bool"},{"internalType":"uint16","name":"pid","type":"uint16"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"address","name":"referral","type":"address"},{"internalType":"uint256","name":"refRate","type":"uint256"},{"internalType":"uint256","name":"lockAt","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"unlockAt","type":"uint256"},{"internalType":"bool","name":"closed","type":"bool"}],"internalType":"struct IDeFiChefStateV2.Stake","name":"stake","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalPoolsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary_","type":"address"},{"internalType":"uint16","name":"pid_","type":"uint16"},{"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"isStakeUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"referral_","type":"address"}],"name":"referralBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"cooldown_","type":"uint256"}],"name":"setupCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minAmount_","type":"uint256"},{"internalType":"uint256","name":"baseRate_","type":"uint256"},{"internalType":"uint256","name":"boostRate_","type":"uint256"},{"internalType":"uint256","name":"affRate_","type":"uint256"},{"internalType":"uint256","name":"refRate_","type":"uint256"},{"internalType":"uint256","name":"duration_","type":"uint256"},{"internalType":"enum IDeFiChefStateV2.PoolType","name":"type_","type":"uint8"},{"internalType":"bool","name":"enabled_","type":"bool"}],"name":"setupPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"referrals_","type":"address[]"},{"internalType":"enum IDeFiChefStateV2.Lvl[]","name":"lvls_","type":"uint8[]"},{"internalType":"uint16[]","name":"pools_","type":"uint16[]"},{"internalType":"uint256[]","name":"rates_","type":"uint256[]"}],"name":"setupReferrals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vesting_","type":"address"}],"name":"setupVesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"},{"internalType":"uint256","name":"minAmount_","type":"uint256"},{"internalType":"uint256","name":"baseRate_","type":"uint256"},{"internalType":"uint256","name":"boostRate_","type":"uint256"},{"internalType":"uint256","name":"affRate_","type":"uint256"},{"internalType":"uint256","name":"refRate_","type":"uint256"},{"internalType":"uint256","name":"duration_","type":"uint256"},{"internalType":"bool","name":"enabled_","type":"bool"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"referralCliff_","type":"uint256"}],"name":"updateReferralCliff","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"referralDuration_","type":"uint256"}],"name":"updateReferralDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"referrals_","type":"address[]"},{"internalType":"uint16[]","name":"pools_","type":"uint16[]"},{"internalType":"uint256[]","name":"rates_","type":"uint256[]"}],"name":"updateReferrals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"},{"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"pid_","type":"uint16"},{"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"withdrawRequest","outputs":[],"stateMutability":"nonpayable","type":"function"}]