编译器
0.8.18+commit.87f61d96
文件 1 的 21: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(uint160(account), 20),
" 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 的 21: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 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
) internal 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);
}
}
}
}
文件 3 的 21: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 的 21: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;
}
}
文件 5 的 21:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
文件 6 的 21:HighTableVault.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeCast.sol";
import "./IHighTableVault.sol";
contract HighTableVault is IHighTableVault, AccessControl, ERC20 {
using SafeERC20 for IERC20;
uint256 public constant SECONDS_IN_A_YEAR = 365 * 86400;
bytes32 public constant AUDITOR_ROLE = keccak256("AUDITOR_ROLE");
IERC20 internal immutable assetToken;
FeeConfig public feeConfig;
FundConfig public fundConfig;
address[] public nftEnabled;
GlobalState public globalState;
mapping(uint32 => CycleState) public cycleState;
mapping(address => UserState) public userState;
Price public initialPrice;
Price public closePrice;
constructor(
string memory _name,
string memory _symbol,
address _asset,
uint128 _priceNumerator,
uint128 _priceDenominator,
uint64 _startTimestamp,
address _initialAdmin)
ERC20(_name, _symbol) {
if (_priceNumerator == 0 || _priceDenominator == 0) revert InvalidInitialPrice();
_grantRole(DEFAULT_ADMIN_ROLE, _initialAdmin);
assetToken = IERC20(_asset);
initialPrice = Price(_priceNumerator, _priceDenominator);
globalState.cycleStartTimestamp = _startTimestamp;
emit FundInitialized(msg.sender, _priceNumerator, _priceDenominator, _startTimestamp, _initialAdmin);
}
function setEnabledNFTs(address[] calldata _nfts) external override {
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) revert OnlyAvailableToAdmins();
nftEnabled = _nfts;
emit NFTEnabled(msg.sender, globalState.cycleIndex, _nfts);
}
function setDisableNFTChecks(bool _checks) external override {
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) revert OnlyAvailableToAdmins();
fundConfig.disableNFTChecks = _checks;
emit DisableNFTChecks(msg.sender, globalState.cycleIndex, _checks);
}
function setFeeConfig(FeeConfig calldata _feeConfig) external override {
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) revert OnlyAvailableToAdmins();
if (_feeConfig.managerEntryFee + _feeConfig.platformEntryFee +
_feeConfig.managerExitFee + _feeConfig.platformExitFee > 1000000) revert InvalidFeePercentage();
if (_feeConfig.managerPerformanceFee + _feeConfig.platformPerformanceFee > 1000000) revert InvalidFeePercentage();
if (_feeConfig.managerManagementFee + _feeConfig.platformManagementFee > 1000000) revert InvalidFeePercentage();
feeConfig = _feeConfig;
emit FeeConfigChanged(msg.sender, globalState.cycleIndex, _feeConfig);
}
function setTeaVaultV2(address _teaVaultV2) external override {
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) revert OnlyAvailableToAdmins();
fundConfig.teaVaultV2 = ITeaVaultV2(_teaVaultV2);
emit UpdateTeaVaultV2(msg.sender, globalState.cycleIndex, _teaVaultV2);
}
function enterNextCycle(
uint32 _cycleIndex,
uint128 _fundValue,
uint128 _depositLimit,
uint128 _withdrawAmount,
uint64 _cycleStartTimestamp,
uint64 _fundingLockTimestamp,
bool _closeFund) external override returns (uint256 platformFee, uint256 managerFee) {
if (_withdrawAmount > 0) {
fundConfig.teaVaultV2.withdraw(address(this), address(assetToken), _withdrawAmount);
}
(platformFee, managerFee) = _internalEnterNextCycle(_cycleIndex, _fundValue, _depositLimit, _cycleStartTimestamp, _fundingLockTimestamp, _closeFund);
if (platformFee > 0) {
assetToken.safeTransfer(feeConfig.platformVault, platformFee);
}
if (managerFee > 0) {
assetToken.safeTransfer(feeConfig.managerVault, managerFee);
}
uint256 deposits = _internalCheckDeposits();
if (deposits > 0) {
assetToken.safeApprove(address(fundConfig.teaVaultV2), deposits);
fundConfig.teaVaultV2.deposit(address(assetToken), deposits);
}
}
function previewNextCycle(uint128 _fundValue, uint64 _timestamp) external override view returns (uint256 withdrawAmount) {
if (globalState.cycleIndex > 0) {
(uint256 pFee, uint256 mFee) = _calculatePMFees(_fundValue, _timestamp);
withdrawAmount += pFee + mFee;
}
uint32 cycleIndex = globalState.cycleIndex;
if (cycleState[cycleIndex].requestedWithdrawals > 0) {
uint256 fundValueAfterPMFee = _fundValue - withdrawAmount;
withdrawAmount += uint256(cycleState[cycleIndex].requestedWithdrawals) * fundValueAfterPMFee / totalSupply();
}
if (cycleState[cycleIndex].requestedDeposits > 0) {
uint256 requestedDeposits = cycleState[cycleIndex].requestedDeposits;
uint256 platformFee = requestedDeposits * feeConfig.platformEntryFee / 1000000;
uint256 managerFee = requestedDeposits * feeConfig.managerEntryFee / 1000000;
withdrawAmount += platformFee + managerFee;
if (withdrawAmount > requestedDeposits) {
withdrawAmount -= requestedDeposits;
}
else {
withdrawAmount = 0;
}
}
}
function setFundLockingTimestamp(uint64 _fundLockingTimestamp) external override {
if (!hasRole(AUDITOR_ROLE, msg.sender)) revert OnlyAvailableToAuditors();
globalState.fundingLockTimestamp = _fundLockingTimestamp;
emit FundLockingTimestampUpdated(msg.sender, globalState.cycleIndex, _fundLockingTimestamp);
}
function setDepositLimit(uint128 _depositLimit) external override {
if (!hasRole(AUDITOR_ROLE, msg.sender)) revert OnlyAvailableToAuditors();
globalState.depositLimit = _depositLimit;
emit DepositLimitUpdated(msg.sender, globalState.cycleIndex, _depositLimit);
}
function setDisableFunding(bool _disableDepositing, bool _disableWithdrawing, bool _disableCancelDepositing, bool _disableCancelWithdrawing) external override {
if (!hasRole(AUDITOR_ROLE, msg.sender)) revert OnlyAvailableToAuditors();
fundConfig.disableDepositing = _disableDepositing;
fundConfig.disableWithdrawing = _disableWithdrawing;
fundConfig.disableCancelDepositing = _disableCancelDepositing;
fundConfig.disableCancelWithdrawing = _disableCancelWithdrawing;
emit FundingChanged(msg.sender, globalState.cycleIndex, _disableDepositing, _disableWithdrawing, _disableCancelDepositing, _disableCancelWithdrawing);
}
function depositToVault(uint256 _value) external override {
if (!hasRole(AUDITOR_ROLE, msg.sender)) revert OnlyAvailableToAuditors();
uint256 balance = assetToken.balanceOf(address(this));
if (balance - globalState.lockedAssets < _value) revert NotEnoughAssets();
assetToken.safeApprove(address(fundConfig.teaVaultV2), _value);
fundConfig.teaVaultV2.deposit(address(assetToken), _value);
emit DepositToVault(msg.sender, globalState.cycleIndex, address(fundConfig.teaVaultV2), _value);
}
function withdrawFromVault(uint256 _value) external override {
if (!hasRole(AUDITOR_ROLE, msg.sender)) revert OnlyAvailableToAuditors();
fundConfig.teaVaultV2.withdraw(address(this), address(assetToken), _value);
emit WithdrawFromVault(msg.sender, globalState.cycleIndex, address(fundConfig.teaVaultV2), _value);
}
function asset() external override view returns (address assetTokenAddress) {
return address(assetToken);
}
function requestDeposit(uint256 _assets, address _receiver) public override {
assetToken.safeTransferFrom(msg.sender, address(this), _assets);
_internalRequestDeposit(_assets, _receiver);
}
function claimAndRequestDeposit(uint256 _assets, address _receiver) external override returns (uint256 assets) {
assets = claimOwedAssets(msg.sender);
requestDeposit(_assets, _receiver);
}
function cancelDeposit(uint256 _assets, address _receiver) external override {
_internalCancelDeposit(_assets, _receiver);
assetToken.safeTransfer(_receiver, _assets);
}
function requestWithdraw(uint256 _shares, address _owner) public override {
if (fundConfig.disableWithdrawing) revert WithdrawDisabled();
if (globalState.fundClosed) revert FundIsClosed();
if (block.timestamp > globalState.fundingLockTimestamp) revert FundingLocked();
if (_owner != msg.sender) {
_spendAllowance(_owner, msg.sender, _shares);
}
_transfer(_owner, address(this), _shares);
uint32 cycleIndex = globalState.cycleIndex;
uint128 shares = SafeCast.toUint128(_shares);
cycleState[cycleIndex].requestedWithdrawals += shares;
_convertPreviousRequests(_owner);
userState[_owner].requestedWithdrawals += shares;
userState[_owner].requestCycleIndex = cycleIndex;
emit WithdrawalRequested(msg.sender, cycleIndex, _owner, _shares);
}
function claimAndRequestWithdraw(uint256 _shares, address _owner) external override returns (uint256 shares) {
shares = claimOwedShares(msg.sender);
requestWithdraw(_shares, _owner);
}
function cancelWithdraw(uint256 _shares, address _receiver) external override {
if (block.timestamp > globalState.fundingLockTimestamp) revert FundingLocked();
if (fundConfig.disableCancelWithdrawing) revert CancelWithdrawDisabled();
uint32 cycleIndex = globalState.cycleIndex;
if (userState[msg.sender].requestCycleIndex != cycleIndex) revert NotEnoughWithdrawals();
if (userState[msg.sender].requestedWithdrawals < _shares) revert NotEnoughWithdrawals();
uint128 shares = SafeCast.toUint128(_shares);
cycleState[cycleIndex].requestedWithdrawals -= shares;
userState[msg.sender].requestedWithdrawals -= shares;
_transfer(address(this), _receiver, _shares);
emit WithdrawalCanceled(msg.sender, cycleIndex, _receiver, _shares);
}
function requestedFunds(address _owner) external override view returns (uint256 assets, uint256 shares) {
if (userState[_owner].requestCycleIndex != globalState.cycleIndex) {
return (0, 0);
}
assets = userState[_owner].requestedDeposits;
shares = userState[_owner].requestedWithdrawals;
}
function claimOwedAssets(address _receiver) public override returns (uint256 assets) {
assets = _internalClaimOwedAssets(_receiver);
if (assets > 0) {
assetToken.safeTransfer(_receiver, assets);
}
}
function claimOwedShares(address _receiver) public override returns (uint256 shares) {
_convertPreviousRequests(msg.sender);
if (userState[msg.sender].owedShares > 0) {
shares = userState[msg.sender].owedShares;
userState[msg.sender].owedShares = 0;
_transfer(address(this), _receiver, shares);
emit ClaimOwedShares(msg.sender, _receiver, shares);
}
}
function claimOwedFunds(address _receiver) external override returns (uint256 assets, uint256 shares) {
assets = claimOwedAssets(_receiver);
shares = claimOwedShares(_receiver);
}
function closePosition(uint256 _shares, address _owner) public override returns (uint256 assets) {
if (!globalState.fundClosed) revert FundIsNotClosed();
if (_owner != msg.sender) {
_spendAllowance(_owner, msg.sender, _shares);
}
_burn(_owner, _shares);
assets = _shares * closePrice.numerator / closePrice.denominator;
userState[_owner].owedAssets += SafeCast.toUint128(assets);
}
function closePositionAndClaim(address _receiver) external override returns (uint256 assets) {
claimOwedShares(msg.sender);
uint256 shares = balanceOf(msg.sender);
closePosition(shares, msg.sender);
assets = claimOwedAssets(_receiver);
}
function _internalEnterNextCycle(
uint32 _cycleIndex,
uint128 _fundValue,
uint128 _depositLimit,
uint64 _cycleStartTimestamp,
uint64 _fundingLockTimestamp,
bool _closeFund) internal returns (uint256 platformFee, uint256 managerFee) {
if (!hasRole(AUDITOR_ROLE, msg.sender)) revert OnlyAvailableToAuditors();
if (address(fundConfig.teaVaultV2) == address(0)) revert IncorrectVaultAddress();
if (feeConfig.platformVault == address(0)) revert IncorrectVaultAddress();
if (feeConfig.managerVault == address(0)) revert IncorrectVaultAddress();
if (globalState.fundClosed) revert FundIsClosed();
if (_cycleIndex != globalState.cycleIndex) revert IncorrectCycleIndex();
if (_cycleStartTimestamp <= globalState.cycleStartTimestamp || _cycleStartTimestamp > block.timestamp) revert IncorrectCycleStartTimestamp();
cycleState[_cycleIndex].totalFundValue = _fundValue;
uint256 pFee;
uint256 mFee;
if (_cycleIndex > 0) {
(pFee, mFee) = _calculatePMFees(_fundValue, _cycleStartTimestamp);
platformFee += pFee;
managerFee += mFee;
}
uint256 fundValueAfterPMFees = _fundValue - platformFee - managerFee;
uint256 currentTotalSupply = totalSupply();
if (currentTotalSupply > 0 && fundValueAfterPMFees == 0) revert InvalidFundValue();
if (currentTotalSupply == 0 && cycleState[_cycleIndex].requestedDeposits == 0) revert NoDeposits();
(pFee, mFee) = _processRequests(fundValueAfterPMFees);
platformFee += pFee;
managerFee += mFee;
if (_closeFund) {
(pFee, mFee) = _calculateCloseFundFees();
platformFee += pFee;
managerFee += mFee;
uint128 finalFundValue = SafeCast.toUint128(cycleState[globalState.cycleIndex].fundValueAfterRequests - pFee - mFee);
closePrice = Price(finalFundValue, SafeCast.toUint128(totalSupply()));
globalState.lockedAssets += finalFundValue;
globalState.fundClosed = true;
}
if (currentTotalSupply == 0) {
emit EnterNextCycle(
msg.sender,
_cycleIndex,
_fundValue,
initialPrice.numerator,
initialPrice.denominator,
_depositLimit,
_cycleStartTimestamp,
_fundingLockTimestamp,
_closeFund,
platformFee,
managerFee);
}
else {
emit EnterNextCycle(
msg.sender,
_cycleIndex,
_fundValue,
fundValueAfterPMFees,
currentTotalSupply,
_depositLimit,
_cycleStartTimestamp,
_fundingLockTimestamp,
_closeFund,
platformFee,
managerFee);
}
globalState.cycleIndex ++;
globalState.cycleStartTimestamp = _cycleStartTimestamp;
globalState.depositLimit = _depositLimit;
globalState.fundingLockTimestamp = _fundingLockTimestamp;
}
function _internalCheckDeposits() internal view returns (uint256 deposits) {
deposits = assetToken.balanceOf(address(this));
if (deposits < globalState.lockedAssets) revert NotEnoughAssets();
unchecked {
deposits = deposits - globalState.lockedAssets;
}
}
function _calculatePMFees(uint128 _fundValue, uint64 _timestamp) internal view returns (uint256 platformFee, uint256 managerFee) {
uint256 fundValue = _fundValue;
uint64 timeDiff = _timestamp - globalState.cycleStartTimestamp;
unchecked {
platformFee = fundValue * feeConfig.platformManagementFee * timeDiff / (SECONDS_IN_A_YEAR * 1000000);
managerFee = fundValue * feeConfig.managerManagementFee * timeDiff / (SECONDS_IN_A_YEAR * 1000000);
}
if (fundValue > cycleState[globalState.cycleIndex - 1].fundValueAfterRequests) {
unchecked {
uint256 profits = fundValue - cycleState[globalState.cycleIndex - 1].fundValueAfterRequests;
platformFee += profits * feeConfig.platformPerformanceFee / 1000000;
managerFee += profits * feeConfig.managerPerformanceFee / 1000000;
}
}
}
function _calculateCloseFundFees() internal view returns (uint256 platformFee, uint256 managerFee) {
uint256 fundValue = cycleState[globalState.cycleIndex].fundValueAfterRequests;
unchecked {
platformFee = fundValue * feeConfig.platformExitFee / 1000000;
managerFee = fundValue * feeConfig.managerExitFee / 1000000;
}
}
function _processRequests(uint256 _fundValueAfterPMFees) internal returns (uint256 platformFee, uint256 managerFee) {
uint32 cycleIndex = globalState.cycleIndex;
uint256 currentTotalSupply = totalSupply();
uint256 fundValueAfterRequests = _fundValueAfterPMFees;
if (cycleState[cycleIndex].requestedWithdrawals > 0) {
uint256 withdrawnAssets = _fundValueAfterPMFees * cycleState[cycleIndex].requestedWithdrawals / currentTotalSupply;
uint256 pFee;
uint256 mFee;
unchecked {
pFee = withdrawnAssets * feeConfig.platformExitFee / 1000000;
mFee = withdrawnAssets * feeConfig.managerExitFee / 1000000;
}
cycleState[cycleIndex].convertedWithdrawals = SafeCast.toUint128(withdrawnAssets - pFee - mFee);
globalState.lockedAssets += cycleState[cycleIndex].convertedWithdrawals;
fundValueAfterRequests -= SafeCast.toUint128(withdrawnAssets);
platformFee += pFee;
managerFee += mFee;
_burn(address(this), cycleState[cycleIndex].requestedWithdrawals);
}
if (cycleState[cycleIndex].requestedDeposits > 0) {
uint256 requestedDeposits = cycleState[cycleIndex].requestedDeposits;
uint256 pFee;
uint256 mFee;
unchecked {
pFee = requestedDeposits * feeConfig.platformEntryFee / 1000000;
mFee = requestedDeposits * feeConfig.managerEntryFee / 1000000;
}
globalState.lockedAssets -= cycleState[cycleIndex].requestedDeposits;
requestedDeposits = requestedDeposits - pFee - mFee;
fundValueAfterRequests += SafeCast.toUint128(requestedDeposits);
if (currentTotalSupply == 0) {
cycleState[cycleIndex].convertedDeposits = SafeCast.toUint128(requestedDeposits * initialPrice.denominator / initialPrice.numerator);
}
else {
cycleState[cycleIndex].convertedDeposits = SafeCast.toUint128(requestedDeposits * currentTotalSupply / _fundValueAfterPMFees);
}
platformFee += pFee;
managerFee += mFee;
_mint(address(this), cycleState[cycleIndex].convertedDeposits);
}
cycleState[cycleIndex].fundValueAfterRequests = SafeCast.toUint128(fundValueAfterRequests);
}
function _convertPreviousRequests(address _receiver) internal {
uint32 cycleIndex = userState[_receiver].requestCycleIndex;
if (cycleIndex >= globalState.cycleIndex) {
return;
}
if (userState[_receiver].requestedDeposits > 0) {
uint256 owedShares = uint256(userState[_receiver].requestedDeposits) * cycleState[cycleIndex].convertedDeposits / cycleState[cycleIndex].requestedDeposits;
userState[_receiver].owedShares += SafeCast.toUint128(owedShares);
emit ConvertToShares(_receiver, cycleIndex, userState[_receiver].requestedDeposits, owedShares);
userState[_receiver].requestedDeposits = 0;
}
if (userState[_receiver].requestedWithdrawals > 0) {
uint256 owedAssets = uint256(userState[_receiver].requestedWithdrawals) * cycleState[cycleIndex].convertedWithdrawals / cycleState[cycleIndex].requestedWithdrawals;
userState[_receiver].owedAssets += SafeCast.toUint128(owedAssets);
emit ConvertToAssets(_receiver, cycleIndex, userState[_receiver].requestedWithdrawals, owedAssets);
userState[_receiver].requestedWithdrawals = 0;
}
}
function _internalRequestDeposit(uint256 _assets, address _receiver) internal {
if (fundConfig.disableDepositing) revert DepositDisabled();
if (globalState.fundClosed) revert FundIsClosed();
if (block.timestamp > globalState.fundingLockTimestamp) revert FundingLocked();
if (_assets + cycleState[globalState.cycleIndex].requestedDeposits > globalState.depositLimit) revert ExceedDepositLimit();
if (!_hasNFT(_receiver)) revert ReceiverDoNotHasNFT();
uint32 cycleIndex = globalState.cycleIndex;
uint128 assets = SafeCast.toUint128(_assets);
cycleState[cycleIndex].requestedDeposits += assets;
globalState.lockedAssets += assets;
_convertPreviousRequests(_receiver);
userState[_receiver].requestedDeposits += assets;
userState[_receiver].requestCycleIndex = cycleIndex;
emit DepositRequested(msg.sender, cycleIndex, _receiver, _assets);
}
function _internalCancelDeposit(uint256 _assets, address _receiver) internal {
if (block.timestamp > globalState.fundingLockTimestamp) revert FundingLocked();
if (fundConfig.disableCancelDepositing) revert CancelDepositDisabled();
uint32 cycleIndex = globalState.cycleIndex;
if (userState[msg.sender].requestCycleIndex != cycleIndex) revert NotEnoughDeposits();
if (userState[msg.sender].requestedDeposits < _assets) revert NotEnoughDeposits();
uint128 assets = SafeCast.toUint128(_assets);
cycleState[cycleIndex].requestedDeposits -= assets;
globalState.lockedAssets -= assets;
userState[msg.sender].requestedDeposits -= assets;
emit DepositCanceled(msg.sender, cycleIndex, _receiver, _assets);
}
function _internalClaimOwedAssets(address _receiver) internal returns (uint256 assets) {
_convertPreviousRequests(msg.sender);
if (userState[msg.sender].owedAssets > 0) {
assets = userState[msg.sender].owedAssets;
globalState.lockedAssets -= userState[msg.sender].owedAssets;
userState[msg.sender].owedAssets = 0;
emit ClaimOwedAssets(msg.sender, _receiver, assets);
}
}
function _hasNFT(address _receiver) internal view returns (bool hasNFT) {
if (fundConfig.disableNFTChecks) {
return true;
}
uint256 i;
uint256 length = nftEnabled.length;
for (i = 0; i < length; ) {
if (IERC721(nftEnabled[i]).balanceOf(_receiver) > 0) {
return true;
}
unchecked {
++i;
}
}
return false;
}
}
文件 7 的 21:HighTableVaultETH.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./HighTableVault.sol";
import "./IHighTableVaultETH.sol";
import "./IWETH9.sol";
contract HighTableVaultETH is HighTableVault, IHighTableVaultETH, ReentrancyGuard {
constructor(
string memory _name,
string memory _symbol,
address _weth9,
uint128 _priceNumerator,
uint128 _priceDenominator,
uint64 _startTimestamp,
address _initialAdmin)
HighTableVault(_name, _symbol, _weth9, _priceNumerator, _priceDenominator, _startTimestamp, _initialAdmin) {
if (keccak256(abi.encode(IWETH9(_weth9).symbol())) != keccak256(abi.encode("WETH"))) revert AssetNotWETH9();
}
receive() external payable {
if (msg.sender != address(this) &&
msg.sender != address(assetToken) &&
msg.sender != address(fundConfig.teaVaultV2)) revert NotAcceptingETH();
}
function enterNextCycleETH(
uint32 _cycleIndex,
uint128 _fundValue,
uint128 _depositLimit,
uint128 _withdrawAmount,
uint64 _cycleStartTimestamp,
uint64 _fundingLockTimestamp,
bool _closeFund) external override returns (uint256 platformFee, uint256 managerFee) {
if (_withdrawAmount > 0) {
fundConfig.teaVaultV2.withdrawETH(payable(this), _withdrawAmount);
IWETH9(address(assetToken)).deposit{ value: _withdrawAmount }();
}
(platformFee, managerFee) = _internalEnterNextCycle(_cycleIndex, _fundValue, _depositLimit, _cycleStartTimestamp, _fundingLockTimestamp, _closeFund);
uint256 converts = platformFee + managerFee;
if (converts > 0) {
IWETH9(address(assetToken)).withdraw(converts);
if (platformFee > 0) {
Address.sendValue(payable(feeConfig.platformVault), platformFee);
}
if (managerFee > 0) {
Address.sendValue(payable(feeConfig.managerVault), managerFee);
}
}
uint256 deposits = _internalCheckDeposits();
if (deposits > 0) {
IWETH9(address(assetToken)).withdraw(deposits);
fundConfig.teaVaultV2.depositETH{ value: deposits }(deposits);
}
}
function depositToVaultETH(uint256 _value) external override {
if (!hasRole(AUDITOR_ROLE, msg.sender)) revert OnlyAvailableToAuditors();
uint256 balance = assetToken.balanceOf(address(this));
if (balance - globalState.lockedAssets < _value) revert NotEnoughAssets();
IWETH9(address(assetToken)).withdraw(_value);
fundConfig.teaVaultV2.depositETH{ value: _value }(_value);
emit DepositToVault(msg.sender, globalState.cycleIndex, address(fundConfig.teaVaultV2), _value);
}
function withdrawFromVaultETH(uint256 _value) external override {
if (!hasRole(AUDITOR_ROLE, msg.sender)) revert OnlyAvailableToAuditors();
fundConfig.teaVaultV2.withdrawETH(payable(this), _value);
IWETH9(address(assetToken)).deposit{ value: _value }();
emit WithdrawFromVault(msg.sender, globalState.cycleIndex, address(fundConfig.teaVaultV2), _value);
}
function requestDepositETH(uint256 _assets, address _receiver) external override payable nonReentrant {
if (msg.value != _assets) revert IncorrectETHAmount();
IWETH9(address(assetToken)).deposit{ value: _assets }();
_internalRequestDeposit(_assets, _receiver);
}
function claimAndRequestDepositETH(uint256 _assets, address _receiver) external override payable nonReentrant returns (uint256 assets) {
assets = _internalClaimOwedAssets(payable(address(this)));
if (assets > 0) {
IWETH9(address(assetToken)).withdraw(assets);
Address.sendValue(payable(address(this)), assets);
}
if (msg.value + assets < _assets) revert IncorrectETHAmount();
IWETH9(address(assetToken)).deposit{ value: _assets }();
_internalRequestDeposit(_assets, _receiver);
uint256 remainingAssets = msg.value + assets - _assets;
if (remainingAssets > 0) {
Address.sendValue(payable(msg.sender), remainingAssets);
}
}
function cancelDepositETH(uint256 _assets, address payable _receiver) external override nonReentrant {
_internalCancelDeposit(_assets, _receiver);
IWETH9(address(assetToken)).withdraw(_assets);
Address.sendValue(_receiver, _assets);
}
function claimOwedAssetsETH(address payable _receiver) public override nonReentrant returns (uint256 assets) {
assets = _internalClaimOwedAssets(_receiver);
if (assets > 0) {
IWETH9(address(assetToken)).withdraw(assets);
Address.sendValue(_receiver, assets);
}
}
function claimOwedFundsETH(address payable _receiver) external override returns (uint256 assets, uint256 shares) {
assets = claimOwedAssetsETH(_receiver);
shares = claimOwedShares(_receiver);
}
function closePositionAndClaimETH(address payable _receiver) external override returns (uint256 assets) {
claimOwedShares(msg.sender);
uint256 shares = balanceOf(msg.sender);
closePosition(shares, msg.sender);
assets = claimOwedAssetsETH(_receiver);
}
}
文件 8 的 21: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;
}
文件 9 的 21:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 10 的 21: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);
}
文件 11 的 21:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 12 的 21:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 13 的 21:IHighTableVault.sol
pragma solidity ^0.8.0;
import "./ITeaVaultV2.sol";
error OnlyAvailableToAdmins();
error OnlyAvailableToAuditors();
error ReceiverDoNotHasNFT();
error IncorrectVaultAddress();
error IncorrectReceiverAddress();
error NotEnoughAssets();
error FundingLocked();
error ExceedDepositLimit();
error DepositDisabled();
error WithdrawDisabled();
error NotEnoughDeposits();
error NotEnoughWithdrawals();
error InvalidInitialPrice();
error FundIsClosed();
error FundIsNotClosed();
error InvalidFeePercentage();
error IncorrectCycleIndex();
error IncorrectCycleStartTimestamp();
error InvalidFundValue();
error NoDeposits();
error CancelDepositDisabled();
error CancelWithdrawDisabled();
interface IHighTableVault {
struct Price {
uint128 numerator;
uint128 denominator;
}
struct FeeConfig {
address platformVault;
address managerVault;
uint24 platformEntryFee;
uint24 managerEntryFee;
uint24 platformExitFee;
uint24 managerExitFee;
uint24 platformPerformanceFee;
uint24 managerPerformanceFee;
uint24 platformManagementFee;
uint24 managerManagementFee;
}
struct FundConfig {
ITeaVaultV2 teaVaultV2;
bool disableNFTChecks;
bool disableDepositing;
bool disableWithdrawing;
bool disableCancelDepositing;
bool disableCancelWithdrawing;
}
struct GlobalState {
uint128 depositLimit;
uint128 lockedAssets;
uint32 cycleIndex;
uint64 cycleStartTimestamp;
uint64 fundingLockTimestamp;
bool fundClosed;
}
struct CycleState {
uint128 totalFundValue;
uint128 fundValueAfterRequests;
uint128 requestedDeposits;
uint128 convertedDeposits;
uint128 requestedWithdrawals;
uint128 convertedWithdrawals;
}
struct UserState {
uint128 requestedDeposits;
uint128 owedShares;
uint128 requestedWithdrawals;
uint128 owedAssets;
uint32 requestCycleIndex;
}
event FundInitialized(address indexed caller, uint256 priceNumerator, uint256 priceDenominator, uint64 startTimestamp, address admin);
event NFTEnabled(address indexed caller, uint32 indexed cycleIndex, address[] nfts);
event DisableNFTChecks(address indexed caller, uint32 indexed cycleIndex, bool disableChecks);
event FeeConfigChanged(address indexed caller, uint32 indexed cycleIndex, FeeConfig feeConfig);
event EnterNextCycle(address indexed caller, uint32 indexed cycleIndex, uint256 fundValue, uint256 priceNumerator, uint256 priceDenominator, uint256 depositLimit, uint64 startTimestamp, uint64 lockTimestamp, bool fundClosed, uint256 platformFee, uint256 managerFee);
event FundLockingTimestampUpdated(address indexed caller, uint32 indexed cycleIndex, uint64 lockTimestamp);
event DepositLimitUpdated(address indexed caller, uint32 indexed cycleIndex, uint256 depositLimit);
event UpdateTeaVaultV2(address indexed caller, uint32 indexed cycleIndex, address teaVaultV2);
event DepositToVault(address indexed caller, uint32 indexed cycleIndex, address teaVaultV2, uint256 value);
event WithdrawFromVault(address indexed caller, uint32 indexed cycleIndex, address teaVaultV2, uint256 value);
event FundingChanged(address indexed caller, uint32 indexed cycleIndex, bool disableDepositing, bool disableWithdrawing, bool disableCancelDepositing, bool disableCancelWithdrawing);
event DepositRequested(address indexed caller, uint32 indexed cycleIndex, address indexed receiver, uint256 assets);
event DepositCanceled(address indexed caller, uint32 indexed cycleIndex, address indexed receiver, uint256 assets);
event WithdrawalRequested(address indexed caller, uint32 indexed cycleIndex, address indexed owner, uint256 shares);
event WithdrawalCanceled(address indexed caller, uint32 indexed cycleIndex, address indexed receiver, uint256 shares);
event ClaimOwedAssets(address indexed caller, address indexed receiver, uint256 assets);
event ClaimOwedShares(address indexed caller, address indexed receiver, uint256 shares);
event ConvertToShares(address indexed owner, uint32 indexed cycleIndex, uint256 assets, uint256 shares);
event ConvertToAssets(address indexed owner, uint32 indexed cycleIndex, uint256 shares, uint256 assets);
function setEnabledNFTs(address[] memory _nfts) external;
function setDisableNFTChecks(bool _checks) external;
function setFeeConfig(FeeConfig calldata _feeConfig) external;
function setTeaVaultV2(address _teaVaultV2) external;
function enterNextCycle(
uint32 _cycleIndex,
uint128 _fundValue,
uint128 _depositLimit,
uint128 _withdrawAmount,
uint64 _cycleStartTimestamp,
uint64 _fundingLockTimestamp,
bool _closeFund) external returns (uint256 platformFee, uint256 managerFee);
function setFundLockingTimestamp(uint64 _fundLockingTimestamp) external;
function setDepositLimit(uint128 _depositLimit) external;
function setDisableFunding(bool _disableDepositing, bool _disableWithdrawing, bool _disableCancelDepositing, bool _disableCancelWithdrawing) external;
function depositToVault(uint256 _value) external;
function withdrawFromVault(uint256 _value) external;
function asset() external view returns (address assetTokenAddress);
function requestDeposit(uint256 _assets, address _receiver) external;
function claimAndRequestDeposit(uint256 _assets, address _receiver) external returns (uint256 assets);
function cancelDeposit(uint256 _assets, address _receiver) external;
function requestWithdraw(uint256 _shares, address _owner) external;
function claimAndRequestWithdraw(uint256 _shares, address _owner) external returns (uint256 shares);
function cancelWithdraw(uint256 _shares, address _receiver) external;
function requestedFunds(address _owner) external view returns (uint256 assets, uint256 shares);
function claimOwedAssets(address _receiver) external returns (uint256 assets);
function claimOwedShares(address _receiver) external returns (uint256 shares);
function claimOwedFunds(address _receiver) external returns (uint256 assets, uint256 shares);
function closePosition(uint256 _shares, address _owner) external returns (uint256 assets);
function closePositionAndClaim(address _receiver) external returns (uint256 assets);
function previewNextCycle(uint128 _fundValue, uint64 _timestamp) external view returns (uint256 withdrawAmount);
}
文件 14 的 21:IHighTableVaultETH.sol
pragma solidity ^0.8.0;
import "./IHighTableVault.sol";
error AssetNotWETH9();
error IncorrectETHAmount();
error NotAcceptingETH();
interface IHighTableVaultETH is IHighTableVault {
function enterNextCycleETH(
uint32 _cycleIndex,
uint128 _fundValue,
uint128 _depositLimit,
uint128 _withdrawAmount,
uint64 _cycleStartTimestamp,
uint64 _fundingLockTimestamp,
bool _closeFund) external returns (uint256 platformFee, uint256 managerFee);
function depositToVaultETH(uint256 _value) external;
function withdrawFromVaultETH(uint256 _value) external;
function requestDepositETH(uint256 _assets, address _receiver) external payable;
function claimAndRequestDepositETH(uint256 _assets, address _receiver) external payable returns (uint256 assets);
function cancelDepositETH(uint256 _assets, address payable _receiver) external;
function claimOwedAssetsETH(address payable _receiver) external returns (uint256 assets);
function claimOwedFundsETH(address payable _receiver) external returns (uint256 assets, uint256 shares);
function closePositionAndClaimETH(address payable _receiver) external returns (uint256 assets);
}
文件 15 的 21:ITeaVaultV2.sol
pragma solidity ^0.8.0;
interface ITeaVaultV2 {
function deposit(address _token, uint256 _amount) external;
function withdraw(address _recipient, address _token, uint256 _amount) external;
function deposit721(address _token, uint256 _tokenId) external;
function withdraw721(address _recipient, address _token, uint256 _tokenId) external;
function deposit1155(address _token, uint256 _tokenId, uint256 _amount) external;
function withdraw1155(address _recipient, address _token, uint256 _tokenId, uint256 _amount) external;
function depositETH(uint256 _amount) external payable;
function withdrawETH(address payable _recipient, uint256 _amount) external;
}
文件 16 的 21:IWETH9.sol
pragma solidity ^0.8.0;
interface IWETH9 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function deposit() external payable;
function withdraw(uint wad) external;
}
文件 17 的 21: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() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 18 的 21:SafeCast.sol
pragma solidity ^0.8.0;
library SafeCast {
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
function toInt248(int256 value) internal pure returns (int248) {
require(value >= type(int248).min && value <= type(int248).max, "SafeCast: value doesn't fit in 248 bits");
return int248(value);
}
function toInt240(int256 value) internal pure returns (int240) {
require(value >= type(int240).min && value <= type(int240).max, "SafeCast: value doesn't fit in 240 bits");
return int240(value);
}
function toInt232(int256 value) internal pure returns (int232) {
require(value >= type(int232).min && value <= type(int232).max, "SafeCast: value doesn't fit in 232 bits");
return int232(value);
}
function toInt224(int256 value) internal pure returns (int224) {
require(value >= type(int224).min && value <= type(int224).max, "SafeCast: value doesn't fit in 224 bits");
return int224(value);
}
function toInt216(int256 value) internal pure returns (int216) {
require(value >= type(int216).min && value <= type(int216).max, "SafeCast: value doesn't fit in 216 bits");
return int216(value);
}
function toInt208(int256 value) internal pure returns (int208) {
require(value >= type(int208).min && value <= type(int208).max, "SafeCast: value doesn't fit in 208 bits");
return int208(value);
}
function toInt200(int256 value) internal pure returns (int200) {
require(value >= type(int200).min && value <= type(int200).max, "SafeCast: value doesn't fit in 200 bits");
return int200(value);
}
function toInt192(int256 value) internal pure returns (int192) {
require(value >= type(int192).min && value <= type(int192).max, "SafeCast: value doesn't fit in 192 bits");
return int192(value);
}
function toInt184(int256 value) internal pure returns (int184) {
require(value >= type(int184).min && value <= type(int184).max, "SafeCast: value doesn't fit in 184 bits");
return int184(value);
}
function toInt176(int256 value) internal pure returns (int176) {
require(value >= type(int176).min && value <= type(int176).max, "SafeCast: value doesn't fit in 176 bits");
return int176(value);
}
function toInt168(int256 value) internal pure returns (int168) {
require(value >= type(int168).min && value <= type(int168).max, "SafeCast: value doesn't fit in 168 bits");
return int168(value);
}
function toInt160(int256 value) internal pure returns (int160) {
require(value >= type(int160).min && value <= type(int160).max, "SafeCast: value doesn't fit in 160 bits");
return int160(value);
}
function toInt152(int256 value) internal pure returns (int152) {
require(value >= type(int152).min && value <= type(int152).max, "SafeCast: value doesn't fit in 152 bits");
return int152(value);
}
function toInt144(int256 value) internal pure returns (int144) {
require(value >= type(int144).min && value <= type(int144).max, "SafeCast: value doesn't fit in 144 bits");
return int144(value);
}
function toInt136(int256 value) internal pure returns (int136) {
require(value >= type(int136).min && value <= type(int136).max, "SafeCast: value doesn't fit in 136 bits");
return int136(value);
}
function toInt128(int256 value) internal pure returns (int128) {
require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
return int128(value);
}
function toInt120(int256 value) internal pure returns (int120) {
require(value >= type(int120).min && value <= type(int120).max, "SafeCast: value doesn't fit in 120 bits");
return int120(value);
}
function toInt112(int256 value) internal pure returns (int112) {
require(value >= type(int112).min && value <= type(int112).max, "SafeCast: value doesn't fit in 112 bits");
return int112(value);
}
function toInt104(int256 value) internal pure returns (int104) {
require(value >= type(int104).min && value <= type(int104).max, "SafeCast: value doesn't fit in 104 bits");
return int104(value);
}
function toInt96(int256 value) internal pure returns (int96) {
require(value >= type(int96).min && value <= type(int96).max, "SafeCast: value doesn't fit in 96 bits");
return int96(value);
}
function toInt88(int256 value) internal pure returns (int88) {
require(value >= type(int88).min && value <= type(int88).max, "SafeCast: value doesn't fit in 88 bits");
return int88(value);
}
function toInt80(int256 value) internal pure returns (int80) {
require(value >= type(int80).min && value <= type(int80).max, "SafeCast: value doesn't fit in 80 bits");
return int80(value);
}
function toInt72(int256 value) internal pure returns (int72) {
require(value >= type(int72).min && value <= type(int72).max, "SafeCast: value doesn't fit in 72 bits");
return int72(value);
}
function toInt64(int256 value) internal pure returns (int64) {
require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
return int64(value);
}
function toInt56(int256 value) internal pure returns (int56) {
require(value >= type(int56).min && value <= type(int56).max, "SafeCast: value doesn't fit in 56 bits");
return int56(value);
}
function toInt48(int256 value) internal pure returns (int48) {
require(value >= type(int48).min && value <= type(int48).max, "SafeCast: value doesn't fit in 48 bits");
return int48(value);
}
function toInt40(int256 value) internal pure returns (int40) {
require(value >= type(int40).min && value <= type(int40).max, "SafeCast: value doesn't fit in 40 bits");
return int40(value);
}
function toInt32(int256 value) internal pure returns (int32) {
require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
return int32(value);
}
function toInt24(int256 value) internal pure returns (int24) {
require(value >= type(int24).min && value <= type(int24).max, "SafeCast: value doesn't fit in 24 bits");
return int24(value);
}
function toInt16(int256 value) internal pure returns (int16) {
require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
return int16(value);
}
function toInt8(int256 value) internal pure returns (int8) {
require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
return int8(value);
}
function toInt256(uint256 value) internal pure returns (int256) {
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
文件 19 的 21:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-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 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
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");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
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");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 20 的 21:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_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);
}
}
文件 21 的 21:draft-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);
}
{
"compilationTarget": {
"contracts/HighTableVaultETH.sol": "HighTableVaultETH"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_weth9","type":"address"},{"internalType":"uint128","name":"_priceNumerator","type":"uint128"},{"internalType":"uint128","name":"_priceDenominator","type":"uint128"},{"internalType":"uint64","name":"_startTimestamp","type":"uint64"},{"internalType":"address","name":"_initialAdmin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AssetNotWETH9","type":"error"},{"inputs":[],"name":"CancelDepositDisabled","type":"error"},{"inputs":[],"name":"CancelWithdrawDisabled","type":"error"},{"inputs":[],"name":"DepositDisabled","type":"error"},{"inputs":[],"name":"ExceedDepositLimit","type":"error"},{"inputs":[],"name":"FundIsClosed","type":"error"},{"inputs":[],"name":"FundIsNotClosed","type":"error"},{"inputs":[],"name":"FundingLocked","type":"error"},{"inputs":[],"name":"IncorrectCycleIndex","type":"error"},{"inputs":[],"name":"IncorrectCycleStartTimestamp","type":"error"},{"inputs":[],"name":"IncorrectETHAmount","type":"error"},{"inputs":[],"name":"IncorrectVaultAddress","type":"error"},{"inputs":[],"name":"InvalidFeePercentage","type":"error"},{"inputs":[],"name":"InvalidFundValue","type":"error"},{"inputs":[],"name":"InvalidInitialPrice","type":"error"},{"inputs":[],"name":"NoDeposits","type":"error"},{"inputs":[],"name":"NotAcceptingETH","type":"error"},{"inputs":[],"name":"NotEnoughAssets","type":"error"},{"inputs":[],"name":"NotEnoughDeposits","type":"error"},{"inputs":[],"name":"NotEnoughWithdrawals","type":"error"},{"inputs":[],"name":"OnlyAvailableToAdmins","type":"error"},{"inputs":[],"name":"OnlyAvailableToAuditors","type":"error"},{"inputs":[],"name":"ReceiverDoNotHasNFT","type":"error"},{"inputs":[],"name":"WithdrawDisabled","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"}],"name":"ClaimOwedAssets","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"ClaimOwedShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"}],"name":"ConvertToAssets","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"ConvertToShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"}],"name":"DepositCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"depositLimit","type":"uint256"}],"name":"DepositLimitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"}],"name":"DepositRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"address","name":"teaVaultV2","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"DepositToVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"bool","name":"disableChecks","type":"bool"}],"name":"DisableNFTChecks","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"fundValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceDenominator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositLimit","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"lockTimestamp","type":"uint64"},{"indexed":false,"internalType":"bool","name":"fundClosed","type":"bool"},{"indexed":false,"internalType":"uint256","name":"platformFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"managerFee","type":"uint256"}],"name":"EnterNextCycle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"components":[{"internalType":"address","name":"platformVault","type":"address"},{"internalType":"address","name":"managerVault","type":"address"},{"internalType":"uint24","name":"platformEntryFee","type":"uint24"},{"internalType":"uint24","name":"managerEntryFee","type":"uint24"},{"internalType":"uint24","name":"platformExitFee","type":"uint24"},{"internalType":"uint24","name":"managerExitFee","type":"uint24"},{"internalType":"uint24","name":"platformPerformanceFee","type":"uint24"},{"internalType":"uint24","name":"managerPerformanceFee","type":"uint24"},{"internalType":"uint24","name":"platformManagementFee","type":"uint24"},{"internalType":"uint24","name":"managerManagementFee","type":"uint24"}],"indexed":false,"internalType":"struct IHighTableVault.FeeConfig","name":"feeConfig","type":"tuple"}],"name":"FeeConfigChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"priceNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceDenominator","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"FundInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"uint64","name":"lockTimestamp","type":"uint64"}],"name":"FundLockingTimestampUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"bool","name":"disableDepositing","type":"bool"},{"indexed":false,"internalType":"bool","name":"disableWithdrawing","type":"bool"},{"indexed":false,"internalType":"bool","name":"disableCancelDepositing","type":"bool"},{"indexed":false,"internalType":"bool","name":"disableCancelWithdrawing","type":"bool"}],"name":"FundingChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"address[]","name":"nfts","type":"address[]"}],"name":"NFTEnabled","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":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"address","name":"teaVaultV2","type":"address"}],"name":"UpdateTeaVaultV2","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":false,"internalType":"address","name":"teaVaultV2","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"WithdrawFromVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"WithdrawalCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"WithdrawalRequested","type":"event"},{"inputs":[],"name":"AUDITOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECONDS_IN_A_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"assetTokenAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"cancelDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"},{"internalType":"address payable","name":"_receiver","type":"address"}],"name":"cancelDepositETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"cancelWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"claimAndRequestDeposit","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"claimAndRequestDepositETH","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"name":"claimAndRequestWithdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"claimOwedAssets","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_receiver","type":"address"}],"name":"claimOwedAssetsETH","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"claimOwedFunds","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_receiver","type":"address"}],"name":"claimOwedFundsETH","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"claimOwedShares","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"name":"closePosition","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"closePositionAndClaim","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_receiver","type":"address"}],"name":"closePositionAndClaimETH","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"closePrice","outputs":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"cycleState","outputs":[{"internalType":"uint128","name":"totalFundValue","type":"uint128"},{"internalType":"uint128","name":"fundValueAfterRequests","type":"uint128"},{"internalType":"uint128","name":"requestedDeposits","type":"uint128"},{"internalType":"uint128","name":"convertedDeposits","type":"uint128"},{"internalType":"uint128","name":"requestedWithdrawals","type":"uint128"},{"internalType":"uint128","name":"convertedWithdrawals","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"depositToVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"depositToVaultETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_cycleIndex","type":"uint32"},{"internalType":"uint128","name":"_fundValue","type":"uint128"},{"internalType":"uint128","name":"_depositLimit","type":"uint128"},{"internalType":"uint128","name":"_withdrawAmount","type":"uint128"},{"internalType":"uint64","name":"_cycleStartTimestamp","type":"uint64"},{"internalType":"uint64","name":"_fundingLockTimestamp","type":"uint64"},{"internalType":"bool","name":"_closeFund","type":"bool"}],"name":"enterNextCycle","outputs":[{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"managerFee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_cycleIndex","type":"uint32"},{"internalType":"uint128","name":"_fundValue","type":"uint128"},{"internalType":"uint128","name":"_depositLimit","type":"uint128"},{"internalType":"uint128","name":"_withdrawAmount","type":"uint128"},{"internalType":"uint64","name":"_cycleStartTimestamp","type":"uint64"},{"internalType":"uint64","name":"_fundingLockTimestamp","type":"uint64"},{"internalType":"bool","name":"_closeFund","type":"bool"}],"name":"enterNextCycleETH","outputs":[{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"managerFee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeConfig","outputs":[{"internalType":"address","name":"platformVault","type":"address"},{"internalType":"address","name":"managerVault","type":"address"},{"internalType":"uint24","name":"platformEntryFee","type":"uint24"},{"internalType":"uint24","name":"managerEntryFee","type":"uint24"},{"internalType":"uint24","name":"platformExitFee","type":"uint24"},{"internalType":"uint24","name":"managerExitFee","type":"uint24"},{"internalType":"uint24","name":"platformPerformanceFee","type":"uint24"},{"internalType":"uint24","name":"managerPerformanceFee","type":"uint24"},{"internalType":"uint24","name":"platformManagementFee","type":"uint24"},{"internalType":"uint24","name":"managerManagementFee","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fundConfig","outputs":[{"internalType":"contract ITeaVaultV2","name":"teaVaultV2","type":"address"},{"internalType":"bool","name":"disableNFTChecks","type":"bool"},{"internalType":"bool","name":"disableDepositing","type":"bool"},{"internalType":"bool","name":"disableWithdrawing","type":"bool"},{"internalType":"bool","name":"disableCancelDepositing","type":"bool"},{"internalType":"bool","name":"disableCancelWithdrawing","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalState","outputs":[{"internalType":"uint128","name":"depositLimit","type":"uint128"},{"internalType":"uint128","name":"lockedAssets","type":"uint128"},{"internalType":"uint32","name":"cycleIndex","type":"uint32"},{"internalType":"uint64","name":"cycleStartTimestamp","type":"uint64"},{"internalType":"uint64","name":"fundingLockTimestamp","type":"uint64"},{"internalType":"bool","name":"fundClosed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialPrice","outputs":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftEnabled","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"_fundValue","type":"uint128"},{"internalType":"uint64","name":"_timestamp","type":"uint64"}],"name":"previewNextCycle","outputs":[{"internalType":"uint256","name":"withdrawAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"requestDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"requestDepositETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"name":"requestWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"requestedFunds","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_depositLimit","type":"uint128"}],"name":"setDepositLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_disableDepositing","type":"bool"},{"internalType":"bool","name":"_disableWithdrawing","type":"bool"},{"internalType":"bool","name":"_disableCancelDepositing","type":"bool"},{"internalType":"bool","name":"_disableCancelWithdrawing","type":"bool"}],"name":"setDisableFunding","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_checks","type":"bool"}],"name":"setDisableNFTChecks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_nfts","type":"address[]"}],"name":"setEnabledNFTs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"platformVault","type":"address"},{"internalType":"address","name":"managerVault","type":"address"},{"internalType":"uint24","name":"platformEntryFee","type":"uint24"},{"internalType":"uint24","name":"managerEntryFee","type":"uint24"},{"internalType":"uint24","name":"platformExitFee","type":"uint24"},{"internalType":"uint24","name":"managerExitFee","type":"uint24"},{"internalType":"uint24","name":"platformPerformanceFee","type":"uint24"},{"internalType":"uint24","name":"managerPerformanceFee","type":"uint24"},{"internalType":"uint24","name":"platformManagementFee","type":"uint24"},{"internalType":"uint24","name":"managerManagementFee","type":"uint24"}],"internalType":"struct IHighTableVault.FeeConfig","name":"_feeConfig","type":"tuple"}],"name":"setFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_fundLockingTimestamp","type":"uint64"}],"name":"setFundLockingTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_teaVaultV2","type":"address"}],"name":"setTeaVaultV2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userState","outputs":[{"internalType":"uint128","name":"requestedDeposits","type":"uint128"},{"internalType":"uint128","name":"owedShares","type":"uint128"},{"internalType":"uint128","name":"requestedWithdrawals","type":"uint128"},{"internalType":"uint128","name":"owedAssets","type":"uint128"},{"internalType":"uint32","name":"requestCycleIndex","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdrawFromVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdrawFromVaultETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]