Skip to content

Commit b9acc50

Browse files
committed
add proxy support to graph add
1 parent 588738b commit b9acc50

File tree

2 files changed

+76
-36
lines changed

2 files changed

+76
-36
lines changed

packages/cli/src/commands/add.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ export default class AddCommand extends Command {
8888

8989
let startBlock = startBlockFlag ? parseInt(startBlockFlag).toString() : startBlockFlag;
9090
let contractName = contractNameFlag || DEFAULT_CONTRACT_NAME;
91-
let ethabi = null;
91+
92+
let ethabi: EthereumABI | null = null;
93+
let implAddress = null;
9294

9395
if (sourcifyContractInfo) {
9496
startBlock ??= sourcifyContractInfo.startBlock;
@@ -112,6 +114,36 @@ export default class AddCommand extends Command {
112114
),
113115
);
114116
if (!ethabi) throw Error;
117+
const isProxy = ethabi.callFunctionSignatures()?.includes('upgradeTo(address)');
118+
if (isProxy) {
119+
const impl = await retryWithPrompt(() =>
120+
withSpinner(
121+
'Fetching proxy implementation address...',
122+
'Failed to fetch proxy implementation address',
123+
'Warning fetching proxy implementation address',
124+
() => contractService.getProxyImplementation(network, address),
125+
),
126+
);
127+
if (impl) {
128+
const useImplementation = await prompt.confirm(
129+
`Proxy contract detected. Index implementation contract at ${impl}?`,
130+
true,
131+
);
132+
133+
if (useImplementation) {
134+
implAddress = impl;
135+
ethabi = await retryWithPrompt(() =>
136+
withSpinner(
137+
'Fetching implementation contract ABI...',
138+
'Failed to fetch implementation ABI',
139+
'Warning fetching implementation ABI',
140+
() => contractService.getABI(EthereumABI, network, implAddress!),
141+
),
142+
);
143+
}
144+
if (!ethabi) throw Error;
145+
}
146+
}
115147
} catch (error) {
116148
// we cannot ask user to do prompt in test environment
117149
if (process.env.NODE_ENV !== 'test') {
@@ -136,10 +168,15 @@ export default class AddCommand extends Command {
136168
}
137169
}
138170
}
171+
if (!ethabi) {
172+
this.error('Failed to load ABI', { exit: 1 });
173+
}
139174

140175
try {
141176
if (isLocalHost) throw Error; // Triggers user prompting without waiting for Etherscan lookup to fail
142-
startBlock ||= Number(await contractService.getStartBlock(network, address)).toString();
177+
startBlock ||= Number(
178+
await contractService.getStartBlock(network, implAddress ?? address),
179+
).toString();
143180
} catch (error) {
144181
// we cannot ask user to do prompt in test environment
145182
if (process.env.NODE_ENV !== 'test') {
@@ -166,7 +203,8 @@ export default class AddCommand extends Command {
166203
if (isLocalHost) throw Error; // Triggers user prompting without waiting for Etherscan lookup to fail
167204
if (contractName === DEFAULT_CONTRACT_NAME) {
168205
contractName =
169-
(await contractService.getContractName(network, address)) ?? DEFAULT_CONTRACT_NAME;
206+
(await contractService.getContractName(network, implAddress ?? address)) ??
207+
DEFAULT_CONTRACT_NAME;
170208
}
171209
} catch (error) {
172210
// not asking user to do prompt in test environment
@@ -266,8 +304,6 @@ export default class AddCommand extends Command {
266304
'Warning during codegen',
267305
async () => await system.run(yarn ? 'yarn codegen' : 'npm run codegen'),
268306
);
269-
270-
this.exit(0);
271307
}
272308
}
273309

packages/cli/src/commands/init.ts

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -648,38 +648,42 @@ async function processInitForm(
648648
initDebugger.extend('processInitForm')("abiFromEtherscan len: '%s'", abiFromApi?.name);
649649
} else {
650650
abiFromApi = initAbi;
651-
const isProxy =
652-
abiFromApi?.callFunctions().some(entry => entry.get('name') === 'implementation') ??
653-
false;
654-
initDebugger.extend('processInitForm')('isProxy: %O', isProxy);
655-
if (isProxy) {
656-
const impl = await retryWithPrompt(() =>
657-
withSpinner(
658-
'Fetching proxy implementation address...',
659-
'Failed to fetch proxy implementation address',
660-
'Warning fetching proxy implementation address',
661-
() => contractService.getProxyImplementation(network.id, address),
662-
),
651+
}
652+
653+
const isProxy =
654+
abiFromApi
655+
?.callFunctions()
656+
.some(
657+
entry => entry.get('name') === 'implementation' || entry.get('name') === 'upgradeTo',
658+
) ?? false;
659+
initDebugger.extend('processInitForm')('isProxy: %O', isProxy);
660+
661+
if (isProxy) {
662+
const impl = await retryWithPrompt(() =>
663+
withSpinner(
664+
'Fetching proxy implementation address...',
665+
'Failed to fetch proxy implementation address',
666+
'Warning fetching proxy implementation address',
667+
() => contractService.getProxyImplementation(network.id, address),
668+
),
669+
);
670+
initDebugger.extend('processInitForm')("proxyImplementation: '%s'", impl);
671+
if (impl) {
672+
const useImplementation = await prompt.confirm(
673+
`Proxy contract detected. Index implementation contract at ${impl}?`,
674+
true,
663675
);
664-
initDebugger.extend('processInitForm')("proxyImplementation: '%s'", impl);
665-
if (impl) {
666-
const useImplementation = await prompt.confirm(
667-
`Proxy contract detected. Index implementation contract at ${impl}?`,
668-
true,
669-
);
670676

671-
if (useImplementation) {
672-
implAddress = impl;
673-
abiFromApi = await retryWithPrompt(() =>
674-
withSpinner(
675-
'Fetching implementation contract ABI...',
676-
'Failed to fetch implementation ABI',
677-
'Warning fetching implementation ABI',
678-
() =>
679-
contractService.getABI(protocolInstance.getABI(), network.id, implAddress!),
680-
),
681-
);
682-
}
677+
if (useImplementation) {
678+
implAddress = impl;
679+
abiFromApi = await retryWithPrompt(() =>
680+
withSpinner(
681+
'Fetching implementation contract ABI...',
682+
'Failed to fetch implementation ABI',
683+
'Warning fetching implementation ABI',
684+
() => contractService.getABI(protocolInstance.getABI(), network.id, implAddress!),
685+
),
686+
);
683687
}
684688
}
685689
}
@@ -1338,7 +1342,7 @@ async function addAnotherContract(
13381342
name: 'contract',
13391343
initial: ProtocolContract.identifierName(),
13401344
required: true,
1341-
message: () => `\nContract ${ProtocolContract.identifierName()}`,
1345+
message: () => `Contract ${ProtocolContract.identifierName()}`,
13421346
validate: value => {
13431347
const { valid, error } = validateContract(value, ProtocolContract);
13441348
return valid ? true : error;

0 commit comments

Comments
 (0)