Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
feat: update to use new math sdk (#391)
Browse files Browse the repository at this point in the history
  • Loading branch information
LuizAsFight authored Oct 14, 2022
1 parent 3dcabfa commit c706416
Show file tree
Hide file tree
Showing 45 changed files with 2,332 additions and 4,586 deletions.
2 changes: 1 addition & 1 deletion .github/setup-rust/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: 'Setup Rust env'
inputs:
rust-version:
description: 'Rust version'
default: 1.63.0
default: 1.64.0

runs:
using: "composite"
Expand Down
12 changes: 8 additions & 4 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ jobs:
run:
pnpm recursive install --frozen-lockfile

- name: Setup scripts
run: |
pnpm scripts:setup
- name: Build Contracts
run: |
pnpm contracts:build
# As contracts are really Heavy to build
# and test we only test it when some
# contract was updated on the PR
Expand All @@ -71,10 +79,6 @@ jobs:
run: |
./scripts/test-contracts.sh
- name: Setup scripts
run: |
pnpm scripts:setup
- name: Run test
run: |
pnpm ci:test:coverage
Expand Down
2 changes: 1 addition & 1 deletion packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"decimal.js": "^10.3.1",
"ethers": "^5.6.9",
"framer-motion": "^6.3.15",
"fuels": "0.16.0",
"fuels": "^0.17.0",
"graphql": "^16.5.0",
"graphql-request": "^4.3.0",
"jotai": "^1.7.2",
Expand Down
8 changes: 4 additions & 4 deletions packages/app/src/systems/Core/components/CoinBalance.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import cx from "classnames";
import { bn, format } from "fuels";
import { useMemo } from "react";

import type { CoinBalanceProps } from "../hooks";
import { useBalances } from "../hooks";
import { format, isZero, safeBN } from "../utils";

import { Button, Tooltip } from "~/systems/UI";

Expand All @@ -19,10 +19,10 @@ export const CoinBalance = ({

const balance = useMemo(() => {
const coinBalance = balances?.find((i) => i.assetId === coin?.assetId);
return safeBN(coinBalance?.amount);
return bn(coinBalance?.amount);
}, [balances, coin?.assetId]);

const maxButtonText = isZero(gasFee)
const maxButtonText = bn(gasFee).isZero()
? format(balance)
: `Max = ${format(balance)} (${coin?.symbol} balance)${
gasFee ? ` - ${format(gasFee)} (network fee)` : ``
Expand All @@ -38,7 +38,7 @@ export const CoinBalance = ({
Balance: {format(balance)}
</div>
)}
{showMaxButton && !isZero(balance) && (
{showMaxButton && !bn(balance).isZero() && (
<Tooltip content={maxButtonText}>
<Button
aria-label="Set Maximum Balance"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { BN } from "fuels";

import { format } from "../utils";
import { format } from "fuels";

import { PreviewItem } from "./PreviewTable";

Expand Down
5 changes: 3 additions & 2 deletions packages/app/src/systems/Core/hooks/__mocks__/useBalances.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { CoinQuantity } from 'fuels';
import { bn } from 'fuels';

import { COIN_ETH, parseUnits } from '../../utils';
import { COIN_ETH } from '../../utils';
import * as useBalances from '../useBalances';

import { DECIMAL_UNITS } from '~/config';

const FAKE_BALANCE = [{ amount: parseUnits('3', DECIMAL_UNITS), assetId: COIN_ETH }];
const FAKE_BALANCE = [{ amount: bn.parseUnits('3', DECIMAL_UNITS), assetId: COIN_ETH }];

export function mockUseBalances(balances?: CoinQuantity[]) {
const mock = {
Expand Down
18 changes: 9 additions & 9 deletions packages/app/src/systems/Core/hooks/useCoinInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { ReactNode } from 'react';
import { useMemo, useEffect, useState } from 'react';
import type { NumberFormatValues } from 'react-number-format';

import { formatUnits, isCoinEth, parseInputValueBN, safeBN, ZERO } from '../utils';
import { isCoinEth, ZERO } from '../utils';

import { useBalances } from './useBalances';

Expand Down Expand Up @@ -71,7 +71,7 @@ export type CoinBalanceProps = {
type DisplayType = 'input' | 'text';

const formatValue = (amount: Maybe<BN>) => {
return amount ? formatUnits(amount) : '';
return amount ? amount.formatUnits() : '';
};

export function useCoinInput({
Expand All @@ -86,23 +86,23 @@ export function useCoinInput({
...params
}: UseCoinParams): UseCoinInput {
const [amount, setAmount] = useState<Maybe<BN>>(null);
const [gasFee, setGasFee] = useState<Maybe<BN>>(safeBN(initialGasFee));
const [gasFee, setGasFee] = useState<Maybe<BN>>(bn(initialGasFee));
const { data: balances } = useBalances();
const coinBalance = balances?.find((item) => item.assetId === coin?.assetId);
const isEth = useMemo(() => isCoinEth(coin), [coin?.assetId]);

// TODO: consider real gas fee, replacing GAS_FEE variable.
// For now we need to keep 1 unit in the wallet(it's not spent) in order to complete "create pool" transaction.
function getSafeMaxBalance() {
const next = safeBN(coinBalance?.amount);
const value = next > ZERO ? next.sub(safeBN(gasFee)) : next;
const next = bn(coinBalance?.amount);
const value = next > ZERO ? next.sub(bn(gasFee)) : next;
if (value < ZERO) return ZERO;
return value;
}

function handleInputPropsChange(val: string) {
if (isReadOnly) return;
const next = val !== '' ? parseInputValueBN(val) : null;
const next = val !== '' ? bn.parseUnits(val) : null;
if (typeof onChange === 'function') {
onChange(next);
} else {
Expand All @@ -112,7 +112,7 @@ export function useCoinInput({

function isAllowed({ value }: NumberFormatValues) {
const max = params.max ? params.max : bn(Number.MAX_SAFE_INTEGER);
return parseInputValueBN(value).lt(max);
return bn.parseUnits(value).lt(max);
}

function getInputProps() {
Expand All @@ -122,7 +122,7 @@ export function useCoinInput({
displayType: (isReadOnly ? 'text' : 'input') as DisplayType,
onInput,
onChange: handleInputPropsChange,
balance: formatValue(safeBN(coinBalance?.amount)),
balance: formatValue(bn(coinBalance?.amount)),
isAllowed,
} as CoinInputProps;
}
Expand Down Expand Up @@ -172,6 +172,6 @@ export function useCoinInput({
getCoinSelectorProps,
getCoinBalanceProps,
formatted: formatValue(amount),
hasEnoughBalance: getSafeMaxBalance().gte(safeBN(amount)),
hasEnoughBalance: getSafeMaxBalance().gte(bn(amount)),
};
}
4 changes: 3 additions & 1 deletion packages/app/src/systems/Core/hooks/useEthBalance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { TOKENS, format } from '../utils';
import { format } from 'fuels';

import { TOKENS } from '../utils';

import { useBalances } from './useBalances';

Expand Down
6 changes: 3 additions & 3 deletions packages/app/src/systems/Core/utils/gas.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReceiptType } from 'fuels';
import { bn, ReceiptType } from 'fuels';
import type {
BN,
CallResult,
Expand All @@ -7,7 +7,7 @@ import type {
TxParams,
} from 'fuels';

import { multiply, safeBN, ZERO } from './math';
import { multiply, ZERO } from './math';

import { GAS_PRICE } from '~/config';

Expand Down Expand Up @@ -72,7 +72,7 @@ export async function getTransactionCost(
}

export function getOverrides(overrides?: TxParams): TxParams {
const gasLimit = safeBN(overrides?.gasLimit);
const gasLimit = bn(overrides?.gasLimit);
const ret = {
gasPrice: GAS_PRICE,
gasLimit: !gasLimit.isZero() ? gasLimit : 100_000_000,
Expand Down
3 changes: 2 additions & 1 deletion packages/app/src/systems/Core/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export function sleep(ms: number) {
});
}

export function omit<T>(list: string[], props: T) {
// eslint-disable-next-line @typescript-eslint/ban-types
export function omit<T extends Object>(list: string[], props: T) {
return Object.entries(props).reduce((obj, [key, value]) => {
if (list.some((k) => k === key)) return obj;
return { ...obj, [key]: value };
Expand Down
39 changes: 0 additions & 39 deletions packages/app/src/systems/Core/utils/math.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,6 @@ import { bn } from 'fuels';
import * as math from './math';

describe('Math utilities', () => {
it('Math.parseUnits', () => {
expect(math.parseUnits('1').toHex()).toEqual(bn('1000000000').toHex());
expect(math.parseUnits('0.000000002').toHex()).toEqual(bn(2).toHex());
expect(math.parseUnits('0.00002').toHex()).toEqual(bn('20000').toHex());
expect(math.parseUnits('100.00002').toHex()).toEqual(bn('100000020000').toHex());
expect(math.parseUnits('100,100.00002').toHex()).toEqual(bn('100100000020000').toHex());
expect(math.parseUnits('100,100.00002', 5).toHex()).toEqual(bn('10010000002').toHex());
expect(() => {
math.parseUnits('100,100.000002', 5);
}).toThrow("Decimal can't be bigger than the precision");
});
it('Math.formatUnits', () => {
expect(math.formatUnits(bn('1000000000'))).toEqual('1.000000000');
expect(math.formatUnits(bn('2'))).toEqual('0.000000002');
expect(math.formatUnits(bn('20000'))).toEqual('0.000020000');
expect(math.formatUnits(bn('100000020000'))).toEqual('100.000020000');
expect(math.formatUnits(bn('100100000020000'))).toEqual('100100.000020000');
});

it('Math.format', () => {
expect(math.format(bn('399999988'))).toEqual('0.399');
expect(math.format(bn('1399999988'))).toEqual('1.399');
expect(math.format(bn('1399999988'))).toEqual('1.399');
expect(math.format(bn('3900'))).toEqual('0.000003');
expect(math.format(bn('1000003900'))).toEqual('1.000');
expect(math.format(bn('100000020000'))).toEqual('100.000');
expect(math.format(bn('100100000020000'))).toEqual('100,100.000');
expect(math.format(bn('100100100000020000'))).toEqual('100,100,100.000');
});

it('Math.isZero', () => {
expect(math.isZero('0')).toBeTruthy();
expect(math.isZero(bn(0))).toBeTruthy();
});

it('Math.multiply', () => {
expect(math.multiply(bn(100), 1.2).toHex()).toEqual(bn(120).toHex());
expect(math.multiply(bn(2), 0.5).toHex()).toEqual(bn(1).toHex());
Expand All @@ -58,10 +23,6 @@ describe('Math utilities', () => {
expect(math.maxAmount(bn(1), bn(2)).toHex()).toEqual(bn(2).toHex());
});

it('Math.safeBN', () => {
expect(math.safeBN().toHex()).toEqual(math.ZERO.toHex());
});

it('Math.isValidNumber', () => {
expect(math.isValidNumber(bn('0xFFFFFFFFFFFFFFFF'))).toBeTruthy();
expect(math.isValidNumber(bn('0x1FFFFFFFFFFFFFFFF'))).toBeFalsy();
Expand Down
72 changes: 3 additions & 69 deletions packages/app/src/systems/Core/utils/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,16 @@ import { Decimal } from 'decimal.js';
import { bn } from 'fuels';
import type { BigNumberish, BN } from 'fuels';

import { DECIMAL_UNITS, FIXED_UNITS } from '~/config';
import { DECIMAL_UNITS } from '~/config';
import type { Maybe } from '~/types';

/** Zero BN function */
export const ZERO = bn(0);
/** One Asset Amount 1000000000 */
export const ONE_ASSET = parseUnits('1', DECIMAL_UNITS);
export const ONE_ASSET = bn.parseUnits('1', DECIMAL_UNITS);
/** Max value from Sway Contract */
export const MAX_U64_STRING = '0xFFFFFFFFFFFFFFFF';

export function isZero(number: Maybe<BigNumberish>): boolean {
return bn(number || 0).eq(0);
}

export function formatUnits(number: BN, precision: number = DECIMAL_UNITS) {
const valueUnits = number.toString().slice(0, precision * -1);
const valueDecimals = number.toString().slice(precision * -1);
const length = valueDecimals.length;
const defaultDecimals = Array.from({ length: precision - length })
.fill('0')
.join('');

return `${valueUnits ? `${valueUnits}.` : '0.'}${defaultDecimals}${valueDecimals}`;
}

export function format(
value: BN = ZERO,
maxDecimals: number = FIXED_UNITS,
precision: number = DECIMAL_UNITS
) {
return toFixed(formatUnits(value, precision), maxDecimals);
}

export function toFixed(value: Maybe<string>, maxDecimals: number = FIXED_UNITS) {
const [valueUnits = '0', valueDecimals = '0'] = String(value || '0.0').split('.');
const groupRegex = new RegExp(`(\\d)(?=(\\d{${maxDecimals}})+\\b)`, 'g');
const units = valueUnits.replace(groupRegex, '$1,');
let decimals = valueDecimals.slice(0, maxDecimals);

if (valueUnits === '0') {
const firstNonZero = valueDecimals.match(/[1-9]/);

if (firstNonZero && firstNonZero.index && firstNonZero.index + 1 > maxDecimals) {
decimals = valueDecimals.slice(0, firstNonZero.index + 1);
}
}

return `${units}.${decimals}`;
}

export function parseUnits(value: string, precision: number = DECIMAL_UNITS): BN {
const [valueUnits = '0', valueDecimals = '0'] = value.split('.');
const length = valueDecimals.length;

if (length > precision) {
throw new Error("Decimal can't be bigger than the precision");
}

const decimals = Array.from({ length: precision }).fill('0');
decimals.splice(0, length, valueDecimals);
const amount = `${valueUnits.replace(',', '')}${decimals.join('')}`;
return bn(amount);
}

export function parseInputValueBN(value: string): BN {
if (value !== '') {
const nextValue = value === '.' ? '0.' : value;
return bn(parseUnits(nextValue));
}
return ZERO;
}

export function getNumberOrHex(value: Maybe<BigNumberish>): number | string {
if (typeof value === 'number') {
return value;
Expand All @@ -97,14 +35,10 @@ export function maxAmount(value: BigNumberish, max: BigNumberish): BN {
return bn(max).lt(value) ? bn(value) : bn(max);
}

export function safeBN(value?: Maybe<BigNumberish>, defaultValue?: BigNumberish): BN {
return bn(value || defaultValue || 0);
}

export function isValidNumber(value: BigNumberish) {
try {
if (typeof value === 'string') {
return bn(parseUnits(value)).lte(MAX_U64_STRING);
return bn.parseUnits(value).lte(MAX_U64_STRING);
}
return bn(value).lte(MAX_U64_STRING);
} catch (e) {
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/systems/Faucet/hooks/useCaptcha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type MachineContext = {
type MachineEvents = { type: 'LOAD' } | { type: 'SET_CAPTCHA'; value: string };

const captchaMachine = createMachine<MachineContext>({
predictableActionArguments: true,
schema: {
context: {} as MachineContext,
events: {} as MachineEvents,
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/systems/Faucet/hooks/useFaucet.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import fetch from 'cross-fetch';
import { bn, format } from 'fuels';
import { useMemo } from 'react';
import { useMutation, useQuery } from 'react-query';

import { FUEL_FAUCET_URL } from '~/config';
import { useBalances, useWallet } from '~/systems/Core';
import { format, safeBN } from '~/systems/Core/utils/math';
import type { Maybe } from '~/types';
import { Queries } from '~/types';

Expand Down Expand Up @@ -62,7 +62,7 @@ export function useFaucet(opts: UseFaucetOpts = {}) {
}

const faucetAmount = useMemo(() => {
const amount = safeBN(query.data?.amount);
const amount = bn(query.data?.amount);
return format(amount);
}, [query.status]);

Expand Down
Loading

0 comments on commit c706416

Please sign in to comment.