Skip to content

Commit

Permalink
Merge pull request #1004 from madfish-solutions/QUIPU-322-logic-remov…
Browse files Browse the repository at this point in the history
…e-liq-form

QUIPU-322 logic for remove liq form
  • Loading branch information
00-22-11 authored Sep 22, 2022
2 parents 61ae9c0 + aaad979 commit 418fdff
Show file tree
Hide file tree
Showing 45 changed files with 593 additions and 251 deletions.
5 changes: 5 additions & 0 deletions src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const LP_INPUT_KEY = 'lp-input';

//#region arrays
export const FISRT_INDEX = 0;
export const OPPOSITE_INDEX = 1;
//#endregion

//#region default value for token search
Expand Down Expand Up @@ -185,3 +186,7 @@ export const ZERO_BAKER_ADDRESS = 'tz1burnburnburnburnburnburnburjAYjjX';

// Choose token
export const SINGLE_TOKEN_VALUE = 1;

// toRealIfPossible / toAtomicIfPossible
export const DECIMALS_BASE = 10;
export const FALLBACK_DECIMALS = 0;
15 changes: 10 additions & 5 deletions src/modules/new-liquidity/api/add-dex-two-liquidity.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { TezosToolkit } from '@taquito/taquito';
import { BigNumber } from 'bignumber.js';

import { withApproveApiForManyTokens } from '@blockchain';
import { ZERO_BAKER_ADDRESS } from '@config/constants';
import { DEX_TWO_CONTRACT_ADDRESS } from '@config/environment';
import { isGreaterThanZero, sortTokensAmounts } from '@shared/helpers';
import { isGreaterThanZero } from '@shared/helpers';
import { AmountToken } from '@shared/types';

const ZERO_BAKER_ADDRESS = 'tz1burnburnburnburnburnburnburjAYjjX';
import { getTezValue } from '../helpers/get-tez-value';

