Skip to content

Commit

Permalink
feat: better return types (#11)
Browse files Browse the repository at this point in the history
* feat: better return types

* feat: better subreport return types

* feat: add some docs
  • Loading branch information
sakulstra authored May 31, 2023
1 parent 6d7b8c8 commit fccb6fd
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 27 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@
## Diff-Snapshots

`aave-cli diff <from> <to>` can be used to diff two config snapshots & generate a human readable report.

## Simulate

`aave-cli simulate-proposal [proposalId]` can be used to simulate a certain proposal on tenderly.

**Note**: currently nothing else is done in this script. You need to manually check the tenderly changes.
In the future we plan to support seatbelt report generation from here.
13 changes: 4 additions & 9 deletions src/simulate/networks/mainnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,7 @@ const aaveGovernanceV2Contract = getContract({
publicClient: mainnetClient,
});

export const mainnet: MainnetModule<
typeof AAVE_GOVERNANCE_V2_ABI,
'ProposalCreated',
'ProposalQueued',
'ProposalExecuted'
> = {
export const mainnet: MainnetModule<'ProposalCreated', 'ProposalQueued', 'ProposalExecuted'> = {
name: 'Mainnet',
async cacheLogs() {
const createdLogs = await getLogs(mainnetClient, (fromBLock, toBlock) =>
Expand Down Expand Up @@ -78,11 +73,11 @@ export const mainnet: MainnetModule<
throw new Error('Proposal not found');
},
async simulateOnTenderly({ state, log, proposalId }) {
const proposal = await aaveGovernanceV2Contract.read.getProposalById([proposalId]);
if (state === ProposalState.EXECUTED) {
const tx = await mainnetClient.getTransaction({ hash: log.transactionHash! });
return tenderly.simulateTx(mainnetClient.chain.id, tx);
return { proposal, simulation: await tenderly.simulateTx(mainnetClient.chain.id, tx) };
}
const proposal = await aaveGovernanceV2Contract.read.getProposalById([proposalId]);
const slots = getAaveGovernanceV2Slots(proposalId, proposal.executor);
const executorContract = getContract({
address: proposal.executor,
Expand Down Expand Up @@ -155,6 +150,6 @@ export const mainnet: MainnetModule<
},
},
};
return tenderly.simulate(simulationPayload);
return { proposal, simulation: await tenderly.simulate(simulationPayload) };
},
};
33 changes: 18 additions & 15 deletions src/simulate/networks/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Abi } from 'abitype';
import { TenderlySimulationResponse, Trace } from '../../utils/tenderlyClient';
import { GetFilterLogsReturnType } from 'viem';
import { GetFilterLogsReturnType, ReadContractReturnType } from 'viem';
import { AAVE_GOVERNANCE_V2_ABI } from '../abis/AaveGovernanceV2';

type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[]
? ElementType
Expand Down Expand Up @@ -63,51 +64,53 @@ export enum ProposalState {
}

export interface MainnetModule<
TAbi extends Abi | readonly unknown[],
TCreatedEventName extends string | undefined,
TQueuedEventName extends string | undefined,
TExecutedEventName extends string | undefined
> {
name: string;
cacheLogs: () => Promise<{
createdLogs: GetFilterLogsReturnType<TAbi, TCreatedEventName>;
queuedLogs: GetFilterLogsReturnType<TAbi, TQueuedEventName>;
executedLogs: GetFilterLogsReturnType<TAbi, TExecutedEventName>;
createdLogs: GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TCreatedEventName>;
queuedLogs: GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TQueuedEventName>;
executedLogs: GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TExecutedEventName>;
}>;
getProposalState: (args: {
proposalId: bigint;
createdLogs: GetFilterLogsReturnType<TAbi, TCreatedEventName>;
queuedLogs: GetFilterLogsReturnType<TAbi, TQueuedEventName>;
executedLogs: GetFilterLogsReturnType<TAbi, TExecutedEventName>;
createdLogs: GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TCreatedEventName>;
queuedLogs: GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TQueuedEventName>;
executedLogs: GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TExecutedEventName>;
}) =>
| {
state: ProposalState.EXECUTED;
log: ArrayElement<GetFilterLogsReturnType<TAbi, TExecutedEventName>>;
log: ArrayElement<GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TExecutedEventName>>;
}
| {
state: ProposalState.QUEUED;
log: ArrayElement<GetFilterLogsReturnType<TAbi, TQueuedEventName>>;
log: ArrayElement<GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TQueuedEventName>>;
}
| {
state: ProposalState.CREATED;
log: ArrayElement<GetFilterLogsReturnType<TAbi, TCreatedEventName>>;
log: ArrayElement<GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TCreatedEventName>>;
};
simulateOnTenderly: (
args: {
proposalId: bigint;
} & (
| {
state: ProposalState.EXECUTED;
log: ArrayElement<GetFilterLogsReturnType<TAbi, TExecutedEventName>>;
log: ArrayElement<GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TExecutedEventName>>;
}
| {
state: ProposalState.QUEUED;
log: ArrayElement<GetFilterLogsReturnType<TAbi, TQueuedEventName>>;
log: ArrayElement<GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TQueuedEventName>>;
}
| {
state: ProposalState.CREATED;
log: ArrayElement<GetFilterLogsReturnType<TAbi, TCreatedEventName>>;
log: ArrayElement<GetFilterLogsReturnType<typeof AAVE_GOVERNANCE_V2_ABI, TCreatedEventName>>;
}
)
) => Promise<TenderlySimulationResponse>;
) => Promise<{
proposal: ReadContractReturnType<typeof AAVE_GOVERNANCE_V2_ABI, 'getProposalById'>;
simulation: TenderlySimulationResponse;
}>;
}
9 changes: 6 additions & 3 deletions src/simulate/simulate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { arbitrum } from './networks/arbitrum';
import { mainnet } from './networks/mainnet';
import { optimism } from './networks/optimism';
import { polygon } from './networks/polygon';
import { L2NetworkModule } from './networks/types';

