Skip to content

Commit cabecac

Browse files
authored
fix: v3.1 phantom pendingInvestOrder (#242)
* fix: v3.1 phantom pendingInvestOrder Fixes #238 * chore: remove unnecessary logging
1 parent 11c4bce commit cabecac

File tree

8 files changed

+86
-62
lines changed

8 files changed

+86
-62
lines changed

.cursorignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Log files
2+
*.log
3+
**/*.log
4+
.env.*
5+

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ src/registry.generated.ts
2727
tsconfig.tsbuildinfo
2828

2929
/.vscode/
30-
/.idea/
30+
/.idea/
31+
32+
**/*.sql.gz

compose.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
volumes:
2+
pgData:
3+
4+
services:
5+
db:
6+
image: postgres:17
7+
volumes:
8+
- pgData:/var/lib/postgresql/data
9+
ports:
10+
- 5432:5432
11+
environment:
12+
POSTGRES_USER: postgres
13+
POSTGRES_PASSWORD: postgres
14+
POSTGRES_DB: postgres
15+
healthcheck:
16+
test: ["CMD-SHELL", "pg_isready -U postgres"]
17+
interval: 10s
18+
timeout: 5s
19+
retries: 5
20+
restart: always

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"predev": "pnpm update-registry",
7+
"predev": "pnpm update-registry && docker compose up -d",
88
"dev": "ponder dev --port 8000 --disable-ui",
9+
"postdev": "docker compose down",
910
"prestart": "pnpm update-registry",
1011
"start": "ponder start",
1112
"preserve": "pnpm update-registry",
@@ -22,7 +23,9 @@
2223
"prepare": "husky",
2324
"update-registry": "node scripts/fetch-registry.mjs",
2425
"evgrep": "scripts/evgrep.sh",
25-
"compare-schema": "graphql-inspector diff https://api.centrifuge.io generated/schema.graphql --rule safeUnreachable --rule ignoreDescriptionChanges | grep 'Field.*removed'"
26+
"compare-schema": "graphql-inspector diff https://api.centrifuge.io generated/schema.graphql --rule safeUnreachable --rule ignoreDescriptionChanges | grep 'Field.*removed'",
27+
"sync:export": "docker compose exec -T db sh -lc 'pg_dump --dbname=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB --schema=ponder_sync --no-owner --no-privileges --clean --if-exists' | gzip > $(date +%Y%m%d)_ponder_sync.sql.gz",
28+
"sync:restore": "LATEST=$(ls -t *_ponder_sync.sql.gz 2>/dev/null | head -n 1) && [ -n \"$LATEST\" ] && gzip -dc \"$LATEST\" | docker compose exec -T db sh -lc 'psql --dbname=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB'"
2629
},
2730
"dependencies": {
2831
"@ponder/utils": "^0.2.17",

ponder.config.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createConfig } from "ponder";
22
import { chains, blocks } from "./src/chains";
33
import { decorateDeploymentContracts } from "./src/contracts";
44
import { ERC20Abi } from "./abis/ERC20";
5+
import { V3_1_MIGRATION_BLOCKS } from "./src/config";
56

67
export const contractsV3 = decorateDeploymentContracts(
78
"v3",
@@ -60,7 +61,8 @@ export const contractsV3 = decorateDeploymentContracts(
6061
eventParameter: "token",
6162
},
6263
},
63-
} as const
64+
} as const,
65+
V3_1_MIGRATION_BLOCKS
6466
);
6567

6668
export const contractsV3_1 = decorateDeploymentContracts(
@@ -122,8 +124,7 @@ export const contractsV3_1 = decorateDeploymentContracts(
122124
eventParameter: "token",
123125
},
124126
},
125-
} as const,
126-
240
127+
} as const
127128
);
128129

129130
export const contracts = { ...contractsV3, ...contractsV3_1 };

