文件 1 的 11:Address.sol
pragma solidity ^0.7.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 11:Context.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
}
文件 3 的 11:IERC20.sol
pragma solidity ^0.7.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 4 的 11:IWETH.sol
pragma solidity ^0.7.6;
interface IWETH {
function deposit() external payable;
function withdraw(uint256 wad) external;
}
文件 5 的 11:IZap.sol
pragma solidity ^0.7.6;
interface IZap {
function zap(
address _fromToken,
uint256 _amountIn,
address _toToken,
uint256 _minOut
) external payable returns (uint256);
function zapWithRoutes(
address _fromToken,
uint256 _amountIn,
address _toToken,
uint256[] calldata _routes,
uint256 _minOut
) external payable returns (uint256);
function zapFrom(
address _fromToken,
uint256 _amountIn,
address _toToken,
uint256 _minOut
) external payable returns (uint256);
}
文件 6 的 11:Ownable.sol
pragma solidity ^0.7.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
文件 7 的 11:ReentrancyGuard.sol
pragma solidity ^0.7.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 8 的 11:SafeERC20.sol
pragma solidity ^0.7.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 9 的 11:SafeMath.sol
pragma solidity ^0.7.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
文件 10 的 11:TokenSale.sol
pragma solidity ^0.7.6;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "../interfaces/IWETH.sol";
import "../interfaces/IZap.sol";
import "./Vesting.sol";
contract TokenSale is Ownable, ReentrancyGuard {
using SafeERC20 for IERC20;
using SafeMath for uint256;
event Buy(address indexed sender, address _token, uint256 _amountIn, uint256 _refundAmount, uint256 _amountOut);
event Claim(address indexed _recipient, uint256 _vestingAmount, uint256 _claimAmount);
event UpdatePrice(uint256 _initialPrice, uint256 _upRatio, uint256 _variation);
event UpdateSaleTime(uint256 _whitelistSaleTime, uint256 _publicSaleTime, uint256 _publicSaleDuration);
event UpdateVesting(address _vesting, uint256 _vestRatio, uint256 _duration);
event UpdateWhitelistCap(address indexed _whitelist, uint256 _cap);
event UpdateSupportedToken(address indexed _token, bool _status);
event UpdateCap(uint128 _cap);
uint256 private constant PRICE_PRECISION = 1e18;
uint256 private constant RATIO_PRECISION = 1e9;
address public immutable weth;
address public immutable base;
address public immutable zap;
address public quota;
struct PriceData {
uint96 initialPrice;
uint32 upRatio;
uint128 variation;
}
struct SaleTimeData {
uint64 whitelistSaleTime;
uint64 publicSaleTime;
uint64 saleDuration;
}
struct VestingData {
address vesting;
uint32 vestRatio;
uint64 duration;
}
SaleTimeData public saleTimeData;
PriceData public priceData;
VestingData public vestingData;
uint128 public cap;
uint128 public totalSold;
mapping(address => bool) public isSupported;
mapping(address => uint256) public whitelistCap;
mapping(address => uint256) public shares;
mapping(address => bool) public claimed;
constructor(
address _weth,
address _base,
address _zap,
uint128 _cap
) {
weth = _weth;
base = _base;
zap = _zap;
cap = _cap;
}
function getPrice() public view returns (uint256) {
PriceData memory _data = priceData;
uint256 _totalSold = totalSold;
uint256 _level = _totalSold / _data.variation;
return RATIO_PRECISION.add(_level.mul(_data.upRatio)).mul(_data.initialPrice).div(RATIO_PRECISION);
}
function buy(
address _token,
uint256 _amountIn,
uint256 _minOut
) external payable nonReentrant returns (uint256) {
require(_amountIn > 0, "TokenSale: zero input amount");
require(isSupported[_token], "TokenSale: token not support");
SaleTimeData memory _saleTime = saleTimeData;
require(block.timestamp >= _saleTime.whitelistSaleTime, "TokenSale: sale not start");
require(block.timestamp <= _saleTime.publicSaleTime + _saleTime.saleDuration, "TokenSale: sale ended");
uint256 _cap = cap;
uint256 _totalSold = totalSold;
uint256 _saleCap = _cap.sub(_totalSold);
require(_saleCap > 0, "TokenSale: sold out");
uint256 _userCap;
if (block.timestamp < _saleTime.publicSaleTime) {
_userCap = whitelistCap[msg.sender].sub(shares[msg.sender]);
if (_userCap > _saleCap) {
_userCap = _saleCap;
}
} else {
_userCap = _saleCap;
}
require(_userCap > 0, "TokenSale: no cap to buy");
if (_token == address(0)) {
require(_amountIn == msg.value, "TokenSale: msg.value mismatch");
_token = weth;
IWETH(_token).deposit{ value: _amountIn }();
} else {
require(0 == msg.value, "TokenSale: nonzero msg.value");
uint256 _before = IERC20(_token).balanceOf(address(this));
IERC20(_token).safeTransferFrom(msg.sender, address(this), _amountIn);
_amountIn = IERC20(_token).balanceOf(address(this)) - _before;
}
address _base = base;
uint256 _baseAmountIn;
if (_token != _base) {
address _zap = zap;
IERC20(_token).safeTransfer(_zap, _amountIn);
_baseAmountIn = IZap(_zap).zap(_token, _amountIn, _base, 0);
} else {
_baseAmountIn = _amountIn;
}
uint256 _price = getPrice();
uint256 _amountOut = _baseAmountIn.mul(PRICE_PRECISION).div(_price);
uint256 _refundAmount;
if (_userCap < _amountOut) {
_refundAmount = (_amountOut - _userCap).mul(_price).div(PRICE_PRECISION);
_amountOut = _userCap;
}
require(_amountOut >= _minOut, "TokenSale: insufficient output");
shares[msg.sender] += _amountOut;
_totalSold += _amountOut;
require(_totalSold <= uint128(-1), "TokenSale: overflow");
totalSold = uint128(_totalSold);
if (_refundAmount > 0) {
_refundAmount = _refund(_token, _refundAmount);
}
emit Buy(msg.sender, msg.value > 0 ? address(0) : _token, _amountIn, _refundAmount, _amountOut);
return _amountOut;
}
function claim() external nonReentrant {
SaleTimeData memory _saleTime = saleTimeData;
require(block.timestamp > _saleTime.publicSaleTime + _saleTime.saleDuration, "TokenSale: sale not end");
require(!claimed[msg.sender], "TokenSale: already claimed");
VestingData memory _vesting = vestingData;
uint256 _claimAmount = shares[msg.sender];
require(_claimAmount > 0, "TokenSale: no share to claim");
claimed[msg.sender] = true;
address _quota = quota;
uint256 _vestingAmount = _claimAmount.mul(_vesting.vestRatio).div(RATIO_PRECISION);
if (_vestingAmount > 0) {
IERC20(_quota).safeApprove(_vesting.vesting, 0);
IERC20(_quota).safeApprove(_vesting.vesting, _vestingAmount);
Vesting(_vesting.vesting).newVesting(
msg.sender,
uint128(_vestingAmount),
uint64(block.timestamp),
uint64(block.timestamp + _vesting.duration)
);
}
_claimAmount = _claimAmount - _vestingAmount;
if (_claimAmount > 0) {
IERC20(_quota).safeTransfer(msg.sender, _claimAmount);
}
emit Claim(msg.sender, _vestingAmount, _claimAmount);
}
function updateCap(uint128 _cap) external onlyOwner {
cap = _cap;
emit UpdateCap(_cap);
}
function updateSupportedTokens(address[] memory _tokens, bool _status) external onlyOwner {
for (uint256 i = 0; i < _tokens.length; i++) {
isSupported[_tokens[i]] = _status;
emit UpdateSupportedToken(_tokens[i], _status);
}
}
function updateWhitelistCap(address[] memory _whitelist, uint256[] memory _caps) external onlyOwner {
require(_whitelist.length == _caps.length, "TokenSale: length mismatch");
for (uint256 i = 0; i < _whitelist.length; i++) {
whitelistCap[_whitelist[i]] = _caps[i];
emit UpdateWhitelistCap(_whitelist[i], _caps[i]);
}
}
function updateSaleTime(
uint64 _whitelistSaleTime,
uint64 _publicSaleTime,
uint64 _publicSaleDuration
) external onlyOwner {
require(_whitelistSaleTime >= block.timestamp, "TokenSale: start time too small");
require(_whitelistSaleTime <= _publicSaleTime, "TokenSale: whitelist after public");
SaleTimeData memory _saleTime = saleTimeData;
require(
_saleTime.whitelistSaleTime == 0 || block.timestamp < _saleTime.whitelistSaleTime,
"TokenSale: sale started"
);
saleTimeData = SaleTimeData(_whitelistSaleTime, _publicSaleTime, _publicSaleDuration);
emit UpdateSaleTime(_whitelistSaleTime, _publicSaleTime, _publicSaleDuration);
}
function updatePrice(
uint96 _initialPrice,
uint32 _upRatio,
uint128 _variation
) external onlyOwner {
require(_upRatio <= RATIO_PRECISION, "TokenSale: ratio too large");
require(_variation > 0, "TokenSale: zero variation");
SaleTimeData memory _saleTime = saleTimeData;
require(
_saleTime.whitelistSaleTime == 0 || block.timestamp < _saleTime.whitelistSaleTime,
"TokenSale: sale started"
);
priceData = PriceData(_initialPrice, _upRatio, _variation);
emit UpdatePrice(_initialPrice, _upRatio, _variation);
}
function updateVesting(
address _quota,
address _vesting,
uint32 _vestRatio,
uint64 _duration
) external onlyOwner {
require(_vestRatio <= RATIO_PRECISION, "TokenSale: ratio too large");
require(_duration > 0, "TokenSale: zero duration");
quota = _quota;
vestingData = VestingData(_vesting, _vestRatio, _duration);
emit UpdateVesting(_vesting, _vestRatio, _duration);
}
function withdrawFund(address[] memory _tokens, address _recipient) external onlyOwner {
for (uint256 i = 0; i < _tokens.length; i++) {
if (_tokens[i] == address(0)) {
uint256 _balance = address(this).balance;
(bool success, ) = _recipient.call{ value: _balance }("");
require(success, "TokenSale: failed to withdraw ETH");
} else {
uint256 _balance = IERC20(_tokens[i]).balanceOf(address(this));
IERC20(_tokens[i]).safeTransfer(_recipient, _balance);
}
}
}
function _refund(address _token, uint256 _amount) internal returns (uint256) {
address _base = base;
if (_token != _base) {
address _zap = zap;
IERC20(_base).safeTransfer(_zap, _amount);
uint256 _before = IERC20(_token).balanceOf(address(this));
IZap(_zap).zap(_base, _amount, _token, 0);
_amount = IERC20(_token).balanceOf(address(this)) - _before;
}
if (msg.value > 0) {
IWETH(_token).withdraw(_amount);
(bool success, ) = msg.sender.call{ value: _amount }("");
require(success, "TokenSale: failed to refund ETH");
} else {
IERC20(_token).safeTransfer(msg.sender, _amount);
}
return _amount;
}
receive() external payable {}
}
文件 11 的 11:Vesting.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
contract Vesting is Ownable {
using SafeERC20 for IERC20;
event Vest(address indexed _recipient, uint256 indexed _index, uint256 _amount, uint256 _startTime, uint256 _endTime);
event Cancle(address indexed _recipient, uint256 indexed _index, uint256 _unvested, uint256 _cancleTime);
event Claim(address indexed _recipient, uint256 _amount);
address public immutable token;
struct VestState {
uint128 vestingAmount;
uint128 claimedAmount;
uint64 startTime;
uint64 endTime;
uint64 cancleTime;
}
mapping(address => VestState[]) public vesting;
mapping(address => bool) public isWhitelist;
constructor(address _token) {
require(_token != address(0), "Vesting: zero address token");
token = _token;
}
function getUserVest(address _recipient) external view returns (VestState[] memory) {
return vesting[_recipient];
}
function vested(address _recipient) external view returns (uint256 _vested) {
uint256 _length = vesting[_recipient].length;
for (uint256 i = 0; i < _length; i++) {
_vested += _getVested(vesting[_recipient][i], block.timestamp);
}
return _vested;
}
function locked(address _recipient) external view returns (uint256 _unvested) {
uint256 _length = vesting[_recipient].length;
for (uint256 i = 0; i < _length; i++) {
VestState memory _state = vesting[_recipient][i];
_unvested += _state.vestingAmount - _getVested(_state, block.timestamp);
}
}
function claim() external returns (uint256 _claimable) {
uint256 _length = vesting[msg.sender].length;
for (uint256 i = 0; i < _length; i++) {
VestState memory _state = vesting[msg.sender][i];
uint256 _vested = _getVested(_state, block.timestamp);
vesting[msg.sender][i].claimedAmount = uint128(_vested);
_claimable += _vested - _state.claimedAmount;
}
IERC20(token).safeTransfer(msg.sender, _claimable);
emit Claim(msg.sender, _claimable);
}
function newVesting(
address _recipient,
uint128 _amount,
uint64 _startTime,
uint64 _endTime
) external {
require(_startTime < _endTime, "Vesting: invalid timestamp");
require(isWhitelist[msg.sender], "Vesting: caller not whitelisted");
IERC20(token).safeTransferFrom(msg.sender, address(this), _amount);
uint256 _index = vesting[_recipient].length;
vesting[_recipient].push(
VestState({ vestingAmount: _amount, claimedAmount: 0, startTime: _startTime, endTime: _endTime, cancleTime: 0 })
);
emit Vest(_recipient, _index, _amount, _startTime, _endTime);
}
function cancle(address _user, uint256 _index) external onlyOwner {
VestState memory _state = vesting[_user][_index];
require(_state.cancleTime == 0, "already cancled");
uint256 _vestedAmount = _getVested(_state, block.timestamp);
uint256 _unvested = _state.vestingAmount - _vestedAmount;
IERC20(token).safeTransfer(msg.sender, _unvested);
vesting[_user][_index].cancleTime = uint64(block.timestamp);
emit Cancle(_user, _index, _unvested, block.timestamp);
}
function updateWhitelist(address[] memory _accounts, bool _status) external onlyOwner {
for (uint256 i = 0; i < _accounts.length; i++) {
isWhitelist[_accounts[i]] = _status;
}
}
function _getVested(VestState memory _state, uint256 _claimTime) internal pure returns (uint256) {
if (_state.cancleTime != 0 && _state.cancleTime < _claimTime) {
_claimTime = _state.cancleTime;
}
if (_claimTime < _state.startTime) {
return 0;
} else if (_claimTime >= _state.endTime) {
return _state.vestingAmount;
} else {
return (uint256(_state.vestingAmount) * (_claimTime - _state.startTime)) / (_state.endTime - _state.startTime);
}
}
}
{
"compilationTarget": {
"contracts/misc/TokenSale.sol": "TokenSale"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_base","type":"address"},{"internalType":"address","name":"_zap","type":"address"},{"internalType":"uint128","name":"_cap","type":"uint128"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_refundAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amountOut","type":"uint256"}],"name":"Buy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"_vestingAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_claimAmount","type":"uint256"}],"name":"Claim","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":false,"internalType":"uint128","name":"_cap","type":"uint128"}],"name":"UpdateCap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_initialPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_upRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_variation","type":"uint256"}],"name":"UpdatePrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_whitelistSaleTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_publicSaleTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_publicSaleDuration","type":"uint256"}],"name":"UpdateSaleTime","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"bool","name":"_status","type":"bool"}],"name":"UpdateSupportedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_vesting","type":"address"},{"indexed":false,"internalType":"uint256","name":"_vestRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"UpdateVesting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_whitelist","type":"address"},{"indexed":false,"internalType":"uint256","name":"_cap","type":"uint256"}],"name":"UpdateWhitelistCap","type":"event"},{"inputs":[],"name":"base","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"uint256","name":"_minOut","type":"uint256"}],"name":"buy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSupported","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":"priceData","outputs":[{"internalType":"uint96","name":"initialPrice","type":"uint96"},{"internalType":"uint32","name":"upRatio","type":"uint32"},{"internalType":"uint128","name":"variation","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quota","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleTimeData","outputs":[{"internalType":"uint64","name":"whitelistSaleTime","type":"uint64"},{"internalType":"uint64","name":"publicSaleTime","type":"uint64"},{"internalType":"uint64","name":"saleDuration","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSold","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_cap","type":"uint128"}],"name":"updateCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"_initialPrice","type":"uint96"},{"internalType":"uint32","name":"_upRatio","type":"uint32"},{"internalType":"uint128","name":"_variation","type":"uint128"}],"name":"updatePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_whitelistSaleTime","type":"uint64"},{"internalType":"uint64","name":"_publicSaleTime","type":"uint64"},{"internalType":"uint64","name":"_publicSaleDuration","type":"uint64"}],"name":"updateSaleTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"updateSupportedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_quota","type":"address"},{"internalType":"address","name":"_vesting","type":"address"},{"internalType":"uint32","name":"_vestRatio","type":"uint32"},{"internalType":"uint64","name":"_duration","type":"uint64"}],"name":"updateVesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_whitelist","type":"address[]"},{"internalType":"uint256[]","name":"_caps","type":"uint256[]"}],"name":"updateWhitelistCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vestingData","outputs":[{"internalType":"address","name":"vesting","type":"address"},{"internalType":"uint32","name":"vestRatio","type":"uint32"},{"internalType":"uint64","name":"duration","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"withdrawFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"zap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]