More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,207 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deposit | 22296707 | 1 hr ago | IN | 0 ETH | 0.00012469 | ||||
Deposit | 22268884 | 3 days ago | IN | 0 ETH | 0.00045372 | ||||
Deposit | 22268000 | 4 days ago | IN | 0 ETH | 0.00075814 | ||||
Withdraw | 22259779 | 5 days ago | IN | 0 ETH | 0.00029318 | ||||
Withdraw Request | 22251751 | 6 days ago | IN | 0 ETH | 0.00014095 | ||||
Deposit | 22250435 | 6 days ago | IN | 0 ETH | 0.00045372 | ||||
Deposit | 22250291 | 6 days ago | IN | 0 ETH | 0.00045374 | ||||
Deposit | 22241016 | 7 days ago | IN | 0 ETH | 0.00057615 | ||||
Deposit | 22237258 | 8 days ago | IN | 0 ETH | 0.00026203 | ||||
Deposit From | 22227109 | 9 days ago | IN | 0 ETH | 0.00063236 | ||||
Deposit | 22220197 | 10 days ago | IN | 0 ETH | 0.00045374 | ||||
Deposit | 22193639 | 14 days ago | IN | 0 ETH | 0.00021664 | ||||
Withdraw | 22186570 | 15 days ago | IN | 0 ETH | 0.00025898 | ||||
Deposit | 22184876 | 15 days ago | IN | 0 ETH | 0.00045374 | ||||
Deposit | 22183744 | 15 days ago | IN | 0 ETH | 0.00074123 | ||||
Withdraw | 22180015 | 16 days ago | IN | 0 ETH | 0.00011654 | ||||
Withdraw Request | 22178291 | 16 days ago | IN | 0 ETH | 0.00014095 | ||||
Withdraw Request | 22172577 | 17 days ago | IN | 0 ETH | 0.00007752 | ||||
Deposit From | 22165297 | 18 days ago | IN | 0 ETH | 0.00058925 | ||||
Withdraw | 22152078 | 20 days ago | IN | 0 ETH | 0.00006259 | ||||
Withdraw Request | 22139674 | 21 days ago | IN | 0 ETH | 0.00004978 | ||||
Withdraw | 22136314 | 22 days ago | IN | 0 ETH | 0.0002771 | ||||
Deposit | 22133709 | 22 days ago | IN | 0 ETH | 0.00045374 | ||||
Deposit | 22133398 | 22 days ago | IN | 0 ETH | 0.00045374 | ||||
Deposit | 22129336 | 23 days ago | IN | 0 ETH | 0.00011714 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
DeFiChefV2
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT 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; /// @notice Address of the reward contract. IERC20 public immutable DEFI; /// @notice Address of the stake token. IERC20 public immutable STAKE; /// @notice Address of the vesting contract. IDeFiVestingV2Actions public VESTING; /// @notice Cool down timeout. uint256 private _cooldown = 1 days; /// @notice Pools index. uint16 private _poolsIndex = 1; /// @notice Total stake. uint256 private _totalStaked; /// @notice Mapping for pooltype/pool. mapping(PoolType => uint16) private _customPools; /// @notice Info of each reward pool. mapping(uint16 => Pool) private _pools; /// @notice Info of each beneficiary pool/stake. mapping(address => mapping(uint16 => mapping(uint256 => Stake))) private _stakes; /// @notice Info of beneficiary/pool/position mapping(address => mapping(uint16 => uint256)) private _positions; /// @notice Referral cliff. uint256 private _referralCliff = 7 days; /// @notice Referral vesting duration. uint256 private _referralDuration = 180 days; /// @notice Referral info. mapping(address => Referral) private _referrals; /// @notice Referral balances. mapping(address => uint256) private _referralsBalances; /** * @param DEFI_ The DEFI token contract address. * @param STAKE_ The STAKE token contract address. * @param VESTING_ The vesting contract address. */ 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ 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; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ 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) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 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)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ 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)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ 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)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to * 0 before setting it to a non-zero 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); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ 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"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. 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"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ 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"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ 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"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ 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); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ 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); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ 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); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ 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 { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ 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; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. 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); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ 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); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 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; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ 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); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 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; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ 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); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ 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; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ 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); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ 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); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import './IDeFiChefStateV2.sol'; interface IDeFiChefActionsV2 { /** * @notice Setups new vesting contract. * @param vesting_ vesting contract address. */ function setupVesting(address vesting_) external; /** * @notice Setups new cooldown duration. * @param cooldown_ the cooldown of the withdrawal. */ function setupCooldown(uint256 cooldown_) external; /** * @notice Initializes new staking pool * @param minAmount_ min stake amount. * @param baseRate_ base allocation rate. * @param boostRate_ boosted allocation rate. * @param affRate_ affiliate allocation rate. * @param refRate_ referral allocation rate. * @param duration_ stake duration. * @param type_ pool type. * @param enabled_ if pool enabled. */ function setupPool( uint256 minAmount_, uint256 baseRate_, uint256 boostRate_, uint256 affRate_, uint256 refRate_, uint256 duration_, IDeFiChefStateV2.PoolType type_, bool enabled_ ) external; /** * @notice Updates pool. * @param pid_ the id of the pool. * @param minAmount_ min stake amount. * @param baseRate_ base allocation rate. * @param boostRate_ boosted allocation rate. * @param affRate_ affiliate allocation rate. * @param refRate_ referral allocation rate. * @param duration_ stake duration. * @param enabled_ if pool enabled. */ function updatePool( uint16 pid_, uint256 minAmount_, uint256 baseRate_, uint256 boostRate_, uint256 affRate_, uint256 refRate_, uint256 duration_, bool enabled_ ) external; /** * @notice Closes the pool. * @param pid_ the id of the staking pool. */ function closePool(uint16 pid_) external; /** * @notice Enables the pool. * @param pid_ the id of the staking pool. */ function enablePool(uint16 pid_) external; /** * @notice Disables the pool. * @param pid_ the id of the staking pool. */ function disablePool(uint16 pid_) external; /** * @notice Setups referrals. * @param referrals_ referral addresses. * @param lvls_ referral level values. * @param pools_ pool ids. * @param rates_ rate by each pool. */ function setupReferrals( address[] calldata referrals_, IDeFiChefStateV2.Lvl[] calldata lvls_, uint16[] calldata pools_, uint256[] calldata rates_ ) external; /** * @notice Updates referrals rates. * @param referrals_ referral addresses. * @param pools_ pool ids. * @param rates_ rate by each pool. */ function updateReferrals( address[] calldata referrals_, uint16[] calldata pools_, uint256[] calldata rates_ ) external; /** * @notice Updates referral cliff delay. * @param referralCliff_ referral cliff. */ function updateReferralCliff(uint256 referralCliff_) external; /** * @notice Updates referral vesting duration. * @param referralDuration_ referral duration. */ function updateReferralDuration(uint256 referralDuration_) external; /** * @notice Enables referral. * @param referral_ referral address. */ function enableReferral(address referral_) external; /** * @notice Disables referral. * @param referral_ referral address. */ function disableReferral(address referral_) external; /** * @notice Deposits tokens to the staking pool. * @param pid_ the id of the staking pool. * @param amount_ amount of the tokens to deposit. * @param referral_ referral address. */ function deposit(uint16 pid_, uint256 amount_, address referral_) external; /** * @notice Deposit tokens to the staking pool from vesting SC. * @param vesting_ vesting SC address. * @param vid_ the id of the vesting pool. * @param pid_ the id of the staking pool. * @param message_ beneficiary message. */ function depositFrom(address vesting_, uint256 vid_, uint16 pid_, bytes calldata message_) external; /** * @notice Withdraws staked tokens from the pool. * @param pid_ the id of the staking pool. * @param pos_ the position of the stake. */ function withdraw(uint16 pid_, uint256 pos_) external returns (uint256 amount, uint256 reward); /** * @notice Requests a withdraw of the staked tokens from the pool. * @param pid_ the id of the staking pool. * @param pos_ the position of the stake. */ function withdrawRequest(uint16 pid_, uint256 pos_) external; /** * @notice Claims referral rewards. */ function claim() external returns (uint256 amount); /** * @dev Allows to recover erc20 tokens. * @param token_ token address. * @param amount_ amount to be recovered. */ function recoverERC20(address token_, uint256 amount_) external; /** * @notice Returns stake info. * @param beneficiary_ beneficiary address. * @param pid_ the id of the staking pool. * @param pos_ stake position. */ function getStake(address beneficiary_, uint16 pid_, uint256 pos_) external view returns (IDeFiChefStateV2.Stake memory stake); /** * @notice Returns if stake unlocked. * @param beneficiary_ beneficiary address. * @param pid_ the id of the staking pool. * @param pos_ stake position. */ function isStakeUnlocked(address beneficiary_, uint16 pid_, uint256 pos_) external view returns (bool); /** * @notice Returns baseline duration. * @param beneficiary_ beneficiary address. * @param pid_ the id of the staking pool. * @param pos_ stake position. */ function getBaselineDuration(address beneficiary_, uint16 pid_, uint256 pos_) external view returns (uint256); /** * @notice Returns referral lvl. * @param referral_ referral address. */ function getReferralLvl(address referral_) external view returns (IDeFiChefStateV2.Lvl, uint256); /** * @notice Returns referral rate. * @param referral_ referral address. * @param pid_ the id of the staking pool. */ function getReferralRate(address referral_, uint16 pid_) external view returns (uint256); /** * @notice Returns referral balance. * @param referral_ referral address. */ function referralBalanceOf(address referral_) external view returns (uint256); /** * @notice Returns total staked amount. */ function getTotalStakeAmount() external view returns (uint256); /** * @notice Returns total pools count. */ function getTotalPoolsCount() external view returns (uint256); /** * @notice Returns pools info. * @param pid_ the id of the staking pool. */ function getPool(uint16 pid_) external view returns (IDeFiChefStateV2.Pool memory pool); /** * @notice Returns baseline pool id. */ function getBaselinePoolId() external view returns (uint256); /** * @notice Returns cooldown duration. */ function getCooldown() external view returns (uint256); /** * @notice Returns total position count per beneficiary/pool. * @param beneficiary_ beneficiary address. * @param pid_ the id of the staking pool. */ function getPosCount(address beneficiary_, uint16 pid_) external view returns (uint256); /** * @notice Returns referral cliff. */ function getReferralCliff() external view returns (uint256); /** * @notice Returns referral vesting duration. */ function getReferralDuration() external view returns (uint256); }
// SPDX-License-Identifier: MIT 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(); }
// SPDX-License-Identifier: MIT 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); }
// SPDX-License-Identifier: MIT 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; } }
// SPDX-License-Identifier: MIT 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 { }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface IDeFiMerkleVestingActions { /** * @dev Initialize new vesting pool. * @param startTime_ vesting start time. * @param endTime_ vesting end time. * @param merkleRoot_ merkle root. * @param lockable_ if pool lockable. * @param baseRate_ pool base rate. * @param boostRate_ pool boost rate. */ function setupPool( uint256 startTime_, uint256 endTime_, bytes32 merkleRoot_, bool lockable_, uint256 baseRate_, uint256 boostRate_ ) external returns (uint256 pid); /** * @dev Sets new timing parameters of the vesting pool. * @param pid_ pool id. * @param startTime_ vesting start time. * @param endTime_ vesting end time. */ function updatePoolTiming(uint256 pid_, uint256 startTime_, uint256 endTime_) external; /** * @dev Sets new merkle root of the vesting pool. * @param pid_ pool id. * @param merkleRoot_ merkle root. */ function updatePoolRoot(uint256 pid_, bytes32 merkleRoot_) external; /** * @dev Sets new rate parameters of the vesting pool. * @param pid_ pool id. * @param lockable_ if pool lockable. * @param baseRate_ pool base rate. * @param boostRate_ pool boost rate. */ function updatePoolRate(uint256 pid_, bool lockable_, uint256 baseRate_, uint256 boostRate_) external; /** * @dev Enables beneficiary per pools. * @param pids_ pool ids. * @param beneficiary_ beneficiary address. */ function enableBeneficiary(uint256[] calldata pids_, address beneficiary_) external; /** * @dev Disables beneficiary per pools(in case wallet was exploited). * @param pids_ pool ids. * @param beneficiary_ beneficiary address. */ function disableBeneficiary(uint256[] calldata pids_, address beneficiary_) external; /** * @dev Recovers beneficiary to a predefined state(in case wallet was exploited). * @param pid_ pool id. * @param beneficiary_ beneficiary address. * @param disabled_ if beneficiary disabled. * @param withdrawn_ how many tokens beneficiary have withdrawn. * @param locked_ if beneficiary locked pool. * @param lockedAt_ if when beneficiary was locked. * @param rate_ beneficiary lock rate. */ function recoverBeneficiary(uint256 pid_, address beneficiary_, bool disabled_, uint256 withdrawn_, bool locked_, uint256 lockedAt_, uint256 rate_) external; /** * @dev Allows beneficiary to claim vested tokens. * @param pid_ pool id. * @param message_ beneficiary message. */ function claim(uint256 pid_, bytes calldata message_) external returns (uint256 amount); /** * @dev Allows third party to claim beneficiaries vested tokens(in case of integration with other contracts). * @param pid_ pool id. * @param from_ beneficiary address. * @param to_ address where the tokens will be transferred. * @param message_ beneficiary message. */ function claimFrom(uint256 pid_, address from_, address to_, bytes calldata message_) external returns (uint256 amount); /** * @dev Allows beneficiary to lock vesting tokens(for the vesting duration) to earn interest rate. * @param pid_ pool id. * @param message_ beneficiary message. */ function lock(uint256 pid_, bytes calldata message_) external; /** * @dev Allows to unlock vesting tokens. * @param pid_ pool id. * @param beneficiaries_ beneficiaries addresses. */ function unlock(uint256 pid_, address[] calldata beneficiaries_) external; /** * @dev Allows to recover erc20 tokens. * @param token_ token address. * @param amount_ amount to be recovered. */ function recoverERC20(address token_, uint256 amount_) external; /** * @dev Returns amount of releasable tokens per beneficiary per pool. * @param pid_ pool id. * @param beneficiary_ beneficiary address. * @param message_ beneficiary message. */ function getReleasableAmount(uint256 pid_, address beneficiary_, bytes calldata message_) external view returns (uint256); /** * @dev Returns amount of vested tokens per beneficiary per timestamp. * @param pid_ pool id. * @param beneficiary_ beneficiary address. * @param message_ beneficiary message. * @param time_ time of vesting. */ function getVestedAmount(uint256 pid_, address beneficiary_, bytes calldata message_, uint256 time_) external view returns (uint256); /** * @dev Returns beneficiary details per pool. * @param pid_ pool id. * @param beneficiary_ beneficiary address. * @param message_ beneficiary message. */ 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 ); /** * @dev Returns count of pools. */ function getPoolsCount() external view returns (uint256 poolsCount); /** * @dev Returns pool details. * @param pid_ pool id. */ function getPool(uint256 pid_) external view returns ( uint256 startTime, uint256 endTime, bytes32 merkleRoot, bool lockable, uint256 baseRate, uint256 boostRate ); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface IDeFiVestingV2Actions { /** * @dev Initialize new vesting pool. * @param startTime_ pool start time. * @param endTime_ pool end time. * @param lockable_ if pool lockable. * @param baseRate_ pool base rate. * @param boostRate_ pool boost rate. */ function setupPool(uint256 startTime_, uint256 endTime_, bool lockable_, uint256 baseRate_, uint256 boostRate_) external returns (uint256 pid); /** * @dev Updates timing parameters of the vesting pool. * @param pid_ pool id. * @param startTime_ pool start time. * @param endTime_ pool end time. */ function updatePoolTiming(uint256 pid_, uint256 startTime_, uint256 endTime_) external; /** * @dev Updates rate parameters of the vesting pool. * @param pid_ pool id. * @param lockable_ if pool lockable. * @param baseRate_ pool base rate. * @param boostRate_ pool boost rate. */ function updatePoolRate(uint256 pid_, bool lockable_, uint256 baseRate_, uint256 boostRate_) external; /** * @dev Adds new beneficiary to the pool. * @param pid_ pool id. * @param beneficiary_ new beneficiary. * @param lockedAmount_ amount to be locked for distribution. */ function setupBeneficiary(uint256 pid_, address beneficiary_, uint256 lockedAmount_) external; /** * @dev Adds new beneficiaries to the pool. * @param pid_ pool id. * @param beneficiaries_ array of beneficiaries. * @param lockedAmounts_ array of amounts to be locked for distribution. */ function setupBeneficiaryBatches(uint256 pid_, address[] calldata beneficiaries_, uint256[] calldata lockedAmounts_) external; /** * @dev Disables beneficiary in the pool(in case wallet was expolited). * @param pids_ pool ids. * @param beneficiary_ beneficiary address. */ function disableBeneficiary(uint256[] calldata pids_, address beneficiary_) external; /** * @dev Recovers beneficiary to a predefined state(in case wallet was exploited). * @param pids_ pool ids. * @param beneficiary_ beneficiary address. * @param disabled_ if beneficiary disabled. * @param withdrawn_ how many tokens beneficiary have withdrawn. * @param lockedAmount how many tokens beneficiary has under lock. * @param locked_ if beneficiary locked pool. * @param lockedAt_ if when beneficiary was locked. * @param rate_ beneficiary lock rate. */ function recoverBeneficiary(uint256[] calldata pids_, address beneficiary_, bool disabled_, uint256 withdrawn_, uint256 lockedAmount, bool locked_, uint256 lockedAt_, uint256 rate_) external; /** * @dev Allows to claim beneficiary locked amount. * @param pid_ pool id. */ function claim(uint256 pid_) external returns (uint256 amount); /** * @dev Allows to claim beneficiary locked amount. * @param pid_ pool id. * @param from_ beneficiary address. * @param to_ address where funds will be sent. */ function claimFrom(uint256 pid_, address from_, address to_) external returns (uint256 amount); /** * @dev Allows to claim beneficiary locked amount. * @param pid_ pool id. */ function lock(uint256 pid_) external; /** * @dev Returns amount of releasable funds per beneficiary. * @param pid_ pool id. * @param beneficiary_ beneficiary address. */ function getReleasableAmount(uint256 pid_, address beneficiary_) external view returns (uint256); /** * @dev Returns amount of available for vesting token per beneficiary and time. * @param pid_ pool id. * @param beneficiary_ beneficiary address. * @param time_ time of vesting. */ function getVestedAmount(uint256 pid_, address beneficiary_, uint256 time_) external view returns (uint256); /** * @dev Returns beneficiary details per pool. * @param pid_ pool id. * @param beneficiary_ beneficiary address. */ 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 ); /** * @dev Returns amount of pools */ function getPoolsCount() external view returns (uint256 poolsCount); /** * @dev Returns pool details * @param pid_ pool id */ function getPool(uint256 pid_) external view returns ( uint256 startTime, uint256 endTime, bool lockable, uint256 baseRate, uint256 boostRate ); }
{ "optimizer": { "enabled": true, "runs": 200 }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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"}]
Contract Creation Code
60c0346200029f57601f6200433038819003918201601f191683019291906001600160401b03841183851017620002a45781606092849260409687528339810103126200029f576200005181620002ba565b906020918362000063848401620002ba565b9201516001600160a01b038082169490918590036200029f5760ff1960019080825416825581600255620151806004558161ffff19600554161760055562093a80600b5562ed4e00600c55600091828052828452888320338452845260ff8984205416156200026a575b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929808452838552898420338552855260ff8a852054161562000233575b507f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a93848452838152898420338552815260ff8a8520541615620001fa575b505050505080821615620001e957821615620001d8578215620001d85760805260a052600380546001600160a01b031916919091179055516140409081620002d082396080518181816110eb01528181611e8b0152612880015260a0518181816114910152818161156b015281816120c00152818161214601528181612186015281816127f50152612fcb0152f35b83516303e71bcf60e31b8152600490fd5b84516303e71bcf60e31b8152600490fd5b848452838152898420903385525288832091825416179055339160008051602062004310833981519152339280a4388080808062000149565b8084528385528984203385528552898420828482541617905533903390600080516020620043108339815191528680a4386200010a565b82805282845288832033845284528883208183825416179055333384600080516020620043108339815191528180a4620000cd565b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036200029f5756fe608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a7146131635750806306daeaa2146130275780630f0064a214612ffa578063125fdbbc14612fb557806314c2a1bc14612f97578063156ca89414612f6e57806317027a0a14612f2057806318a5501614612ed25780632107120114612e21578063218e4a1514612e03578063248a9ca314612dd75780632ce1266914612cce5780632f2ff15d14612c2057806334e07d5d14612abd57806336568abe14612a2a5780633d912033146126505780633f4ba83a146125bb5780634092b24b14611f795780634653464914611f405780634e71d92d14611e1b57806353037dac14611dcd5780635c975abb14611daa578063613defbe14611c11578063687ff38b14611bd65780636e0806db14611b875780636e4ed6a714611b6357806373d5022814611a7f57806380c4ec8e146118e35780638194f9e61461130857806383914540146112e95780638456cb591461128f578063855c5d46146112495780638980f11f146111d05780638be2bd2f1461116257806391d148541461111a5780639bbf4b91146110d55780639dddfbd414610b54578063a217fddf14610b38578063a94a21ac14610ae6578063aa00618e14610ac8578063aac644b9146108d8578063aaf5eb68146108b5578063bcf92ee414610807578063c3acc70614610548578063c9f7531b14610526578063d547741f146104e6578063e63ab1e9146104ab578063e9de5fb014610392578063ede4ef0214610366578063ef39c4ba146102b8578063f5b541a61461027d5763f5d6621f1461025d57600080fd5b3461027a578060031936011261027a576020600b54604051908152f35b80fd5b503461027a578060031936011261027a5760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b503461027a57602036600319011261027a576102d26131b8565b6102da61329f565b6001600160a01b0316808252600d602052604082205460ff81169081610358575b5061034057808252600d60205260408220805461ffff19166101011790557fdee93a1edc83a961c8568e6abd0ea56cc40d3486eb57405439ab5a6171e4747b8280a280f35b6024906040519063689f93ef60e11b82526004820152fd5b60ff915060081c16386102fb565b503461027a578060031936011261027a5761ffff60408260016020945260078452205416604051908152f35b503461027a57602036600319011261027a5761ffff6103af6131fa565b6103b761329f565b1680158015610494575b61047c57808252600860205260ff6008604084200154166104645780825260086020527fbfcdd5a33f53869f2caee45fc0f989c13636ecb3f4269f9aa962c52c2b110dda60e06040842061010061ff001982541617815560018101549060028101549060038101546004820154906006600584015493015493604051958652602086015260408501526060840152608083015260a0820152600160c0820152a280f35b6024906040519063e1e702a160e01b82526004820152fd5b60249060405190630beda8fd60e31b82526004820152fd5b50808252600860205260ff604083205416156103c1565b503461027a578060031936011261027a5760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b503461027a57604036600319011261027a576105236004356105066131d3565b908084528360205261051e6001604086200154613570565b613736565b80f35b503461027a57602061054061053a3661320b565b91613d05565b604051908152f35b503461027a57608036600319011261027a576001600160401b036004358181116108035761057a90369060040161324f565b916024358181116107ff5761059390369060040161324f565b9390916044358181116107fb576105ae90369060040161324f565b90916064359081116107f7576105c890369060040161324f565b9690936105d361329f565b8181036107e5578783036107e55788969196915b8183106105f2578980f35b61060a6106058484849d9a9b9c9d613937565b613947565b97610616848b83613937565b359960028b10156107e1576001600160a01b038a168952600d602052604089205460ff166107c0576001600160a01b038a168952600d6020526040892080546101019062ff00008e6106678161327f565b60101b169062ffffff19161717905561067f8b61327f565b60018b14610796575b885b8661ffff82161015610742578c6106be6106b16106ac61ffff85168b8d613937565b61395b565b9161ffff8416908c613937565b359061ffff8116158015610727575b61070a5790610705929161ffff60028f8f60409160018060a01b03168152600d60205220019116600052602052604060002055613915565b61068a565b604051630beda8fd60e31b815261ffff9091166004820152602490fd5b5061ffff81168c52600860205260ff60408d205416156106cd565b509390979a997f0752ae1769eb39d626491a3a7594a9edffcd47634f9c9794fd792ea0f3e32b9f602061078f949b6040519361077d8161327f565b84526001600160a01b031692a2613928565b91966105e7565b6107a2600b54426137d3565b6001600160a01b038b168a52600d60205260408a2060010155610688565b604051630bf2388760e21b81526001600160a01b038b166004820152602490fd5b8880fd5b60405163b31f14b360e01b8152600490fd5b8780fd5b8680fd5b8480fd5b8280fd5b503461027a57602036600319011261027a576108216131b8565b61082961329f565b6001600160a01b0316808252600d602052604082205460ff811690816108a6575b5061088e57808252600d60205260408220805461ffff191660011790557fc04b676c7814734db85196b059bccd1616ebcbcce673a0cbd07e9cbde3136ddd8280a280f35b6024906040519063100ddd0960e01b82526004820152fd5b60ff915060081c16153861084a565b503461027a578060031936011261027a576020604051670de0b6b3a76400008152f35b503461027a5761010036600319011261027a5760c4356002811015610ac4577f42a029b60fb4744fc47772bae69f90bebd9c5231dfb1c50c110e88d48f2bb23d610920613240565b61092861329f565b600554610a9761ffff928361093e818516613915565b1661ffff198416176005556040516109558161369c565b60018152811515602082015260043596876040830152610a4260243592836060820152604435608082015260643560a082015260843560c082015260a43560e082015260088b610100830181815260e060406101208601938085528d8d1681528560205220946109d481511515879060ff801983541691151516179055565b6020810151865461ff00191690151560081b61ff001617865560408101516001870155606081015160028701556080810151600387015560a0810151600487015560c081015160058701550151600685015551600784015551151591019060ff801983541691151516179055565b610a4b8161327f565b60018114610a9d575b50604080519788526020880191909152604435908701526064356060870152608435608087015260a43560a0870152151560c086015291169290819060e0820190565b0390a280f35b610aa68161327f565b8852600760205260408820805461ffff191685871617905538610a54565b5080fd5b503461027a578060031936011261027a576020600c54604051908152f35b503461027a57602036600319011261027a5760409081906001600160a01b03610b0d6131b8565b168152600d60205220600160ff825460101c16910154825191610b2f8161327f565b82526020820152f35b503461027a578060031936011261027a57602090604051908152f35b503461027a57602036600319011261027a576004356001600160401b038111610ac457610b8590369060040161324f565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929808452836020526040842033855260205260ff908160408620541615610f195750610bd082613bda565b90610bde60405192836136e9565b828252601f19610bed84613bda565b01366020840137845b838110610e40575050600a420191824211610e2c576020610c19600c54856137d3565b60a460018060a01b036003541695886040519788948593639568e27360e01b8552600485015260248401528160448401528160648401528160848401525af1928315610e21578593610ded575b506003546001600160a01b0316803b15610de95785604051809263271aa9f760e01b8252846064830188600485015260606024850152526084820188845b878110610dad5750508281036003190160448401528651808252602091820191880190855b818110610d91575050508383809203925af18015610d8657610d57575b50845b818110610cf4578580f35b80610d06610605610d52938589613937565b7fd2943975e041d2f442aec941e728af0bc98a4c7302e0fcdb9c8368261e3163ee6040610d338488613bf1565b518151908152602081018990526001600160a01b0390931692a2613928565b610ce9565b6001600160401b038196929611610d72576040529338610ce6565b634e487b7160e01b82526041600452602482fd5b6040513d88823e3d90fd5b825184528c965087955060209384019390920191600101610cc9565b92945092508235906001600160a01b0382168203610de55760208091600193848060a01b031681520193019101918993918593610ca4565b8a80fd5b8580fd5b9092506020813d602011610e19575b81610e09602093836136e9565b810103126107ff57519138610c66565b3d9150610dfc565b6040513d87823e3d90fd5b634e487b7160e01b85526011600452602485fd5b6001600160a01b03610e56610605838789613937565b16808752600d80602052604088205484808260081c1615918215610eff575b50508015610ee8575b610ecf5790610eca9291610e94600b54426137d3565b90828a52602052600160408a200155600e90816020526040892054610eb98488613bf1565b528852602052866040812055613928565b610bf6565b6040516311653f5b60e11b815260048101839052602490fd5b508188528060205242600160408a20015411610e7e565b6001925060101c16610f108161327f565b14158438610e75565b8490610f2433613807565b909160405192610f33846136ce565b60428452602084019160603684378451156110c157603083538451906001918210156110c15790607860218701536041915b8183116110535750505061100f576048610fe492610ff39261100b9560405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b6020860152610fbb815180926020603789019101613679565b8401917001034b99036b4b9b9b4b733903937b6329607d1b603784015251809386840190613679565b010360288101845201826136e9565b60405162461bcd60e51b81529182916004830161370a565b0390fd5b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f811660108110156110ad576f181899199a1a9b1b9c1cb0b131b232b360811b901a61108385896137e0565b5360041c92801561109957600019019190610f65565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b503461027a578060031936011261027a576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461027a57604036600319011261027a5760ff604060209261113b6131d3565b60043582528185528282206001600160a01b03909116825284522054604051911615158152f35b503461027a57602036600319011261027a577ff0f2090c784d1e860eac46382d0c8ea31585fe9d01a8a9ef819363c1b84de0c4602061119f6131b8565b6111a761329f565b600380546001600160a01b0319166001600160a01b03929092169182179055604051908152a180f35b503461027a57604036600319011261027a577f505b28e6941631badc363841ecbf8e1214b9379c643936458e87be718e15799961120b6131b8565b6024359061121761329f565b61122b82336001600160a01b038416613b97565b604080516001600160a01b039290921682526020820192909252a180f35b503461027a578060031936011261027a5761ffff6000198160055416019080821161127b576020925060405191168152f35b634e487b7160e01b83526011600452602483fd5b503461027a578060031936011261027a576112a861342a565b6112b06138d1565b600160ff19815416176001557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a180f35b503461027a578060031936011261027a5760206040516301da9c008152f35b503461027a57608036600319011261027a576113226131b8565b61ffff6044351660443503610ac4576001600160401b03806064351161080357366023606435011215610803576064356004013511610ac45736602460643560040135606435010111610ac457611377613977565b61137f6138d1565b7fda489a047deffcd16558555da4614a51cef323c3497eaee639b4874ead8e5d978252602082815260408084206001600160a01b038416855290915282205460ff16156118d15761ffff60443516825260086020526040822060ff604051916113e78361369c565b805480831615158452600890811c83161580156020860152600183015460408601526002830154606086015260038301546080860152600483015460a0860152600583015460c0860152600683015460e0860152600783015461010086015291015490911615156101208301526118b35760018352600760205261ffff60408420541661ffff6044351614611895576040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561188a578491611858575b50604051631495c61560e11b81526024356004820152336024820152306044820152608060648201526064356004013560848201526064356004013560246064350160a483013760a46064356004013582810182018790526020918391601f19601f9091011682018290030181886001600160a01b0389165af18015610e2157611829575b506040516370a0823160e01b8152306004820152906020826024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa8015610e215785906117f5575b6115ac925061396a565b604082015181106117d7576115e66115db6115d060608501516080860151906137d3565b60c0850151906137d3565b60a0840151906137d3565b90338552600a6020526040852061ffff60443516865260205261173360e06040872054940151604051906116198261369c565b6001825261ffff6044351660208301528360408301528460608301528760808301528760a08301524260c083015260e0820152866101008201528661012082015233875260096020526040872061ffff604435168852602052604087208588526020526008610120604089209261169f81511515859060ff801983541691151516179055565b602081015162ffff00855491851b169062ffff00191617845560408101516001850155606081015160028501556003840160018060a01b036080830151166bffffffffffffffffffffffff60a01b82541617905560a0810151600485015560c0810151600585015560e0810151600685015561010081015160078501550151151591019060ff801983541691151516179055565b600183018084116117c357907fa6330c7380c1378833c0d7e864e71b2a4dc8c6f7ebc29a23ca6bda67060330ef9291338752600a6020526040872061ffff604435168852602052604087205561178b816006546137d3565b6006556040805160443561ffff1681526020810195909552840152606083015233926001600160a01b031691608090a3600160025580f35b634e487b7160e01b86526011600452602486fd5b60405163cd4a58a160e01b815260443561ffff166004820152602490fd5b506020823d602011611821575b8161180f602093836136e9565b810103126107ff576115ac91516115a2565b3d9150611802565b602090813d8311611851575b61183f81836136e9565b8101031261184d573861154e565b8380fd5b503d611835565b90506020813d602011611882575b81611873602093836136e9565b8101031261184d5751386114c9565b3d9150611866565b6040513d86823e3d90fd5b60405163baaacd7d60e01b815260443561ffff166004820152602490fd5b604051633b7db10560e11b815260443561ffff166004820152602490fd5b6040516331187d0d60e11b8152600490fd5b503461027a57606036600319011261027a576001600160401b036004358181116108035761191590369060040161324f565b906024358381116107ff5761192e90369060040161324f565b919093604435908111610de95761194990369060040161324f565b94909161195461329f565b8584036107e557939286945b84861061196b578780f35b959694959394936001600160a01b03611988610605898985613937565b1695868652600d60205260ff60408720541615611a6657855b8361ffff82161015611a2a576119bf6106ac61ffff83168688613937565b6119ce61ffff83168c89613937565b359061ffff8116158015611a0f575b61070a5790611a0a92918a8a52600d60205261ffff600260408c200191168a526020526040892055613915565b6119a1565b5061ffff81168952600860205260ff60408a205416156119dd565b509596611a5e91929598977f5e71a15d1be6f162dc632909413dea6eb05ec443222493a0709e7ce488ee24678a80a2613928565b949390611960565b6040516335f2c0e560e01b815260048101889052602490fd5b503461027a57602036600319011261027a5761ffff611a9c6131fa565b611aa461329f565b1680158015611b4c575b61047c57808252600860205260ff6008604084200154166104645780825260086020527fbfcdd5a33f53869f2caee45fc0f989c13636ecb3f4269f9aa962c52c2b110dda60e06040842061ff0019815416815560018101549060028101549060038101546004820154906006600584015493015493604051958652602086015260408501526060840152608083015260a08201528460c0820152a280f35b50808252600860205260ff60408320541615611aae565b503461027a576020611b7d611b773661320b565b91613c05565b6040519015158152f35b503461027a57604036600319011261027a576040602091611ba66131b8565b611bae6131e9565b6001600160a01b039091168252600a845282822061ffff909116825283522054604051908152f35b503461027a578060031936011261027a5760206040517fda489a047deffcd16558555da4614a51cef323c3497eaee639b4874ead8e5d978152f35b503461027a57604036600319011261027a57611c2b6131fa565b602435611c36613977565b611c3e6138d1565b33835260209060098252604084209261ffff80911693848652835260408520828652835260408520604051611c728161369c565b81549260ff841615938415835260081c1685820152600182015460408201526002820154606082015260018060a01b036003830154166080820152600482015460a082015260058201549260c0820193845261012060ff600860068601549560e08601968752600781015461010087015201541692019115158252611d985751611d8657611d0391519051906137d3565b4210611d7457611d15600454426137d3565b913385526009815260408520848652815260408520828652815282600760408720015560405193845283015260408201527f68437cdadf632abea004c96dfc71439db683d4b6807d07e3732f0b6c8a8d3d0160603392a2600160025580f35b604051633f10437b60e11b8152600490fd5b6040516332c2d48160e21b8152600490fd5b60405163e9dc455560e01b8152600490fd5b503461027a578060031936011261027a57602060ff600154166040519015158152f35b503461027a57602036600319011261027a577fa41e9cfbfaa6a8fe4db72570a1db0e0d6db6511d3cd5a1e69bc1b8237778fc2a6020600435611e0d61329f565b80600455604051908152a180f35b503461027a578060031936011261027a57611e34613977565b611e3c6138d1565b338152600d602052604081205460ff811615908115611f30575b8115611f17575b50611eff57338152600e60205260408120548015611ee757602091338152600e83526040812055611eaf81337f0000000000000000000000000000000000000000000000000000000000000000613b97565b6040518181527fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a833392a26001600255604051908152f35b60405163540a86c960e11b8152336004820152602490fd5b60405163dded60b760e01b8152336004820152602490fd5b60ff915060101c16611f288161327f565b151538611e5d565b905060ff8160081c161590611e56565b503461027a57602036600319011261027a576020906040906001600160a01b03611f686131b8565b168152600e83522054604051908152f35b503461027a57606036600319011261027a57611f936131fa565b6044356001600160a01b0381169003610ac457611fae613977565b611fb66138d1565b6044356001600160a01b03168252600d602052604082205460ff811690816125ac575b506125895761ffff8116825260086020526040822060ff600860405192611fff8461369c565b82815481811615158652831c1615156020850152600181015460408501526002810154606085015260038101546080850152600481015460a0850152600581015460c0850152600681015460e0850152600781015461010085015201541615156101208201526024351561257757336044356001600160a01b031614612565576020810151156125495760018352600760205261ffff60408420541661ffff83161461252d576040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561188a5784916124fb575b506040516323b872dd60e01b60208201523360248201523060448201526024356064820152606481528060a08101106001600160401b0360a0830111176124e7578060a061216a92016040527f00000000000000000000000000000000000000000000000000000000000000006139cb565b6040516370a0823160e01b8152306004820152906020826024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa8015610e215785906124b3575b6121c7925061396a565b9060408101518210612497576121e660608201516080830151906137d3565b846044356001600160a01b0316612345575b6122b490338752600a6020526040872061ffff8716885260205260e06040882054940151604051916122298361369c565b6001835261ffff8816602084015286604084015284606084015260018060a01b0360443516608084015260a08301524260c083015260e0820152866101008201528661012082015233875260096020526040872061ffff87168852602052604087208488526020526008610120604089209261169f81511515859060ff801983541691151516179055565b600182018083116117c3577fb72dfd9900a27aaf2fe4baf3ab01838d85186e950a0d198e739776db4b28c99193929161233a91338852600a6020526040882061ffff88168952602052604088205561230e846006546137d3565b6006556040519384933397859094939260609261ffff6080840197168352602083015260408201520152565b0390a2600160025580f35b506044356001600160a01b03168552600d60205260408520805461237c92919060ff81161561244b575b505060a0830151906137d3565b6122b461238b85604435613ec8565b6044356001600160a01b03168752600d602052604087205460019060101c60ff166123b58161327f565b146123c2575b90506121f8565b670de0b6b3a76400006301da9c006123e86123dd84896137aa565b60e0880151906137aa565b040460018060a01b03604435168852600e6020526040882061240b8282546137d3565b90556040519081526044356001600160a01b0316907f0f7bfbed227cea846f22b3e79ebaea515904b63d1fc0b5dec4d8ab2c803aa41c90602090a26123bb565b62ffffff19166101011790556040518681526044356001600160a01b0316907f0752ae1769eb39d626491a3a7594a9edffcd47634f9c9794fd792ea0f3e32b9f90602090a2388061236f565b60405163cd4a58a160e01b815261ffff84166004820152602490fd5b506020823d6020116124df575b816124cd602093836136e9565b810103126107ff576121c791516121bd565b3d91506124c0565b634e487b7160e01b85526041600452602485fd5b90506020813d602011612525575b81612516602093836136e9565b8101031261184d5751386120f8565b3d9150612509565b60405163baaacd7d60e01b815261ffff83166004820152602490fd5b604051633b7db10560e11b815261ffff83166004820152602490fd5b604051630e83d5b560e11b8152600490fd5b6040516368a8b25160e01b8152600490fd5b60405163100ddd0960e01b81526044356001600160a01b03166004820152602490fd5b60ff915060081c161538611fd9565b503461027a578060031936011261027a576125d461342a565b60015460ff8116156126145760ff19166001557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a180f35b60405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606490fd5b503461027a57604036600319011261027a5761266a6131fa565b90612673613977565b61267b6138d1565b33815260096020526040812061ffff8316825260205260408120602435825260205260408120604051906126ae8261369c565b805460ff8181161580158552600892831c61ffff166020860152600184015460408601526002840154606086015260038401546001600160a01b03166080860152600484015460a0860152600584015460c0860152600684015460e086015260078401546101008601529290910154161515610120830190815290611d985751611d865761273f6024358433613c05565b15611d745760409283820151926127588460065461396a565b6006556127686024358333613d05565b92338252600960205285822061ffff841683526020528582206024358352602052600886832001600160ff19825416179055670de0b6b3a76400006301da9c006127c46127b96060850151896137aa565b60e0850151906137aa565b04049380612959575b5060808101516001600160a01b03168015159081612937575b506128a9575b505061281983337f0000000000000000000000000000000000000000000000000000000000000000613b97565b81612879575b835161ffff9190911681526024356020820152604081018390526060810182905233907fa3e86eaae4ddfade39e5e4da82ddc476525ad7c4945c4a5df30b110c12bef11b90608090a2600160025582519182526020820152f35b6128a482337f0000000000000000000000000000000000000000000000000000000000000000613b97565b61281f565b60208187670de0b6b3a76400006301da9c006128f86128ed60a07f0f7bfbed227cea846f22b3e79ebaea515904b63d1fc0b5dec4d8ab2c803aa41c9801518c6137aa565b60e0860151906137aa565b04049460018060a01b036080840151168152600e84522061291a8582546137d3565b90556080015187519384526001600160a01b031692a238806127ec565b835250600d6020528582205460101c60ff166129528161327f565b15386127e6565b93670de0b6b3a76400006301da9c00612a1b612a23949760018752600760205261ffff8b8820541687526008602052612a16612a108c89208d5161299c8161369c565b60ff82548181161515835260081c161515602082015260018201548f82015260028201549081606082015261012060ff6008600386015495866080860152600481015460a0860152600581015460c0860152600681015460e0860152600781015461010086015201541615159101526137d3565b8b6137aa565b6137aa565b0404906137d3565b92386127cd565b503461027a57604036600319011261027a57612a446131d3565b336001600160a01b03821603612a605761052390600435613736565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608490fd5b503461027a5761010036600319011261027a57612ad86131fa565b602435604435906064359260843560a43560c4359161ffff612af8613240565b94612b0161329f565b169687158015612c09575b612bf057878952600860205260ff600860408b20015416612bd75791610a9793917fbfcdd5a33f53869f2caee45fc0f989c13636ecb3f4269f9aa962c52c2b110dda97969593898b526008602052612b9e8560408d208960018201558a60028201558360038201558460048201558560058201558660068201559061ff00825491151560081b169061ff001916179055565b60405197889788959260c09592989794919860e08801998852602088015260408701526060860152608085015260a08401521515910152565b60405163e1e702a160e01b815260048101899052602490fd5b604051630beda8fd60e31b815260048101899052602490fd5b50878952600860205260ff60408a20541615612b0c565b503461027a57604036600319011261027a57600435612c3d6131d3565b81835282602052612c546001604085200154613570565b818352602083815260408085206001600160a01b039093168086529290915283205460ff1615612c82578280f35b818352826020526040832081845260205260408320600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8480a438808280f35b503461027a57602036600319011261027a5760406101409161ffff612cf16131fa565b612cf9613fbe565b50168152600860205220604051612d0f8161369c565b815460ff811615159283835260ff602084019260081c1615158252600181015460408401908152600282015460608501908152600383015460808601908152600484015460a0870190815260058501549160c0880192835260068601549360e0890194855260078701549560ff6008610100998a8d01998a5201541698610120809b019915158a526040519b8c5251151560208c01525160408b01525160608a01525160808901525160a08801525160c08701525160e0860152519084015251151590820152f35b503461027a57602036600319011261027a57600160406020926004358152808452200154604051908152f35b503461027a578060031936011261027a576020600454604051908152f35b503461027a57602036600319011261027a5761ffff612e3e6131fa565b612e4661329f565b1680158015612ebb575b61047c57808252600860205260ff600860408420015416610464578082526008602081905260408320805461ff001916815542600782015501805460ff191660011790557fc5b5e8e1528413352485f962aed60afe5fc8f66ecda11b977795a7bc49f75c058280a280f35b50808252600860205260ff60408320541615612e50565b503461027a57602036600319011261027a577fc7424b5b1af011526d99d735a59928c6aec93e238a757b34b78bc3d628136c2f6020600435612f1261329f565b80600b55604051908152a180f35b503461027a57602036600319011261027a577ff7cf4c13c8c5efd46eac4a9c982c64ffef54781457a9cc75775f0fcec6f2f6b06020600435612f6061329f565b80600c55604051908152a180f35b503461027a578060031936011261027a576003546040516001600160a01b039091168152602090f35b503461027a578060031936011261027a576020600654604051908152f35b503461027a578060031936011261027a576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461027a57604036600319011261027a5760206105406130196131b8565b6130216131e9565b90613ec8565b503461027a5760406101409161303c3661320b565b91613045613fbe565b5060018060a01b03168352600960205261ffff848420911683526020528282209082526020522061012060405161307b8161369c565b82549260ff84161515825261ffff8460081c166020830152600181015460408301526002810154606083015260018060a01b036003820154166080830152600481015460a0830152600581015460c0830152600681015460e083015260ff6008600783015492610100938486015201541615158383015260ff60405194161515845261ffff6020830151166020850152604082015160408501526060820151606085015260018060a01b03608083015116608085015260a082015160a085015260c082015160c085015260e082015160e0850152808201519084015201511515610120820152f35b905034610ac4576020366003190112610ac45760043563ffffffff60e01b81168091036108035760209250637965db0b60e01b81149081156131a7575b5015158152f35b6301ffc9a760e01b149050386131a0565b600435906001600160a01b03821682036131ce57565b600080fd5b602435906001600160a01b03821682036131ce57565b6024359061ffff821682036131ce57565b6004359061ffff821682036131ce57565b60609060031901126131ce576004356001600160a01b03811681036131ce579060243561ffff811681036131ce579060443590565b60e4359081151582036131ce57565b9181601f840112156131ce578235916001600160401b0383116131ce576020808501948460051b0101116131ce57565b6002111561328957565b634e487b7160e01b600052602160045260246000fd5b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602090815260408083205490929060ff16156132e157505050565b6132ea33613807565b835190826132f7836136ce565b604283528483019360603686378351156110c157603085538351906001918210156110c15790607860218601536041915b8183116133e4575050506133a257610fbb93859361338c9361337d60489461100b9951988576020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8b978801528251928391603789019101613679565b010360288101855201836136e9565b5162461bcd60e51b81529182916004830161370a565b60648486519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f811660108110156110ad576f181899199a1a9b1b9c1cb0b131b232b360811b901a61341485886137e0565b5360041c92801561109957600019019190613328565b3360009081527ff7c9542c591017a21c74b6f3fab6263c7952fc0aaf9db4c22a2a04ddc7f8674f60209081526040808320549092907f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9060ff161561348f5750505050565b61349833613807565b8451916134a4836136ce565b604283528483019360603686378351156110c157603085538351906001918210156110c15790607860218601536041915b81831161352a575050506133a257610fbb93859361338c9361337d60489461100b9951988576020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8b978801528251928391603789019101613679565b909192600f811660108110156110ad576f181899199a1a9b1b9c1cb0b131b232b360811b901a61355a85886137e0565b5360041c928015611099576000190191906134d5565b6000818152602090808252604092838220338352835260ff8483205416156135985750505050565b6135a133613807565b8451916135ad836136ce565b604283528483019360603686378351156110c157603085538351906001918210156110c15790607860218601536041915b818311613633575050506133a257610fbb93859361338c9361337d60489461100b9951988576020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8b978801528251928391603789019101613679565b909192600f811660108110156110ad576f181899199a1a9b1b9c1cb0b131b232b360811b901a61366385886137e0565b5360041c928015611099576000190191906135de565b60005b83811061368c5750506000910152565b818101518382015260200161367c565b61014081019081106001600160401b038211176136b857604052565b634e487b7160e01b600052604160045260246000fd5b608081019081106001600160401b038211176136b857604052565b90601f801991011681019081106001600160401b038211176136b857604052565b6040916020825261372a8151809281602086015260208686019101613679565b601f01601f1916010190565b9060009180835282602052604083209160018060a01b03169182845260205260ff60408420541661376657505050565b80835282602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b818102929181159184041417156137bd57565b634e487b7160e01b600052601160045260246000fd5b919082018092116137bd57565b9081518110156137f1570160200190565b634e487b7160e01b600052603260045260246000fd5b60405190606082018281106001600160401b038211176136b857604052602a82526020820160403682378251156137f1576030905381516001908110156137f157607860218401536029905b80821161386357505061100f5790565b9091600f811660108110156138bc576f181899199a1a9b1b9c1cb0b131b232b360811b901a61389284866137e0565b5360041c9180156138a7576000190190613853565b60246000634e487b7160e01b81526011600452fd5b60246000634e487b7160e01b81526032600452fd5b60ff600154166138dd57565b60405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606490fd5b61ffff8091169081146137bd5760010190565b60001981146137bd5760010190565b91908110156137f15760051b0190565b356001600160a01b03811681036131ce5790565b3561ffff811681036131ce5790565b919082039182116137bd57565b60028054146139865760028055565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b60018060a01b031690604051604081016001600160401b0390828110828211176136b8576040526020938483527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564858401526000808587829751910182855af1903d15613afb573d9283116124e75790613a6593929160405192613a5888601f19601f84011601856136e9565b83523d868885013e613b06565b805191821591848315613ad7575b505050905015613a805750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b919381809450010312610ac45782015190811515820361027a575080388084613a73565b90613a659392506060915b91929015613b685750815115613b1a575090565b3b15613b235790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015613b7b5750805190602001fd5b60405162461bcd60e51b815290819061100b906004830161370a565b60405163a9059cbb60e01b60208201526001600160a01b03929092166024830152604480830193909352918152613bd891613bd36064836136e9565b6139cb565b565b6001600160401b0381116136b85760051b60200190565b80518210156137f15760209160051b010190565b9160018060a01b03908160009416845260096020526040842061ffff809416855260205260408420908452602052604083209160405191613c458361369c565b83549060ff8216159283159283865260081c16602085015260018501546040850152600285015460608501526003850154166080840152600484015460a08401526101206005850154928360c08601526006860154948560e082015260ff60086007890154986101008401998a520154161515928391015291613cfd575b50613cf75760045415613ce557505051908115613ce05750421190565b905090565b909150613cf292506137d3565b421190565b50505090565b905038613cc3565b7fb39221ace053465ec3453ce2b36430bd138b997ecea25c1043da0c366812b8285461ffff908116600090815260086020908152604080832081519397969594909391613d518361369c565b84549760ff808a1615998a15865260081c161515858501526001860154828501526002860154606085015260038601546080850152600486015460a0850152600586015460c0850152600686015460e085015260078601549760ff6008610100988988019b8c52015416996101208096019a15158b52613ebb576001600160a01b039788168b5260098652828b209084168b528552818a20908a528452808920815190969091613e008361369c565b87549560ff8716159485159788865260081c1690840152600188015490830152600287015460608301526003870154166080820152600486015460a082015260ff60086005880154978860c08501526006810154978860e08601526007820154908501520154161515928391015291613eb3575b50613eac57613e82916137d3565b915115613ea557515b81811115613ea057613e9d925061396a565b90565b505090565b5042613e8b565b5050505090565b905038613e74565b5050505050505050505090565b9061ffff1660009080825260086020526040822090604051613ee98161369c565b60ff83548181161515835260081c1615156020820152600183015460408201526002830154606082015260038301546080820152600483015460a082015261012060ff60086005860154958660c0860152600681015460e086015260078101546101008601520154161515910152819360018060a01b03168352600d6020526040832090815460ff81169081613fb0575b50613f86575050505090565b8352600201602052604090912054915080821115613fa957505b38808080613eac565b9050613fa0565b60ff915060081c1638613f7a565b60405190613fcb8261369c565b816101206000918281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e082015282610100820152015256fea2646970667358221220422ae452b98a929f91fccaf47ab91fc93e11190d4ea3aa096f8f59a57deaeaff64736f6c634300081300332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31310000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31310000000000000000000000004307adb2b4fc069d46a3f3c1317cbeb7cae53262
Deployed Bytecode
0x608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a7146131635750806306daeaa2146130275780630f0064a214612ffa578063125fdbbc14612fb557806314c2a1bc14612f97578063156ca89414612f6e57806317027a0a14612f2057806318a5501614612ed25780632107120114612e21578063218e4a1514612e03578063248a9ca314612dd75780632ce1266914612cce5780632f2ff15d14612c2057806334e07d5d14612abd57806336568abe14612a2a5780633d912033146126505780633f4ba83a146125bb5780634092b24b14611f795780634653464914611f405780634e71d92d14611e1b57806353037dac14611dcd5780635c975abb14611daa578063613defbe14611c11578063687ff38b14611bd65780636e0806db14611b875780636e4ed6a714611b6357806373d5022814611a7f57806380c4ec8e146118e35780638194f9e61461130857806383914540146112e95780638456cb591461128f578063855c5d46146112495780638980f11f146111d05780638be2bd2f1461116257806391d148541461111a5780639bbf4b91146110d55780639dddfbd414610b54578063a217fddf14610b38578063a94a21ac14610ae6578063aa00618e14610ac8578063aac644b9146108d8578063aaf5eb68146108b5578063bcf92ee414610807578063c3acc70614610548578063c9f7531b14610526578063d547741f146104e6578063e63ab1e9146104ab578063e9de5fb014610392578063ede4ef0214610366578063ef39c4ba146102b8578063f5b541a61461027d5763f5d6621f1461025d57600080fd5b3461027a578060031936011261027a576020600b54604051908152f35b80fd5b503461027a578060031936011261027a5760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b503461027a57602036600319011261027a576102d26131b8565b6102da61329f565b6001600160a01b0316808252600d602052604082205460ff81169081610358575b5061034057808252600d60205260408220805461ffff19166101011790557fdee93a1edc83a961c8568e6abd0ea56cc40d3486eb57405439ab5a6171e4747b8280a280f35b6024906040519063689f93ef60e11b82526004820152fd5b60ff915060081c16386102fb565b503461027a578060031936011261027a5761ffff60408260016020945260078452205416604051908152f35b503461027a57602036600319011261027a5761ffff6103af6131fa565b6103b761329f565b1680158015610494575b61047c57808252600860205260ff6008604084200154166104645780825260086020527fbfcdd5a33f53869f2caee45fc0f989c13636ecb3f4269f9aa962c52c2b110dda60e06040842061010061ff001982541617815560018101549060028101549060038101546004820154906006600584015493015493604051958652602086015260408501526060840152608083015260a0820152600160c0820152a280f35b6024906040519063e1e702a160e01b82526004820152fd5b60249060405190630beda8fd60e31b82526004820152fd5b50808252600860205260ff604083205416156103c1565b503461027a578060031936011261027a5760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b503461027a57604036600319011261027a576105236004356105066131d3565b908084528360205261051e6001604086200154613570565b613736565b80f35b503461027a57602061054061053a3661320b565b91613d05565b604051908152f35b503461027a57608036600319011261027a576001600160401b036004358181116108035761057a90369060040161324f565b916024358181116107ff5761059390369060040161324f565b9390916044358181116107fb576105ae90369060040161324f565b90916064359081116107f7576105c890369060040161324f565b9690936105d361329f565b8181036107e5578783036107e55788969196915b8183106105f2578980f35b61060a6106058484849d9a9b9c9d613937565b613947565b97610616848b83613937565b359960028b10156107e1576001600160a01b038a168952600d602052604089205460ff166107c0576001600160a01b038a168952600d6020526040892080546101019062ff00008e6106678161327f565b60101b169062ffffff19161717905561067f8b61327f565b60018b14610796575b885b8661ffff82161015610742578c6106be6106b16106ac61ffff85168b8d613937565b61395b565b9161ffff8416908c613937565b359061ffff8116158015610727575b61070a5790610705929161ffff60028f8f60409160018060a01b03168152600d60205220019116600052602052604060002055613915565b61068a565b604051630beda8fd60e31b815261ffff9091166004820152602490fd5b5061ffff81168c52600860205260ff60408d205416156106cd565b509390979a997f0752ae1769eb39d626491a3a7594a9edffcd47634f9c9794fd792ea0f3e32b9f602061078f949b6040519361077d8161327f565b84526001600160a01b031692a2613928565b91966105e7565b6107a2600b54426137d3565b6001600160a01b038b168a52600d60205260408a2060010155610688565b604051630bf2388760e21b81526001600160a01b038b166004820152602490fd5b8880fd5b60405163b31f14b360e01b8152600490fd5b8780fd5b8680fd5b8480fd5b8280fd5b503461027a57602036600319011261027a576108216131b8565b61082961329f565b6001600160a01b0316808252600d602052604082205460ff811690816108a6575b5061088e57808252600d60205260408220805461ffff191660011790557fc04b676c7814734db85196b059bccd1616ebcbcce673a0cbd07e9cbde3136ddd8280a280f35b6024906040519063100ddd0960e01b82526004820152fd5b60ff915060081c16153861084a565b503461027a578060031936011261027a576020604051670de0b6b3a76400008152f35b503461027a5761010036600319011261027a5760c4356002811015610ac4577f42a029b60fb4744fc47772bae69f90bebd9c5231dfb1c50c110e88d48f2bb23d610920613240565b61092861329f565b600554610a9761ffff928361093e818516613915565b1661ffff198416176005556040516109558161369c565b60018152811515602082015260043596876040830152610a4260243592836060820152604435608082015260643560a082015260843560c082015260a43560e082015260088b610100830181815260e060406101208601938085528d8d1681528560205220946109d481511515879060ff801983541691151516179055565b6020810151865461ff00191690151560081b61ff001617865560408101516001870155606081015160028701556080810151600387015560a0810151600487015560c081015160058701550151600685015551600784015551151591019060ff801983541691151516179055565b610a4b8161327f565b60018114610a9d575b50604080519788526020880191909152604435908701526064356060870152608435608087015260a43560a0870152151560c086015291169290819060e0820190565b0390a280f35b610aa68161327f565b8852600760205260408820805461ffff191685871617905538610a54565b5080fd5b503461027a578060031936011261027a576020600c54604051908152f35b503461027a57602036600319011261027a5760409081906001600160a01b03610b0d6131b8565b168152600d60205220600160ff825460101c16910154825191610b2f8161327f565b82526020820152f35b503461027a578060031936011261027a57602090604051908152f35b503461027a57602036600319011261027a576004356001600160401b038111610ac457610b8590369060040161324f565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929808452836020526040842033855260205260ff908160408620541615610f195750610bd082613bda565b90610bde60405192836136e9565b828252601f19610bed84613bda565b01366020840137845b838110610e40575050600a420191824211610e2c576020610c19600c54856137d3565b60a460018060a01b036003541695886040519788948593639568e27360e01b8552600485015260248401528160448401528160648401528160848401525af1928315610e21578593610ded575b506003546001600160a01b0316803b15610de95785604051809263271aa9f760e01b8252846064830188600485015260606024850152526084820188845b878110610dad5750508281036003190160448401528651808252602091820191880190855b818110610d91575050508383809203925af18015610d8657610d57575b50845b818110610cf4578580f35b80610d06610605610d52938589613937565b7fd2943975e041d2f442aec941e728af0bc98a4c7302e0fcdb9c8368261e3163ee6040610d338488613bf1565b518151908152602081018990526001600160a01b0390931692a2613928565b610ce9565b6001600160401b038196929611610d72576040529338610ce6565b634e487b7160e01b82526041600452602482fd5b6040513d88823e3d90fd5b825184528c965087955060209384019390920191600101610cc9565b92945092508235906001600160a01b0382168203610de55760208091600193848060a01b031681520193019101918993918593610ca4565b8a80fd5b8580fd5b9092506020813d602011610e19575b81610e09602093836136e9565b810103126107ff57519138610c66565b3d9150610dfc565b6040513d87823e3d90fd5b634e487b7160e01b85526011600452602485fd5b6001600160a01b03610e56610605838789613937565b16808752600d80602052604088205484808260081c1615918215610eff575b50508015610ee8575b610ecf5790610eca9291610e94600b54426137d3565b90828a52602052600160408a200155600e90816020526040892054610eb98488613bf1565b528852602052866040812055613928565b610bf6565b6040516311653f5b60e11b815260048101839052602490fd5b508188528060205242600160408a20015411610e7e565b6001925060101c16610f108161327f565b14158438610e75565b8490610f2433613807565b909160405192610f33846136ce565b60428452602084019160603684378451156110c157603083538451906001918210156110c15790607860218701536041915b8183116110535750505061100f576048610fe492610ff39261100b9560405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b6020860152610fbb815180926020603789019101613679565b8401917001034b99036b4b9b9b4b733903937b6329607d1b603784015251809386840190613679565b010360288101845201826136e9565b60405162461bcd60e51b81529182916004830161370a565b0390fd5b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f811660108110156110ad576f181899199a1a9b1b9c1cb0b131b232b360811b901a61108385896137e0565b5360041c92801561109957600019019190610f65565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b503461027a578060031936011261027a576040517f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31316001600160a01b03168152602090f35b503461027a57604036600319011261027a5760ff604060209261113b6131d3565b60043582528185528282206001600160a01b03909116825284522054604051911615158152f35b503461027a57602036600319011261027a577ff0f2090c784d1e860eac46382d0c8ea31585fe9d01a8a9ef819363c1b84de0c4602061119f6131b8565b6111a761329f565b600380546001600160a01b0319166001600160a01b03929092169182179055604051908152a180f35b503461027a57604036600319011261027a577f505b28e6941631badc363841ecbf8e1214b9379c643936458e87be718e15799961120b6131b8565b6024359061121761329f565b61122b82336001600160a01b038416613b97565b604080516001600160a01b039290921682526020820192909252a180f35b503461027a578060031936011261027a5761ffff6000198160055416019080821161127b576020925060405191168152f35b634e487b7160e01b83526011600452602483fd5b503461027a578060031936011261027a576112a861342a565b6112b06138d1565b600160ff19815416176001557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a180f35b503461027a578060031936011261027a5760206040516301da9c008152f35b503461027a57608036600319011261027a576113226131b8565b61ffff6044351660443503610ac4576001600160401b03806064351161080357366023606435011215610803576064356004013511610ac45736602460643560040135606435010111610ac457611377613977565b61137f6138d1565b7fda489a047deffcd16558555da4614a51cef323c3497eaee639b4874ead8e5d978252602082815260408084206001600160a01b038416855290915282205460ff16156118d15761ffff60443516825260086020526040822060ff604051916113e78361369c565b805480831615158452600890811c83161580156020860152600183015460408601526002830154606086015260038301546080860152600483015460a0860152600583015460c0860152600683015460e0860152600783015461010086015291015490911615156101208301526118b35760018352600760205261ffff60408420541661ffff6044351614611895576040516370a0823160e01b81523060048201526020816024817f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31316001600160a01b03165afa90811561188a578491611858575b50604051631495c61560e11b81526024356004820152336024820152306044820152608060648201526064356004013560848201526064356004013560246064350160a483013760a46064356004013582810182018790526020918391601f19601f9091011682018290030181886001600160a01b0389165af18015610e2157611829575b506040516370a0823160e01b8152306004820152906020826024817f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31316001600160a01b03165afa8015610e215785906117f5575b6115ac925061396a565b604082015181106117d7576115e66115db6115d060608501516080860151906137d3565b60c0850151906137d3565b60a0840151906137d3565b90338552600a6020526040852061ffff60443516865260205261173360e06040872054940151604051906116198261369c565b6001825261ffff6044351660208301528360408301528460608301528760808301528760a08301524260c083015260e0820152866101008201528661012082015233875260096020526040872061ffff604435168852602052604087208588526020526008610120604089209261169f81511515859060ff801983541691151516179055565b602081015162ffff00855491851b169062ffff00191617845560408101516001850155606081015160028501556003840160018060a01b036080830151166bffffffffffffffffffffffff60a01b82541617905560a0810151600485015560c0810151600585015560e0810151600685015561010081015160078501550151151591019060ff801983541691151516179055565b600183018084116117c357907fa6330c7380c1378833c0d7e864e71b2a4dc8c6f7ebc29a23ca6bda67060330ef9291338752600a6020526040872061ffff604435168852602052604087205561178b816006546137d3565b6006556040805160443561ffff1681526020810195909552840152606083015233926001600160a01b031691608090a3600160025580f35b634e487b7160e01b86526011600452602486fd5b60405163cd4a58a160e01b815260443561ffff166004820152602490fd5b506020823d602011611821575b8161180f602093836136e9565b810103126107ff576115ac91516115a2565b3d9150611802565b602090813d8311611851575b61183f81836136e9565b8101031261184d573861154e565b8380fd5b503d611835565b90506020813d602011611882575b81611873602093836136e9565b8101031261184d5751386114c9565b3d9150611866565b6040513d86823e3d90fd5b60405163baaacd7d60e01b815260443561ffff166004820152602490fd5b604051633b7db10560e11b815260443561ffff166004820152602490fd5b6040516331187d0d60e11b8152600490fd5b503461027a57606036600319011261027a576001600160401b036004358181116108035761191590369060040161324f565b906024358381116107ff5761192e90369060040161324f565b919093604435908111610de95761194990369060040161324f565b94909161195461329f565b8584036107e557939286945b84861061196b578780f35b959694959394936001600160a01b03611988610605898985613937565b1695868652600d60205260ff60408720541615611a6657855b8361ffff82161015611a2a576119bf6106ac61ffff83168688613937565b6119ce61ffff83168c89613937565b359061ffff8116158015611a0f575b61070a5790611a0a92918a8a52600d60205261ffff600260408c200191168a526020526040892055613915565b6119a1565b5061ffff81168952600860205260ff60408a205416156119dd565b509596611a5e91929598977f5e71a15d1be6f162dc632909413dea6eb05ec443222493a0709e7ce488ee24678a80a2613928565b949390611960565b6040516335f2c0e560e01b815260048101889052602490fd5b503461027a57602036600319011261027a5761ffff611a9c6131fa565b611aa461329f565b1680158015611b4c575b61047c57808252600860205260ff6008604084200154166104645780825260086020527fbfcdd5a33f53869f2caee45fc0f989c13636ecb3f4269f9aa962c52c2b110dda60e06040842061ff0019815416815560018101549060028101549060038101546004820154906006600584015493015493604051958652602086015260408501526060840152608083015260a08201528460c0820152a280f35b50808252600860205260ff60408320541615611aae565b503461027a576020611b7d611b773661320b565b91613c05565b6040519015158152f35b503461027a57604036600319011261027a576040602091611ba66131b8565b611bae6131e9565b6001600160a01b039091168252600a845282822061ffff909116825283522054604051908152f35b503461027a578060031936011261027a5760206040517fda489a047deffcd16558555da4614a51cef323c3497eaee639b4874ead8e5d978152f35b503461027a57604036600319011261027a57611c2b6131fa565b602435611c36613977565b611c3e6138d1565b33835260209060098252604084209261ffff80911693848652835260408520828652835260408520604051611c728161369c565b81549260ff841615938415835260081c1685820152600182015460408201526002820154606082015260018060a01b036003830154166080820152600482015460a082015260058201549260c0820193845261012060ff600860068601549560e08601968752600781015461010087015201541692019115158252611d985751611d8657611d0391519051906137d3565b4210611d7457611d15600454426137d3565b913385526009815260408520848652815260408520828652815282600760408720015560405193845283015260408201527f68437cdadf632abea004c96dfc71439db683d4b6807d07e3732f0b6c8a8d3d0160603392a2600160025580f35b604051633f10437b60e11b8152600490fd5b6040516332c2d48160e21b8152600490fd5b60405163e9dc455560e01b8152600490fd5b503461027a578060031936011261027a57602060ff600154166040519015158152f35b503461027a57602036600319011261027a577fa41e9cfbfaa6a8fe4db72570a1db0e0d6db6511d3cd5a1e69bc1b8237778fc2a6020600435611e0d61329f565b80600455604051908152a180f35b503461027a578060031936011261027a57611e34613977565b611e3c6138d1565b338152600d602052604081205460ff811615908115611f30575b8115611f17575b50611eff57338152600e60205260408120548015611ee757602091338152600e83526040812055611eaf81337f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b3131613b97565b6040518181527fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a833392a26001600255604051908152f35b60405163540a86c960e11b8152336004820152602490fd5b60405163dded60b760e01b8152336004820152602490fd5b60ff915060101c16611f288161327f565b151538611e5d565b905060ff8160081c161590611e56565b503461027a57602036600319011261027a576020906040906001600160a01b03611f686131b8565b168152600e83522054604051908152f35b503461027a57606036600319011261027a57611f936131fa565b6044356001600160a01b0381169003610ac457611fae613977565b611fb66138d1565b6044356001600160a01b03168252600d602052604082205460ff811690816125ac575b506125895761ffff8116825260086020526040822060ff600860405192611fff8461369c565b82815481811615158652831c1615156020850152600181015460408501526002810154606085015260038101546080850152600481015460a0850152600581015460c0850152600681015460e0850152600781015461010085015201541615156101208201526024351561257757336044356001600160a01b031614612565576020810151156125495760018352600760205261ffff60408420541661ffff83161461252d576040516370a0823160e01b81523060048201526020816024817f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31316001600160a01b03165afa90811561188a5784916124fb575b506040516323b872dd60e01b60208201523360248201523060448201526024356064820152606481528060a08101106001600160401b0360a0830111176124e7578060a061216a92016040527f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31316139cb565b6040516370a0823160e01b8152306004820152906020826024817f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31316001600160a01b03165afa8015610e215785906124b3575b6121c7925061396a565b9060408101518210612497576121e660608201516080830151906137d3565b846044356001600160a01b0316612345575b6122b490338752600a6020526040872061ffff8716885260205260e06040882054940151604051916122298361369c565b6001835261ffff8816602084015286604084015284606084015260018060a01b0360443516608084015260a08301524260c083015260e0820152866101008201528661012082015233875260096020526040872061ffff87168852602052604087208488526020526008610120604089209261169f81511515859060ff801983541691151516179055565b600182018083116117c3577fb72dfd9900a27aaf2fe4baf3ab01838d85186e950a0d198e739776db4b28c99193929161233a91338852600a6020526040882061ffff88168952602052604088205561230e846006546137d3565b6006556040519384933397859094939260609261ffff6080840197168352602083015260408201520152565b0390a2600160025580f35b506044356001600160a01b03168552600d60205260408520805461237c92919060ff81161561244b575b505060a0830151906137d3565b6122b461238b85604435613ec8565b6044356001600160a01b03168752600d602052604087205460019060101c60ff166123b58161327f565b146123c2575b90506121f8565b670de0b6b3a76400006301da9c006123e86123dd84896137aa565b60e0880151906137aa565b040460018060a01b03604435168852600e6020526040882061240b8282546137d3565b90556040519081526044356001600160a01b0316907f0f7bfbed227cea846f22b3e79ebaea515904b63d1fc0b5dec4d8ab2c803aa41c90602090a26123bb565b62ffffff19166101011790556040518681526044356001600160a01b0316907f0752ae1769eb39d626491a3a7594a9edffcd47634f9c9794fd792ea0f3e32b9f90602090a2388061236f565b60405163cd4a58a160e01b815261ffff84166004820152602490fd5b506020823d6020116124df575b816124cd602093836136e9565b810103126107ff576121c791516121bd565b3d91506124c0565b634e487b7160e01b85526041600452602485fd5b90506020813d602011612525575b81612516602093836136e9565b8101031261184d5751386120f8565b3d9150612509565b60405163baaacd7d60e01b815261ffff83166004820152602490fd5b604051633b7db10560e11b815261ffff83166004820152602490fd5b604051630e83d5b560e11b8152600490fd5b6040516368a8b25160e01b8152600490fd5b60405163100ddd0960e01b81526044356001600160a01b03166004820152602490fd5b60ff915060081c161538611fd9565b503461027a578060031936011261027a576125d461342a565b60015460ff8116156126145760ff19166001557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a180f35b60405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606490fd5b503461027a57604036600319011261027a5761266a6131fa565b90612673613977565b61267b6138d1565b33815260096020526040812061ffff8316825260205260408120602435825260205260408120604051906126ae8261369c565b805460ff8181161580158552600892831c61ffff166020860152600184015460408601526002840154606086015260038401546001600160a01b03166080860152600484015460a0860152600584015460c0860152600684015460e086015260078401546101008601529290910154161515610120830190815290611d985751611d865761273f6024358433613c05565b15611d745760409283820151926127588460065461396a565b6006556127686024358333613d05565b92338252600960205285822061ffff841683526020528582206024358352602052600886832001600160ff19825416179055670de0b6b3a76400006301da9c006127c46127b96060850151896137aa565b60e0850151906137aa565b04049380612959575b5060808101516001600160a01b03168015159081612937575b506128a9575b505061281983337f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b3131613b97565b81612879575b835161ffff9190911681526024356020820152604081018390526060810182905233907fa3e86eaae4ddfade39e5e4da82ddc476525ad7c4945c4a5df30b110c12bef11b90608090a2600160025582519182526020820152f35b6128a482337f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b3131613b97565b61281f565b60208187670de0b6b3a76400006301da9c006128f86128ed60a07f0f7bfbed227cea846f22b3e79ebaea515904b63d1fc0b5dec4d8ab2c803aa41c9801518c6137aa565b60e0860151906137aa565b04049460018060a01b036080840151168152600e84522061291a8582546137d3565b90556080015187519384526001600160a01b031692a238806127ec565b835250600d6020528582205460101c60ff166129528161327f565b15386127e6565b93670de0b6b3a76400006301da9c00612a1b612a23949760018752600760205261ffff8b8820541687526008602052612a16612a108c89208d5161299c8161369c565b60ff82548181161515835260081c161515602082015260018201548f82015260028201549081606082015261012060ff6008600386015495866080860152600481015460a0860152600581015460c0860152600681015460e0860152600781015461010086015201541615159101526137d3565b8b6137aa565b6137aa565b0404906137d3565b92386127cd565b503461027a57604036600319011261027a57612a446131d3565b336001600160a01b03821603612a605761052390600435613736565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608490fd5b503461027a5761010036600319011261027a57612ad86131fa565b602435604435906064359260843560a43560c4359161ffff612af8613240565b94612b0161329f565b169687158015612c09575b612bf057878952600860205260ff600860408b20015416612bd75791610a9793917fbfcdd5a33f53869f2caee45fc0f989c13636ecb3f4269f9aa962c52c2b110dda97969593898b526008602052612b9e8560408d208960018201558a60028201558360038201558460048201558560058201558660068201559061ff00825491151560081b169061ff001916179055565b60405197889788959260c09592989794919860e08801998852602088015260408701526060860152608085015260a08401521515910152565b60405163e1e702a160e01b815260048101899052602490fd5b604051630beda8fd60e31b815260048101899052602490fd5b50878952600860205260ff60408a20541615612b0c565b503461027a57604036600319011261027a57600435612c3d6131d3565b81835282602052612c546001604085200154613570565b818352602083815260408085206001600160a01b039093168086529290915283205460ff1615612c82578280f35b818352826020526040832081845260205260408320600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8480a438808280f35b503461027a57602036600319011261027a5760406101409161ffff612cf16131fa565b612cf9613fbe565b50168152600860205220604051612d0f8161369c565b815460ff811615159283835260ff602084019260081c1615158252600181015460408401908152600282015460608501908152600383015460808601908152600484015460a0870190815260058501549160c0880192835260068601549360e0890194855260078701549560ff6008610100998a8d01998a5201541698610120809b019915158a526040519b8c5251151560208c01525160408b01525160608a01525160808901525160a08801525160c08701525160e0860152519084015251151590820152f35b503461027a57602036600319011261027a57600160406020926004358152808452200154604051908152f35b503461027a578060031936011261027a576020600454604051908152f35b503461027a57602036600319011261027a5761ffff612e3e6131fa565b612e4661329f565b1680158015612ebb575b61047c57808252600860205260ff600860408420015416610464578082526008602081905260408320805461ff001916815542600782015501805460ff191660011790557fc5b5e8e1528413352485f962aed60afe5fc8f66ecda11b977795a7bc49f75c058280a280f35b50808252600860205260ff60408320541615612e50565b503461027a57602036600319011261027a577fc7424b5b1af011526d99d735a59928c6aec93e238a757b34b78bc3d628136c2f6020600435612f1261329f565b80600b55604051908152a180f35b503461027a57602036600319011261027a577ff7cf4c13c8c5efd46eac4a9c982c64ffef54781457a9cc75775f0fcec6f2f6b06020600435612f6061329f565b80600c55604051908152a180f35b503461027a578060031936011261027a576003546040516001600160a01b039091168152602090f35b503461027a578060031936011261027a576020600654604051908152f35b503461027a578060031936011261027a576040517f0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31316001600160a01b03168152602090f35b503461027a57604036600319011261027a5760206105406130196131b8565b6130216131e9565b90613ec8565b503461027a5760406101409161303c3661320b565b91613045613fbe565b5060018060a01b03168352600960205261ffff848420911683526020528282209082526020522061012060405161307b8161369c565b82549260ff84161515825261ffff8460081c166020830152600181015460408301526002810154606083015260018060a01b036003820154166080830152600481015460a0830152600581015460c0830152600681015460e083015260ff6008600783015492610100938486015201541615158383015260ff60405194161515845261ffff6020830151166020850152604082015160408501526060820151606085015260018060a01b03608083015116608085015260a082015160a085015260c082015160c085015260e082015160e0850152808201519084015201511515610120820152f35b905034610ac4576020366003190112610ac45760043563ffffffff60e01b81168091036108035760209250637965db0b60e01b81149081156131a7575b5015158152f35b6301ffc9a760e01b149050386131a0565b600435906001600160a01b03821682036131ce57565b600080fd5b602435906001600160a01b03821682036131ce57565b6024359061ffff821682036131ce57565b6004359061ffff821682036131ce57565b60609060031901126131ce576004356001600160a01b03811681036131ce579060243561ffff811681036131ce579060443590565b60e4359081151582036131ce57565b9181601f840112156131ce578235916001600160401b0383116131ce576020808501948460051b0101116131ce57565b6002111561328957565b634e487b7160e01b600052602160045260246000fd5b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602090815260408083205490929060ff16156132e157505050565b6132ea33613807565b835190826132f7836136ce565b604283528483019360603686378351156110c157603085538351906001918210156110c15790607860218601536041915b8183116133e4575050506133a257610fbb93859361338c9361337d60489461100b9951988576020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8b978801528251928391603789019101613679565b010360288101855201836136e9565b5162461bcd60e51b81529182916004830161370a565b60648486519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f811660108110156110ad576f181899199a1a9b1b9c1cb0b131b232b360811b901a61341485886137e0565b5360041c92801561109957600019019190613328565b3360009081527ff7c9542c591017a21c74b6f3fab6263c7952fc0aaf9db4c22a2a04ddc7f8674f60209081526040808320549092907f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9060ff161561348f5750505050565b61349833613807565b8451916134a4836136ce565b604283528483019360603686378351156110c157603085538351906001918210156110c15790607860218601536041915b81831161352a575050506133a257610fbb93859361338c9361337d60489461100b9951988576020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8b978801528251928391603789019101613679565b909192600f811660108110156110ad576f181899199a1a9b1b9c1cb0b131b232b360811b901a61355a85886137e0565b5360041c928015611099576000190191906134d5565b6000818152602090808252604092838220338352835260ff8483205416156135985750505050565b6135a133613807565b8451916135ad836136ce565b604283528483019360603686378351156110c157603085538351906001918210156110c15790607860218601536041915b818311613633575050506133a257610fbb93859361338c9361337d60489461100b9951988576020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8b978801528251928391603789019101613679565b909192600f811660108110156110ad576f181899199a1a9b1b9c1cb0b131b232b360811b901a61366385886137e0565b5360041c928015611099576000190191906135de565b60005b83811061368c5750506000910152565b818101518382015260200161367c565b61014081019081106001600160401b038211176136b857604052565b634e487b7160e01b600052604160045260246000fd5b608081019081106001600160401b038211176136b857604052565b90601f801991011681019081106001600160401b038211176136b857604052565b6040916020825261372a8151809281602086015260208686019101613679565b601f01601f1916010190565b9060009180835282602052604083209160018060a01b03169182845260205260ff60408420541661376657505050565b80835282602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b818102929181159184041417156137bd57565b634e487b7160e01b600052601160045260246000fd5b919082018092116137bd57565b9081518110156137f1570160200190565b634e487b7160e01b600052603260045260246000fd5b60405190606082018281106001600160401b038211176136b857604052602a82526020820160403682378251156137f1576030905381516001908110156137f157607860218401536029905b80821161386357505061100f5790565b9091600f811660108110156138bc576f181899199a1a9b1b9c1cb0b131b232b360811b901a61389284866137e0565b5360041c9180156138a7576000190190613853565b60246000634e487b7160e01b81526011600452fd5b60246000634e487b7160e01b81526032600452fd5b60ff600154166138dd57565b60405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606490fd5b61ffff8091169081146137bd5760010190565b60001981146137bd5760010190565b91908110156137f15760051b0190565b356001600160a01b03811681036131ce5790565b3561ffff811681036131ce5790565b919082039182116137bd57565b60028054146139865760028055565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b60018060a01b031690604051604081016001600160401b0390828110828211176136b8576040526020938483527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564858401526000808587829751910182855af1903d15613afb573d9283116124e75790613a6593929160405192613a5888601f19601f84011601856136e9565b83523d868885013e613b06565b805191821591848315613ad7575b505050905015613a805750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b919381809450010312610ac45782015190811515820361027a575080388084613a73565b90613a659392506060915b91929015613b685750815115613b1a575090565b3b15613b235790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015613b7b5750805190602001fd5b60405162461bcd60e51b815290819061100b906004830161370a565b60405163a9059cbb60e01b60208201526001600160a01b03929092166024830152604480830193909352918152613bd891613bd36064836136e9565b6139cb565b565b6001600160401b0381116136b85760051b60200190565b80518210156137f15760209160051b010190565b9160018060a01b03908160009416845260096020526040842061ffff809416855260205260408420908452602052604083209160405191613c458361369c565b83549060ff8216159283159283865260081c16602085015260018501546040850152600285015460608501526003850154166080840152600484015460a08401526101206005850154928360c08601526006860154948560e082015260ff60086007890154986101008401998a520154161515928391015291613cfd575b50613cf75760045415613ce557505051908115613ce05750421190565b905090565b909150613cf292506137d3565b421190565b50505090565b905038613cc3565b7fb39221ace053465ec3453ce2b36430bd138b997ecea25c1043da0c366812b8285461ffff908116600090815260086020908152604080832081519397969594909391613d518361369c565b84549760ff808a1615998a15865260081c161515858501526001860154828501526002860154606085015260038601546080850152600486015460a0850152600586015460c0850152600686015460e085015260078601549760ff6008610100988988019b8c52015416996101208096019a15158b52613ebb576001600160a01b039788168b5260098652828b209084168b528552818a20908a528452808920815190969091613e008361369c565b87549560ff8716159485159788865260081c1690840152600188015490830152600287015460608301526003870154166080820152600486015460a082015260ff60086005880154978860c08501526006810154978860e08601526007820154908501520154161515928391015291613eb3575b50613eac57613e82916137d3565b915115613ea557515b81811115613ea057613e9d925061396a565b90565b505090565b5042613e8b565b5050505090565b905038613e74565b5050505050505050505090565b9061ffff1660009080825260086020526040822090604051613ee98161369c565b60ff83548181161515835260081c1615156020820152600183015460408201526002830154606082015260038301546080820152600483015460a082015261012060ff60086005860154958660c0860152600681015460e086015260078101546101008601520154161515910152819360018060a01b03168352600d6020526040832090815460ff81169081613fb0575b50613f86575050505090565b8352600201602052604090912054915080821115613fa957505b38808080613eac565b9050613fa0565b60ff915060081c1638613f7a565b60405190613fcb8261369c565b816101206000918281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e082015282610100820152015256fea2646970667358221220422ae452b98a929f91fccaf47ab91fc93e11190d4ea3aa096f8f59a57deaeaff64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31310000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b31310000000000000000000000004307adb2b4fc069d46a3f3c1317cbeb7cae53262
-----Decoded View---------------
Arg [0] : DEFI_ (address): 0x6B0FaCA7bA905a86F221CEb5CA404f605e5b3131
Arg [1] : STAKE_ (address): 0x6B0FaCA7bA905a86F221CEb5CA404f605e5b3131
Arg [2] : VESTING_ (address): 0x4307adb2b4FC069D46a3F3C1317CbeB7cAE53262
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b3131
Arg [1] : 0000000000000000000000006b0faca7ba905a86f221ceb5ca404f605e5b3131
Arg [2] : 0000000000000000000000004307adb2b4fc069d46a3f3c1317cbeb7cae53262
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.003536 | 11,802,150.0023 | $41,735.12 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.