src/config.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,34 @@ export const INITIAL_HOLDERS: Record<string, string[]> = {
3131
"0x2033B1D0714b5DDd66f78d8B75317F1a0d4440De",
3232
"0xb3DacC732509Ba6B7F25Ad149e56cA44fE901AB9",
3333
"0xB19Cdd566E5ee580E068ED099136d52906e2ca09",
34-
"0x0000000005F458Fd6ba9EEb5f365D83b7dA913dD"
35-
],
34+
"0x0000000005F458Fd6ba9EEb5f365D83b7dA913dD",
35+
],
3636
"281474976710663-0x00010000000000070000000000000001-1": [
3737
"0x491EDFB0B8b608044e227225C715981a30F3A44E",
3838
"0x227942bD9C3e4ECA1b76E8199e407e6c52fdacd6",
3939
"0xB0EC6c4482Ac1Ef77bE239C0AC833CF37A27c876",
4040
"0xb3DacC732509Ba6B7F25Ad149e56cA44fE901AB9",
4141
"0xcf5C83A12E0bd55a8c02fc7802203BC23e3efB30",
4242
"0xb5E93B4434e63B86A2e16e3C37732E24a6af68D6",
43-
"0x0000000005F458Fd6ba9EEb5f365D83b7dA913dD"
43+
"0x0000000005F458Fd6ba9EEb5f365D83b7dA913dD",
4444
],
4545
};
4646

4747
export const getInitialHolders = (
48-
poolId: bigint,
49-
tokenId: string,
50-
centrifugeId: string
48+
poolId: bigint,
49+
tokenId: string,
50+
centrifugeId: string
5151
): string[] => {
52-
const key = `${poolId}-${tokenId.toLowerCase()}-${centrifugeId.toLowerCase()}`;
53-
return INITIAL_HOLDERS[key] || [];
54-
};
52+
const key = `${poolId}-${tokenId.toLowerCase()}-${centrifugeId.toLowerCase()}`;
53+
return INITIAL_HOLDERS[key] || [];
54+
};
55+
56+
//https://coins.llama.fi/block/chainid/1770163200
57+
export const V3_1_MIGRATION_BLOCKS = {
58+
"1": 24379763,
59+
"42161": 428355962,
60+
"43114": 77214282,
61+
"8453": 41686927,
62+
"98866": 49444791,
63+
"56": 79150546,
64+
} as const;

src/contracts.ts

Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { factory, mergeAbis } from "ponder";
22
import { type Abi, getAbiItem } from "viem";
33
import fullRegistry from "../generated";
4-
import { skipBlocks, type RegistryVersions, type Registry, type NetworkNames } from "./chains";
4+
import { type RegistryVersions, type Registry, type NetworkNames } from "./chains";
55
import { networkNames } from "./chains";
66

