Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/beta' into docs/shareholder-taxw…
Browse files Browse the repository at this point in the history
…ithholding-invest-erc20balance
  • Loading branch information
Victor Wiebe committed Jan 8, 2020
2 parents dd29daa + 92e16de commit 7ca9ded
Show file tree
Hide file tree
Showing 17 changed files with 2,209 additions and 186 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@polymathnetwork/sdk",
"version": "2.0.1-beta.87",
"version": "2.0.1-beta.90",
"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
12 changes: 6 additions & 6 deletions src/entities/Sto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {
TogglePauseSto,
AssignStoRole,
FinalizeSto,
ModifyBeneficialInvestments,
ModifyPreIssuing,
ToggleAllowBeneficialInvestments,
ToggleAllowPreIssuing,
} from '../procedures';

export interface UniqueIdentifiers {
Expand Down Expand Up @@ -183,7 +183,7 @@ export abstract class Sto<P> extends Entity<P> {
public allowPreIssuing = async () => {
const { address: stoAddress, stoType, securityTokenSymbol: symbol } = this;

const procedure = new ModifyPreIssuing(
const procedure = new ToggleAllowPreIssuing(
{ stoAddress, stoType, symbol, allowPreIssuing: true },
this.context
);
Expand All @@ -198,7 +198,7 @@ export abstract class Sto<P> extends Entity<P> {
public disallowPreIssuing = async () => {
const { address: stoAddress, stoType, securityTokenSymbol: symbol } = this;

const procedure = new ModifyPreIssuing(
const procedure = new ToggleAllowPreIssuing(
{ stoAddress, stoType, symbol, allowPreIssuing: false },
this.context
);
Expand All @@ -212,7 +212,7 @@ export abstract class Sto<P> extends Entity<P> {
public allowBeneficialInvestments = async () => {
const { address: stoAddress, stoType, securityTokenSymbol: symbol } = this;

const procedure = new ModifyBeneficialInvestments(
const procedure = new ToggleAllowBeneficialInvestments(
{ stoAddress, stoType, symbol, allowBeneficialInvestments: true },
this.context
);
Expand All @@ -226,7 +226,7 @@ export abstract class Sto<P> extends Entity<P> {
public disallowBeneficialInvestments = async () => {
const { address: stoAddress, stoType, securityTokenSymbol: symbol } = this;

const procedure = new ModifyBeneficialInvestments(
const procedure = new ToggleAllowBeneficialInvestments(
{ stoAddress, stoType, symbol, allowBeneficialInvestments: false },
this.context
);
Expand Down
102 changes: 59 additions & 43 deletions src/procedures/FinalizeSto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,40 @@ import {
import { PolymathError } from '../PolymathError';
import { isValidAddress } from '../utils';
import { SecurityToken, SimpleSto, TieredSto } from '../entities';
import { Factories } from '../Context';

export const createRefreshStoFactoryResolver = (
factories: Factories,
symbol: string,
stoType: StoType,
stoAddress: string
) => async () => {
const securityTokenId = SecurityToken.generateId({ symbol });

switch (stoType) {
case StoType.Simple: {
return factories.simpleStoFactory.refresh(
SimpleSto.generateId({
securityTokenId,
stoType,
address: stoAddress,
})
);
}
case StoType.Tiered: {
return factories.tieredStoFactory.refresh(
TieredSto.generateId({
securityTokenId,
stoType,
address: stoAddress,
})
);
}
default: {
return undefined;
}
}
};

export class FinalizeSto extends Procedure<FinalizeStoProcedureArgs> {
public type = ProcedureType.FinalizeSto;
Expand All @@ -30,17 +64,18 @@ export class FinalizeSto extends Procedure<FinalizeStoProcedureArgs> {
if (statusCode !== TransferStatusCode.TransferSuccess) {
throw new PolymathError({
code: ErrorCode.ProcedureValidationError,
message: `Treasury wallet "${to}" is not cleared to
receive the remaining ${amount} "${symbol}" tokens from "${fromAddress}".
Please review transfer restrictions regarding this wallet address before
attempting to finalize the STO. Possible reason: "${reasonCode}"`,
message: `Treasury wallet "${to}" is not cleared to \
receive the remaining ${amount} "${symbol}" tokens from "${fromAddress}". \
Please review transfer restrictions regarding this wallet address before attempting \
to finalize the STO. Possible reason: "${reasonCode}"`,
});
}
}

public async prepareTransactions() {
const { stoAddress, stoType, symbol } = this.args;
const { contractWrappers, factories } = this.context;
const { context, args } = this;
const { stoAddress, stoType, symbol } = args;
const { contractWrappers, factories, currentWallet } = context;

/*
* Validation
Expand All @@ -65,6 +100,11 @@ export class FinalizeSto extends Procedure<FinalizeStoProcedureArgs> {
});
}

const stoModuleError = new PolymathError({
code: ErrorCode.ProcedureValidationError,
message: `STO ${stoAddress} is either archived or hasn't been launched`,
});

let stoModule;
let remainingTokens: BigNumber;

Expand All @@ -75,13 +115,18 @@ export class FinalizeSto extends Procedure<FinalizeStoProcedureArgs> {
address: stoAddress,
});

if (!stoModule) {
throw stoModuleError;
}

if (isCappedSTO_3_0_0(stoModule)) {
throw new PolymathError({
code: ErrorCode.IncorrectVersion,
message:
'Capped STO version is 3.0.0. Version 3.1.0 or greater is required for forced finalization',
});
}

const { totalTokensSold, cap } = await stoModule.getSTODetails();
remainingTokens = cap.minus(totalTokensSold);

Expand All @@ -93,6 +138,10 @@ export class FinalizeSto extends Procedure<FinalizeStoProcedureArgs> {
address: stoAddress,
});

if (!stoModule) {
throw stoModuleError;
}

const { tokensSold, capPerTier } = await stoModule.getSTODetails();
const totalCap = capPerTier.reduce((prev, next) => prev.plus(next), new BigNumber(0));
remainingTokens = totalCap.minus(tokensSold);
Expand All @@ -107,13 +156,6 @@ export class FinalizeSto extends Procedure<FinalizeStoProcedureArgs> {
}
}

if (!stoModule) {
throw new PolymathError({
code: ErrorCode.ProcedureValidationError,
message: `STO ${stoAddress} is either archived or hasn't been launched`,
});
}

const [isFinalized, treasuryWallet] = await Promise.all([
stoModule.isFinalized(),
contractWrappers.getTreasuryWallet({ module: stoModule }),
Expand All @@ -126,13 +168,15 @@ export class FinalizeSto extends Procedure<FinalizeStoProcedureArgs> {
});
}

const address = await currentWallet.address();

const { statusCode, reasonCode } = await securityToken.canTransfer({
to: treasuryWallet,
value: remainingTokens,
});
this.checkTransferStatus(
statusCode,
await this.context.currentWallet.address(),
address,
symbol,
treasuryWallet,
reasonCode,
Expand All @@ -144,35 +188,7 @@ export class FinalizeSto extends Procedure<FinalizeStoProcedureArgs> {
*/
await this.addTransaction(stoModule.finalize, {
tag: PolyTransactionTag.FinalizeSto,
resolvers: [
async () => {
const securityTokenId = SecurityToken.generateId({ symbol });

switch (stoType) {
case StoType.Simple: {
return factories.simpleStoFactory.refresh(
SimpleSto.generateId({
securityTokenId,
stoType,
address: stoAddress,
})
);
}
case StoType.Tiered: {
return factories.tieredStoFactory.refresh(
TieredSto.generateId({
securityTokenId,
stoType,
address: stoAddress,
})
);
}
default: {
return undefined;
}
}
},
],
resolvers: [createRefreshStoFactoryResolver(factories, symbol, stoType, stoAddress)],
})({});
}
}
11 changes: 8 additions & 3 deletions src/procedures/InvestInSimpleSto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ export const createRefreshSecurityTokenFactoryResolver = (
return factories.securityTokenFactory.refresh(securityTokenId);
};

export const createRefreshSimpleStoFactoryResolver = (
factories: Factories,
simpleStoId: string
) => async () => {
return factories.simpleStoFactory.refresh(simpleStoId);
};

export class InvestInSimpleSto extends Procedure<InvestInSimpleStoProcedureArgs> {
public type = ProcedureType.InvestInSimpleSto;

Expand Down Expand Up @@ -110,9 +117,7 @@ export class InvestInSimpleSto extends Procedure<InvestInSimpleStoProcedureArgs>
}

const resolvers = [
async () => {
return factories.simpleStoFactory.refresh(simpleStoId);
},
createRefreshSimpleStoFactoryResolver(factories, simpleStoId),
createRefreshSecurityTokenFactoryResolver(factories, securityTokenId),
];

Expand Down
66 changes: 32 additions & 34 deletions src/procedures/InvestInTieredSto.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ModuleName, BigNumber } from '@polymathnetwork/contract-wrappers';
import { BigNumber, FundRaiseType, ModuleName } from '@polymathnetwork/contract-wrappers';
import { Procedure } from './Procedure';
import {
ProcedureType,
PolyTransactionTag,
InvestInTieredStoProcedureArgs,
ErrorCode,
StoType,
Currency,
ErrorCode,
InvestInTieredStoProcedureArgs,
isInvestWithStableCoinArgs,
PolyTransactionTag,
ProcedureType,
StoType,
} from '../types';
import { PolymathError } from '../PolymathError';
import { isValidAddress } from '../utils';
Expand All @@ -22,6 +22,13 @@ export const createRefreshSecurityTokenFactoryResolver = (
return factories.securityTokenFactory.refresh(securityTokenId);
};

export const createRefreshTieredStoFactoryResolver = (
factories: Factories,
tieredStoId: string
) => async () => {
return factories.tieredStoFactory.refresh(tieredStoId);
};

export class InvestInTieredSto extends Procedure<InvestInTieredStoProcedureArgs> {
public type = ProcedureType.InvestInTieredSto;

Expand Down Expand Up @@ -51,6 +58,13 @@ export class InvestInTieredSto extends Procedure<InvestInTieredStoProcedureArgs>
});
}

const securityTokenId = SecurityToken.generateId({ symbol });
const tieredStoId = TieredSto.generateId({
securityTokenId,
stoType: StoType.Tiered,
address: stoAddress,
});

const stoModule = await contractWrappers.moduleFactory.getModuleInstance({
name: ModuleName.UsdTieredSTO,
address: stoAddress,
Expand All @@ -63,25 +77,17 @@ export class InvestInTieredSto extends Procedure<InvestInTieredStoProcedureArgs>
});
}

const [
const [sto, currentAddress] = await Promise.all([
factories.tieredStoFactory.fetch(tieredStoId),
context.currentWallet.address(),
]);
const {
isFinalized,
isPaused,
currentAddress,
beneficialInvestmentsAllowed,
startDate,
canRaiseInEth,
canRaiseInPoly,
canRaiseInStableCoin,
] = await Promise.all([
stoModule.isFinalized(),
stoModule.paused(),
context.currentWallet.address(),
stoModule.allowBeneficialInvestments(),
stoModule.startTime(),
stoModule.fundRaiseTypes({ type: Currency.ETH }),
stoModule.fundRaiseTypes({ type: Currency.POLY }),
stoModule.fundRaiseTypes({ type: Currency.StableCoin }),
]);
beneficialInvestmentsAllowed,
fundraiseCurrencies,
} = sto;

if (startDate > new Date()) {
throw new PolymathError({
Expand Down Expand Up @@ -113,16 +119,8 @@ export class InvestInTieredSto extends Procedure<InvestInTieredStoProcedureArgs>

beneficiary = beneficiary || currentAddress;

const securityTokenId = SecurityToken.generateId({ symbol });
const tieredStoId = TieredSto.generateId({
securityTokenId,
stoType: StoType.Tiered,
address: stoAddress,
});
const resolvers = [
async () => {
return factories.tieredStoFactory.refresh(tieredStoId);
},
createRefreshTieredStoFactoryResolver(factories, tieredStoId),
createRefreshSecurityTokenFactoryResolver(factories, securityTokenId),
];

Expand All @@ -134,7 +132,7 @@ export class InvestInTieredSto extends Procedure<InvestInTieredStoProcedureArgs>
if (isInvestWithStableCoinArgs(args)) {
const { stableCoinAddress } = args;

if (!canRaiseInStableCoin) {
if (!fundraiseCurrencies.includes(FundRaiseType.StableCoin)) {
throw unsupportedCurrencyError;
}

Expand All @@ -154,7 +152,7 @@ export class InvestInTieredSto extends Procedure<InvestInTieredStoProcedureArgs>
investedSC: amount,
});
} else if (currency === Currency.POLY) {
if (!canRaiseInPoly) {
if (!fundraiseCurrencies.includes(FundRaiseType.POLY)) {
throw unsupportedCurrencyError;
}

Expand All @@ -172,7 +170,7 @@ export class InvestInTieredSto extends Procedure<InvestInTieredStoProcedureArgs>
investedPOLY: amount,
});
} else {
if (!canRaiseInEth) {
if (!fundraiseCurrencies.includes(FundRaiseType.ETH)) {
throw unsupportedCurrencyError;
}

Expand Down
Loading

0 comments on commit 7ca9ded

Please sign in to comment.