Skip to content

Commit 592c92c

Browse files
committed
feat: add createEvmScript for new-vote
1 parent 973f4a2 commit 592c92c

File tree

5 files changed

+177
-3
lines changed

5 files changed

+177
-3
lines changed

src/constants/dao/actions.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import {IDict} from "../../interfaces";
2+
import gaugeControllerABI from "../abis/gaugecontroller.json" assert { type: 'json' };
3+
import votingEscrowABI from '../abis/votingescrow.json' assert { type: 'json' };
4+
5+
export const poolActions = [
6+
'commit_new_fee',
7+
'ramp_A',
8+
'commit_transfer_ownership',
9+
'withdraw_admin_fees',
10+
'unkill_me',
11+
'apply_transfer_ownership',
12+
'revert_transfer_ownership',
13+
'apply_new_fee',
14+
'stop_ramp_A',
15+
'revert_new_parameters',
16+
]
17+
18+
export const DaoAbiDictionaries: Record<string, IDict<any>> = {
19+
pools: {
20+
'commit_new_fee': undefined,
21+
'ramp_A': undefined,
22+
'commit_transfer_ownership': undefined,
23+
'withdraw_admin_fees': undefined,
24+
'unkill_me': undefined,
25+
'apply_transfer_ownership': undefined,
26+
'revert_transfer_ownership': undefined,
27+
'apply_new_fee': undefined,
28+
'stop_ramp_A': undefined,
29+
'revert_new_parameters': undefined,
30+
},
31+
gauges: {
32+
'commit_transfer_ownership': gaugeControllerABI,
33+
'add_type': gaugeControllerABI,
34+
'add_gauge': gaugeControllerABI,
35+
'change_type_weight': gaugeControllerABI,
36+
'change_gauge_weight': gaugeControllerABI,
37+
'apply_transfer_ownership': gaugeControllerABI,
38+
},
39+
member: {
40+
'mint': undefined,
41+
'burn': undefined,
42+
},
43+
escrow: {
44+
'commit_transfer_ownership': votingEscrowABI,
45+
'commit_smart_wallet_checker': votingEscrowABI,
46+
'apply_transfer_ownership': votingEscrowABI,
47+
'apply_smart_wallet_checker': votingEscrowABI,
48+
},
49+
poolProxy: {
50+
'commit_set_admins': undefined,
51+
'set_burner': undefined,
52+
'apply_set_admins': undefined,
53+
},
54+
registry: {
55+
'add_pool': undefined,
56+
'add_pool_without_underlying': undefined,
57+
'remove_pool': undefined,
58+
'set_returns_none': undefined,
59+
'set_gas_estimate_contract': undefined,
60+
'set_calculator': undefined,
61+
'set_burner': undefined,
62+
'apply_set_admins': undefined,
63+
'commit_transfer_ownership': undefined,
64+
'apply_transfer_ownership': undefined,
65+
'revert_transfer_ownership': undefined,
66+
'claim_token_balance': undefined,
67+
'claim_eth_balance': undefined,
68+
},
69+
vesting: {
70+
'fund_individual': undefined,
71+
'toggle_disable': undefined,
72+
'disable_can_disable': undefined,
73+
},
74+
}