77
// ============================================================================
@@ -270,7 +270,7 @@ export function decorateDeploymentContracts<
270270
registryVersion: V,
271271
selectedAbiNames: A,
272272
additionalMappings: AM,
273-
overlappingHours?: number
273+
endblocks?: Partial<Record<keyof typeof networkNames, number>>
274274
): ContractsWithAdditionalMappings<V, A[number], AM, keyof AM & string> {
275275
// Validate registry version exists
276276
const abis = Abis[registryVersion];
@@ -297,7 +297,7 @@ export function decorateDeploymentContracts<
297297
`${toContractCase(abiName)}${registryVersion.toUpperCase()}`,
298298
{
299299
abi,
300-
chain: getContractChain(registryVersion, abiName),
300+
chain: getContractChain(registryVersion, abiName, endblocks),
301301
},
302302
];
303303
});
@@ -398,7 +398,7 @@ export function decorateDeploymentContracts<
398398
mappingName,
399399
{
400400
abi: resolvedAbi,
401-
chain: getContractChain(registryVersion, m.factory.abi, overlappingHours, {
401+
chain: getContractChain(registryVersion, m.factory.abi, endblocks, {
402402
// Type assertion: event name is validated above to exist in factory ABI
403403
// Cast through unknown to satisfy type system while maintaining runtime safety
404404
event: m.factory.eventName,
@@ -427,7 +427,7 @@ export function decorateDeploymentContracts<
427427
function getContractChain<V extends RegistryVersions, N extends AbiName<V>>(
428428
registryVersion: V,
429429
abiName: N,
430-
overlappingHours?: number,
430+
endBlocks?: Partial<Record<keyof typeof networkNames, number | undefined>>,
431431
factoryConfig?: {
432432
event: AbiEventName<V, N>;
433433
parameter: AbiEventParameter<V, N, AbiEventName<V, N>>;
@@ -465,12 +465,7 @@ function getContractChain<V extends RegistryVersions, N extends AbiName<V>>(
465465
}
466466

467467
const startBlock = chainValue.deployment.startBlock as number;
468-
const endBlock = computeEndBlock(
469-
chainId,
470-
toContractCase(abiName),
471-
registryVersion,
472-
overlappingHours
473-
);
468+
const endBlock = computeEndBlock(chainId, toContractCase(abiName), registryVersion, endBlocks);
474469
return [chainName, { address, startBlock, endBlock }];
475470
});
476471

@@ -496,62 +491,50 @@ function computeEndBlock(
496491
chainId: keyof typeof networkNames,
497492
contractName: string,
498493
startVersion: RegistryVersions,
499-
overlappingHours?: number
494+
endBlocks?: Partial<Record<keyof typeof networkNames, number | undefined>>
500495
): number | undefined {
496+
if (endBlocks) return endBlocks[chainId];
497+
501498
// Get the versions array
502499
const versions = Object.keys(fullRegistry) as RegistryVersions[];
503500

504501
// Find the index of startVersion in the versions array
505-
const startVersionIndex = versions.indexOf(startVersion);
502+
const currentVersionIndex = versions.indexOf(startVersion);
506503

507-
if (startVersionIndex === -1) {
504+
if (currentVersionIndex === -1)
508505
throw new Error(`Start version "${startVersion}" not found in registry versions`);
509-
}
510506

511-
// Get the next version after startVersion
512-
const endVersionIndex = startVersionIndex + 1;
507+
const nextVersionIndex = currentVersionIndex + 1;
513508

514-
if (endVersionIndex >= versions.length) {
515-
return undefined;
516-
}
509+
if (nextVersionIndex >= versions.length) return undefined;
517510

518-
const endVersion = versions[endVersionIndex];
519-
if (!endVersion) {
520-
return undefined;
521-
}
511+
const nextVersion = versions[nextVersionIndex];
512+
if (!nextVersion) return undefined;
522513

523514
// Get the registry for the next version
524-
const endRegistry = fullRegistry[endVersion] as Registry<RegistryVersions>;
515+
const nextRegistry = fullRegistry[nextVersion] as Registry<RegistryVersions>;
525516

526517
// Access the chain for the given chainId
527518
// Use Object.entries to safely access chains
528-
const chainEntries = Object.entries(endRegistry.chains) as Entries<typeof endRegistry.chains>;
529-
const chainEntry = chainEntries.find(([id]) => id === chainId);
530-
if (!chainEntry) {
531-
return undefined;
532-
}
533-
const chain = chainEntry[1];
519+
const nextChainEntries = Object.entries(nextRegistry.chains) as Entries<
520+
typeof nextRegistry.chains
521+
>;
522+
const nextChainEntry = nextChainEntries.find(([id]) => id === chainId);
523+
if (!nextChainEntry) return undefined;
524+
525+
const nextChain = nextChainEntry[1];
534526

535527
// Check if the contract exists in this version
536-
const contract = chain.contracts[contractName as keyof typeof chain.contracts];
537-
if (!contract) {
538-
return undefined;
539-
}
528+
const newContract = nextChain.contracts[contractName as keyof typeof nextChain.contracts];
529+
if (!newContract) return undefined;
540530

541531
// Get the block number: use contract.blockNumber if available, otherwise fallback to chain.deployment.startBlock
542-
const contractData = contract as { blockNumber?: number | null };
543-
const startBlock = contractData.blockNumber ?? chain.deployment.startBlock;
544-
545-
if (startBlock === null || startBlock === undefined) {
546-
return undefined;
547-
}
532+
const nextContractData = newContract as { blockNumber?: number | null };
533+
const nextContractStartBlock = nextContractData.blockNumber ?? nextChain.deployment.startBlock;
548534

549-
const endBlock = overlappingHours
550-
? startBlock + overlappingHours * skipBlocks[chainId as keyof typeof skipBlocks]
551-
: startBlock - 1;
535+
if (!nextContractStartBlock) return undefined;
552536

553-
// Return the end block (start block of next version minus 1)
554-
return endBlock;
537+
return nextContractStartBlock - 1;
555538
}
556539

557540
/** Ordered registry version keys (e.g. ["v3", "v3_1"]) for use as message/payload version index. */

src/handlers/gatewayHandlers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { multiMapper } from "../helpers/multiMapper";
22
import { logEvent, serviceError } from "../helpers/logger";
3-
import { BlockchainService } from "../services/BlockchainService";
3+
import { BlockchainService } from "../services";
44
import { timestamper } from "../helpers/timestamper";
55

66
import {

0 commit comments

Comments
 (0)