Skip to content

Commit 9d0b619

Browse files
fix: track upon vault events correctly (#225)
* fix: track upon vault events correctly * feat: initialize holdings per user of old tokens
1 parent d44eb75 commit 9d0b619

File tree

5 files changed

+90
-82
lines changed

5 files changed

+90
-82
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ src/registry.generated.ts
2626
**/*.log
2727
tsconfig.tsbuildinfo
2828

29-
/.vscode/
29+
/.vscode/
30+
/.idea/

ponder.schema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ export const TokenRelations = relations(Token, ({ one, many }) => ({
172172
offRampAddresses: many(OffRampAddress, { relationName: "offRampAddresses" }),
173173
}));
174174

175+
// NOTE: Sync is not supported in the protocol atm, but it is in the enum
175176
export const VaultKinds = ["Async", "Sync", "SyncDepositAsyncRedeem"] as const;
176177
export const VaultKind = onchainEnum("vault_kind", VaultKinds);
177178
export const VaultStatuses = ["LinkInProgress", "UnlinkInProgress", "Linked", "Unlinked"] as const;

src/config.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,33 @@ export const V2_POOLS = {
2222
],
2323
},
2424
} as const;
25+
26+
export const INITIAL_HOLDERS: Record<string, string[]> = {
27+
"281474976710662-0x00010000000000060000000000000001-1": [
28+
"0x491EDFB0B8b608044e227225C715981a30F3A44E",
29+
"0x2923c1B5313F7375fdaeE80b7745106deBC1b53E",
30+
"0x523DC886302932a469Cd804Cb18292d7D5C30512",
31+
"0x2033B1D0714b5DDd66f78d8B75317F1a0d4440De",
32+
"0xb3DacC732509Ba6B7F25Ad149e56cA44fE901AB9",
33+
"0xB19Cdd566E5ee580E068ED099136d52906e2ca09",
34+
"0x0000000005F458Fd6ba9EEb5f365D83b7dA913dD"
35+
],
36+
"281474976710663-0x00010000000000070000000000000001-1": [
37+
"0x491EDFB0B8b608044e227225C715981a30F3A44E",
38+
"0x227942bD9C3e4ECA1b76E8199e407e6c52fdacd6",
39+
"0xB0EC6c4482Ac1Ef77bE239C0AC833CF37A27c876",
40+
"0xb3DacC732509Ba6B7F25Ad149e56cA44fE901AB9",
41+
"0xcf5C83A12E0bd55a8c02fc7802203BC23e3efB30",
42+
"0xb5E93B4434e63B86A2e16e3C37732E24a6af68D6",
43+
"0x0000000005F458Fd6ba9EEb5f365D83b7dA913dD"
44+
],
45+
};
46+
47+
export const getInitialHolders = (
48+
poolId: bigint,
49+
tokenId: string,
50+
centrifugeId: string
51+
): string[] => {
52+
const key = `${poolId}-${tokenId.toLowerCase()}-${centrifugeId.toLowerCase()}`;
53+
return INITIAL_HOLDERS[key] || [];
54+
};

src/handlers/spokeHandlers.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@ import {
88
TokenService,
99
InvestorTransactionService,
1010
AccountService,
11+
TokenInstancePositionService,
1112
} from "../services";
1213
import { ERC20Abi } from "../../abis/ERC20";
1314
import { Abis } from "../contracts";
1415
import { RegistryChains } from "../chains";
1516
import { snapshotter } from "../helpers/snapshotter";
1617
import { HoldingEscrowSnapshot } from "ponder:schema";
1718
import { deployVault, linkVault, unlinkVault } from "./vaultRegistryHandlers";
19+
import { getInitialHolders } from "../config";
20+
import { initialisePosition } from "../services/TokenInstancePositionService";
1821

1922
multiMapper("spoke:DeployVault", deployVault);
2023

@@ -91,6 +94,26 @@ multiMapper("spoke:AddShareClass", async ({ event, context }) => {
9194
// Only increase token total issuance if this is a new token instance
9295
if (prevInstanceIssuance === 0n) {
9396
token.increaseTotalIssuance(totalSupply);
97+
98+
// Fetch initial holders from hardcoded list
99+
const initialHolders: string[] = getInitialHolders(poolId, tokenId, centrifugeId);
100+
if (initialHolders.length > 0) {
101+
await Promise.all(
102+
initialHolders.map(async (holder: string) => {
103+
(await TokenInstancePositionService.getOrInit(
104+
context,
105+
{
106+
tokenId,
107+
centrifugeId,
108+
accountAddress: holder.toLowerCase() as `0x${string}`,
109+
},
110+
event,
111+
async (tokenInstancePosition) =>
112+
await initialisePosition(context, tokenAddress, tokenInstancePosition)
113+
)) as TokenInstancePositionService;
114+
})
115+
);
116+
}
94117
}
95118

96119
await token.save(event);

src/handlers/vaultHandlers.ts

Lines changed: 34 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import {
55
AssetService,
66
BlockchainService,
77
EpochInvestOrderService,
8-
EpochRedeemOrderService,
98
InvestOrderService,
10-
RedeemOrderService,
119
TokenInstancePositionService,
1210
TokenInstanceService,
1311
TokenService,
@@ -300,9 +298,8 @@ multiMapper("vault:RedeemClaimable", async ({ event, context }) => {
300298
centrifugeId,
301299
})) as VaultService;
302300
if (!vault) return serviceError(`Vault not found. Cannot retrieve vault configuration`);
303-
const { poolId, tokenId, kind, assetAddress } = vault.read();
301+
const { poolId, tokenId, assetAddress } = vault.read();
304302

305-
if (kind === "Sync") return;
306303

307304
const asset = (await AssetService.get(context, {
308305
address: assetAddress,
@@ -411,8 +408,23 @@ multiMapper("vault:Deposit", async ({ event, context }) => {
411408
switch (kind) {
412409
case "Async":
413410
await InvestorTransactionService.claimDeposit(context, itData, event);
411+
const vaultInvestOrder = (await VaultInvestOrderService.getOrInit(
412+
context,
413+
{
414+
centrifugeId,
415+
poolId,
416+
tokenId,
417+
assetId,
418+
accountAddress: investorAddress,
419+
},
420+
event,
421+
undefined,
422+
true
423+
)) as VaultInvestOrderService;
424+
await vaultInvestOrder.deposit(assets).saveOrClear(event);
414425
break;
415-
default:
426+
case "SyncDepositAsyncRedeem":
427+
case "Sync":
416428
await InvestorTransactionService.syncDeposit(context, itData, event);
417429
const investOrderIndex =
418430
(await InvestOrderService.count(context, {
@@ -435,6 +447,7 @@ multiMapper("vault:Deposit", async ({ event, context }) => {
435447
issuedSharesAmount: shares,
436448
issuedWithNavAssetPerShare: getSharePrice(assets, shares, assetDecimals, shareDecimals),
437449
...timestamper("claimed", event),
450+
claimedSharesAmount: shares,
438451
},
439452
event
440453
);
@@ -464,22 +477,9 @@ multiMapper("vault:Deposit", async ({ event, context }) => {
464477
event
465478
)) as EpochInvestOrderService;
466479
break;
480+
default:
481+
return serviceError("Unknown vault kind");
467482
}
468-
469-
const vaultInvestOrder = (await VaultInvestOrderService.getOrInit(
470-
context,
471-
{
472-
centrifugeId,
473-
poolId,
474-
tokenId,
475-
assetId,
476-
accountAddress: investorAddress,
477-
},
478-
event,
479-
undefined,
480-
true
481-
)) as VaultInvestOrderService;
482-
await vaultInvestOrder.deposit(assets).saveOrClear(event);
483483
});
484484

485485
multiMapper("vault:Withdraw", async ({ event, context }) => {
@@ -530,79 +530,32 @@ multiMapper("vault:Withdraw", async ({ event, context }) => {
530530
currencyAssetId: assetId,
531531
};
532532

533+
533534
switch (kind) {
534535
case "Sync":
535-
await InvestorTransactionService.syncRedeem(context, itData, event);
536-
const redeemOrderIndex =
537-
(await RedeemOrderService.count(context, {
538-
poolId,
539-
tokenId,
540-
account: investorAddress,
541-
index_lte: 0,
542-
})) * -1;
543-
await RedeemOrderService.insert(
544-
context,
545-
{
546-
poolId,
547-
tokenId,
548-
assetId,
549-
account: investorAddress,
550-
index: redeemOrderIndex,
551-
...timestamper("approved", event),
552-
approvedSharesAmount: shares,
553-
...timestamper("revoked", event),
554-
revokedAssetsAmount: assets,
555-
revokedPoolAmount: assets,
556-
revokedWithNavAssetPerShare: getSharePrice(assets, shares, assetDecimals, shareDecimals),
557-
...timestamper("claimed", event),
558-
},
559-
event
560-
);
561-
562-
const epochRedeemIndex =
563-
(await EpochRedeemOrderService.count(context, {
564-
poolId,
565-
tokenId,
566-
assetId,
567-
index_lte: 0,
568-
})) * -1;
569-
(await EpochRedeemOrderService.insert(
536+
return serviceError("Sync vaults are not supported yet");
537+
case "SyncDepositAsyncRedeem":
538+
case "Async":
539+
const vaultRedeemOrder = (await VaultRedeemOrderService.getOrInit(
570540
context,
571541
{
542+
centrifugeId,
572543
poolId,
573544
tokenId,
574545
assetId,
575-
index: epochRedeemIndex,
576-
...timestamper("approved", event),
577-
approvedSharesAmount: shares,
578-
approvedPercentageOfTotalPending: 100n * 10n ** BigInt(shareDecimals),
579-
...timestamper("revoked", event),
580-
revokedAssetsAmount: assets,
581-
revokedWithNavAssetPerShare: getSharePrice(assets, shares, assetDecimals, shareDecimals),
546+
accountAddress: investorAddress,
582547
},
583-
event
584-
)) as EpochRedeemOrderService;
548+
event,
549+
undefined,
550+
true
551+
)) as VaultRedeemOrderService;
552+
await vaultRedeemOrder.redeem(shares).saveOrClear(event);
585553

586-
break;
587-
default:
588554
await InvestorTransactionService.claimRedeem(context, itData, event);
589555
break;
556+
default:
557+
return serviceError("Unknown vault kind");
590558
}
591-
592-
const vaultRedeemOrder = (await VaultRedeemOrderService.getOrInit(
593-
context,
594-
{
595-
centrifugeId,
596-
poolId,
597-
tokenId,
598-
assetId,
599-
accountAddress: investorAddress,
600-
},
601-
event,
602-
undefined,
603-
true
604-
)) as VaultRedeemOrderService;
605-
await vaultRedeemOrder.redeem(shares).saveOrClear(event);
606559
});
607560

608561
/**

0 commit comments

Comments
 (0)