Created
August 26, 2021 14:21
-
-
Save HoneyIsMoney/e511c063ae75a46f89293a2cc1f1e56e to your computer and use it in GitHub Desktop.
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
const Web3 = require("web3"); | |
const ethers = require("ethers"); | |
const ethProvider = require("eth-provider"); | |
const abi = require("web3-eth-abi"); | |
const pkg = require("web3-utils"); | |
const { keccak256 } = pkg; | |
// Settings | |
const lendingPool = ""; | |
const voting = ""; | |
const agent = ""; | |
const run = async () => { | |
// This script uses frame for safe signing in the command line, ensure | |
// the account your using has signed the Garden agreement and staked funds | |
// avalable, also your frame account needs to be unlocked | |
const provider = new ethers.providers.Web3Provider( | |
new Web3(ethProvider())._provider | |
); | |
const signer = provider.getSigner(); | |
//console.log(`using: ${(await provider.provider.enable())[0]}`); | |
// 1. encode lending pool call data | |
const lendingPoolCallData = await encodeActCall("setPause(bool)", [true]); | |
// 2. using the call data from the lending pool call the execute function | |
// on the agent | |
// https://github.com/aragon/aragon-apps/blob/631048d54b9cc71058abb8bd7c17f6738755d950/apps/agent/contracts/Agent.sol#L70 | |
const agentCallData = await encodeActCall("execute(address,uint256,bytes)", [ | |
lendingPool, | |
0, | |
lendingPoolCallData, | |
]); | |
// 3. create call script | |
const callscript = encodeCallScript([ | |
{ | |
to: agent, | |
calldata: agentCallData, | |
}, | |
]); | |
// 4. create the voting contract we want to interact with | |
const votingApp = new ethers.Contract( | |
voting, | |
["function newVote(bytes,bytes) external"], | |
signer | |
); | |
// 5. create transaction logging the callscript to the console for enacting | |
// the vote when it passes, (only nessasary for disputable voting) | |
console.log(` | |
${callscript} | |
`); | |
await votingApp.newVote(callscript, "0x"); | |
}; | |
run() | |
.then(() => process.exit(0)) | |
.catch((e) => { | |
console.error(e); | |
process.exit(1); | |
}); | |
////////////////////////////////////////////////////////////// | |
//////////////////// Just Some EVM Magic ///////////////////// | |
/////////////////// Nothing to see here! //////////////////// | |
////////////////////////////////////////////////////////////// | |
function stripBytePrefix(bytes) { | |
return bytes.substring(0, 2) === "0x" ? bytes.slice(2) : bytes; | |
} | |
function createExecutorId(id) { | |
return `0x${String(id).padStart(8, "0")}`; | |
} | |
function encodeCallScript(actions, specId = 1) { | |
return actions.reduce((script, { to, calldata }) => { | |
const addr = abi.encodeParameter("address", to); | |
const calldataBytes = stripBytePrefix(calldata.slice(2)); | |
const length = abi.encodeParameter("uint256", calldataBytes.length / 2); | |
return ( | |
script + | |
stripBytePrefix(addr).slice(24) + | |
stripBytePrefix(length).slice(56) + | |
calldataBytes | |
); | |
}, createExecutorId(specId)); | |
} | |
function encodeActCall(signature, params = []) { | |
const sigBytes = abi.encodeFunctionSignature(signature); | |
const types = signature.replace(")", "").split("(")[1]; | |
if (types === "") { | |
return sigBytes; | |
} | |
const paramBytes = abi.encodeParameters(types.split(","), params); | |
return `${sigBytes}${paramBytes.slice(2)}`; | |
} | |
const EMPTY_CALLS_SCRIPT = createExecutorId(1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment