Files
scroll/contracts/scripts/encode.ts
Max Wolff e59a1d4fba demo
2023-06-19 00:40:26 -07:00

103 lines
3.1 KiB
TypeScript

import { ethers } from "ethers";
import { Safeabi__factory, Forwarder__factory, Target__factory, Timelock__factory } from "../safeAbi";
const L2_SCROLL_SAFE_ADDR = "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853";
const L2_SCROLL_TIMELOCK_ADDR = "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318";
const L2_FORWARDER_ADDR = "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0";
const L2_TARGET_ADDR = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82";
const L2_DEPLOYER_PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
/*
TODO:
* read from env
* use approve hash flow
* read nonce from safe
* split script into schedule and execute
* add gas limit
* document how to use
* how to get addresses from deployment?
* get abis in a reasonable way
*/
/*
to get safe abi
* forge build
* cat artifacts/src/Safe.sol/Safe.json| jq .abi >> safeabi.json
* mkdir safeAbi
* npx typechain --target=ethers-v5 safeabi.json --out-dir safeAbi
repeat for forwarder, timelock, target
*/
async function main() {
const provider = new ethers.providers.JsonRpcProvider("http://localhost:1234");
const wallet = new ethers.Wallet(L2_DEPLOYER_PRIVATE_KEY, provider);
const safeContract = Safeabi__factory.connect(L2_SCROLL_SAFE_ADDR, provider);
const forwarderContract = Forwarder__factory.connect(L2_FORWARDER_ADDR, provider);
const timelockContract = Timelock__factory.connect(L2_SCROLL_TIMELOCK_ADDR, provider);
const targetContract = Target__factory.connect(L2_TARGET_ADDR, provider);
const targetCalldata = targetContract.interface.encodeFunctionData("err");
const forwarderCalldata = forwarderContract.interface.encodeFunctionData("forward", [L2_TARGET_ADDR, targetCalldata]);
const timelockScheduleCalldata = timelockContract.interface.encodeFunctionData("schedule", [
L2_FORWARDER_ADDR,
0,
forwarderCalldata,
ethers.constants.HashZero,
ethers.constants.HashZero,
0,
]);
const scheduleSafeTxHash = await safeContract.getTransactionHash(
L2_SCROLL_TIMELOCK_ADDR,
0,
timelockScheduleCalldata,
0,
0,
0,
0,
ethers.constants.AddressZero,
ethers.constants.AddressZero,
0
);
const sigRawSchedule = await wallet.signMessage(ethers.utils.arrayify(scheduleSafeTxHash));
const sigSchedule = editSig(sigRawSchedule);
await safeContract.checkNSignatures(scheduleSafeTxHash, ethers.utils.arrayify("0x00"), sigSchedule, 1);
await safeContract
.connect(wallet)
.execTransaction(
L2_SCROLL_TIMELOCK_ADDR,
0,
timelockScheduleCalldata,
0,
0,
0,
0,
ethers.constants.AddressZero,
ethers.constants.AddressZero,
sigSchedule,
{ gasLimit: 1000000 }
);
console.log("scheduled");
await timelockContract
.connect(wallet)
.execute(L2_FORWARDER_ADDR, 0, forwarderCalldata, ethers.constants.HashZero, ethers.constants.HashZero, {
gasLimit: 1000000,
});
}
// add 4 to the v byte at the end of the signature
function editSig(sig: string) {
const v = parseInt(sig.slice(-2), 16);
const newV = v + 4;
const newSig = sig.slice(0, -2) + newV.toString(16);
return newSig;
}
main();