编译器
0.8.21+commit.d9974bed
文件 1 的 10:Address.sol
pragma solidity ^0.8.20;
library Address {
error AddressInsufficientBalance(address account);
error AddressEmptyCode(address target);
error FailedInnerCall();
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
function _revert(bytes memory returndata) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}
文件 2 的 10:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 3 的 10:IAccountInfo.sol
pragma solidity >=0.8.19;
interface IAccountInfo {
function getAccountCount() external view returns (uint32);
function getAccountByIndex(uint32 index) external view returns (address);
}
文件 4 的 10:IContractInfo.sol
pragma solidity >=0.8.19;
interface IContractInfo {
function getContractName() external view returns (string memory);
function getContractVersion() external view returns (string memory);
}
文件 5 的 10:IERC20.sol
pragma solidity ^0.8.20;
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 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 6 的 10:IERC20Permit.sol
pragma solidity ^0.8.20;
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);
}
文件 7 的 10:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 8 的 10:ReentrancyGuard.sol
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
_status = ENTERED;
}
function _nonReentrantAfter() private {
_status = NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
文件 9 的 10:SQRVesting.sol
pragma solidity >=0.8.20;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IContractInfo} from "./IContractInfo.sol";
import {IAccountInfo} from "./IAccountInfo.sol";
contract SQRVesting is Ownable, ReentrancyGuard, IContractInfo, IAccountInfo {
using SafeERC20 for IERC20;
string public constant VERSION = "2.6";
IERC20 public erc20Token;
uint32 public startDate;
uint32 public cliffPeriod;
uint256 public firstUnlockPercent;
uint32 public unlockPeriod;
uint256 public unlockPeriodPercent;
bool public availableRefund;
uint32 public refundStartDate;
uint32 public refundCloseDate;
mapping(address account => Allocation allocation) public allocations;
address[] private _accountAddresses;
uint256 public constant PERCENT_DIVIDER = 1e18 * 100;
constructor(ContractParams memory contractParams) Ownable(contractParams.newOwner) {
if (contractParams.erc20Token == address(0)) {
revert ERC20TokenNotZeroAddress();
}
if (contractParams.firstUnlockPercent > PERCENT_DIVIDER) {
revert FirstUnlockPercentMustBeLessThanPercentDivider();
}
if (contractParams.startDate < uint32(block.timestamp)) {
revert StartDateMustBeGreaterThanCurrentTime();
}
if (contractParams.unlockPeriod == 0) {
revert UnlockPeriodNotZero();
}
if (contractParams.unlockPeriodPercent == 0) {
revert UnlockPeriodPercentNotZero();
}
if (contractParams.availableRefund) {
if (contractParams.refundStartDate < uint32(block.timestamp)) {
revert RefundStartDateMustBeGreaterThanCurrentTime();
}
if (contractParams.refundStartDate > contractParams.refundCloseDate) {
revert RefundCloseDateMustBeGreaterThanRefundStartDate();
}
}
erc20Token = IERC20(contractParams.erc20Token);
startDate = contractParams.startDate;
cliffPeriod = contractParams.cliffPeriod;
firstUnlockPercent = contractParams.firstUnlockPercent;
unlockPeriod = contractParams.unlockPeriod;
unlockPeriodPercent = contractParams.unlockPeriodPercent;
availableRefund = contractParams.availableRefund;
refundStartDate = contractParams.refundStartDate;
refundCloseDate = contractParams.refundCloseDate;
}
uint256 public totalReserved;
uint256 public totalAllocated;
uint256 public totalClaimed;
uint32 public allocationCount;
uint32 public refundCount;
modifier accountExist() {
if (!allocations[_msgSender()].exist) {
revert AccountNotExist();
}
_;
}
modifier alreadyRefunded() {
if (allocations[_msgSender()].refunded) {
revert AlreadyRefunded();
}
_;
}
struct ContractParams {
address newOwner;
address erc20Token;
uint32 startDate;
uint32 cliffPeriod;
uint256 firstUnlockPercent;
uint32 unlockPeriod;
uint256 unlockPeriodPercent;
bool availableRefund;
uint32 refundStartDate;
uint32 refundCloseDate;
}
struct Allocation {
uint256 amount;
uint256 claimed;
uint32 claimCount;
uint32 claimedAt;
bool exist;
bool refunded;
}
struct ClaimInfo {
uint256 amount;
bool canClaim;
uint256 claimed;
uint32 claimCount;
uint32 claimedAt;
bool exist;
uint256 available;
uint256 remain;
uint256 nextAvailable;
uint32 nextClaimAt;
bool canRefund;
bool refunded;
}
event Claim(address indexed account, uint256 amount);
event Refund(address indexed account);
event SetAllocation(address indexed account, uint256 amount);
event WithdrawExcessAmount(address indexed to, uint256 amount);
event ForceWithdraw(address indexed token, address indexed to, uint256 amount);
event SetAvailableRefund(address indexed account, bool value);
event SetRefundStartDate(address indexed account, uint32 value);
event SetRefundCloseDate(address indexed account, uint32 value);
error ERC20TokenNotZeroAddress();
error FirstUnlockPercentMustBeLessThanPercentDivider();
error UnlockPeriodNotZero();
error UnlockPeriodPercentNotZero();
error StartDateMustBeGreaterThanCurrentTime();
error ArrayLengthsNotEqual();
error AccountNotZeroAddress();
error ContractMustHaveSufficientFunds();
error AccountNotExist();
error NothingToClaim();
error CantChangeOngoingVesting();
error AlreadyRefunded();
error AlreadyClaimed();
error RefundStartDateMustBeGreaterThanCurrentTime();
error RefundStartDateMustBeLessThanRefundCloseDate();
error RefundCloseDateMustBeGreaterThanCurrentTime();
error RefundCloseDateMustBeGreaterThanRefundStartDate();
error RefundUnavailable();
error TooEarlyToRefund();
error TooLateToRefund();
function getContractName() external pure returns (string memory) {
return "Vesting";
}
function getContractVersion() external pure returns (string memory) {
return VERSION;
}
function getAccountCount() public view returns (uint32) {
return (uint32)(_accountAddresses.length);
}
function getAccountByIndex(uint32 index) public view returns (address) {
return _accountAddresses[index];
}
function getBalance() public view returns (uint256) {
return erc20Token.balanceOf(address(this));
}
function canClaim(address account) public view returns (bool) {
return (calculateClaimAmount(account, 0) > 0);
}
function calculatePassedPeriod() public view returns (uint32) {
uint32 timestamp = (uint32)(block.timestamp);
if (timestamp > startDate + cliffPeriod) {
return (timestamp - startDate - cliffPeriod) / unlockPeriod;
}
return 0;
}
function calculateMaxPeriod() public view returns (uint256) {
return PERCENT_DIVIDER / unlockPeriodPercent;
}
function calculateFinishDate() public view returns (uint32) {
return startDate + cliffPeriod + (uint32)(calculateMaxPeriod()) * unlockPeriod;
}
function calculateClaimAmount(
address account,
uint32 periodOffset
) public view returns (uint256) {
if (block.timestamp < startDate && periodOffset == 0) {
return 0;
}
Allocation memory allocation = allocations[account];
uint256 firstUnlockAmount = (allocation.amount * firstUnlockPercent) / PERCENT_DIVIDER;
uint256 claimed = allocation.claimed;
uint256 amount = allocation.amount;
if (block.timestamp < startDate + cliffPeriod && claimed == 0) {
return firstUnlockAmount;
} else {
uint256 claimAmount = ((calculatePassedPeriod() + periodOffset) *
(amount * unlockPeriodPercent)) /
PERCENT_DIVIDER +
firstUnlockAmount -
claimed;
if (claimAmount > amount - claimed) {
return amount - claimed;
}
return claimAmount;
}
}
function isAllocationFinished(address account) public view returns (bool) {
return (allocations[account].claimed == allocations[account].amount);
}
function isAfterRefundCloseDate() public view returns (bool) {
return block.timestamp > refundCloseDate;
}
function calculateClaimAt(address account, uint32 periodOffset) public view returns (uint32) {
if (isAllocationFinished(account)) {
return 0;
}
if (allocations[account].claimed == 0) {
return startDate;
} else {
if (block.timestamp - startDate < cliffPeriod) {
return startDate + cliffPeriod + unlockPeriod;
}
uint32 passedPeriod = calculatePassedPeriod();
return (uint32)(startDate + cliffPeriod + (passedPeriod + periodOffset) * unlockPeriod);
}
}
function calculateRemainAmount(address account) public view returns (uint256) {
return allocations[account].amount - allocations[account].claimed;
}
function canRefund(address account) public view returns (bool) {
return
availableRefund &&
refundStartDate <= (uint32)(block.timestamp) &&
(uint32)(block.timestamp) <= refundCloseDate &&
allocations[account].claimed == 0 &&
!allocations[account].refunded;
}
function fetchClaimInfo(address account) external view returns (ClaimInfo memory) {
Allocation memory allocation = allocations[account];
bool canClaim_ = canClaim(account);
uint256 available = calculateClaimAmount(account, 0);
uint256 remain = calculateRemainAmount(account);
uint256 nextAvailable = calculateClaimAmount(account, 1);
uint32 nextClaimAt = calculateClaimAt(account, 1);
bool canRefund_ = canRefund(account);
return
ClaimInfo(
allocation.amount,
canClaim_,
allocation.claimed,
allocation.claimCount,
allocation.claimedAt,
allocation.exist,
available,
remain,
nextAvailable,
nextClaimAt,
canRefund_,
allocation.refunded
);
}
function calculatedRequiredAmount() public view returns (uint256) {
uint256 contractBalance = getBalance();
if (totalReserved > contractBalance) {
return totalReserved - contractBalance;
}
return 0;
}
function calculateExcessAmount() public view returns (uint256) {
uint256 contractBalance = getBalance();
if (contractBalance > totalReserved) {
return contractBalance - totalReserved;
}
return 0;
}
function _setAllocation(address account, uint256 amount) private nonReentrant {
if (account == address(0)) {
revert AccountNotZeroAddress();
}
Allocation storage allocation = allocations[account];
if (!allocation.exist) {
allocationCount++;
_accountAddresses.push(account);
}
totalAllocated -= allocation.amount;
totalReserved -= allocation.amount;
allocation.amount = amount;
allocation.exist = true;
totalAllocated += amount;
totalReserved += amount;
emit SetAllocation(account, amount);
}
function setAllocation(address account, uint256 amount) public onlyOwner {
if (block.timestamp > startDate) {
revert CantChangeOngoingVesting();
}
_setAllocation(account, amount);
}
function setAllocations(
address[] calldata recipients,
uint256[] calldata amounts
) external onlyOwner {
if (recipients.length != amounts.length) {
revert ArrayLengthsNotEqual();
}
for (uint32 i = 0; i < recipients.length; i++) {
setAllocation(recipients[i], amounts[i]);
}
}
function claim() external nonReentrant accountExist alreadyRefunded {
address sender = _msgSender();
uint256 claimAmount = calculateClaimAmount(sender, 0);
if (claimAmount == 0) {
revert NothingToClaim();
}
if (getBalance() < claimAmount) {
revert ContractMustHaveSufficientFunds();
}
Allocation storage allocation = allocations[sender];
allocation.claimed += claimAmount;
allocation.claimCount += 1;
allocation.claimedAt = (uint32)(block.timestamp);
totalReserved -= claimAmount;
totalClaimed += claimAmount;
erc20Token.safeTransfer(sender, claimAmount);
emit Claim(sender, claimAmount);
}
function refund() external alreadyRefunded {
if (!availableRefund) {
revert RefundUnavailable();
}
if ((uint32)(block.timestamp) < refundStartDate) {
revert TooEarlyToRefund();
}
if ((uint32)(block.timestamp) > refundCloseDate) {
revert TooLateToRefund();
}
address sender = _msgSender();
Allocation storage allocation = allocations[sender];
if (allocation.claimed > 0) {
revert AlreadyClaimed();
}
allocation.refunded = true;
_setAllocation(sender, 0);
refundCount++;
emit Refund(sender);
}
function setAvailableRefund(bool value) external onlyOwner {
availableRefund = value;
emit SetAvailableRefund(_msgSender(), value);
}
function setRefundStartDate(uint32 value) external onlyOwner {
if (value < uint32(block.timestamp)) {
revert RefundStartDateMustBeGreaterThanCurrentTime();
}
if (value > refundCloseDate) {
revert RefundStartDateMustBeLessThanRefundCloseDate();
}
refundStartDate = value;
emit SetRefundStartDate(_msgSender(), value);
}
function setRefundCloseDate(uint32 value) external onlyOwner {
if (value < uint32(block.timestamp)) {
revert RefundCloseDateMustBeGreaterThanCurrentTime();
}
if (value < refundStartDate) {
revert RefundCloseDateMustBeGreaterThanRefundStartDate();
}
refundCloseDate = value;
emit SetRefundCloseDate(_msgSender(), value);
}
function withdrawExcessAmount() external onlyOwner {
uint256 amount = calculateExcessAmount();
address to = owner();
erc20Token.safeTransfer(to, amount);
emit WithdrawExcessAmount(to, amount);
}
function forceWithdraw(address token, address to, uint256 amount) external onlyOwner {
IERC20 _token = IERC20(token);
_token.safeTransfer(to, amount);
emit ForceWithdraw(token, to, amount);
}
}
文件 10 的 10:SafeERC20.sol
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
error SafeERC20FailedOperation(address token);
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
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(token).code.length > 0;
}
}
{
"compilationTarget": {
"contracts/SQRVesting.sol": "SQRVesting"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 800
},
"remappings": []
}
[{"inputs":[{"components":[{"internalType":"address","name":"newOwner","type":"address"},{"internalType":"address","name":"erc20Token","type":"address"},{"internalType":"uint32","name":"startDate","type":"uint32"},{"internalType":"uint32","name":"cliffPeriod","type":"uint32"},{"internalType":"uint256","name":"firstUnlockPercent","type":"uint256"},{"internalType":"uint32","name":"unlockPeriod","type":"uint32"},{"internalType":"uint256","name":"unlockPeriodPercent","type":"uint256"},{"internalType":"bool","name":"availableRefund","type":"bool"},{"internalType":"uint32","name":"refundStartDate","type":"uint32"},{"internalType":"uint32","name":"refundCloseDate","type":"uint32"}],"internalType":"struct SQRVesting.ContractParams","name":"contractParams","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountNotExist","type":"error"},{"inputs":[],"name":"AccountNotZeroAddress","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"AlreadyRefunded","type":"error"},{"inputs":[],"name":"ArrayLengthsNotEqual","type":"error"},{"inputs":[],"name":"CantChangeOngoingVesting","type":"error"},{"inputs":[],"name":"ContractMustHaveSufficientFunds","type":"error"},{"inputs":[],"name":"ERC20TokenNotZeroAddress","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"FirstUnlockPercentMustBeLessThanPercentDivider","type":"error"},{"inputs":[],"name":"NothingToClaim","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"RefundCloseDateMustBeGreaterThanCurrentTime","type":"error"},{"inputs":[],"name":"RefundCloseDateMustBeGreaterThanRefundStartDate","type":"error"},{"inputs":[],"name":"RefundStartDateMustBeGreaterThanCurrentTime","type":"error"},{"inputs":[],"name":"RefundStartDateMustBeLessThanRefundCloseDate","type":"error"},{"inputs":[],"name":"RefundUnavailable","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"StartDateMustBeGreaterThanCurrentTime","type":"error"},{"inputs":[],"name":"TooEarlyToRefund","type":"error"},{"inputs":[],"name":"TooLateToRefund","type":"error"},{"inputs":[],"name":"UnlockPeriodNotZero","type":"error"},{"inputs":[],"name":"UnlockPeriodPercentNotZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ForceWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SetAllocation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"SetAvailableRefund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint32","name":"value","type":"uint32"}],"name":"SetRefundCloseDate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint32","name":"value","type":"uint32"}],"name":"SetRefundStartDate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawExcessAmount","type":"event"},{"inputs":[],"name":"PERCENT_DIVIDER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allocationCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"allocations","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"claimed","type":"uint256"},{"internalType":"uint32","name":"claimCount","type":"uint32"},{"internalType":"uint32","name":"claimedAt","type":"uint32"},{"internalType":"bool","name":"exist","type":"bool"},{"internalType":"bool","name":"refunded","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"availableRefund","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"periodOffset","type":"uint32"}],"name":"calculateClaimAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"periodOffset","type":"uint32"}],"name":"calculateClaimAt","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateExcessAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateFinishDate","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateMaxPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculatePassedPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"calculateRemainAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculatedRequiredAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"canClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"canRefund","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cliffPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc20Token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"fetchClaimInfo","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"canClaim","type":"bool"},{"internalType":"uint256","name":"claimed","type":"uint256"},{"internalType":"uint32","name":"claimCount","type":"uint32"},{"internalType":"uint32","name":"claimedAt","type":"uint32"},{"internalType":"bool","name":"exist","type":"bool"},{"internalType":"uint256","name":"available","type":"uint256"},{"internalType":"uint256","name":"remain","type":"uint256"},{"internalType":"uint256","name":"nextAvailable","type":"uint256"},{"internalType":"uint32","name":"nextClaimAt","type":"uint32"},{"internalType":"bool","name":"canRefund","type":"bool"},{"internalType":"bool","name":"refunded","type":"bool"}],"internalType":"struct SQRVesting.ClaimInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"firstUnlockPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"forceWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"index","type":"uint32"}],"name":"getAccountByIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAccountCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"isAfterRefundCloseDate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isAllocationFinished","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"refundCloseDate","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refundCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refundStartDate","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setAllocation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"setAllocations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setAvailableRefund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"value","type":"uint32"}],"name":"setRefundCloseDate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"value","type":"uint32"}],"name":"setRefundStartDate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startDate","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unlockPeriodPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawExcessAmount","outputs":[],"stateMutability":"nonpayable","type":"function"}]