Skip to content

Commit

Permalink
Merge pull request #1750 from iotaledger/tooling-wallet-dashboard/ref…
Browse files Browse the repository at this point in the history
…actor-vesting

refactor: separate vesting from timelock
  • Loading branch information
begonaalvarezd authored Aug 12, 2024
2 parents b310c31 + 25cebda commit 17c7dbc
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 62 deletions.
6 changes: 3 additions & 3 deletions apps/wallet-dashboard/lib/constants/vesting.constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { Timelocked, TimelockedStakedIota } from '../interfaces';
import { TimelockedObject, TimelockedStakedIota } from '../interfaces';
import { DAYS_PER_WEEK, DAYS_PER_YEAR, MILLISECONDS_PER_DAY } from './time.constants';

export const SUPPLY_INCREASE_VESTING_PAYOUT_SCHEDULE = 2 * DAYS_PER_WEEK;
Expand All @@ -18,7 +18,7 @@ export const SUPPLY_INCREASE_INVESTOR_VESTING_DURATION = 4; // Years
export const SUPPLY_INCREASE_VESTING_LABEL =
'000000000000000000000000000000000000000000000000000000000000107a::stardust_upgrade_label::STARDUST_UPGRADE_LABEL';

export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: Timelocked[] = [
export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject[] = [
{
id: {
id: '0xfe755ca67e3a0714f97ec3c49cfc6f3ecdab2673d96b5840294d3a5db376c99',
Expand Down Expand Up @@ -680,7 +680,7 @@ export const MOCKED_VESTING_TIMELOCKED_STAKED_OBJECTS: TimelockedStakedIota[] =
];

export const MOCKED_VESTING_TIMELOCKED_AND_TIMELOCK_STAKED_OBJECTS: (
| Timelocked
| TimelockedObject
| TimelockedStakedIota
)[] = [
{
Expand Down
1 change: 1 addition & 0 deletions apps/wallet-dashboard/lib/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
// SPDX-License-Identifier: Apache-2.0

export * from './transactions.interface';
export * from './timelock.interface';
export * from './vesting.interface';
38 changes: 38 additions & 0 deletions apps/wallet-dashboard/lib/interfaces/timelock.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

export interface UID {
id: string;
}

export interface Balance {
value: number;
}

export interface TimelockedObject {
id: UID;
locked: Balance; // TODO: extend to support other types of locked assets
expirationTimestampMs: number;
label?: string;
}

export interface TimelockedIotaResponse {
id: UID;
locked: string;
expiration_timestamp_ms: string;
label?: string;
}

export interface StakedIota {
id: UID;
poolId: string;
stakeActivationEpoch: number;
principal: Balance;
}

export interface TimelockedStakedIota {
id: UID;
stakedIota: StakedIota;
expirationTimestampMs: number;
label?: string | null | undefined;
}
36 changes: 0 additions & 36 deletions apps/wallet-dashboard/lib/interfaces/vesting.interface.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,6 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

export interface UID {
id: string;
}

export interface Balance {
value: number;
}

export interface Timelocked {
id: UID;
locked: Balance;
expirationTimestampMs: number;
label?: string;
}

export interface TimelockedIotaResponse {
id: UID;
locked: string;
expiration_timestamp_ms: string;
label?: string;
}

export interface StakedIota {
id: UID;
poolId: string;
stakeActivationEpoch: number;
principal: Balance;
}

export interface TimelockedStakedIota {
id: UID;
stakedIota: StakedIota;
expirationTimestampMs: number;
label?: string | null | undefined;
}

export enum SupplyIncreaseUserType {
Staker = 'Staker',
Entity = 'Entity',
Expand Down
15 changes: 6 additions & 9 deletions apps/wallet-dashboard/lib/utils/timelock.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { SUPPLY_INCREASE_VESTING_LABEL } from '../constants';
import { Timelocked, TimelockedStakedIota } from '../interfaces';
import { TimelockedObject, TimelockedStakedIota } from '../interfaces';

export function isTimelockedStakedIota(
obj: Timelocked | TimelockedStakedIota,
obj: TimelockedObject | TimelockedStakedIota,
): obj is TimelockedStakedIota {
const referenceProperty: keyof TimelockedStakedIota = 'stakedIota';
return referenceProperty in obj;
}

export function isTimelocked(obj: Timelocked | TimelockedStakedIota): obj is Timelocked {
const referenceProperty: keyof Timelocked = 'locked';
export function isTimelockedObject(
obj: TimelockedObject | TimelockedStakedIota,
): obj is TimelockedObject {
const referenceProperty: keyof TimelockedObject = 'locked';
return referenceProperty in obj;
}

export function isVesting(obj: Timelocked | TimelockedStakedIota): boolean {
return obj.label === SUPPLY_INCREASE_VESTING_LABEL;
}
4 changes: 2 additions & 2 deletions apps/wallet-dashboard/lib/utils/vesting/vesting.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '../../constants';

import { SupplyIncreaseUserType, SupplyIncreaseVestingPayout } from '../../interfaces';
import { isTimelocked, isTimelockedStakedIota } from '../timelock';
import { isTimelockedObject, isTimelockedStakedIota } from '../timelock';

import {
getVestingOverview,
Expand Down Expand Up @@ -220,7 +220,7 @@ describe('vesting overview', () => {
.reduce((acc, current) => acc + current.stakedIota.principal.value, 0);
expect(vestingOverview.totalStaked).toEqual(totalStaked);

const timelockObjects = mixedObjects.filter(isTimelocked);
const timelockObjects = mixedObjects.filter(isTimelockedObject);
const availableClaiming = timelockObjects.reduce(
(acc, current) =>
current.expirationTimestampMs <= Date.now() ? acc + current.locked.value : acc,
Expand Down
30 changes: 18 additions & 12 deletions apps/wallet-dashboard/lib/utils/vesting/vesting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@ import {
SUPPLY_INCREASE_INVESTOR_VESTING_DURATION,
SUPPLY_INCREASE_STAKER_VESTING_DURATION,
SUPPLY_INCREASE_STARTING_VESTING_YEAR,
SUPPLY_INCREASE_VESTING_LABEL,
SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR,
SUPPLY_INCREASE_VESTING_PAYOUT_SCHEDULE_MILLISECONDS,
} from '../../constants';

import {
SupplyIncreaseUserType,
SupplyIncreaseVestingPayout,
SupplyIncreaseVestingPortfolio,
Timelocked,
TimelockedIotaResponse,
TimelockedObject,
TimelockedStakedIota,
VestingOverview,
} from '../../interfaces';
import { isTimelocked, isTimelockedStakedIota, isVesting } from '../timelock';
import { isTimelockedObject, isTimelockedStakedIota } from '../timelock';

export function getLastSupplyIncreaseVestingPayout(
objects: (Timelocked | TimelockedStakedIota)[],
objects: (TimelockedObject | TimelockedStakedIota)[],
): SupplyIncreaseVestingPayout | undefined {
const vestingObjects = objects.filter(isVesting);
const vestingObjects = objects.filter(isSupplyIncreaseVestingObject);

if (vestingObjects.length === 0) {
return undefined;
Expand All @@ -38,14 +38,14 @@ export function getLastSupplyIncreaseVestingPayout(
}

function supplyIncreaseVestingObjectsToPayoutMap(
vestingObjects: (Timelocked | TimelockedStakedIota)[],
vestingObjects: (TimelockedObject | TimelockedStakedIota)[],
): Map<number, SupplyIncreaseVestingPayout> {
const expirationToVestingPayout = new Map<number, SupplyIncreaseVestingPayout>();

for (const vestingObject of vestingObjects) {
let objectValue = 0;
if (isTimelocked(vestingObject)) {
objectValue = (vestingObject as Timelocked).locked.value;
if (isTimelockedObject(vestingObject)) {
objectValue = (vestingObject as TimelockedObject).locked.value;
} else if (isTimelockedStakedIota(vestingObject)) {
objectValue = (vestingObject as TimelockedStakedIota).stakedIota.principal.value;
}
Expand Down Expand Up @@ -111,10 +111,10 @@ export function buildSupplyIncreaseVestingSchedule(
}

export function getVestingOverview(
objects: (Timelocked | TimelockedStakedIota)[],
objects: (TimelockedObject | TimelockedStakedIota)[],
currentEpochTimestamp: number,
): VestingOverview {
const vestingObjects = objects.filter(isVesting);
const vestingObjects = objects.filter(isSupplyIncreaseVestingObject);
const latestPayout = getLastSupplyIncreaseVestingPayout(vestingObjects);

if (vestingObjects.length === 0 || !latestPayout) {
Expand Down Expand Up @@ -148,7 +148,7 @@ export function getVestingOverview(
0,
);

const timelockedObjects = vestingObjects.filter(isTimelocked);
const timelockedObjects = vestingObjects.filter(isTimelockedObject);

const totalAvailableClaimingAmount = timelockedObjects.reduce(
(acc, current) =>
Expand Down Expand Up @@ -185,7 +185,7 @@ export function getSupplyIncreaseVestingPayoutsCount(userType: SupplyIncreaseUse
return SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR * vestingDuration;
}

export function mapTimelockObjects(iotaObjects: IotaObjectData[]): Timelocked[] {
export function mapTimelockObjects(iotaObjects: IotaObjectData[]): TimelockedObject[] {
return iotaObjects.map((iotaObject) => {
if (!iotaObject?.content?.dataType || iotaObject.content.dataType !== 'moveObject') {
return {
Expand Down Expand Up @@ -226,3 +226,9 @@ export function timelockObjectsFromIotaObjects(
});
return result;
}

export function isSupplyIncreaseVestingObject(
obj: TimelockedObject | TimelockedStakedIota,
): boolean {
return obj.label === SUPPLY_INCREASE_VESTING_LABEL;
}

0 comments on commit 17c7dbc

Please sign in to comment.