src/dao.ts

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { Contract } from "ethers";
33
import { _getAllGauges, _getDaoProposalList, _getDaoProposal } from './external-api.js';
44
import {
55
_getAddress,
6-
DIGas, ensureAllowance, ensureAllowanceEstimateGas, hasAllowance,
6+
DIGas,
7+
ensureAllowance,
8+
ensureAllowanceEstimateGas,
9+
hasAllowance,
710
mulBy1_3,
811
parseUnits,
912
smartNumber,
@@ -17,8 +20,14 @@ import {
1720
IDaoProposalUserListItem,
1821
IDaoProposal,
1922
IDict,
23+
IDaoAction,
24+
TDaoActionType,
25+
TDaoAvailableMethodsOfPool,
2026
} from './interfaces';
2127
import feeDistributorViewABI from "./constants/abis/fee_distributor_view.json" assert { type: 'json' };
28+
import {poolActions} from "./constants/dao/actions";
29+
import gaugeControllerABI from "./constants/abis/gaugecontroller.json";
30+
import axios from "axios";
2231

2332

2433
// ----------------- Refactored boosting stuff -----------------
@@ -382,3 +391,75 @@ export const voteForProposalEstimateGas = async (type: "PARAMETER" | "OWNERSHIP"
382391
export const voteForProposal = async (type: "PARAMETER" | "OWNERSHIP", id: number, support: boolean): Promise<string> => {
383392
return await _voteForProposal(type, id, support, false) as string;
384393
}
394+
395+
export const getAvailableMethodsOfPool = (address: string):TDaoAvailableMethodsOfPool => {
396+
const result: TDaoAvailableMethodsOfPool = {};
397+
poolActions.forEach((item) => {
398+
if(curve.contracts[address].contract.interface.fragments.find((method: any) => method.name === item)) {
399+
result[item] = true;
400+
} else {
401+
result[item] = false;
402+
}
403+
})
404+
405+
return result;
406+
}
407+
408+
export const createActionForVote = (actionType: TDaoActionType, address: string, method: string, args: any[]): IDaoAction => {
409+
if(actionType === 'pools') {
410+
if(!getAvailableMethodsOfPool(address)[method]) {
411+
throw Error(`Method ${{method}} is not available for this pool`);
412+
} else {
413+
return {
414+
address,
415+
contract: curve.contracts[address].contract,
416+
method,
417+
args,
418+
}
419+
}
420+
}
421+
if(actionType === 'gauges') {
422+
return {
423+
address,
424+
contract: new Contract(address, gaugeControllerABI, curve.signer || curve.provider),
425+
method,
426+
args,
427+
}
428+
}
429+
430+
throw Error('Unavailable pool type')
431+
}
432+
433+
export const createEvmScript = async (address: string, abi: any, action: IDaoAction) => {
434+
const agent = new Contract(address, abi, curve.signer || curve.provider)
435+
const zeroPad = (num: string, places: number) =>
436+
String(num).padStart(places, "0");
437+
438+
let evm_script = "0x00000001"
439+
440+
const contract = action.contract;
441+
const call_data = contract.interface.encodeFunctionData(action.method, [...action.args])
442+
443+
const agent_calldata = agent.interface
444+
.encodeFunctionData("execute", [action.address, 0, call_data])
445+
.substring(2);
446+
447+
const length = zeroPad((Math.floor(agent_calldata.length) / 2).toString(16), 8);
448+
449+
evm_script = `${evm_script}${address.substring(2)}${length}${agent_calldata}`;
450+
451+
return evm_script
452+
}
453+
454+
export const createVoteDescription = async (description: string) => {
455+
const vote_description = description.replace(/(\r\n|\n|\r)/gm, "");
456+
const vote_data = {
457+
text: vote_description,
458+
};
459+
460+
const data = new FormData();
461+
data.append("file", JSON.stringify(vote_data));
462+
const url = `https://ipfs.infura.io:5001/api/v0/add`;
463+
const response = await axios.post(url, data);
464+
return response.data.Hash;
465+
}

src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ import {
125125
userProposalVotes,
126126
voteForProposalEstimateGas,
127127
voteForProposal,
128+
createEvmScript,
129+
createVoteDescription,
130+
createActionForVote,
128131
} from "./dao.js";
129132

130133
async function init (
@@ -356,6 +359,8 @@ const curve = {
356359
userProposalVotes,
357360
// Transaction methods
358361
voteForProposal,
362+
createEvmScript,
363+
createVoteDescription,
359364

360365
estimateGas: {
361366
// --- CRV lock ---

src/interfaces.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,15 @@ export interface IDaoProposal extends IDaoProposalListItem{
250250
creatorVotingPower: number,
251251
script: string,
252252
votes: IDaoProposalVote[],
253-
}
253+
}
254+
255+
export type TDaoActionType = 'pools' | 'gauges'
256+
257+
export type TDaoAvailableMethodsOfPool = Record<string, boolean>
258+
259+
export interface IDaoAction {
260+
address: string,
261+
contract: Contract,
262+
method: string,
263+
args: any[],
264+
}

tsconfig.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
// "incremental": true, /* Enable incremental compilation */
77
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
88
"module": "ESNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
9-
"lib": ["ES2020"], /* Specify library files to be included in the compilation. */
9+
"lib": [
10+
"ES2020",
11+
"dom"
12+
], /* Specify library files to be included in the compilation. */
1013
// "allowJs": true, /* Allow javascript files to be compiled. */
1114
// "checkJs": true, /* Report errors in .js files. */
1215
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */

0 commit comments

Comments
 (0)