From 683e71d60e7320a17db15fba742644f90144de93 Mon Sep 17 00:00:00 2001 From: cpl121 <100352899+cpl121@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:03:47 +0100 Subject: [PATCH] fix(wallet-dashboard, tooling-core): review staking numbers for bigints (#4483) * feat(core, dashboard): review staking numbers for bigints * fix(dashboard): format and error in bigint with decimals * fix(explorer): linter * fix: improve types in unstake transaction * fix(core): linter * fix: clean debris * fix: linter --------- Co-authored-by: Marc Espin --- apps/core/src/components/stake/StakedCard.tsx | 2 +- .../info/UnstakeTransactionInfo.tsx | 12 +-- apps/core/src/utils/getStakeIotaByIotaId.ts | 2 +- .../Dialogs/vesting/VestingScheduleBox.tsx | 2 +- .../StakedTimelockObject.tsx | 4 +- .../transactions/TransactionAmount.tsx | 2 +- .../lib/constants/vesting.constants.ts | 66 ++++++++-------- .../lib/interfaces/timelock.interface.ts | 2 +- .../lib/interfaces/vesting.interface.ts | 2 +- apps/wallet-dashboard/lib/utils/timelock.ts | 4 +- .../lib/utils/vesting/vesting.spec.ts | 76 +++++++------------ .../lib/utils/vesting/vesting.ts | 10 +-- 12 files changed, 83 insertions(+), 101 deletions(-) diff --git a/apps/core/src/components/stake/StakedCard.tsx b/apps/core/src/components/stake/StakedCard.tsx index 58bc5c82f20..92f6b0e8184 100644 --- a/apps/core/src/components/stake/StakedCard.tsx +++ b/apps/core/src/components/stake/StakedCard.tsx @@ -37,7 +37,7 @@ export function StakedCard({ // For inactive validator, show principal + rewards const [principalStaked, symbol] = useFormatCoin( - inactiveValidator ? principal + rewards : principal, + inactiveValidator ? BigInt(principal) + rewards : principal, IOTA_TYPE_ARG, ); diff --git a/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx b/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx index bb69cf69226..94e120821d3 100644 --- a/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx +++ b/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx @@ -27,21 +27,21 @@ export function UnstakeTransactionInfo({ renderExplorerLink, }: UnstakeTransactionInfoProps) { const json = event.parsedJson as { - principal_amount?: number; - reward_amount?: number; + principal_amount?: string; + reward_amount?: string; validator_address?: string; }; - const principalAmount = json?.principal_amount || 0; - const rewardAmount = json?.reward_amount || 0; + const principalAmount = json?.principal_amount || '0'; + const rewardAmount = json?.reward_amount || '0'; const validatorAddress = json?.validator_address; - const totalAmount = Number(principalAmount) + Number(rewardAmount); + const totalAmount = BigInt(principalAmount) + BigInt(rewardAmount); const [formatPrinciple, symbol] = useFormatCoin(principalAmount, IOTA_TYPE_ARG); const [formatRewards] = useFormatCoin(rewardAmount || 0, IOTA_TYPE_ARG); return (
{validatorAddress && } - {totalAmount && ( + {totalAmount !== 0n && ( )} diff --git a/apps/core/src/utils/getStakeIotaByIotaId.ts b/apps/core/src/utils/getStakeIotaByIotaId.ts index 5bdaa2a01ee..ba2e8837c99 100644 --- a/apps/core/src/utils/getStakeIotaByIotaId.ts +++ b/apps/core/src/utils/getStakeIotaByIotaId.ts @@ -10,7 +10,7 @@ export function getStakeIotaByIotaId(allDelegation: DelegatedStake[], stakeIotaI allDelegation.reduce((acc, curr) => { const total = BigInt( curr.stakes.find(({ stakedIotaId }) => stakedIotaId === stakeIotaId)?.principal || - 0, + 0n, ); return total + acc; }, 0n) || 0n diff --git a/apps/wallet-dashboard/components/Dialogs/vesting/VestingScheduleBox.tsx b/apps/wallet-dashboard/components/Dialogs/vesting/VestingScheduleBox.tsx index 25f861590a0..d9a93fc8d7c 100644 --- a/apps/wallet-dashboard/components/Dialogs/vesting/VestingScheduleBox.tsx +++ b/apps/wallet-dashboard/components/Dialogs/vesting/VestingScheduleBox.tsx @@ -8,7 +8,7 @@ import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { LockLocked } from '@iota/ui-icons'; interface VestingScheduleBoxProps { - amount: number; + amount: bigint; expirationTimestampMs: number; } diff --git a/apps/wallet-dashboard/components/staked-timelock-object/StakedTimelockObject.tsx b/apps/wallet-dashboard/components/staked-timelock-object/StakedTimelockObject.tsx index 8696705bc12..f7e21915a3a 100644 --- a/apps/wallet-dashboard/components/staked-timelock-object/StakedTimelockObject.tsx +++ b/apps/wallet-dashboard/components/staked-timelock-object/StakedTimelockObject.tsx @@ -27,11 +27,11 @@ export function StakedTimelockObject({ // TODO probably we could calculate estimated reward on grouping stage. const summary = timelockedStakedObject.stakes.reduce( (acc, stake) => { - const estimatedReward = stake.status === 'Active' ? stake.estimatedReward : 0; + const estimatedReward = stake.status === 'Active' ? BigInt(stake.estimatedReward) : 0n; return { principal: BigInt(stake.principal) + acc.principal, - estimatedReward: BigInt(estimatedReward) + acc.estimatedReward, + estimatedReward: estimatedReward + acc.estimatedReward, stakeRequestEpoch: stake.stakeRequestEpoch, }; }, diff --git a/apps/wallet-dashboard/components/transactions/TransactionAmount.tsx b/apps/wallet-dashboard/components/transactions/TransactionAmount.tsx index ae7654b0273..498ebc19522 100644 --- a/apps/wallet-dashboard/components/transactions/TransactionAmount.tsx +++ b/apps/wallet-dashboard/components/transactions/TransactionAmount.tsx @@ -5,7 +5,7 @@ import { useFormatCoin } from '@iota/core'; interface TransactionAmountProps { - amount: string | number; + amount: string | number | bigint; coinType: string; label: string; approximation?: boolean; diff --git a/apps/wallet-dashboard/lib/constants/vesting.constants.ts b/apps/wallet-dashboard/lib/constants/vesting.constants.ts index 5e290e70e06..51ace2168a7 100644 --- a/apps/wallet-dashboard/lib/constants/vesting.constants.ts +++ b/apps/wallet-dashboard/lib/constants/vesting.constants.ts @@ -32,7 +32,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xfe755ca67e3a0714f97ec3c49cfc6f3ecdab2673d96b5840294d3a5db376c99', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1697320800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -42,7 +42,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x682d14613231dd1dde39397977cdfafb6b6263b5683b6782348c597c104b834', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1698530400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -52,7 +52,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x93f2bf2d044e45e1a85c010c22357892d1625436b8c95b26dcdb6f309319064', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1699740000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -62,7 +62,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x44fa510ba216cd555ecd6b99d1ebd612f82e2bf421091c973bca49b064dc72b', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1700949600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -72,7 +72,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xacd861b6dc5d108af03655a2175545ac6d432c526bcbe294b90e722fa36b459', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1702159200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -82,7 +82,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x8f9eeb5953c77d53dcff3057619af7a29be1d9ce67bf66c86ad5309379d17e5', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1703368800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -92,7 +92,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x70b1063c1104760afc06df5217bebdf02f937e1aff51211fc0472e677ba8c74', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1704578400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -102,7 +102,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xb0aa6f655d08f630c15a2cfb4e3e13e307ce9d96c52c1e91c65a71a204819bd', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1705788000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -112,7 +112,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x65224b9a3b9eadc55be4cb6efa363f283b924607496d60c02deef2aa6bf9e22', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1706997600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -122,7 +122,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x68f9a2af0ebd0bcd9e3cc836ac7103670a9602e8dca8fd28e7b2b5a693898f2', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1708207200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -132,7 +132,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x637e6b758efdb8d49ee96397ca909d579bb77b79f8b64e7e7f1af13ad4f7ce4', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1709416800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -142,7 +142,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xbd0f349c21b67faec992b6c9a1b9b6343b4ff1f2ad5f33b0b4cd0fc31be2b31', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1710626400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -152,7 +152,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xfb8c3539b22e4086bd03417027e70515e6fb6d18f366876ad5ad0d8da3bde0f', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1711836000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -162,7 +162,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xbfb7c1a941885cc55a191e579c7c6d5dc345d6b5b9cfa439f724a343d354032', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1713045600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -172,7 +172,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x8935a904f90e23f6f453cb0c85a03859e07f1c9e5a5d1644b2fbe7005d8e158', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1714255200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -182,7 +182,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x73be6f8df4b73b83f8ccf909d61aabb56c56c56aa597d2806eccf3ab4fac66b', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1715464800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -192,7 +192,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x20075cc2ebd5fa6e069829e58e55e6e010ad115e8cbc48d7a3d98d079ce649a', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1716674400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -202,7 +202,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xce03433d496cb231ead90a661fe08b924eb9b0cfb43dd560ea02a8060f6afd0', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1717884000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -212,7 +212,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xf111b8705ba276f8c6b76bdf72a4a46889cb8207cc5a80d3df0f40d9576116a', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1719093600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -222,7 +222,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xbc27940fb9c6f96ae9e2c11ad151446e30de5281172e48aac7f600d1da92c10', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1720303200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -232,7 +232,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x016fae8797d3d12a26e215ec1815ee8adce70bb93149b4d55eb06a81c476ff9', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1721512800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -242,7 +242,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x06f1e354ff551d76da8dc890eab728a65319defb3608991b4c70a1a2b30e8f1', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1722722400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -252,7 +252,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xc4cf3ea32480aab7d78784c6f00b9210ce0ffaabbcbb8cddd846073e7455386', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1723932000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -262,7 +262,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x6dc10a8008855549b8d92e7704c799253a953d9835af001970426414fdd3ba7', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1725141600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -272,7 +272,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xa5f7a66c575db3f74c5fe7043c28f7231a2127aec4dc2de88f5b9d3cf020511', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1726351200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -282,7 +282,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xde0a4c2e0f16541983302c596339815ffa4d4743509e8115bc06fcf7f71ea8f', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1727560800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -292,7 +292,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xccc5d23ab69789b934b9bf7f5006e43eef45c2d7a251e3eec8b7dd24bc20a07', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1728770400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -302,7 +302,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x503dc8844b0cd6e74e735433751328e8283569e81b4602aaa6941ce3fe826bb', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1729980000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -312,7 +312,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x0fac98b5ac955644dffa0700933aababe438fae6fc58b8a4bd1f740c8aba941', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1731189600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -322,7 +322,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x756483e3c7dd3491ea405f682df6c5dc1e4a59d8b5c9725b0d194815a25ea95', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1732399200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -332,7 +332,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x72c4318876f51bed94c2228b395d18f5dce5f243039c7e3d8fad690dfe918fc', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1733608800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -342,7 +342,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x37f68fd72af05b4c923268b64a0baa7511f27bc4cbd90641e444e7116f02604', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1734818400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -352,7 +352,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x97bedf66e48392a0b9baf8a8280e72fcce9b32ff980832edfe1a90a14ce9047', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1736028000000, label: SUPPLY_INCREASE_VESTING_LABEL, diff --git a/apps/wallet-dashboard/lib/interfaces/timelock.interface.ts b/apps/wallet-dashboard/lib/interfaces/timelock.interface.ts index 12b26daeecb..2cb58e1a988 100644 --- a/apps/wallet-dashboard/lib/interfaces/timelock.interface.ts +++ b/apps/wallet-dashboard/lib/interfaces/timelock.interface.ts @@ -6,7 +6,7 @@ export interface UID { } export interface Balance { - value: number; + value: bigint; } export interface TimelockedObject { diff --git a/apps/wallet-dashboard/lib/interfaces/vesting.interface.ts b/apps/wallet-dashboard/lib/interfaces/vesting.interface.ts index ba846d71e6c..4eac7bcc774 100644 --- a/apps/wallet-dashboard/lib/interfaces/vesting.interface.ts +++ b/apps/wallet-dashboard/lib/interfaces/vesting.interface.ts @@ -7,7 +7,7 @@ export enum SupplyIncreaseUserType { } export interface SupplyIncreaseVestingPayout { - amount: number; + amount: bigint; expirationTimestampMs: number; } diff --git a/apps/wallet-dashboard/lib/utils/timelock.ts b/apps/wallet-dashboard/lib/utils/timelock.ts index 90c77c0ba9f..f8e06340922 100644 --- a/apps/wallet-dashboard/lib/utils/timelock.ts +++ b/apps/wallet-dashboard/lib/utils/timelock.ts @@ -42,14 +42,14 @@ export function mapTimelockObjects(iotaObjects: IotaObjectData[]): TimelockedObj if (!iotaObject?.content?.dataType || iotaObject.content.dataType !== 'moveObject') { return { id: { id: '' }, - locked: { value: 0 }, + locked: { value: 0n }, expirationTimestampMs: 0, }; } const fields = iotaObject.content.fields as unknown as TimelockedIotaResponse; return { id: fields.id, - locked: { value: Number(fields.locked) }, + locked: { value: BigInt(fields.locked) }, expirationTimestampMs: Number(fields.expiration_timestamp_ms), label: fields.label, }; diff --git a/apps/wallet-dashboard/lib/utils/vesting/vesting.spec.ts b/apps/wallet-dashboard/lib/utils/vesting/vesting.spec.ts index e0bb1f37bd5..3612418d48b 100644 --- a/apps/wallet-dashboard/lib/utils/vesting/vesting.spec.ts +++ b/apps/wallet-dashboard/lib/utils/vesting/vesting.spec.ts @@ -21,10 +21,6 @@ import { const MOCKED_CURRENT_EPOCH_TIMESTAMP = Date.now() + MILLISECONDS_PER_HOUR * 6; // 6 hours later -function bigIntRound(n: number) { - return BigInt(Math.floor(n)); -} - describe('get last supply increase vesting payout', () => { it('should get the object with highest expirationTimestampMs', () => { const timelockedObjects = MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS; @@ -48,7 +44,7 @@ describe('get last supply increase vesting payout', () => { describe('get supply increase user type', () => { it('should return staker, if last payout is two years away from vesting starting year (2023)', () => { const vestingPayout: SupplyIncreaseVestingPayout = { - amount: 1000, + amount: 1000n, expirationTimestampMs: 1735689661000, // Wednesday, 1 January 2025 00:01:01 }; const userType = getSupplyIncreaseVestingUserType([vestingPayout]); @@ -57,7 +53,7 @@ describe('get supply increase user type', () => { it('should return entity, if last payout is more than two years away from vesting starting year (2023)', () => { const vestingPayout: SupplyIncreaseVestingPayout = { - amount: 1000, + amount: 1000n, expirationTimestampMs: 1798761661000, // Friday, 1 January 2027 00:01:01 }; const userType = getSupplyIncreaseVestingUserType([vestingPayout]); @@ -125,12 +121,12 @@ describe('vesting overview', () => { it('should get correct vesting overview data with timelocked objects', () => { const timelockedObjects = MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS; const lastPayout = timelockedObjects[timelockedObjects.length - 1]; - const totalAmount = bigIntRound( - (SUPPLY_INCREASE_STAKER_VESTING_DURATION * - SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR * + const totalAmount = + (BigInt(SUPPLY_INCREASE_STAKER_VESTING_DURATION) * + BigInt(SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR) * + 10n * lastPayout.locked.value) / - 0.9, - ); + 9n; const vestingOverview = getVestingOverview(timelockedObjects, Date.now()); expect(vestingOverview.totalVested).toEqual(totalAmount); @@ -145,9 +141,7 @@ describe('vesting overview', () => { const lockedAmount = vestingPortfolio.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.amount) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.amount : acc, 0n, ); @@ -159,16 +153,12 @@ describe('vesting overview', () => { const lockedObjectsAmount = timelockedObjects.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.locked.value) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.locked.value : acc, 0n, ); const unlockedObjectsAmount = timelockedObjects.reduce( (acc, current) => - current.expirationTimestampMs <= Date.now() - ? acc + bigIntRound(current.locked.value) - : acc, + current.expirationTimestampMs <= Date.now() ? acc + current.locked.value : acc, 0n, ); @@ -182,20 +172,20 @@ describe('vesting overview', () => { formatDelegatedTimelockedStake(timelockedStakedObjects); const lastPayout = extendedTimelockedStakedObjects[extendedTimelockedStakedObjects.length - 1]; - const lastPayoutValue = Number(lastPayout.principal); - const totalAmount = bigIntRound( - (SUPPLY_INCREASE_STAKER_VESTING_DURATION * - SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR * - lastPayoutValue) / - 0.9, - ); + const lastPayoutValue = BigInt(lastPayout.principal); + const totalAmount = + (BigInt(SUPPLY_INCREASE_STAKER_VESTING_DURATION) * + BigInt(SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR) * + lastPayoutValue * + 10n) / + 9n; const vestingOverview = getVestingOverview(extendedTimelockedStakedObjects, Date.now()); expect(vestingOverview.totalVested).toEqual(totalAmount); const vestingPortfolio = buildVestingPortfolio( { - amount: lastPayoutValue, + amount: BigInt(lastPayoutValue), expirationTimestampMs: Number(lastPayout.expirationTimestampMs), }, Date.now(), @@ -203,9 +193,7 @@ describe('vesting overview', () => { const lockedAmount = vestingPortfolio.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.amount) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.amount : acc, 0n, ); @@ -215,7 +203,7 @@ describe('vesting overview', () => { let totalStaked = 0n; for (const timelockedStakedObject of timelockedStakedObjects) { const stakesAmount = timelockedStakedObject.stakes.reduce( - (acc, current) => acc + bigIntRound(Number(current.principal)), + (acc, current) => acc + BigInt(current.principal), 0n, ); totalStaked += stakesAmount; @@ -239,12 +227,12 @@ describe('vesting overview', () => { mixedObjects, MOCKED_CURRENT_EPOCH_TIMESTAMP, )!; - const totalAmount = bigIntRound( - (SUPPLY_INCREASE_STAKER_VESTING_DURATION * - SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR * + const totalAmount = + (BigInt(SUPPLY_INCREASE_STAKER_VESTING_DURATION) * + BigInt(SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR) * + 10n * lastPayout.amount) / - 0.9, - ); + 9n; const vestingOverview = getVestingOverview(mixedObjects, Date.now()); expect(vestingOverview.totalVested).toEqual(totalAmount); @@ -259,9 +247,7 @@ describe('vesting overview', () => { const lockedAmount = vestingPortfolio.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.amount) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.amount : acc, 0n, ); @@ -269,7 +255,7 @@ describe('vesting overview', () => { expect(vestingOverview.totalUnlocked).toEqual(totalAmount - lockedAmount); const totalStaked = extendedTimelockedStakedObjects.reduce( - (acc, current) => acc + bigIntRound(Number(current.principal)), + (acc, current) => acc + BigInt(current.principal), 0n, ); @@ -278,16 +264,12 @@ describe('vesting overview', () => { const timelockObjects = mixedObjects.filter(isTimelockedObject); const availableClaiming = timelockObjects.reduce( (acc, current) => - current.expirationTimestampMs <= Date.now() - ? acc + bigIntRound(current.locked.value) - : acc, + current.expirationTimestampMs <= Date.now() ? acc + current.locked.value : acc, 0n, ); const availableStaking = timelockObjects.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.locked.value) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.locked.value : acc, 0n, ); expect(vestingOverview.availableClaiming).toEqual(availableClaiming); diff --git a/apps/wallet-dashboard/lib/utils/vesting/vesting.ts b/apps/wallet-dashboard/lib/utils/vesting/vesting.ts index e0bb8a29158..374d9a19204 100644 --- a/apps/wallet-dashboard/lib/utils/vesting/vesting.ts +++ b/apps/wallet-dashboard/lib/utils/vesting/vesting.ts @@ -53,7 +53,7 @@ export function getLatestOrEarliestSupplyIncreaseVestingPayout( } function addVestingPayoutToSupplyIncreaseMap( - value: number, + value: bigint, expirationTimestampMs: number, supplyIncreaseMap: Map, ) { @@ -85,7 +85,7 @@ function supplyIncreaseVestingObjectsToPayoutMap( expirationToVestingPayout, ); } else if (isTimelockedStakedIota(vestingObject)) { - const objectValue = Number(vestingObject.principal); + const objectValue = BigInt(vestingObject.principal); const expirationTimestampMs = Number(vestingObject.expirationTimestampMs); addVestingPayoutToSupplyIncreaseMap( objectValue, @@ -162,7 +162,7 @@ export function getVestingOverview( const userType = getSupplyIncreaseVestingUserType([latestPayout]); const vestingPayoutsCount = getSupplyIncreaseVestingPayoutsCount(userType!); // Note: we add the initial payout to the total rewards, 10% of the total rewards are paid out immediately - const totalVestedAmount = BigInt(Math.floor((vestingPayoutsCount * latestPayout.amount) / 0.9)); + const totalVestedAmount = (BigInt(vestingPayoutsCount) * latestPayout.amount * 10n) / 9n; const vestingPortfolio = buildSupplyIncreaseVestingSchedule( latestPayout, currentEpochTimestamp, @@ -326,7 +326,7 @@ export function prepareObjectsForTimelockedStakingTransaction( targetAmount: bigint, currentEpochMs: string, ): GroupedTimelockObject[] { - if (Number(targetAmount) === 0) { + if (targetAmount === 0n) { return []; } const timelockedMapped = mapTimelockObjects(timelockedObjects); @@ -368,7 +368,7 @@ export function prepareObjectsForTimelockedStakingTransaction( const remainingAmount = totalLocked - targetAmount; // Add splitAmount property to the vesting objects that need to be split - if (remainingAmount > 0) { + if (remainingAmount > 0n) { selectedGroupedTimelockObjects = adjustSplitAmountsInGroupedTimelockObjects( selectedGroupedTimelockObjects, remainingAmount,