编译器
0.8.17+commit.8df45f5f
文件 1 的 11:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 11: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;
}
}
文件 3 的 11: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;
unchecked {
_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 {}
}
文件 4 的 11: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);
}
文件 5 的 11: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);
}
文件 6 的 11:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 7 的 11:RealWorldAssetReceipt.sol
pragma solidity = 0.8.17;
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
abstract contract RealWorldAssetReceipt is ERC20, ReentrancyGuard {
using SafeERC20 for IERC20;
IERC20 public immutable usdt;
IERC20 public immutable receipt;
address private constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
uint public totalAmountListed;
uint public totalListings;
uint public totalDelisted;
bool internal _inbound;
struct User {
uint amountListed;
uint[] listingIds;
uint[] purchasedIds;
}
struct Listing {
uint listingId;
address seller;
address buyer;
uint listedAt;
uint purchasedAt;
uint delistedAt;
uint amount;
uint cost;
}
mapping(address => User) public _users;
mapping(uint => Listing) public _listings;
event Listed(address indexed seller, uint indexed listingId, uint amount, uint cost);
event Delisted(address indexed seller, uint indexed listingId);
event PriceChanged(uint indexed oldListingId, uint indexed newListingId, uint newCost);
event Purchased(address indexed buyer, uint indexed listingId);
modifier onlyActiveListing(uint _listingId) {
require(_listingId < totalListings, "RealWorldAssetReceipt: Listing does not exist");
require(_listings[_listingId].purchasedAt == 0, "RealWorldAssetReceipt: Listing has already been purchased");
require(_listings[_listingId].delistedAt == 0, "RealWorldAssetReceipt: Listing has already been delisted");
_;
}
modifier onlyActivePool() {
require(_isPoolActive(), "RealWorldAssetReceipt: OTC has closed");
_;
}
constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {
usdt = IERC20(USDT);
receipt = IERC20(address(this));
}
function decimals() public pure override returns (uint8) {
return 6;
}
function list(uint _amount, uint _cost) external nonReentrant onlyActivePool {
require(_amount <= balanceOf(_msgSender()), "RealWorldAssetReceipt: Insufficient balance");
require(_amount <= allowance(_msgSender(), address(this)), "RealWorldAssetReceipt: Insufficient allowance");
uint listingId = _list(_amount, _cost);
totalAmountListed += _amount;
_inbound = true;
receipt.safeTransferFrom(_msgSender(), address(this), _amount);
_inbound = false;
emit Listed(_msgSender(), listingId, _amount, _cost);
}
function delist(uint _listingId) external nonReentrant onlyActiveListing(_listingId) onlyActivePool {
uint amount = _delist(_listingId);
totalAmountListed -= amount;
receipt.safeTransfer(_msgSender(), amount);
emit Delisted(_msgSender(), _listingId);
}
function changePrice(uint _listingId, uint _newCost) external nonReentrant onlyActiveListing(_listingId) onlyActivePool {
require(0 < _newCost, "RealWorldAssetReceipt: _cost must be greater than 0");
uint amount = _delist(_listingId);
uint newListingId = _list(amount, _newCost);
emit PriceChanged(_listingId, newListingId, _newCost);
}
function purchase(uint _listingId) external nonReentrant onlyActiveListing(_listingId) onlyActivePool {
Listing storage listing = _listings[_listingId];
require(listing.seller != _msgSender(), "RealWorldAssetReceipt: You cannot purchase your own listing");
require(listing.cost <= usdt.balanceOf(_msgSender()), "RealWorldAssetReceipt: Insufficient USDT balance");
require(listing.cost <= usdt.allowance(_msgSender(), address(this)), "RealWorldAssetReceipt: Insufficient USDT allowance");
listing.purchasedAt = block.timestamp;
listing.buyer = _msgSender();
_users[_msgSender()].purchasedIds.push(_listingId);
_users[listing.seller].amountListed -= listing.amount;
totalAmountListed -= listing.amount;
usdt.safeTransferFrom(_msgSender(), listing.seller, listing.cost);
receipt.safeTransfer(_msgSender(), listing.amount);
emit Purchased(_msgSender(), _listingId);
}
function getUserAmountListed(address _user) external view returns (uint) {
require(_user != address(0), "RealWorldAssetReceipt: _user cannot equal the zero address");
return _getUserAmountListed(_user);
}
function getUserTotalListings(address _user) public view returns (uint) {
require(_user != address(0), "RealWorldAssetReceipt: _user cannot equal the zero address");
return _users[_user].listingIds.length;
}
function getUserTotalPurchases(address _user) public view returns (uint) {
require(_user != address(0), "RealWorldAssetReceipt: _user cannot equal the zero address");
return _users[_user].purchasedIds.length;
}
function getListings(uint _startIndex, uint _endIndex) external view returns (Listing[] memory listings) {
_validateIndexes(_startIndex, _endIndex, totalListings);
listings = new Listing[](_endIndex - _startIndex + 1);
uint listIndex;
for (uint index = _startIndex; index <= _endIndex; index++) {
listings[listIndex] = _listings[index];
listIndex++;
}
return listings;
}
function getUserListings(address _user, uint _startIndex, uint _endIndex) external view returns (Listing[] memory listings) {
uint total = getUserTotalListings(_user);
_validateIndexes(_startIndex, _endIndex, total);
listings = new Listing[](_endIndex - _startIndex + 1);
uint listIndex;
for (uint index = _startIndex; index <= _endIndex; index++) {
listings[listIndex] = _listings[_users[_user].listingIds[index]];
listIndex++;
}
return listings;
}
function getUserPurchases(address _user, uint _startIndex, uint _endIndex) external view returns (Listing[] memory listings) {
uint total = getUserTotalPurchases(_user);
_validateIndexes(_startIndex, _endIndex, total);
listings = new Listing[](_endIndex - _startIndex + 1);
uint listIndex;
for (uint index = _startIndex; index <= _endIndex; index++) {
listings[listIndex] = _listings[_users[_user].purchasedIds[index]];
listIndex++;
}
return listings;
}
function _validateIndexes(uint _startIndex, uint _endIndex, uint _total) private pure {
require(_startIndex <= _endIndex, "RealWorldAssetReceipt: Start index must be less than or equal to end index");
require(_startIndex < _total, "RealWorldAssetReceipt: Invalid start index");
require(_endIndex < _total, "RealWorldAssetReceipt: Invalid end index");
}
function _getUserAmountListed(address _user) internal view returns (uint) {
return _users[_user].amountListed;
}
function _clearUserAmountListed(address _user) internal {
_users[_user].amountListed = 0;
}
function _isPoolActive() internal view virtual returns (bool);
function _list(uint _amount, uint _cost) private returns (uint) {
require(0 < _amount, "RealWorldAssetReceipt: _amount must be greater than 0");
require(0 < _cost, "RealWorldAssetReceipt: _cost must be greater than 0");
User storage user = _users[_msgSender()];
uint listingId = totalListings;
_listings[listingId] = Listing(listingId, _msgSender(), address(0), block.timestamp, 0, 0, _amount, _cost);
user.amountListed += _amount;
user.listingIds.push(listingId);
totalListings++;
return listingId;
}
function _delist(uint _listingId) private returns (uint) {
Listing storage listing = _listings[_listingId];
require(listing.seller == _msgSender(), "RealWorldAssetReceipt: Only the seller can delist their listing");
listing.delistedAt = block.timestamp;
User storage user = _users[_msgSender()];
user.amountListed -= listing.amount;
totalDelisted++;
return listing.amount;
}
}
文件 8 的 11:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
}
文件 9 的 11: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");
}
}
}
文件 10 的 11:StablzIncentiveCannavestPool.sol
pragma solidity = 0.8.17;
import "@openzeppelin/contracts/access/Ownable.sol";
import "contracts/pools/common/RealWorldAssetReceipt.sol";
contract StablzIncentiveCannavestPool is RealWorldAssetReceipt, Ownable {
using SafeERC20 for IERC20;
address public rwaHandler;
IERC20 public stablz;
address private constant STABLZ = 0xA4Eb9C64eC359D093eAc7B65F51Ef933D6e5F7cd;
uint private constant REWARD_FACTOR_ACCURACY = 1_000_000_000_000 ether;
uint private constant LOCK_UP_PERIOD = 365 days;
uint private constant INCENTIVE_PERIOD = 30 days;
uint private constant INCENTIVE_VESTING_PERIOD = 30 days;
uint private constant MAX_CLAIM_SIZE = 100;
uint private constant ONE_USDT = 10 ** 6;
uint private constant MAX_AMOUNT = 5_000_000 * ONE_USDT;
uint private constant INITIAL_STABLZ_REWARDS = 5_000_000 ether;
uint public startedAt;
uint public incentivesEndAt;
bool public isDepositingEnabled;
uint public finalAmount;
uint public finalSupply;
uint public currentRewardFactor;
uint public allTimeRewards;
uint public allTimeRewardsClaimed;
uint public allTimeCirculatingSupplyAtDistribution;
uint public totalStablzAllocated;
uint public totalStablzClaimed;
uint public totalVestments;
struct Reward {
uint factor;
uint held;
}
struct Vestment {
uint vestmentId;
address user;
uint amount;
uint withdrawn;
uint startDate;
}
mapping(uint => Vestment) public vestments;
mapping(address => uint[]) private _userVestments;
mapping(address => Reward) private _rewards;
event Started();
event Ended(uint finalAmount, uint finalSupply);
event RealWorldAssetHandlerUpdated(address rwaHandler);
event DepositingEnabled();
event DepositingDisabled();
event Deposit(address indexed user, uint amount);
event Withdraw(address indexed user, uint expected, uint actual);
event Claimed(address indexed user, uint rewards);
event ClaimedIncentive(address indexed user, uint rewards);
event Distributed(uint rewards, uint circulatingSupply);
event Clawback(uint unallocated);
modifier onlyRWAHandler() {
require(_msgSender() == rwaHandler, "StablzIncentiveCannavestPool: Only the real world asset handler can call this function");
_;
}
constructor(address _rwaHandler) RealWorldAssetReceipt("STABLZ-CANNAVEST", "CANNAVEST") {
require(_rwaHandler != address(0), "StablzIncentiveCannavestPool: _rwaHandler cannot be the zero address");
rwaHandler = _rwaHandler;
stablz = IERC20(STABLZ);
}
function start() external onlyOwner {
require(startedAt == 0, "StablzIncentiveCannavestPool: Already started");
startedAt = block.timestamp;
incentivesEndAt = startedAt + INCENTIVE_PERIOD;
isDepositingEnabled = true;
uint stablzBalance = stablz.balanceOf(address(this));
if (stablzBalance < INITIAL_STABLZ_REWARDS) {
stablz.safeTransferFrom(_msgSender(), address(this), INITIAL_STABLZ_REWARDS - stablzBalance);
} else if (stablzBalance > INITIAL_STABLZ_REWARDS) {
stablz.safeTransfer(_msgSender(), stablzBalance - INITIAL_STABLZ_REWARDS);
}
emit Started();
}
function end(uint _amount) external onlyOwner {
require(block.timestamp > getEndDate(), "StablzIncentiveCannavestPool: You cannot end before the end date");
require(!hasEnded(), "StablzIncentiveCannavestPool: Already ended");
require(0 < _amount && _amount <= totalSupply(), "StablzIncentiveCannavestPool: _amount must be greater than zero and less than or equal to the total staked");
isDepositingEnabled = false;
finalAmount = _amount;
finalSupply = totalSupply();
usdt.safeTransferFrom(_msgSender(), address(this), _amount);
emit Ended(finalAmount, finalSupply);
}
function updateRealWorldAssetHandler(address _rwaHandler) external onlyOwner {
require(_rwaHandler != address(0), "StablzIncentiveCannavestPool: _rwaHandler cannot be the zero address");
rwaHandler = _rwaHandler;
emit RealWorldAssetHandlerUpdated(_rwaHandler);
}
function enableDepositing() external onlyOwner {
require(startedAt > 0, "StablzIncentiveCannavestPool: Pool not started yet");
require(_isPoolActive(), "StablzIncentiveCannavestPool: Pool has already stopped");
require(!isDepositingEnabled, "StablzIncentiveCannavestPool: Depositing is already enabled");
isDepositingEnabled = true;
emit DepositingEnabled();
}
function disableDepositing() external onlyOwner {
require(isDepositingEnabled, "StablzIncentiveCannavestPool: Depositing is already disabled");
isDepositingEnabled = false;
emit DepositingDisabled();
}
function deposit(uint _amount) external nonReentrant {
require(_isPoolActive(), "StablzIncentiveCannavestPool: Depositing is not allowed because the pool has ended");
require(isDepositingEnabled, "StablzIncentiveCannavestPool: Depositing is not allowed at this time");
require(ONE_USDT <= _amount, "StablzIncentiveCannavestPool: _amount must be greater than or equal to 1 USDT");
require(_amount <= usdt.balanceOf(_msgSender()), "StablzIncentiveCannavestPool: Insufficient USDT balance");
require(_amount <= usdt.allowance(_msgSender(), address(this)), "StablzIncentiveCannavestPool: Insufficient USDT allowance");
require(totalSupply() + _amount <= MAX_AMOUNT, "StablzIncentiveCannavestPool: Max amount reached");
if (block.timestamp < incentivesEndAt) {
_allocateIncentiveRewards(_amount);
}
_mint(_msgSender(), _amount);
usdt.safeTransferFrom(_msgSender(), rwaHandler, _amount);
emit Deposit(_msgSender(), _amount);
}
function withdraw() external nonReentrant {
require(hasEnded(), "StablzIncentiveCannavestPool: You can only withdraw once the pool has ended");
uint balance = balanceOf(_msgSender());
uint otc = _getUserAmountListed(_msgSender());
require(0 < balance + otc, "StablzIncentiveCannavestPool: Receipt balance must be greater than zero");
uint amount = _calculateFinalAmount(_msgSender());
if (0 < balance) {
_burn(_msgSender(), balance);
}
if (0 < otc) {
_clearUserAmountListed(_msgSender());
_burn(address(this), otc);
}
usdt.safeTransfer(_msgSender(), amount);
emit Withdraw(_msgSender(), balance, amount);
}
function claimRewards() external nonReentrant {
_mergeRewards(_msgSender());
uint held = _getHeldRewards(_msgSender());
require(0 < held, "StablzIncentiveCannavestPool: No rewards available to claim");
_rewards[_msgSender()].held = 0;
allTimeRewardsClaimed += held;
usdt.safeTransfer(_msgSender(), held);
emit Claimed(_msgSender(), held);
}
function claimStablzRewards(uint _vestmentId) external nonReentrant {
uint incentive = _claimStablzRewards(_vestmentId);
totalStablzClaimed += incentive;
stablz.safeTransfer(_msgSender(), incentive);
emit ClaimedIncentive(_msgSender(), incentive);
}
function claimMultipleStablzRewards(uint[] calldata _vestmentIds) external nonReentrant {
require(_vestmentIds.length <= MAX_CLAIM_SIZE, "StablzIncentiveCannavestPool: _vestmentIds can only contain up to 100 vestment IDs");
uint incentive;
for (uint i; i < _vestmentIds.length; i++) {
incentive += _claimStablzRewards(_vestmentIds[i]);
}
totalStablzClaimed += incentive;
stablz.safeTransfer(_msgSender(), incentive);
emit ClaimedIncentive(_msgSender(), incentive);
}
function distribute(uint _amount) external onlyRWAHandler {
require(!hasEnded(), "StablzIncentiveCannavestPool: Distributions are disabled because the pool has ended");
uint circulatingSupply = _getCirculatingSupply();
require(ONE_USDT <= circulatingSupply, "StablzIncentiveCannavestPool: Total staked must be greater than 1 receipt token");
require(ONE_USDT <= _amount, "StablzIncentiveCannavestPool: _amount must be greater than or equal to 1 USDT");
require(_amount <= usdt.balanceOf(rwaHandler), "StablzIncentiveCannavestPool: Insufficient balance");
require(_amount <= usdt.allowance(rwaHandler, address(this)), "StablzIncentiveCannavestPool: Insufficient allowance");
allTimeCirculatingSupplyAtDistribution += circulatingSupply;
allTimeRewards += _amount;
currentRewardFactor += REWARD_FACTOR_ACCURACY * _amount / circulatingSupply;
usdt.safeTransferFrom(rwaHandler, address(this), _amount);
emit Distributed(_amount, circulatingSupply);
}
function clawback() external onlyOwner {
require(incentivesEndAt <= block.timestamp, "StablzIncentiveCannavestPool: Clawback can only occur after the incentive period");
uint unallocated = getUnallocatedStablz();
require(0 < unallocated, "StablzIncentiveCannavestPool: Nothing to clawback");
stablz.safeTransfer(owner(), unallocated);
emit Clawback(unallocated);
}
function getUnallocatedStablz() public view returns (uint) {
uint stablzBalance = stablz.balanceOf(address(this));
uint inUse = totalStablzAllocated - totalStablzClaimed;
return stablzBalance - inUse;
}
function getEndDate() public view returns (uint) {
require(startedAt > 0, "StablzIncentiveCannavestPool: Pool has not started yet");
return startedAt + LOCK_UP_PERIOD;
}
function getReward(address _user) external view returns (uint) {
require(_user != address(0), "StablzIncentiveCannavestPool: _user cannot equal the zero address");
return _getHeldRewards(_user) + _getCalculatedRewards(_user);
}
function calculateFinalAmount(address _user) external view returns (uint) {
require(hasEnded(), "StablzIncentiveCannavestPool: The pool has not ended yet");
require(_user != address(0), "StablzIncentiveCannavestPool: _user cannot equal the zero address");
return _calculateFinalAmount(_user);
}
function hasEnded() public view returns (bool) {
return finalAmount > 0;
}
function getTotalUserVestments(address _user) public view returns (uint) {
require(_user != address(0), "StablzIncentiveCannavestPool: _user cannot equal the zero address");
return _userVestments[_user].length;
}
function getUserVestments(address _user, uint _startIndex, uint _endIndex) external view returns (Vestment[] memory list) {
uint total = getTotalUserVestments(_user);
require(_startIndex <= _endIndex, "StablzIncentiveCannavestPool: Start index must be less than or equal to end index");
require(_startIndex < total, "StablzIncentiveCannavestPool: Invalid start index");
require(_endIndex < total, "StablzIncentiveCannavestPool: Invalid end index");
list = new Vestment[](_endIndex - _startIndex + 1);
uint listIndex;
for (uint index = _startIndex; index <= _endIndex; index++) {
list[listIndex] = vestments[_userVestments[_user][index]];
listIndex++;
}
return list;
}
function getVestments(uint _startIndex, uint _endIndex) external view returns (Vestment[] memory list) {
require(_startIndex <= _endIndex, "StablzIncentiveCannavestPool: Start index must be less than or equal to end index");
require(_startIndex < totalVestments, "StablzIncentiveCannavestPool: Invalid start index");
require(_endIndex < totalVestments, "StablzIncentiveCannavestPool: Invalid end index");
list = new Vestment[](_endIndex - _startIndex + 1);
uint listIndex;
for (uint vestmentId = _startIndex; vestmentId <= _endIndex; vestmentId++) {
list[listIndex] = vestments[vestmentId];
listIndex++;
}
return list;
}
function _allocateIncentiveRewards(uint _amount) private {
uint rewards = _amount * 10 ** 12;
require(rewards <= getUnallocatedStablz(), "StablzIncentiveCannavestPool: There aren't enough stablz rewards available");
totalStablzAllocated += rewards;
uint vestmentId = totalVestments;
vestments[vestmentId] = Vestment(vestmentId, _msgSender(), rewards, 0, block.timestamp);
_userVestments[_msgSender()].push(vestmentId);
totalVestments++;
}
function _claimStablzRewards(uint _vestmentId) private returns (uint amount) {
require(_vestmentId < totalVestments, "StablzIncentiveCannavestPool: _vestmentId does not exist");
Vestment storage vestment = vestments[_vestmentId];
require(vestment.user == _msgSender(), "StablzIncentiveCannavestPool: Vestment does not belong to you");
require(vestment.withdrawn < vestment.amount, "StablzIncentiveCannavestPool: Already withdrawn full amount for a specific vestment");
uint endDate = vestment.startDate + INCENTIVE_VESTING_PERIOD;
if (block.timestamp >= endDate) {
amount = vestment.amount - vestment.withdrawn;
} else {
uint timeDifference = block.timestamp - vestment.startDate;
amount = (vestment.amount * timeDifference / INCENTIVE_VESTING_PERIOD) - vestment.withdrawn;
}
vestment.withdrawn += amount;
return amount;
}
function _beforeTokenTransfer(
address _from,
address _to,
uint _amount
) internal override {
super._beforeTokenTransfer(_from, _to, _amount);
if (_inbound) {
require(incentivesEndAt <= block.timestamp, "StablzIncentiveCannavestPool: Unable to list during the incentive period");
}
require(0 < _amount, "StablzIncentiveCannavestPool: _amount must be greater than zero");
require(
_from == address(0) ||
_from == address(this) ||
_to == address(0) ||
(_to == address(this) && _inbound),
"StablzIncentiveCannavestPool: Receipt token is only transferrable via OTC, depositing, and withdrawing"
);
if (_from != address(0) && _from != address(this)) {
_mergeRewards(_from);
}
if (_to != address(0) && _to != address(this)) {
_mergeRewards(_to);
}
}
function _calculateFinalAmount(address _user) private view returns (uint) {
return finalAmount * _getTotalBalance(_user) / finalSupply;
}
function _getTotalBalance(address _user) private view returns (uint) {
return balanceOf(_user) + _getUserAmountListed(_user);
}
function _getCirculatingSupply() private view returns (uint) {
return totalSupply() - totalAmountListed;
}
function _mergeRewards(address _user) private {
_holdCalculatedRewards(_user);
_rewards[_user].factor = currentRewardFactor;
}
function _holdCalculatedRewards(address _user) private {
uint calculatedReward = _getCalculatedRewards(_user);
if (calculatedReward > 0) {
_rewards[_user].held += calculatedReward;
}
}
function _getHeldRewards(address _user) private view returns (uint) {
return _rewards[_user].held;
}
function _getCalculatedRewards(address _user) private view returns (uint) {
uint balance = balanceOf(_user);
return balance * (currentRewardFactor - _rewards[_user].factor) / REWARD_FACTOR_ACCURACY;
}
function _isPoolActive() internal view override returns (bool) {
return block.timestamp <= getEndDate() && !hasEnded();
}
}
文件 11 的 11: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/pools/rwa/StablzIncentiveCannavestPool.sol": "StablzIncentiveCannavestPool"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_rwaHandler","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"}],"name":"ClaimedIncentive","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"unallocated","type":"uint256"}],"name":"Clawback","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"uint256","name":"listingId","type":"uint256"}],"name":"Delisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[],"name":"DepositingDisabled","type":"event"},{"anonymous":false,"inputs":[],"name":"DepositingEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"circulatingSupply","type":"uint256"}],"name":"Distributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"finalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"finalSupply","type":"uint256"}],"name":"Ended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"uint256","name":"listingId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cost","type":"uint256"}],"name":"Listed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldListingId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newListingId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCost","type":"uint256"}],"name":"PriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"uint256","name":"listingId","type":"uint256"}],"name":"Purchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rwaHandler","type":"address"}],"name":"RealWorldAssetHandlerUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"Started","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":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"expected","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"actual","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_listings","outputs":[{"internalType":"uint256","name":"listingId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"listedAt","type":"uint256"},{"internalType":"uint256","name":"purchasedAt","type":"uint256"},{"internalType":"uint256","name":"delistedAt","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"cost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_users","outputs":[{"internalType":"uint256","name":"amountListed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allTimeCirculatingSupplyAtDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allTimeRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allTimeRewardsClaimed","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":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"calculateFinalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listingId","type":"uint256"},{"internalType":"uint256","name":"_newCost","type":"uint256"}],"name":"changePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_vestmentIds","type":"uint256[]"}],"name":"claimMultipleStablzRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vestmentId","type":"uint256"}],"name":"claimStablzRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clawback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentRewardFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","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":"_listingId","type":"uint256"}],"name":"delist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableDepositing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableDepositing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"end","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEndDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_endIndex","type":"uint256"}],"name":"getListings","outputs":[{"components":[{"internalType":"uint256","name":"listingId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"listedAt","type":"uint256"},{"internalType":"uint256","name":"purchasedAt","type":"uint256"},{"internalType":"uint256","name":"delistedAt","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"cost","type":"uint256"}],"internalType":"struct RealWorldAssetReceipt.Listing[]","name":"listings","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getTotalUserVestments","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnallocatedStablz","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserAmountListed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_endIndex","type":"uint256"}],"name":"getUserListings","outputs":[{"components":[{"internalType":"uint256","name":"listingId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"listedAt","type":"uint256"},{"internalType":"uint256","name":"purchasedAt","type":"uint256"},{"internalType":"uint256","name":"delistedAt","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"cost","type":"uint256"}],"internalType":"struct RealWorldAssetReceipt.Listing[]","name":"listings","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_endIndex","type":"uint256"}],"name":"getUserPurchases","outputs":[{"components":[{"internalType":"uint256","name":"listingId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"listedAt","type":"uint256"},{"internalType":"uint256","name":"purchasedAt","type":"uint256"},{"internalType":"uint256","name":"delistedAt","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"cost","type":"uint256"}],"internalType":"struct RealWorldAssetReceipt.Listing[]","name":"listings","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserTotalListings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserTotalPurchases","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_endIndex","type":"uint256"}],"name":"getUserVestments","outputs":[{"components":[{"internalType":"uint256","name":"vestmentId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"withdrawn","type":"uint256"},{"internalType":"uint256","name":"startDate","type":"uint256"}],"internalType":"struct StablzIncentiveCannavestPool.Vestment[]","name":"list","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_endIndex","type":"uint256"}],"name":"getVestments","outputs":[{"components":[{"internalType":"uint256","name":"vestmentId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"withdrawn","type":"uint256"},{"internalType":"uint256","name":"startDate","type":"uint256"}],"internalType":"struct StablzIncentiveCannavestPool.Vestment[]","name":"list","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasEnded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentivesEndAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"isDepositingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"list","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listingId","type":"uint256"}],"name":"purchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"receipt","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rwaHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stablz","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"start","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAmountListed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDelisted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalListings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStablzAllocated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStablzClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalVestments","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":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rwaHandler","type":"address"}],"name":"updateRealWorldAssetHandler","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdt","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"vestments","outputs":[{"internalType":"uint256","name":"vestmentId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"withdrawn","type":"uint256"},{"internalType":"uint256","name":"startDate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]