-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from lidofinance/feature/omnibus
Omnibus
- Loading branch information
Showing
24 changed files
with
428 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { program } from '@command'; | ||
import { checkTmCanForward, forwardVoteFromTm } from '@utils'; | ||
import { printVoteTxData, promptVoting } from './omnibus/'; | ||
|
||
const omnibus = program.command('omnibus').description('preparing and launching batches of calls through voting'); | ||
|
||
omnibus | ||
.command('prepare') | ||
.description('prepare omnibus script') | ||
.action(async () => { | ||
const voteTxData = await promptVoting(); | ||
if (!voteTxData) return; | ||
|
||
await printVoteTxData(voteTxData); | ||
}); | ||
|
||
omnibus | ||
.command('run') | ||
.description('run omnibus script') | ||
.action(async () => { | ||
const canForward = await checkTmCanForward(); | ||
if (!canForward) return; | ||
|
||
const voteTxData = await promptVoting(); | ||
if (!voteTxData) return; | ||
|
||
await printVoteTxData(voteTxData); | ||
await forwardVoteFromTm(voteTxData.newVoteCalldata); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export * from './print-vote'; | ||
export * from './prompt-amount'; | ||
export * from './prompt-call'; | ||
export * from './prompt-description'; | ||
export * from './prompt-voting'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { tmContract } from '@contracts'; | ||
import { green } from 'chalk'; | ||
import { printTx } from 'utils'; | ||
import { VoteTxData } from './prompt-voting'; | ||
|
||
export const printVoteTxData = async (voteTxData: VoteTxData) => { | ||
const { voteEvmScript, newVoteCalldata, description } = voteTxData; | ||
console.log(''); | ||
console.log(green('vote calls evmScript:')); | ||
console.log(voteEvmScript); | ||
|
||
console.log(''); | ||
console.log(green('vote description (meta):')); | ||
console.log(description); | ||
|
||
console.log(''); | ||
console.log(green('newVote() calldata:')); | ||
console.log(newVoteCalldata); | ||
|
||
console.log(''); | ||
|
||
await printTx(tmContract, 'forward', [newVoteCalldata]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import prompts from 'prompts'; | ||
|
||
export const promptAmountOfCalls = async () => { | ||
const { amount } = await prompts({ | ||
type: 'number', | ||
name: 'amount', | ||
message: 'enter amount of calls', | ||
}); | ||
|
||
return amount; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { gray, bold, green } from 'chalk'; | ||
import prompts from 'prompts'; | ||
|
||
export const printCallExample = () => { | ||
console.log(''); | ||
console.log(bold('enter calls one by one')); | ||
console.log(`format: ${gray('address "method_signature(uint256,string)" arg1 arg2')}`); | ||
console.log( | ||
`example: ${gray( | ||
`0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC 'setNodeOperatorStakingLimit(uint256,uint64)' 0 150`, | ||
)}`, | ||
); | ||
console.log(''); | ||
}; | ||
|
||
export const printCallsSuccess = () => { | ||
console.log(green('filling the list of calls is completed')); | ||
console.log(''); | ||
}; | ||
|
||
export const promptMethodCall = async (index: number) => { | ||
const { methodCall } = await prompts({ | ||
type: 'text', | ||
name: 'methodCall', | ||
message: `enter call ${index + 1}`, | ||
}); | ||
|
||
return methodCall; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { CallScriptAction, ParsedMethodCall } from '@utils'; | ||
import prompts from 'prompts'; | ||
|
||
export interface OmnibusScript extends ParsedMethodCall { | ||
encoded: string; | ||
call: CallScriptAction; | ||
} | ||
|
||
export const getDefaultOmnibusDescription = (omnibusScripts: OmnibusScript[]) => { | ||
const callList = omnibusScripts | ||
.map(({ address, args, methodName }, index) => `${index + 1}) call ${methodName}(${args}) at ${address}`) | ||
.join('\n'); | ||
|
||
return `omnibus: \n${callList}`; | ||
}; | ||
|
||
export const promptOmnibusDescription = async (omnibusScripts: OmnibusScript[]) => { | ||
const defaultDescription = getDefaultOmnibusDescription(omnibusScripts); | ||
|
||
const { description } = await prompts({ | ||
type: 'text', | ||
name: 'description', | ||
initial: defaultDescription, | ||
message: 'enter voting description (use \\n for new line): \n', | ||
}); | ||
|
||
return (description ?? '').split('\\n').join('\n'); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { encodeCallScript, parseMethodCallToContract } from '@utils'; | ||
import { promptAmountOfCalls } from './prompt-amount'; | ||
import { printCallExample, printCallsSuccess, promptMethodCall } from './prompt-call'; | ||
import { OmnibusScript, promptOmnibusDescription } from './prompt-description'; | ||
import { agentOrDirect, votingNewVote } from '@scripts'; | ||
|
||
export interface VoteTxData { | ||
voteEvmScript: string; | ||
newVoteCalldata: string; | ||
description: string; | ||
} | ||
|
||
export const promptVoting = async (): Promise<VoteTxData | void> => { | ||
const amountOfCalls = await promptAmountOfCalls(); | ||
const omnibusScripts: OmnibusScript[] = []; | ||
|
||
printCallExample(); | ||
|
||
for (let i = 0; i < amountOfCalls; i++) { | ||
const methodCall = await promptMethodCall(i); | ||
|
||
if (methodCall) { | ||
try { | ||
const parsedCall = parseMethodCallToContract(methodCall); | ||
const { contract, method, args } = parsedCall; | ||
|
||
const [encoded, call] = await agentOrDirect(contract, method, args); | ||
omnibusScripts.push({ encoded, call, ...parsedCall }); | ||
} catch (error) { | ||
console.warn((error as Error).message); | ||
return; | ||
} | ||
} else { | ||
console.warn('empty call, aborting'); | ||
return; | ||
} | ||
} | ||
|
||
printCallsSuccess(); | ||
|
||
const description = await promptOmnibusDescription(omnibusScripts); | ||
|
||
const voteEvmScript = encodeCallScript(omnibusScripts.map(({ call }) => call)); | ||
const [newVoteCalldata] = votingNewVote(voteEvmScript, description); | ||
|
||
return { | ||
voteEvmScript, | ||
newVoteCalldata, | ||
description, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { CallScriptAction, authorizedCallTest, encodeCallScript } from '@utils'; | ||
import { aragonAgentAddress, votingAddress } from '@contracts'; | ||
import { Contract } from 'ethers'; | ||
import { agentForward } from './agent'; | ||
import chalk from 'chalk'; | ||
import prompts from 'prompts'; | ||
|
||
const printCallSuccess = (from: string) => { | ||
console.log(chalk`{green successfully called from {bold ${from}}, added to the list}`); | ||
console.log(''); | ||
}; | ||
|
||
export const agentOrDirect = async (contract: Contract, method: string, args: unknown[] = []) => { | ||
const call: CallScriptAction = { | ||
to: await contract.getAddress(), | ||
data: contract.interface.encodeFunctionData(method, args), | ||
}; | ||
|
||
const errors = []; | ||
|
||
try { | ||
await authorizedCallTest(contract, method, args, aragonAgentAddress); | ||
printCallSuccess('agent'); | ||
|
||
return encodeFromAgent(call); | ||
} catch (error) { | ||
errors.push(error); | ||
} | ||
|
||
try { | ||
await authorizedCallTest(contract, method, args, votingAddress); | ||
printCallSuccess('voting'); | ||
|
||
return encodeFromVoting(call); | ||
} catch (error) { | ||
errors.push(error); | ||
} | ||
|
||
console.log(''); | ||
console.warn(chalk`{red calls from voting and agent failed}`); | ||
|
||
const from = await promptFrom(); | ||
|
||
if (from === 'agent') { | ||
return encodeFromAgent(call); | ||
} | ||
|
||
if (from === 'voting') { | ||
return encodeFromVoting(call); | ||
} | ||
|
||
console.dir(errors, { depth: null }); | ||
throw new Error('aborted'); | ||
}; | ||
|
||
export const promptFrom = async () => { | ||
const { from } = await prompts({ | ||
type: 'select', | ||
name: 'from', | ||
message: 'what to do?', | ||
choices: [ | ||
{ title: chalk`abort and show errors`, value: null }, | ||
{ | ||
title: chalk`add as a direct call {red (only choose if you know what you are doing)}`, | ||
value: 'voting', | ||
}, | ||
{ | ||
title: chalk`add as a forwarded call from agent {red (only choose if you know what you are doing)}`, | ||
value: 'agent', | ||
}, | ||
], | ||
initial: 0, | ||
}); | ||
|
||
return from; | ||
}; | ||
|
||
export const encodeFromAgent = (call: CallScriptAction) => { | ||
const encoded = encodeCallScript([call]); | ||
const [agentEncoded, agentCall] = agentForward(encoded); | ||
return [agentEncoded, agentCall] as const; | ||
}; | ||
|
||
export const encodeFromVoting = (call: CallScriptAction) => { | ||
const encoded = encodeCallScript([call]); | ||
return [encoded, call] as const; | ||
}; |
Oops, something went wrong.