编译器
0.8.19+commit.7dd6d404
文件 1 的 22:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 22:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 3 的 22:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 22:DeFiMerkleVesting.sol
pragma solidity 0.8.19;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/access/AccessControl.sol';
import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import '@openzeppelin/contracts/utils/cryptography/MerkleProof.sol';
import '@openzeppelin/contracts/security/Pausable.sol';
import './interfaces/IDeFiMerkleVesting.sol';
import './interfaces/IERC20Mint.sol';
contract DeFiMerkleVesting is Pausable, AccessControl, ReentrancyGuard, IDeFiMerkleVesting {
using SafeERC20 for IERC20Mint;
bytes32 public constant PAUSER_ROLE = keccak256('PAUSER_ROLE');
bytes32 public constant OPERATOR_ROLE = keccak256('OPERATOR_ROLE');
bytes32 public constant EXTERNAL_SOURCE_ROLE = keccak256('EXTERNAL_SOURCE_ROLE');
uint256 public constant ALLOWED_VESTING_UPDATE_THRESHOLD = 365 days;
uint256 public constant YEAR = 365 days;
uint256 public constant PRECISION = 10 ** 18;
IERC20Mint private _token;
Pool[] private _pools;
mapping(uint256 => mapping(address => Beneficiary)) private _beneficiaries;
constructor(address token_) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
_setupRole(OPERATOR_ROLE, _msgSender());
if (token_ == address(0)) revert TokenNullAddressErr();
_token = IERC20Mint(token_);
}
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 setupPool(uint256 startTime_, uint256 endTime_, bytes32 merkleRoot_, bool lockable_, uint256 baseRate_, uint256 boostRate_)
external
onlyRole(OPERATOR_ROLE)
returns (uint256 pid)
{
if (block.timestamp > startTime_) revert PoolInvalidStartErr();
if (startTime_ >= endTime_) revert PoolInvalidEndErr();
pid = (uint256)(_pools.length);
_pools.push(
Pool({
defined: true,
pid: pid,
startTime: startTime_,
endTime: endTime_,
initialStartTime: startTime_,
initialEndTime: endTime_,
merkleRoot: merkleRoot_,
lockable: lockable_,
baseRate: baseRate_,
boostRate: boostRate_
})
);
emit PoolAdded(pid, startTime_, endTime_, merkleRoot_, lockable_, baseRate_, boostRate_);
}
function updatePoolTiming(uint256 pid_, uint256 startTime_, uint256 endTime_)
external
onlyRole(OPERATOR_ROLE)
{
Pool memory pool = _pools[pid_];
if (!pool.defined) revert PoolUndefinedErr(pid_);
if (pool.startTime < block.timestamp) revert PoolStartedErr(pid_);
if (startTime_ < block.timestamp) revert PoolInvalidStartErr();
if (startTime_ >= endTime_) revert PoolInvalidEndErr();
if (pool.initialStartTime + ALLOWED_VESTING_UPDATE_THRESHOLD < startTime_) revert PoolInvalidStartToLargeErr();
if (pool.initialStartTime - ALLOWED_VESTING_UPDATE_THRESHOLD > startTime_) revert PoolInvalidStartToSmallErr();
if (pool.initialEndTime + ALLOWED_VESTING_UPDATE_THRESHOLD < endTime_) revert PoolInvalidEndToLargeErr();
if (pool.initialEndTime - ALLOWED_VESTING_UPDATE_THRESHOLD > endTime_) revert PoolInvalidEndToSmallErr();
_pools[pid_].startTime = startTime_;
_pools[pid_].endTime = endTime_;
emit PoolTimingUpdated(pid_, startTime_, endTime_);
}
function updatePoolRoot(uint256 pid_, bytes32 merkleRoot_)
external
onlyRole(OPERATOR_ROLE)
{
if (!_pools[pid_].defined) revert PoolUndefinedErr(pid_);
_pools[pid_].merkleRoot = merkleRoot_;
emit PoolRootUpdated(pid_, merkleRoot_);
}
function updatePoolRate(uint256 pid_, bool lockable_, uint256 baseRate_, uint256 boostRate_)
external
onlyRole(OPERATOR_ROLE)
{
if (!_pools[pid_].defined) revert PoolUndefinedErr(pid_);
_pools[pid_].lockable = lockable_;
_pools[pid_].baseRate = baseRate_;
_pools[pid_].boostRate = boostRate_;
emit PoolRateUpdated(pid_, lockable_, baseRate_, boostRate_);
}
function enableBeneficiary(uint256[] calldata pids_, address beneficiary_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
for (uint256 i = 0; i < pids_.length; i++) {
uint256 pid_ = pids_[i];
if (!_pools[pid_].defined) revert PoolUndefinedErr(pid_);
_beneficiaries[pid_][beneficiary_].disabled = false;
emit BeneficiaryEnabled(pid_, beneficiary_);
}
}
function disableBeneficiary(uint256[] calldata pids_, address beneficiary_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
for (uint256 i = 0; i < pids_.length; i++) {
uint256 pid_ = pids_[i];
if (!_pools[pid_].defined) revert PoolUndefinedErr(pid_);
_beneficiaries[pid_][beneficiary_].disabled = true;
emit BeneficiaryDisabled(pid_, beneficiary_);
}
}
function recoverBeneficiary(uint256 pid_, address beneficiary_, bool disabled_, uint256 withdrawn_, bool locked_, uint256 lockedAt_, uint256 rate_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (!_pools[pid_].defined) revert PoolUndefinedErr(pid_);
_beneficiaries[pid_][beneficiary_].disabled = disabled_;
_beneficiaries[pid_][beneficiary_].withdrawn = withdrawn_;
_beneficiaries[pid_][beneficiary_].rate = rate_;
_beneficiaries[pid_][beneficiary_].locked = locked_;
_beneficiaries[pid_][beneficiary_].lockedAt = lockedAt_;
emit BeneficiaryRecovered(pid_, beneficiary_);
}
function claim(uint256 pid_, bytes calldata message_)
external
nonReentrant()
whenNotPaused()
returns (uint256 amount)
{
address sender = _msgSender();
Pool memory pool = _pools[pid_];
if (!pool.defined) revert PoolUndefinedErr(pid_);
Beneficiary memory beneficiary = _beneficiaries[pid_][sender];
if (beneficiary.disabled) revert BeneficiaryDisabledErr(sender);
if (pool.endTime > block.timestamp && beneficiary.locked) revert BeneficiaryLockedErr(sender);
(bool valid, ) = decodeMessage(pid_, sender, message_);
if (!valid) revert BeneficiaryProofErr(sender);
amount = getReleasableAmount(pid_, sender, message_);
if (amount == 0) revert BeneficiaryNoFundsErr(sender);
if (beneficiary.locked) {
uint256 duration = pool.endTime - beneficiary.lockedAt;
uint256 vested = getReleasableAmountAt(pid_, sender, message_, beneficiary.lockedAt);
uint256 vestedReward = vested * beneficiary.rate * duration / PRECISION / YEAR;
uint256 vestingReward = (amount - vested) * beneficiary.rate * duration / PRECISION / YEAR / 2;
amount += vestedReward + vestingReward;
}
_beneficiaries[pid_][sender].withdrawn = _beneficiaries[pid_][sender].withdrawn + amount;
if (_token.balanceOf(address(this)) >= amount) {
_token.safeTransfer(sender, amount);
} else {
_token.mint(sender, amount);
}
emit Claimed(pid_, sender, sender, amount);
}
function claimFrom(uint256 pid_, address from_, address to_, bytes calldata message_)
external
nonReentrant()
whenNotPaused()
whenValidSource(_msgSender())
returns (uint256 amount)
{
Pool memory pool = _pools[pid_];
if (!pool.defined) revert PoolUndefinedErr(pid_);
Beneficiary memory beneficiary = _beneficiaries[pid_][from_];
if (beneficiary.disabled) revert BeneficiaryDisabledErr(from_);
if (pool.endTime > block.timestamp && beneficiary.locked) revert BeneficiaryLockedErr(from_);
(bool valid, ) = decodeMessage(pid_, from_, message_);
if (!valid) revert BeneficiaryProofErr(from_);
amount = getReleasableAmount(pid_, from_, message_);
if (amount == 0) revert BeneficiaryNoFundsErr(from_);
if (beneficiary.locked) {
uint256 duration = pool.endTime - beneficiary.lockedAt;
uint256 vested = getReleasableAmountAt(pid_, from_, message_, beneficiary.lockedAt);
uint256 vestedReward = vested * beneficiary.rate * duration / PRECISION / YEAR;
uint256 vestingReward = (amount - vested) * beneficiary.rate * duration / PRECISION / YEAR / 2;
amount += vestedReward + vestingReward;
}
_beneficiaries[pid_][from_].withdrawn = _beneficiaries[pid_][from_].withdrawn + amount;
if (_token.balanceOf(address(this)) >= amount) {
_token.safeTransfer(to_, amount);
} else {
_token.mint(to_, amount);
}
emit Claimed(pid_, from_, to_, amount);
}
function lock(uint256 pid_, bytes calldata message_)
external
nonReentrant()
whenNotPaused()
{
address sender = _msgSender();
Pool memory pool = _pools[pid_];
if (!pool.defined) revert PoolUndefinedErr(pid_);
if (!pool.lockable) revert PoolUnlockableErr(pid_);
if (pool.startTime > block.timestamp) revert PoolStartedErr(pid_);
if (pool.endTime < block.timestamp) revert PoolEndedErr(pid_);
Beneficiary memory beneficiary = _beneficiaries[pid_][sender];
if (beneficiary.disabled) revert BeneficiaryDisabledErr(sender);
if (beneficiary.locked) revert BeneficiaryLockedErr(sender);
(bool valid, ) = decodeMessage(pid_, sender, message_);
if (!valid) revert BeneficiaryProofErr(sender);
uint256 rate = pool.baseRate + pool.boostRate;
_beneficiaries[pid_][sender].rate = rate;
_beneficiaries[pid_][sender].locked = true;
_beneficiaries[pid_][sender].lockedAt = block.timestamp;
emit Locked(pid_, sender, rate);
}
function unlock(uint256 pid_, address[] calldata beneficiaries_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (!_pools[pid_].defined) revert PoolUndefinedErr(pid_);
uint256 length = beneficiaries_.length;
for (uint256 i = 0; i < length; i++) {
address beneficiary = beneficiaries_[i];
_beneficiaries[pid_][beneficiary].rate = 0;
_beneficiaries[pid_][beneficiary].locked = false;
_beneficiaries[pid_][beneficiary].lockedAt = 0;
emit Unlocked(pid_, beneficiary);
}
}
function recoverERC20(address token_, uint256 amount_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
IERC20Mint(token_).safeTransfer(_msgSender(), amount_);
emit ERC20Recovered(token_, amount_);
}
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
)
{
currentTime = block.timestamp;
(bool valid, uint256 amount) = decodeMessage(pid_, beneficiary_, message_);
if (valid) {
Beneficiary memory beneficiary = _beneficiaries[pid_][beneficiary_];
disabled = beneficiary.disabled;
lockedAmount = amount;
withdrawn = beneficiary.withdrawn;
releasableAmount = getReleasableAmount(pid_, beneficiary_, message_);
rate = beneficiary.rate;
locked = beneficiary.locked;
lockedAt = beneficiary.lockedAt;
}
}
function getPoolsCount()
external
view
returns (uint256 _poolsCount)
{
return _pools.length;
}
function getPool(uint256 pid_)
external
view
returns (
uint256 startTime,
uint256 endTime,
bytes32 merkleRoot,
bool lockable,
uint256 baseRate,
uint256 boostRate
)
{
if (pid_ < _pools.length) {
startTime = _pools[pid_].startTime;
endTime = _pools[pid_].endTime;
merkleRoot = _pools[pid_].merkleRoot;
lockable = _pools[pid_].lockable;
baseRate = _pools[pid_].baseRate;
boostRate = _pools[pid_].boostRate;
}
}
function getReleasableAmount(uint256 pid_, address beneficiary_, bytes calldata message_)
public
view
returns (uint256)
{
return getReleasableAmountAt(pid_, beneficiary_, message_, block.timestamp);
}
function getReleasableAmountAt(uint256 pid_, address beneficiary_, bytes calldata message_, uint256 timestamp_)
private
view
returns (uint256)
{
uint256 withdrawn = _beneficiaries[pid_][beneficiary_].withdrawn;
uint256 vestedAmount = getVestedAmount(pid_, beneficiary_, message_, timestamp_);
if (withdrawn >= vestedAmount) {
return 0;
}
return vestedAmount - withdrawn;
}
function getVestedAmount(uint256 pid_, address beneficiary_, bytes calldata message_, uint256 time_)
public
view
returns (uint256)
{
if (pid_ >= _pools.length) { return 0; }
if (time_ < _pools[pid_].startTime) { return 0; }
(bool valid, uint256 lockedAmount) = decodeMessage(pid_, beneficiary_, message_);
if (!valid || lockedAmount == 0) { return 0; }
uint256 vestingDuration = _pools[pid_].endTime - _pools[pid_].startTime;
uint256 timeDuration = time_ - _pools[pid_].startTime;
uint256 amount = lockedAmount * timeDuration / vestingDuration;
if (amount > lockedAmount) {
amount = lockedAmount;
}
return amount;
}
function decodeMessage(uint256 pid_, address beneficiary_, bytes calldata message_)
private
view
returns (bool, uint256)
{
(uint256 amount, bytes32[] memory proof) = abi.decode(message_, (uint256, bytes32[]));
bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(beneficiary_, amount))));
bool valid = MerkleProof.verify(proof, _pools[pid_].merkleRoot, leaf);
return (valid, amount);
}
}
文件 5 的 22:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 22:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 7 的 22:IDeFiMerkleVesting.sol
pragma solidity 0.8.19;
import './DeFiMerkleVesting/IDeFiMerkleVestingActions.sol';
import './DeFiMerkleVesting/IDeFiMerkleVestingErrors.sol';
import './DeFiMerkleVesting/IDeFiMerkleVestingEvents.sol';
import './DeFiMerkleVesting/IDeFiMerkleVestingState.sol';
interface IDeFiMerkleVesting is IDeFiMerkleVestingActions, IDeFiMerkleVestingErrors, IDeFiMerkleVestingEvents, IDeFiMerkleVestingState {
}
文件 8 的 22:IDeFiMerkleVestingActions.sol
pragma solidity 0.8.19;
interface IDeFiMerkleVestingActions {
function setupPool(
uint256 startTime_,
uint256 endTime_,
bytes32 merkleRoot_,
bool lockable_,
uint256 baseRate_,
uint256 boostRate_
) external returns (uint256 pid);
function updatePoolTiming(uint256 pid_, uint256 startTime_, uint256 endTime_) external;
function updatePoolRoot(uint256 pid_, bytes32 merkleRoot_) external;
function updatePoolRate(uint256 pid_, bool lockable_, uint256 baseRate_, uint256 boostRate_) external;
function enableBeneficiary(uint256[] calldata pids_, address beneficiary_) external;
function disableBeneficiary(uint256[] calldata pids_, address beneficiary_) external;
function recoverBeneficiary(uint256 pid_, address beneficiary_, bool disabled_, uint256 withdrawn_, bool locked_, uint256 lockedAt_, uint256 rate_) external;
function claim(uint256 pid_, bytes calldata message_) external returns (uint256 amount);
function claimFrom(uint256 pid_, address from_, address to_, bytes calldata message_) external returns (uint256 amount);
function lock(uint256 pid_, bytes calldata message_) external;
function unlock(uint256 pid_, address[] calldata beneficiaries_) external;
function recoverERC20(address token_, uint256 amount_) external;
function getReleasableAmount(uint256 pid_, address beneficiary_, bytes calldata message_) external view returns (uint256);
function getVestedAmount(uint256 pid_, address beneficiary_, bytes calldata message_, uint256 time_) external view returns (uint256);
function getBeneficiary(uint256 pid_, address beneficiary_, bytes calldata message_)
external
view
returns (
bool disabled,
uint256 lockedAmount,
uint256 withdrawn,
uint256 releasableAmount,
uint256 currentTime,
bool locked,
uint256 lockedAt,
uint256 rate
);
function getPoolsCount() external view returns (uint256 poolsCount);
function getPool(uint256 pid_)
external
view
returns (
uint256 startTime,
uint256 endTime,
bytes32 merkleRoot,
bool lockable,
uint256 baseRate,
uint256 boostRate
);
}
文件 9 的 22:IDeFiMerkleVestingErrors.sol
pragma solidity 0.8.19;
interface IDeFiMerkleVestingErrors {
error ArrayParamsInvalidLengthErr();
error TokenNullAddressErr();
error TokenInvalidErr();
error BeneficiaryDisabledErr(address beneficiary_);
error BeneficiaryNoFundsErr(address beneficiary_);
error BeneficiaryLockedErr(address beneficiary_);
error BeneficiaryProofErr(address beneficiary_);
error PoolUndefinedErr(uint256 pid_);
error PoolStartedErr(uint256 pid_);
error PoolInvalidStartErr();
error PoolInvalidStartToLargeErr();
error PoolInvalidStartToSmallErr();
error PoolInvalidEndErr();
error PoolInvalidEndToLargeErr();
error PoolInvalidEndToSmallErr();
error PoolEndedErr(uint256 pid_);
error PoolUnlockableErr(uint256 pid_);
error ExternalSourceAuthErr();
}
文件 10 的 22:IDeFiMerkleVestingEvents.sol
pragma solidity 0.8.19;
interface IDeFiMerkleVestingEvents {
event BeneficiaryRecovered(uint256 indexed pid, address indexed beneficiary);
event BeneficiaryEnabled(uint256 indexed pid, address indexed beneficiary);
event BeneficiaryDisabled(uint256 indexed pid, address indexed beneficiary);
event Claimed(uint256 indexed pid, address indexed beneficiary, address indexed to, uint256 value);
event Locked(uint256 indexed pid, address indexed beneficiary, uint256 rate);
event Unlocked(uint256 indexed pid, address indexed beneficiary);
event PoolAdded(uint256 indexed pid, uint256 startTime, uint256 endTime, bytes32 merkleRoot, bool lockable, uint256 baseRate, uint256 boostRate);
event PoolTimingUpdated(uint256 indexed pid, uint256 startTime, uint256 endTime);
event PoolRootUpdated(uint256 indexed pid, bytes32 merkleRoot);
event PoolRateUpdated(uint256 indexed pid, bool lockable, uint256 baseRate, uint256 boostRate);
event ERC20Recovered(address token, uint256 amount);
}
文件 11 的 22:IDeFiMerkleVestingState.sol
pragma solidity 0.8.19;
interface IDeFiMerkleVestingState {
struct Beneficiary {
bool disabled;
uint256 withdrawn;
bool locked;
uint256 lockedAt;
uint256 rate;
}
struct Pool {
bool defined;
uint256 pid;
uint256 startTime;
uint256 endTime;
uint256 initialStartTime;
uint256 initialEndTime;
bytes32 merkleRoot;
bool lockable;
uint256 baseRate;
uint256 boostRate;
}
}
文件 12 的 22:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 13 的 22:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 14 的 22:IERC20Mint.sol
pragma solidity 0.8.19;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
interface IERC20Mint is IERC20 {
function mint(address to_, uint256 amount_) external;
}
文件 15 的 22:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 16 的 22:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 17 的 22:MerkleProof.sol
pragma solidity ^0.8.0;
library MerkleProof {
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
文件 18 的 22:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 19 的 22:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
文件 20 的 22:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 21 的 22:SignedMath.sol
pragma solidity ^0.8.0;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 22 的 22:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
{
"compilationTarget": {
"contracts/vesting/DeFiMerkleVesting.sol": "DeFiMerkleVesting"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"viaIR": true
}
[{"inputs":[{"internalType":"address","name":"token_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayParamsInvalidLengthErr","type":"error"},{"inputs":[{"internalType":"address","name":"beneficiary_","type":"address"}],"name":"BeneficiaryDisabledErr","type":"error"},{"inputs":[{"internalType":"address","name":"beneficiary_","type":"address"}],"name":"BeneficiaryLockedErr","type":"error"},{"inputs":[{"internalType":"address","name":"beneficiary_","type":"address"}],"name":"BeneficiaryNoFundsErr","type":"error"},{"inputs":[{"internalType":"address","name":"beneficiary_","type":"address"}],"name":"BeneficiaryProofErr","type":"error"},{"inputs":[],"name":"ExternalSourceAuthErr","type":"error"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"}],"name":"PoolEndedErr","type":"error"},{"inputs":[],"name":"PoolInvalidEndErr","type":"error"},{"inputs":[],"name":"PoolInvalidEndToLargeErr","type":"error"},{"inputs":[],"name":"PoolInvalidEndToSmallErr","type":"error"},{"inputs":[],"name":"PoolInvalidStartErr","type":"error"},{"inputs":[],"name":"PoolInvalidStartToLargeErr","type":"error"},{"inputs":[],"name":"PoolInvalidStartToSmallErr","type":"error"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"}],"name":"PoolStartedErr","type":"error"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"}],"name":"PoolUndefinedErr","type":"error"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"}],"name":"PoolUnlockableErr","type":"error"},{"inputs":[],"name":"TokenInvalidErr","type":"error"},{"inputs":[],"name":"TokenNullAddressErr","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"}],"name":"BeneficiaryDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"}],"name":"BeneficiaryEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"}],"name":"BeneficiaryRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Claimed","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":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"lockable","type":"bool"},{"indexed":false,"internalType":"uint256","name":"baseRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostRate","type":"uint256"}],"name":"PoolAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"bool","name":"lockable","type":"bool"},{"indexed":false,"internalType":"uint256","name":"baseRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostRate","type":"uint256"}],"name":"PoolRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"PoolRootUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"PoolTimingUpdated","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":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"}],"name":"Unlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ALLOWED_VESTING_UPDATE_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"},{"internalType":"bytes","name":"message_","type":"bytes"}],"name":"claim","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"},{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"bytes","name":"message_","type":"bytes"}],"name":"claimFrom","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pids_","type":"uint256[]"},{"internalType":"address","name":"beneficiary_","type":"address"}],"name":"disableBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pids_","type":"uint256[]"},{"internalType":"address","name":"beneficiary_","type":"address"}],"name":"enableBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"},{"internalType":"address","name":"beneficiary_","type":"address"},{"internalType":"bytes","name":"message_","type":"bytes"}],"name":"getBeneficiary","outputs":[{"internalType":"bool","name":"disabled","type":"bool"},{"internalType":"uint256","name":"lockedAmount","type":"uint256"},{"internalType":"uint256","name":"withdrawn","type":"uint256"},{"internalType":"uint256","name":"releasableAmount","type":"uint256"},{"internalType":"uint256","name":"currentTime","type":"uint256"},{"internalType":"bool","name":"locked","type":"bool"},{"internalType":"uint256","name":"lockedAt","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"}],"name":"getPool","outputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"bool","name":"lockable","type":"bool"},{"internalType":"uint256","name":"baseRate","type":"uint256"},{"internalType":"uint256","name":"boostRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPoolsCount","outputs":[{"internalType":"uint256","name":"_poolsCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"},{"internalType":"address","name":"beneficiary_","type":"address"},{"internalType":"bytes","name":"message_","type":"bytes"}],"name":"getReleasableAmount","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":"uint256","name":"pid_","type":"uint256"},{"internalType":"address","name":"beneficiary_","type":"address"},{"internalType":"bytes","name":"message_","type":"bytes"},{"internalType":"uint256","name":"time_","type":"uint256"}],"name":"getVestedAmount","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":"uint256","name":"pid_","type":"uint256"},{"internalType":"bytes","name":"message_","type":"bytes"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"pid_","type":"uint256"},{"internalType":"address","name":"beneficiary_","type":"address"},{"internalType":"bool","name":"disabled_","type":"bool"},{"internalType":"uint256","name":"withdrawn_","type":"uint256"},{"internalType":"bool","name":"locked_","type":"bool"},{"internalType":"uint256","name":"lockedAt_","type":"uint256"},{"internalType":"uint256","name":"rate_","type":"uint256"}],"name":"recoverBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","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":"startTime_","type":"uint256"},{"internalType":"uint256","name":"endTime_","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"},{"internalType":"bool","name":"lockable_","type":"bool"},{"internalType":"uint256","name":"baseRate_","type":"uint256"},{"internalType":"uint256","name":"boostRate_","type":"uint256"}],"name":"setupPool","outputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"},{"internalType":"address[]","name":"beneficiaries_","type":"address[]"}],"name":"unlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"},{"internalType":"bool","name":"lockable_","type":"bool"},{"internalType":"uint256","name":"baseRate_","type":"uint256"},{"internalType":"uint256","name":"boostRate_","type":"uint256"}],"name":"updatePoolRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"name":"updatePoolRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid_","type":"uint256"},{"internalType":"uint256","name":"startTime_","type":"uint256"},{"internalType":"uint256","name":"endTime_","type":"uint256"}],"name":"updatePoolTiming","outputs":[],"stateMutability":"nonpayable","type":"function"}]