Skip to content

Instantly share code, notes, and snippets.

@HoneyIsMoney
Created August 26, 2021 14:21
Show Gist options
  • Save HoneyIsMoney/e511c063ae75a46f89293a2cc1f1e56e to your computer and use it in GitHub Desktop.
Save HoneyIsMoney/e511c063ae75a46f89293a2cc1f1e56e to your computer and use it in GitHub Desktop.
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