Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/beta' into docs/sto-entity
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor Wiebe committed Jan 14, 2020
2 parents 87eddf4 + 87ec5c3 commit 7ac87fa
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 36 deletions.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@polymathnetwork/sdk",
"version": "2.0.1-beta.92",
"version": "2.0.1-beta.93",
"description": "A Javascript SDK for interacting with the Polymath network for the browser and Node.js",
"bugs": {
"url": "https://github.com/PolymathNetwork/polymath-sdk/issues"
Expand Down
76 changes: 61 additions & 15 deletions src/entities/SecurityToken/Issuance/Offerings.ts
Expand Up @@ -24,35 +24,48 @@ interface LaunchTieredStoParams {
currencies: Currency[];
raisedFundsWallet: string;
unsoldTokensWallet: string;
stableCoinAddresses: string[];
stableCoinAddresses?: string[];
customCurrency?: Partial<CustomCurrency>;
allowPreIssuance?: boolean;
}

type OnlyEth =
| [Currency.ETH]
| [Currency.StableCoin, Currency.ETH]
| [Currency.ETH, Currency.StableCoin];
type OnlyPoly =
| [Currency.POLY]
type OnlyEth = [Currency.ETH];
type EthAndStableCoin = [Currency.StableCoin, Currency.ETH] | [Currency.ETH, Currency.StableCoin];
type OnlyPoly = [Currency.POLY];
type PolyAndStableCoin =
| [Currency.StableCoin, Currency.POLY]
| [Currency.POLY, Currency.StableCoin];
type EthAndPoly =
| [Currency.ETH, Currency.POLY]
| [Currency.POLY, Currency.ETH]
type EthAndPoly = [Currency.ETH, Currency.POLY] | [Currency.POLY, Currency.ETH];
type AllCurrencies =
| [Currency.StableCoin, Currency.ETH, Currency.POLY]
| [Currency.ETH, Currency.StableCoin, Currency.POLY]
| [Currency.ETH, Currency.POLY, Currency.StableCoin]
| [Currency.StableCoin, Currency.POLY, Currency.ETH]
| [Currency.POLY, Currency.StableCoin, Currency.ETH]
| [Currency.POLY, Currency.ETH, Currency.StableCoin];

interface LaunchTieredStoNoCustomCurrencyNoStableCoinParams
extends Omit<Omit<LaunchTieredStoParams, 'customCurrency'>, 'stableCoinAddresses'> {
currencies: OnlyEth | OnlyPoly | EthAndPoly;
}

interface LaunchTieredStoNoCustomCurrencyParams
extends Omit<LaunchTieredStoParams, 'customCurrency'> {
currencies: OnlyEth | OnlyPoly | EthAndPoly;
currencies: EthAndStableCoin | PolyAndStableCoin | AllCurrencies;
stableCoinAddresses: string[];
}

interface LaunchTieredStoCustomCurrencyEthParams extends LaunchTieredStoParams {
currencies: OnlyEth | EthAndStableCoin;
customCurrency: {
currencySymbol?: string;
ethOracleAddress: string;
};
stableCoinAddresses: string[];
}

interface LaunchTieredStoCustomCurrencyEthNoStableCoinParams
extends Omit<LaunchTieredStoParams, 'stableCoinAddresses'> {
currencies: OnlyEth;
customCurrency: {
currencySymbol?: string;
Expand All @@ -61,6 +74,16 @@ interface LaunchTieredStoCustomCurrencyEthParams extends LaunchTieredStoParams {
}

interface LaunchTieredStoCustomCurrencyPolyParams extends LaunchTieredStoParams {
currencies: OnlyPoly | PolyAndStableCoin;
customCurrency: {
currencySymbol?: string;
polyOracleAddress: string;
};
stableCoinAddresses: string[];
}

interface LaunchTieredStoCustomCurrencyPolyNoStableCoinParams
extends Omit<LaunchTieredStoParams, 'stableCoinAddresses'> {
currencies: OnlyPoly;
customCurrency: {
currencySymbol?: string;
Expand All @@ -69,6 +92,17 @@ interface LaunchTieredStoCustomCurrencyPolyParams extends LaunchTieredStoParams
}

interface LaunchTieredStoCustomCurrencyBothParams extends LaunchTieredStoParams {
currencies: AllCurrencies;
customCurrency: {
currencySymbol?: string;
ethOracleAddress: string;
polyOracleAddress: string;
};
stableCoinAddresses: string[];
}

interface LaunchTieredStoCustomCurrencyBothNoStableCoinParams
extends Omit<LaunchTieredStoParams, 'stableCoinAddresses'> {
currencies: EthAndPoly;
customCurrency: {
currencySymbol?: string;
Expand All @@ -79,16 +113,28 @@ interface LaunchTieredStoCustomCurrencyBothParams extends LaunchTieredStoParams

interface LaunchTieredStoMethod {
(args: LaunchTieredStoNoCustomCurrencyParams): Promise<
TransactionQueue<LaunchTieredStoProcedureArgs>
TransactionQueue<LaunchTieredStoProcedureArgs, TieredSto>
>;
(args: LaunchTieredStoNoCustomCurrencyNoStableCoinParams): Promise<
TransactionQueue<LaunchTieredStoProcedureArgs, TieredSto>
>;
(args: LaunchTieredStoCustomCurrencyEthParams): Promise<
TransactionQueue<LaunchTieredStoProcedureArgs>
TransactionQueue<LaunchTieredStoProcedureArgs, TieredSto>
>;
(args: LaunchTieredStoCustomCurrencyEthNoStableCoinParams): Promise<
TransactionQueue<LaunchTieredStoProcedureArgs, TieredSto>
>;
(args: LaunchTieredStoCustomCurrencyPolyParams): Promise<
TransactionQueue<LaunchTieredStoProcedureArgs>
TransactionQueue<LaunchTieredStoProcedureArgs, TieredSto>
>;
(args: LaunchTieredStoCustomCurrencyPolyNoStableCoinParams): Promise<
TransactionQueue<LaunchTieredStoProcedureArgs, TieredSto>
>;
(args: LaunchTieredStoCustomCurrencyBothParams): Promise<
TransactionQueue<LaunchTieredStoProcedureArgs>
TransactionQueue<LaunchTieredStoProcedureArgs, TieredSto>
>;
(args: LaunchTieredStoCustomCurrencyBothNoStableCoinParams): Promise<
TransactionQueue<LaunchTieredStoProcedureArgs, TieredSto>
>;
}

Expand Down
14 changes: 10 additions & 4 deletions src/procedures/LaunchSimpleSto.ts
Expand Up @@ -74,10 +74,16 @@ export class LaunchSimpleSto extends Procedure<LaunchSimpleStoProcedureArgs, Sim
usdCost = cost;
}

await this.addProcedure(TransferErc20)({
receiver: securityTokenAddress,
amount: polyCost,
});
const balance = await contractWrappers.polyToken.balanceOf({ owner: securityTokenAddress });
const difference = polyCost.minus(balance);

// only transfer the required amount of POLY
if (difference.gt(new BigNumber(0))) {
await this.addProcedure(TransferErc20)({
receiver: securityTokenAddress,
amount: difference,
});
}

const fundRaiseType =
currency === Currency.ETH ? CappedSTOFundRaiseType.ETH : CappedSTOFundRaiseType.POLY;
Expand Down
23 changes: 18 additions & 5 deletions src/procedures/LaunchTieredSto.ts
Expand Up @@ -35,7 +35,7 @@ export class LaunchTieredSto extends Procedure<LaunchTieredStoProcedureArgs, Tie
currencies,
raisedFundsWallet,
unsoldTokensWallet,
stableCoinAddresses,
stableCoinAddresses = [],
customCurrency,
allowPreIssuing = false,
} = args;
Expand All @@ -57,6 +57,13 @@ export class LaunchTieredSto extends Procedure<LaunchTieredStoProcedureArgs, Tie
});
}

if (currencies.includes(FundRaiseType.StableCoin) && stableCoinAddresses.length === 0) {
throw new PolymathError({
code: ErrorCode.ProcedureValidationError,
message: 'Stable Coin address array cannot be empty if raising in Stable Coin',
});
}

const customOracleAddresses: string[] = [];
let denominatedCurrency = '';

Expand Down Expand Up @@ -116,10 +123,16 @@ export class LaunchTieredSto extends Procedure<LaunchTieredStoProcedureArgs, Tie
usdCost = cost;
}

await this.addProcedure(TransferErc20)({
receiver: securityTokenAddress,
amount: polyCost,
});
const balance = await contractWrappers.polyToken.balanceOf({ owner: securityTokenAddress });
const difference = polyCost.minus(balance);

// only transfer the required amount of POLY
if (difference.gt(new BigNumber(0))) {
await this.addProcedure(TransferErc20)({
receiver: securityTokenAddress,
amount: difference,
});
}

const ratePerTier: BigNumber[] = [];
const ratePerTierDiscountPoly: BigNumber[] = [];
Expand Down
30 changes: 26 additions & 4 deletions src/procedures/__tests__/LaunchSimpleSto.ts
Expand Up @@ -124,9 +124,34 @@ describe('LaunchSimpleSto', () => {

describe('LaunchSimpleSto', () => {
test('should add a transaction to the queue to launch a capped sto with cost in usd', async () => {
const addTransactionSpy = spy(target, 'addTransaction');
securityTokenMock.mock('addModuleWithLabel', Promise.resolve('AddModuleWithLabel'));

// Real call
await target.prepareTransactions();

// Verifications
expect(
addTransactionSpy
.getCall(0)
.calledWith(securityTokenMock.getMockInstance().addModuleWithLabel)
).toEqual(true);
expect(addTransactionSpy.getCall(0).lastArg.fees).toEqual({
usd: costInUsd,
poly: costInPoly,
});
expect(addTransactionSpy.getCall(0).lastArg.tag).toEqual(PolyTransactionTag.EnableCappedSto);
expect(addTransactionSpy.callCount).toEqual(1);
});

test("should transfer POLY to the security token if the token's balance doesn't cover the launch fee", async () => {
const addProcedureSpy = spy(target, 'addProcedure');
const addTransactionSpy = spy(target, 'addTransaction');
securityTokenMock.mock('addModuleWithLabel', Promise.resolve('AddModuleWithLabel'));
polyTokenMock
.mock('balanceOf', Promise.resolve(new BigNumber(20)))
.withArgs({ owner: securityTokenAddress })
.returns(Promise.resolve(new BigNumber(1)));

// Real call
await target.prepareTransactions();
Expand All @@ -143,12 +168,11 @@ describe('LaunchSimpleSto', () => {
});
expect(addTransactionSpy.getCall(0).lastArg.tag).toEqual(PolyTransactionTag.EnableCappedSto);
expect(addTransactionSpy.callCount).toEqual(1);
expect(addProcedureSpy.getCall(0).calledWithExactly(TransferErc20)).toEqual(true);
expect(addProcedureSpy.getCall(0).calledWith(TransferErc20));
expect(addProcedureSpy.callCount).toEqual(1);
});

test('should add a transaction to the queue to launch a capped sto with cost in poly', async () => {
const addProcedureSpy = spy(target, 'addProcedure');
const addTransactionSpy = spy(target, 'addTransaction');

moduleFactoryMock.mock('isCostInPoly', Promise.resolve(true));
Expand All @@ -169,8 +193,6 @@ describe('LaunchSimpleSto', () => {
});
expect(addTransactionSpy.getCall(0).lastArg.tag).toEqual(PolyTransactionTag.EnableCappedSto);
expect(addTransactionSpy.callCount).toEqual(1);
expect(addProcedureSpy.getCall(0).calledWithExactly(TransferErc20)).toEqual(true);
expect(addProcedureSpy.callCount).toEqual(1);
});

test('should throw if corresponding capped sto event is not fired', async () => {
Expand Down
32 changes: 27 additions & 5 deletions src/procedures/__tests__/LaunchTieredSto.ts
Expand Up @@ -136,10 +136,35 @@ describe('LaunchTieredSto', () => {
});

describe('LaunchTieredSto', () => {
test('should add the transaction to the queue to launch usd tiered sto and add a procedure to transfer erc20 token', async () => {
test('should add the transaction to the queue to launch usd tiered sto', async () => {
const addTransactionSpy = spy(target, 'addTransaction');
securityTokenMock.mock('addModuleWithLabel', Promise.resolve('AddModuleWithLabel'));

// Real call
await target.prepareTransactions();

// Verifications
expect(
addTransactionSpy
.getCall(0)
.calledWith(securityTokenMock.getMockInstance().addModuleWithLabel)
).toEqual(true);
expect(addTransactionSpy.getCall(0).lastArg.fees).toEqual({
usd: costIn,
poly: costInPoly,
});
expect(addTransactionSpy.getCall(0).lastArg.tag).toEqual(PolyTransactionTag.EnableTieredSto);
expect(addTransactionSpy.callCount).toEqual(1);
});

test("should transfer POLY to the security token if the token's balance doesn't cover the launch fee", async () => {
const addProcedureSpy = spy(target, 'addProcedure');
const addTransactionSpy = spy(target, 'addTransaction');
securityTokenMock.mock('addModuleWithLabel', Promise.resolve('AddModuleWithLabel'));
polyTokenMock
.mock('balanceOf', Promise.resolve(new BigNumber(20)))
.withArgs({ owner: securityTokenAddress })
.returns(Promise.resolve(new BigNumber(1)));

// Real call
await target.prepareTransactions();
Expand All @@ -156,12 +181,11 @@ describe('LaunchTieredSto', () => {
});
expect(addTransactionSpy.getCall(0).lastArg.tag).toEqual(PolyTransactionTag.EnableTieredSto);
expect(addTransactionSpy.callCount).toEqual(1);
expect(addProcedureSpy.getCall(0).calledWithExactly(TransferErc20)).toEqual(true);
expect(addProcedureSpy.getCall(0).calledWith(TransferErc20));
expect(addProcedureSpy.callCount).toEqual(1);
});

test('should add the transaction to the queue to launch usd tiered sto with cost in poly', async () => {
const addProcedureSpy = spy(target, 'addProcedure');
const addTransactionSpy = spy(target, 'addTransaction');
securityTokenMock.mock('addModuleWithLabel', Promise.resolve('AddModuleWithLabel'));
moduleFactoryMock.mock('isCostInPoly', Promise.resolve(true));
Expand All @@ -181,8 +205,6 @@ describe('LaunchTieredSto', () => {
});
expect(addTransactionSpy.getCall(0).lastArg.tag).toEqual(PolyTransactionTag.EnableTieredSto);
expect(addTransactionSpy.callCount).toEqual(1);
expect(addProcedureSpy.getCall(0).calledWithExactly(TransferErc20)).toEqual(true);
expect(addProcedureSpy.callCount).toEqual(1);
});

test('should throw if corresponding usd tiered sto event is not fired', async () => {
Expand Down
4 changes: 2 additions & 2 deletions src/types/index.ts
Expand Up @@ -404,7 +404,7 @@ export interface LaunchTieredStoProcedureArgs {
currencies: Currency[];
raisedFundsWallet: string;
unsoldTokensWallet: string;
stableCoinAddresses: string[];
stableCoinAddresses?: string[];
customCurrency?: Partial<CustomCurrency>;
allowPreIssuing?: boolean;
}
Expand Down Expand Up @@ -755,7 +755,7 @@ export enum TransferStatusCode {
* @param T - type to exclude from
* @param K - name of the property that will be excluded
*/
export type Omit<T, K> = { [key in Exclude<keyof T, K>]: T[key] };
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

/**
* Transaction method from the contract-wrappers package
Expand Down

0 comments on commit 7ac87fa

Please sign in to comment.