STO

How to Distribute your Security Token

After this tutorial, you'll be able to raise funds via a "Tiered Security Token Offering" or TieredSTO in short. The STO allows investors to participate in one or more tiers of investments, each with its predetermined price, volume, and discounts.

Similar to previous tutorials, load any existing STOs that might be associated with the security token:

useEffect(() => {
  async function getStos() {
    const stos = (await token.issuance.offerings.getStos()).filter(
      sto => sto.stoType === 'Tiered'
    );
    return {
      stos,
    };
  }
  // If we haven't loaded stos, yet.
  if (token && stos === null) {
    asyncAction(
      dispatch,
      () => getStos(),
      'Loading Security Token Offerings.'
    );
  }
}, [token, stos]);

Load STOs using token.issuance.offerings.getStos(), which is wrapped in an asyncAction that updates the UI accordingly.

import { BigNumber, Currency } from '@polymathnetwork/sdk';

/**
 * Launch a Tiered STO
 *
 * @param startDate date when the STO should start
 * @param endDate date when the STO should end
 * @param nonAccreditedInvestmentLimit maximum investment for non-accredited investors
 * @param minimumInvestment minimum investment amount
 * @param currencies array of currencies in which the funds will be raised (ETH, POLY, StableCoin)
 * @param raisedFundsWallet wallet address that will receive the funds that are being raised
 * @param unsoldTokensWallet wallet address that will receive unsold tokens when the end date is reached
 * @param stableCoinAddresses array of stable coins that the offering supports
 * @param allowPreIssuance whether to have all tokens issued on STO start. Default behavior is to issue on purchase
 * @param tiers tier information
 * @param tiers[].tokensOnSale amount of tokens to be sold on that tier
 * @param tiers[].price price of each token on that tier
 * @param tiers[].tokensWithDiscount amount of tokens to be sold on that tier at a discount if paid in POLY (must be less than tokensOnSale, defaults to 0)
 * @param tiers[].discountedPrice price of discounted tokens on that tier (defaults to 0)
 */
 
const userAddress = '0x4f73h....dh47d';

await (
  await token.issuance.offerings.launchTieredSto({
    startDate: new Date(2020, 5, 6),
    endDate: new Date(2020, 7, 8),
    nonAccreditedInvestmentLimit: new BigNumber(10),
    minimumInvestment: new BigNumber(5),
    currencies: [Currency.ETH],
    raisedFundsWallet: userAddress,
    unsoldTokensWallet: userAddress,
    allowPreIssuance: true,
    tiers: [
      {
        tokensOnSale: new BigNumber(1000),
        price: new BigNumber(89),
        tokensOnSale: new BigNumber(100),
        price: new BigNumber(45),
      },
    ],
  })
).run()

There are many parameters required to launch an STO. Some are self-explanatory, such as startDate and endDate.

  • nonAccreditedInvestmentLimit is the limit of tokens that non-accredited investors can buy. Investors are non-accredited by default. You can change their accredited status as follows:token.tokenholders.modifyData({tokenholders: [{address, isAccredited: true}]}).

  • raisedFundsWallet is the wallet to receive raised funds. In the example above, we set it to the user's address.

  • allowPreIssuance means that new tokens will be minted as soon as the STO is launched. In that case, any unsold tokens after the STO ends will be transferred to the address specified with the unsoldTokensWallet parameter. If allowPreIssuance is set to false, then tokens will be issued on purchase instead.

  • tiers[] is a list of STO tiers. Each one declares that amount of tokens sold, their price, and whether there are discounted tokens.

In case you need to denominate investments in a non-USD Stable Coin (e.g., a Stable Coin for CAD), you need to pass two additional parameters to launchTieredSto, as well as adding Stable Coins to the supported currencies:

await (
  await token.issuance.offerings.launchTieredSto({
    ...
    currencies: [Currency.ETH, Currency.StableCoin],
    stableCoinAddresses: [
      // CAD stable coin address
      '0xStableCoinAddress'
    ],
    customCurrency: {
      currencySymbol: 'CAD',  // symbol of the chosen currency (USD, CAD, EUR, etc. Default is USD)
      ethOracleAddress: '0xOracleAddress' // address of the oracle that states the price of ETH in the chosen currency
    },
    tiers: [...],
  })
).run()

currencies allows you to specify the asset that will be raised, such as ETH or Stablecoins.

Changing the currency you want to price your raise in is done via currencySymbol.

The protocol converts the specified price to ETH (or the chosen currency for the raise) via price oracles. You must specify the oracle address (e.g., ethOracleAddress above). You can find a list of oracle addresses on Polymath's Github.

Last updated