USDTieredSTO
Introduced in
2.0.0
Contract name
USDTieredSTO.sol
Type
STO Module
Compatible Protocol Version
^3.0.0
How it works
Allows a security token to be issued in return for investment (security token offering) in various currencies (ETH, POLY & a USD stable coin/ stable coin w.r.t denominated currency). The price of tokens is denominated in denominated Currency (Provided by the issuer at the configuration time) and the STO allows multiple tiers with different price points to be defined. Discounts for investments made in POLY can also be defined.
STO can be of two types on the basis of the token distribution, We are facilitating both types (i.e pre-mint & mint on buying) through a single contract but before the start time of the STO issuer has to choose what kind of STO type they want to go for.
Key functionalities (as defined in the Smart Contract)
Initialization
The contract is initialized with all of the parameters needed to set up the STO (tier information, wallet addresses and so on).
Configuration can be considered in 5 separate sections, each of which can be modified anytime between the creation of the USDTieredSTO and the start time of the STO. When the issuer is configuring their STO, they need to provide an array of addresses of stable coins they will accept.
Allow Pre-Minting
This function is a gateway function to allow pre-minting in the STO. It can only be called before the start time of the STO. It will pre mint all tokens (i.e sum of all the tiers) and assigned to STO contract itself.
Revoke Pre-Minting
This function is used to revoke pre-mint type that will lead to burn all pre-minted tokens.
Modify Times
It allows you to modify the start or end time of the STO.
Modify Tiers
This function allows you to modify the details of your STOs tiers. Primarily, it allows you to customize the rates you want to set for each tier, the discount rates per tier for investors using POLY, the total amount of tokens you want to allocate to each tier and the token amount of tokens you want to allocate to investors getting a discount because they are buying with POLY. If preMintAllowed flag is activated then extra tokens will be minted if total tokens in all tiers is greater than the earlier sum otherwise they get burned.
A few things to note:
Firstly, you can only use this function if the STO hasn’t started.
You can’t have 0 tokens allocated to a tier.
The discounted tokens (for investors using Poly) per tier have to be less than or equal to the total tokens per tier
The discount rate (for investors using Poly) per tier needs to be less than or equal to the rate per tier
Modify Addresses
It allows you to modify the addresses used for the STO. This also allows USDTieredSTO to accept multiple Stable Coin addresses instead of just a single stable coin address
Modify Funding
This function is used to modify the type of funding your STO will be accepted i.e Fundraise type (in ETH, POLY, DAI or all).
Modify Limits
It allows you to modify the limits for non-accredited investors and minimum investment (in USD) for the STO.
Tiers
Each tier defines the following attributes:
You can have as many tiers as needed, and each tier will be filled sequentially. If tokensDiscountPoly
is not 0, then the tier has some quota of tokens which are offered at a discounted price (ratePerTierDiscountPoly
) for POLY investments.
N.B.: While theoretically, it’s possible to have a large number of tiers, due to several loops within the contract’s functions there’s a limit to how many should be entered. In practice, it’s unlikely any issuer would have more than 5-7 of them. We’ll force a max of 5 on the dApp.
Oracles
In order to convert between ETH & POLY investments into USD(default denominated currency) / denominated currency (in which the STO is denominated) the STO makes use of pricing oracles. This function checks to see if the fundraise type is equal to the fundraise rates in POLY, ETH and DAI. For example, it checks the rates with the oracle to see if the fundraise type equals the fundraise type in POLY, ETH and/or DAI and then the Oracle returns the results. The function reverts if it doesn’t have the correct funding.
Get Rate
The getRate
function allows a caller to determine the current rate for each funding currency.
NB - this rate varies over time, so there is no guarantee that the returned rate will still be valid on a subsequent transaction (see Buying Tokens for how to mitigate this).
Modify Oracle
This function is used to change the oracle addresses and can only be called by the owner of the ST. By default, Polymath is providing ETH/USD & POLY/USD oracle while using this functionality issuer can use their own deployed oracle respective to the denominated currency.
Note - If Issuer wants to change the denominatedCurrency
then they have to change the rates as well according to the denominated currency. It is advised to call modifyTiers()
just after calling modifyOracles()
from the dApp side. denominatedCurrency
can only be changed before the STO starts.
The issuer is allowed to set the oracle address for either ETH or POLY or allowed to set both. it depends upon its selected fundraise types. When _denominatedCurrencySymbol != bytes32(0)
it means oracle address array length should be equal 2.
If fund raise type is ETH then
_customOracleAddresses = [ETH_oracle_address, 0x0]
.If raise type POLY then
_customOracleAddresses = [0x0, POLY_oracle_address]
.If raise type ETH and POLY both
_customOracleAddresses = [ETH_oracle_address, POLY_oracle_address]
.
Buying Tokens
Tokens can be issued in return for investments made in ETH, POLY or DAI (or generally any USD stable coin). The currencies accepted are configured in the STO via the modifyFunding function.
For each currency type, there are two functions that can be used to make an investment. For example, for ETH we have:
buyWithETH
accepts ETH as an investment currency and will purchase a number of tokens that corresponds to the amount of ETH sent with the function.
While buyWithETHRateLimited
accepts ETH as an investment currency and will purchase a number of tokens that correspond to the amount of ETH sent with the function. However, it will also ensure that at least _minTokens are purchased or otherwise revert and return the invested ETH. This allows the investor to establish a guarantee on a minimum ETH / USD rate and tier point that their purchase is made.
For investments made in POLY or with a stable coin, we have equivalent functions. Before calling this buyWith…
functions though, the investor must have approved a corresponding amount of tokens to the STO address (called approve on the POLY or stable coin contract with the address of the STO contract, and the amount of POLY / stable coin being invested). These functions also take as a parameter the exact amount of tokens being invested.
If STO type is preMint then required tokens are transferred from the STO balance.
Refunds
If funds are sent which can’t be fully invested (for example if a non-accredited investor limit is reached, or the STO has sold all tokens) any uninvested funds are refunded to the investor. This can also happen if the underlying security token only allows tokens with a certain granularity and the sent funds would result in purchasing tokens with a more granular quantity.
Accredited vs. Non-Accredited Investor Limits
Note: The below functions work in a way that controls situations when an investor (accredited or not) is buying tokens from an issuer. For example, when an investor wants to invest in a token, these functions control situations such as if there is a minimum limit of investment that every investor must respect or when a non-accredited investor can’t buy any more tokens due to a non-accredited investor limit. The difference between accredited and non accredited in this situation is that an accredited investor doesn’t have any limit on what they can buy whereas a non accredited investor has a limit (However, accredited may have a minimum amount they have to buy).
Non-accredited Limit
It allows you to change the non-accredited investors' limit.
Finalization
The USDTieredSTO can be finalized at any time. Finalizing the STO will close it to any further investments, and mint (or transfer in the case of preMint
) any remaining unsold tokens to the treasuryWallet specified in modifyAddresses()
.
Note- When the end of the STO is reached the STO will not auto-mint outstanding tokens. The Issuer has to manually call finalize() in order for the unsold tokens to be minted.
Change allows beneficial investments
This function allows the issuer to set the allowed beneficiary to different from the funder. The only input parameter a boolean to allow or disallow beneficial investments.
STO Information (get() functions)
Get Token Sold
This function allows you to check the total number of tokens that have been sold to investors.
Get Tokens Minted
This function allows you to check the total number of tokens that have been minted.
Get Tokens Sold For
This function allows you to check the total number of tokens that have been sold to investors for ETH.
Get Number of Tiers
This function allows you to check the total number of tiers that you have in your STO.
Get tokens minted by tier
This function Return array of minted tokens in each fundraise type for a given tier.
Get tokens sold by tier
This function is used to return the total number of tokens sold in a given tier.
Get STO details
This function returns all of the details for issuers to review their USDTieredSTO.
Get Accredited data
This function returns investor accredited & non-accredited override information
Get USD Tokens
This function returns the USD tokens accepted by the STO.
To know whether STO is running or not
This function returns whether or not the STO is in fundraising mode (open)
Cap Reached
Checks whether the cap has been reached or not.
Get Custom Oracle Address
Use to get the custom oracle addresses set by the issuer itself.
Special considerations / notes
Function with modifiers like withPerm(ADMIN)
or withPerm(OPERATOR)
can be called by the delegates as well who have the ADMIN & OPERATOR
permission assigned.
Last updated
Was this helpful?