const l2Modules = [arbitrum, polygon, optimism];

Expand All @@ -18,13 +19,14 @@ export async function simulateProposal(proposalId: bigint) {
});

logInfo(mainnet.name, 'Simulate on tenderly');
const mainnetSimulationResult = await mainnet.simulateOnTenderly({
const { proposal, simulation: mainnetSimulationResult } = await mainnet.simulateOnTenderly({
...mainnetState,
proposalId,
});
const subResults: {
name: string;
simulation: TenderlySimulationResponse;
moduleState: ReturnType<typeof optimism.getProposalState>;
}[] = [];
for (const module of l2Modules) {
logInfo(module.name, 'Updating events cache');
Expand All @@ -40,6 +42,7 @@ export async function simulateProposal(proposalId: bigint) {

for (const trace of moduleBridgeTraces) {
logInfo(module.name, 'Fetching latest known proposal state');
// any casts needed as types are slightly different on polygon vs others
const moduleState = await module.getProposalState({
trace: trace,
...moduleCache,
Expand All @@ -50,7 +53,7 @@ export async function simulateProposal(proposalId: bigint) {
trace: trace,
...moduleState,
} as any);
subResults.push({ name: module.name, simulation: simulationResult });
subResults.push({ name: module.name, simulation: simulationResult, moduleState: moduleState as any });
} else {
logInfo(module.name, 'Simulation on tenderly not supported');
}
Expand All @@ -59,5 +62,5 @@ export async function simulateProposal(proposalId: bigint) {
logInfo(module.name, 'Did not find bridge messages in mainnet trace');
}
}
return { simulation: mainnetSimulationResult, subSimulations: subResults };
return { proposal, simulation: mainnetSimulationResult, subSimulations: subResults };
}
1 change: 1 addition & 0 deletions tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const config: Options = {
},
},
// otherwise .env is ordered wrongly
// https://github.com/evanw/esbuild/issues/399
splitting: false,
};

Expand Down

0 comments on commit fccb6fd

Please sign in to comment.