Skip to content

Commit

Permalink
feat(create st): waive protocol fees for classic token owners
Browse files Browse the repository at this point in the history
Also slightly optimized the way fees are fetched
  • Loading branch information
monitz87 committed May 8, 2021
1 parent f5c3300 commit 17f4e61
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 10 deletions.
37 changes: 35 additions & 2 deletions src/api/procedures/__tests__/createSecurityToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ describe('createSecurityToken procedure', () => {
dsMockUtils.createQueryStub('asset', 'tickerConfig', {
returnValue: dsMockUtils.createMockTickerRegistrationConfig(),
});
dsMockUtils.createQueryStub('asset', 'classicTickers', {
returnValue: dsMockUtils.createMockOption(),
});

transaction = dsMockUtils.createTxStub('asset', 'createAsset');

Expand Down Expand Up @@ -233,7 +236,7 @@ describe('createSecurityToken procedure', () => {
sinon.assert.calledWith(
addTransactionStub.firstCall,
transaction,
{},
{ fee: undefined },
rawName,
rawTicker,
rawTotalSupply,
Expand All @@ -253,7 +256,7 @@ describe('createSecurityToken procedure', () => {
sinon.assert.calledWith(
addTransactionStub.secondCall,
transaction,
{},
{ fee: undefined },
rawName,
rawTicker,
rawTotalSupply,
Expand All @@ -264,6 +267,36 @@ describe('createSecurityToken procedure', () => {
);
});

test('should waive protocol fees if the token was created in Ethereum', async () => {
dsMockUtils.createQueryStub('asset', 'classicTickers', {
returnValue: dsMockUtils.createMockOption(
dsMockUtils.createMockClassicTickerRegistration({
/* eslint-disable @typescript-eslint/camelcase */
eth_owner: 'someAddress',
is_created: true,
/* eslint-enable @typescript-eslint/camelcase */
})
),
});
const proc = procedureMockUtils.getInstance<Params, SecurityToken>(mockContext);

const result = await prepareCreateSecurityToken.call(proc, args);

sinon.assert.calledWith(
addTransactionStub.firstCall,
transaction,
{ fee: new BigNumber(0) },
rawName,
rawTicker,
rawTotalSupply,
rawIsDivisible,
rawType,
rawIdentifiers,
rawFundingRound
);
expect(result).toMatchObject(entityMockUtils.getSecurityTokenInstance({ ticker }));
});

test('should add a document add transaction to the queue', async () => {
const proc = procedureMockUtils.getInstance<Params, SecurityToken>(mockContext);
const tx = dsMockUtils.createTxStub('asset', 'addDocuments');
Expand Down
22 changes: 18 additions & 4 deletions src/api/procedures/createSecurityToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { ProcedureAuthorization } from '~/types/internal';
import {
booleanToBool,
boolToBoolean,
numberToBalance,
stringToAssetName,
stringToFundingRoundName,
Expand Down Expand Up @@ -49,7 +50,7 @@ export async function prepareCreateSecurityToken(
): Promise<SecurityToken> {
const {
context: {
polymeshApi: { tx },
polymeshApi: { tx, query },
},
context,
} = this;
Expand All @@ -66,7 +67,12 @@ export async function prepareCreateSecurityToken(

const reservation = new TickerReservation({ ticker }, context);

const { status } = await reservation.details();
const rawTicker = stringToTicker(ticker, context);

const [{ status }, classicTicker] = await Promise.all([
reservation.details(),
query.asset.classicTickers(rawTicker),
]);

if (status === TickerReservationStatus.TokenCreated) {
throw new PolymeshError({
Expand All @@ -82,7 +88,6 @@ export async function prepareCreateSecurityToken(
});
}

const rawTicker = stringToTicker(ticker, context);
const rawTotalSupply = numberToBalance(totalSupply, context, isDivisible);
const rawName = stringToAssetName(name, context);
const rawIsDivisible = booleanToBool(isDivisible, context);
Expand All @@ -92,9 +97,18 @@ export async function prepareCreateSecurityToken(
);
const rawFundingRound = fundingRound ? stringToFundingRoundName(fundingRound, context) : null;

let fee: undefined | BigNumber;

// we waive any protocol fees
const tokenCreatedInEthereum =
classicTicker.isSome && boolToBoolean(classicTicker.unwrap().is_created);
if (tokenCreatedInEthereum) {
fee = new BigNumber(0);
}

this.addTransaction(
tx.asset.createAsset,
{},
{ fee },
rawName,
rawTicker,
rawTotalSupply,
Expand Down
13 changes: 9 additions & 4 deletions src/base/PolymeshTransactionBase.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AddressOrPair, SubmittableExtrinsic } from '@polkadot/api/types';
import { DispatchError } from '@polkadot/types/interfaces';
import { Balance, DispatchError } from '@polkadot/types/interfaces';
import { ISubmittableResult, RegistryError } from '@polkadot/types/types';
import BigNumber from 'bignumber.js';
import { EventEmitter } from 'events';
Expand Down Expand Up @@ -202,7 +202,7 @@ export abstract class PolymeshTransactionBase<
let unsubscribe = false;

if (receipt.isCompleted) {
// isCompleted === isFinalized || isInBlock || isError
/* isCompleted === isFinalized || isInBlock || isError */

// TODO @monitz87: replace with event object when it is auto-generated by the polkadot fork
const failed = receipt.findRecord('system', 'ExtrinsicFailed');
Expand Down Expand Up @@ -290,10 +290,15 @@ export abstract class PolymeshTransactionBase<
return null;
}

const { partialFee } = await composedTx.paymentInfo(signer);
let partialFee: Balance;

if (!protocolFee) {
protocolFee = await context.getTransactionFees(this.tag);
[{ partialFee }, protocolFee] = await Promise.all([
composedTx.paymentInfo(signer),
context.getTransactionFees(this.tag),
]);
} else {
({ partialFee } = await composedTx.paymentInfo(signer));
}

return {
Expand Down

0 comments on commit 17f4e61

Please sign in to comment.