export const addDexTwoLiquidityApi = async (
tezos: TezosToolkit,
Expand All @@ -20,12 +21,16 @@ export const addDexTwoLiquidityApi = async (
if (!candidate) {
candidate = ZERO_BAKER_ADDRESS;
}

const dexTwoContract = await tezos.wallet.at(DEX_TWO_CONTRACT_ADDRESS);
const sortedTokes = sortTokensAmounts(tokensAndAmounts);

const tezValue = getTezValue(tokensAndAmounts);

const [tokenA, tokenB] = tokensAndAmounts;

const dexTwoLiquidityParams = dexTwoContract.methods
.invest_liquidity(itemId, sortedTokes.amountA, sortedTokes.amountB, shares, accountPkh, candidate, deadline)
.toTransferParams();
.invest_liquidity(itemId, tokenA.amount, tokenB.amount, shares, accountPkh, candidate, deadline)
.toTransferParams({ mutez: true, amount: tezValue.toNumber() });

const cleanedTokensAmount = tokensAndAmounts.filter(({ amount }) => isGreaterThanZero(amount));

Expand Down
2 changes: 2 additions & 0 deletions src/modules/new-liquidity/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from './get-new-liquidity-list.api';
export * from './get-new-liquidity-stats.api';
export * from './add-dex-two-liquidity.api';
export * from './remove-dex-two-liquidity.api';
export * from './create-new-liquidity-pool.api';
31 changes: 31 additions & 0 deletions src/modules/new-liquidity/api/remove-dex-two-liquidity.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { TezosToolkit } from '@taquito/taquito';
import { BigNumber } from 'bignumber.js';

import { sendBatch } from '@blockchain';
import { ZERO_BAKER_ADDRESS } from '@config/constants';
import { DEX_TWO_CONTRACT_ADDRESS } from '@config/environment';
import { AmountToken } from '@shared/types';

export const removeDexTwoLiquidityApi = async (
tezos: TezosToolkit,
shares: BigNumber,
tokensAndAmounts: Array<AmountToken>,
deadline: string,
accountPkh: string,
candidate: string,
itemId: BigNumber
) => {
if (!candidate) {
candidate = ZERO_BAKER_ADDRESS;
}

const dexTwoContract = await tezos.wallet.at(DEX_TWO_CONTRACT_ADDRESS);

const [tokenA, tokenB] = tokensAndAmounts;

const dexTwoLiquidityParams = dexTwoContract.methods
.divest_liquidity(itemId, tokenA.amount, tokenB.amount, shares, accountPkh, candidate, deadline)
.toTransferParams();

return await sendBatch(tezos, [dexTwoLiquidityParams]);
};
6 changes: 6 additions & 0 deletions src/modules/new-liquidity/dto/liquidity-item.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ export class LiquidityItemDto implements LiquidityItem {
@Typed()
type: string;

@Typed()
feesRate: string;

@Typed({ optional: true })
currentDelegate: string;

@Typed()
tvlInUsd: BigNumber;

Expand Down
10 changes: 10 additions & 0 deletions src/modules/new-liquidity/helpers/get-tez-value.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import BigNumber from 'bignumber.js';

import { isTezosToken } from '@shared/helpers';
import { AmountToken } from '@shared/types';

const ZERO_BN = new BigNumber('0');

export const getTezValue = (tokensAndAmounts: Array<AmountToken>) => {
return tokensAndAmounts.find(item => isTezosToken(item.token))?.amount ?? ZERO_BN;
};
9 changes: 9 additions & 0 deletions src/modules/new-liquidity/helpers/get-value-with-fee.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import BigNumber from 'bignumber.js';

import { PERCENTAGE_100 } from '@config/constants';

export const getValueWithFee = (value: BigNumber, fee: BigNumber.Value) => {
const percentFee = new BigNumber(fee).multipliedBy(PERCENTAGE_100);

return value.multipliedBy(PERCENTAGE_100.minus(percentFee)).dividedBy(PERCENTAGE_100);
};
4 changes: 3 additions & 1 deletion src/modules/new-liquidity/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './is-hot-pool.helper';
export * from './is-hot-pool';
export * from './get-value-with-fee';
export * from './get-tez-value';
1 change: 1 addition & 0 deletions src/modules/new-liquidity/hooks/blockchain/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './use-add-liquidity';
export * from './use-remove-liquidity';
37 changes: 28 additions & 9 deletions src/modules/new-liquidity/hooks/blockchain/use-add-liquidity.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import BigNumber from 'bignumber.js';
import { FormikValues } from 'formik';

import { addDexTwoLiquidityApi } from '@modules/new-liquidity/api/add-dex-two-liquidity.api';
import { FISRT_INDEX } from '@config/constants';
import { LP_TOKEN } from '@modules/new-liquidity/pages/item/components/forms/helpers/mock-lp-token';
import { useRootStore } from '@providers/root-store-provider';
import { useAccountPkh } from '@providers/use-dapp';
import { decreaseBySlippage, extractTokens, getTransactionDeadline, isExist, isNull, toAtomic } from '@shared/helpers';
import {
decreaseBySlippage,
extractTokens,
getTransactionDeadline,
isExist,
isNull,
isTezosToken,
sortTokens,
toAtomic
} from '@shared/helpers';
import { useSettingsStore } from '@shared/hooks/use-settings-store';
import { tokensAndAmountsMapper } from '@shared/mapping';
import { useConfirmOperation, useToasts } from '@shared/utils';
import { useTranslation } from '@translation';

import { addDexTwoLiquidityApi } from '../../api';
import { getValueWithFee } from '../../helpers';
import { useNewLiquidityItemStore } from '../store';

export const useAddLiquidity = () => {
Expand All @@ -34,14 +46,21 @@ export const useAddLiquidity = () => {
toAtomic(amount, tokens[index]).integerValue(BigNumber.ROUND_DOWN)
);

const tokensAndAmounts = tokensAndAmountsMapper(tokens, atomicInputAmounts);
const shares = atomicInputAmounts[0]
.multipliedBy(item.totalSupply)
.dividedToIntegerBy(item?.tokensInfo[0].atomicTokenTvl);
const tokensAndAmounts = tokensAndAmountsMapper(tokens, atomicInputAmounts).sort((a, b) =>
sortTokens(a.token, b.token)
);

if (isTezosToken(tokensAndAmounts[FISRT_INDEX].token)) {
tokensAndAmounts.reverse();
}

const shares = atomicInputAmounts[FISRT_INDEX].multipliedBy(item.totalSupply)
.dividedBy(item.tokensInfo[FISRT_INDEX].atomicTokenTvl)
.decimalPlaces(LP_TOKEN.metadata.decimals);

// TODO: Fees for shares
const sharesWithFee = getValueWithFee(shares, item.feesRate).integerValue(BigNumber.ROUND_DOWN);

const sharesWithSlippage = decreaseBySlippage(shares, liquiditySlippage).integerValue(BigNumber.ROUND_DOWN); // should be shares with fee
const sharesWithSlippage = decreaseBySlippage(sharesWithFee, liquiditySlippage).integerValue(BigNumber.ROUND_DOWN);

const deadline = await getTransactionDeadline(tezos, transactionDeadline);

Expand All @@ -55,7 +74,7 @@ export const useAddLiquidity = () => {
candidate,
itemId
);
await confirmOperation(operation.opHash, { message: t('stableswap|successfullyAdded') });
await confirmOperation(operation.opHash, { message: t('newLiquidity|successfullyAdded') });
} catch (error) {
showErrorToast(error as Error);
}
Expand Down
77 changes: 77 additions & 0 deletions src/modules/new-liquidity/hooks/blockchain/use-remove-liquidity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import BigNumber from 'bignumber.js';
import { FormikValues } from 'formik';

import { FISRT_INDEX } from '@config/constants';
import { LP_TOKEN } from '@modules/new-liquidity/pages/item/components/forms/helpers/mock-lp-token';
import { useRootStore } from '@providers/root-store-provider';
import { useAccountPkh } from '@providers/use-dapp';
import {
decreaseBySlippage,
extractTokens,
getTransactionDeadline,
isExist,
isNull,
isTezosToken,
sortTokens,
toAtomic
} from '@shared/helpers';
import { useSettingsStore } from '@shared/hooks/use-settings-store';
import { tokensAndAmountsMapper } from '@shared/mapping';
import { useConfirmOperation, useToasts } from '@shared/utils';
import { useTranslation } from '@translation';

import { removeDexTwoLiquidityApi } from '../../api';
import { useNewLiquidityItemStore } from '../store';

export const useRemoveLiquidity = () => {
const { tezos } = useRootStore();
const { showErrorToast } = useToasts();
const confirmOperation = useConfirmOperation();
const { t } = useTranslation();
const {
settings: { transactionDeadline, liquiditySlippage }
} = useSettingsStore();
const accountPkh = useAccountPkh();
const { item } = useNewLiquidityItemStore();

const removeLiquidity = async (inputAmounts: FormikValues, shares: BigNumber) => {
if (isNull(tezos) || !isExist(item) || isNull(accountPkh) || !inputAmounts.every(isExist)) {
return;
}
const itemId = item.id;
const tokens = extractTokens(item.tokensInfo);

const atomicAndDecresedInputAmounts = inputAmounts.map((amount: BigNumber, index: number) =>
decreaseBySlippage(toAtomic(amount, tokens[index]), liquiditySlippage).minus(1).integerValue(BigNumber.ROUND_DOWN)
);

const tokensAndAmounts = tokensAndAmountsMapper(tokens, atomicAndDecresedInputAmounts).sort((a, b) =>
sortTokens(a.token, b.token)
);

if (isTezosToken(tokensAndAmounts[FISRT_INDEX].token)) {
tokensAndAmounts.reverse();
}

const atomicLpTokenBalance = toAtomic(shares, LP_TOKEN).integerValue(BigNumber.ROUND_DOWN);

const deadline = await getTransactionDeadline(tezos, transactionDeadline);

try {
const operation = await removeDexTwoLiquidityApi(
tezos,
atomicLpTokenBalance,
tokensAndAmounts,
deadline,
accountPkh,
item.currentDelegate,
itemId
);
await confirmOperation(operation.opHash, { message: t('newLiquidity|successfullyRemoved') });
} catch (error) {
showErrorToast(error as Error);
}
};

return { removeLiquidity };
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface LiquidityItem {
volumeForWeek: Nullable<BigNumber>;
poolLabels: Array<string>;
tokensInfo: Array<LiquidityTokenInfo>;
feesRate: string;
}

export interface LiquidityItemResponse {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { operationAmountSchema } from '@shared/helpers';
import { NumberAsStringSchema } from '@shared/validators';
import { useTranslation } from '@translation';

import { getInputSlugByIndexAdd } from '../helpers/forms.helpers';
import { Input } from './use-dex-two-add-liq-form.interface';
import { getInputSlugByIndex } from '../helpers/forms.helpers';
import { Input } from '../interface';

export const useDexTwoAddLiqValidation = (
userBalances: Nullable<BigNumber>[],
Expand All @@ -35,15 +35,16 @@ export const useDexTwoAddLiqValidation = (
});

const shapeMap: Array<[string, NumberAsStringSchema]> = inputAmountSchemas.map((item, index) => {
return [getInputSlugByIndexAdd(index), item.required('Amount is required!')];
return [getInputSlugByIndex(index), item.required('Amount is required!')];
});

const shape: Record<string, NumberAsStringSchema> = Object.fromEntries(shapeMap);

if (shouldShowBakerInput) {
shape[Input.BAKER_INPUT] = yup.string().required('Amount is required');
}
const bakerSchema = shouldShowBakerInput ? yup.string().required('Baker is required') : yup.string();

return yup.object().shape(shape);
return yup.object().shape({
...shape,
[Input.THIRD_INPUT]: bakerSchema
});
}, [dexTwoItem.tokensInfo, shouldShowBakerInput, t, userBalances]);
};

This file was deleted.

Loading

0 comments on commit 418fdff

Please sign in to comment.