diff --git a/cli/.gitignore b/cli/.gitignore new file mode 100644 index 0000000..6a1054c --- /dev/null +++ b/cli/.gitignore @@ -0,0 +1,12 @@ +# project +.env* + +# node +node_modules/ +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* diff --git a/cli/README.md b/cli/README.md new file mode 100644 index 0000000..6dcb174 --- /dev/null +++ b/cli/README.md @@ -0,0 +1,64 @@ +# Protego Cli Scripts + +## Usage + +### 1. Install dependencies + +``` +npm i +``` + +### 2. Run scripts + +List plans in `MCD_PAUSE` since block 16420000 +``` +npm run list 16420000 +``` + +Pending plans in `MCD_PAUSE` since block 19420069 +``` +npm run list-pending 19420069 +``` + +If no block number is passed, the script will fetch all plans since block 0. + +## Output + +``` +╔═══════════════════════╤═══════════════════════════════════╤═══════════════════════╤═══════════════════════════════════╤════════════╤════════════╤════════════╗ +║ SPELL │ HASH │ USR │ TAG │ FAX │ ETA │ STATUS ║ +╟───────────────────────┼───────────────────────────────────┼───────────────────────┼───────────────────────────────────┼────────────┼────────────┼────────────╢ +║ 0xc25A71BDF956229a035 │ 0x76167df75647db1661a3a49b83e589e │ 0xb1F78B20B3aAfdF061b │ 0xd5b5512ac3872a37517151f280f9b9f │ 0x61461954 │ 1723728263 │ EXECUTED ║ +║ e35e8038d3FeE4aBa101C │ 9daaff46af3337552e15eb80ea8acf79f │ 0E85f2D3009c436764294 │ 3f37191196b05620d19af0f3c24f55b2e │ │ │ ║ +╟───────────────────────┼───────────────────────────────────┼───────────────────────┼───────────────────────────────────┼────────────┼────────────┼────────────╢ +║ 0x8c7F12C7cE07916f631 │ 0x1e4a20372c4647e9428efabca662d47 │ 0x46DD85e91Eab604ca15 │ 0x54561a83a0e6eb1959742ac526aeaa0 │ 0x61461954 │ 1722371399 │ EXECUTED ║ +║ B25ce148e419FeFf19d46 │ 59f996f1353d2dcb05d52ed50def420f0 │ 0c26853a947617e7Ab322 │ 2e1d074fbbb8e26294b2a46a508c3ccf3 │ │ │ ║ +╟───────────────────────┼───────────────────────────────────┼───────────────────────┼───────────────────────────────────┼────────────┼────────────┼────────────╢ +║ 0x452a39C34f9539E0d50 │ 0x11e3af57c6821e4b4b45559c92f5c9d │ 0xA13D7e21643bD46E2cC │ 0x041f68b86ef5961f3d578a7192a09f1 │ 0x61461954 │ 1721070179 │ EXECUTED ║ +║ C9e33Ad423a15C6f45df4 │ a681f2b7d2d232f91d7b64aa14d317f6a │ 09E87cFB91c5B951Bd955 │ 980b42bcefa8fecb810816369420c1e0c │ │ │ ║ +╟───────────────────────┼───────────────────────────────────┼───────────────────────┼───────────────────────────────────┼────────────┼────────────┼────────────╢ +║ 0x0c0B4DA7e02960F98c2 │ 0xb8f4b59cbfe45ba425eb9c10c8a50bd │ 0x0871e28D09c29C41966 │ 0xc8dec11fc102e8810674c4db724fb12 │ 0x61461954 │ 1720383443 │ EXECUTED ║ +║ AFf2778F6f3E37321B5Dd │ 1eb919325eefdf095c44369098fd21e59 │ 9D82901d53d60A649B36D │ 9a790f93767cf54b691cbe3d2d33dd3d8 │ │ │ ║ +╟───────────────────────┼───────────────────────────────────┼───────────────────────┼───────────────────────────────────┼────────────┼────────────┼────────────╢ +║ 0x7fbC867dE58D6e47E43 │ 0x9ca00512f5e87da33fa1fa1e4834581 │ 0x261da1Cdbd788642034 │ 0x5e8fe783452994a42bbbe3b0edde5b9 │ 0x61461954 │ 1719777527 │ EXECUTED ║ +║ 0eB257B50481F6E878f65 │ c8684ebd9091c7883355ea0ca959a78f2 │ 288B6574d749198FDf75b │ 901ff6bd7561b680b42af92293206bb32 │ │ │ ║ +╟───────────────────────┼───────────────────────────────────┼───────────────────────┼───────────────────────────────────┼────────────┼────────────┼────────────╢ +║ 0x622Ad624491a01a2a6b │ 0xd37c72ea00f67c76b6cda8dc0dda0b1 │ 0x6481e7443D321fFF02A │ 0xf218b00aeb30403e97dbedd8542caf1 │ 0x61461954 │ 1718481719 │ EXECUTED ║ +║ eAD916C3Ca3B90BcA0854 │ b6f825145079e9acd23bdbcfe00259a3e │ 9A7ae883DCd13FAb64Ef7 │ a879c0e15796a20b5836cfadfe9a69b43 │ │ │ ║ +╟───────────────────────┼───────────────────────────────────┼───────────────────────┼───────────────────────────────────┼────────────┼────────────┼────────────╢ +║ 0x7B55617f7F04F7B45eE │ 0x2eb42ca4e054352eaa8ef09705925b3 │ 0x612938f231DFcd7F921 │ 0x25f5bbaef576d0cf62af933ec55a6bd │ 0x61461954 │ 1717623383 │ EXECUTED ║ +║ 865fF9066469Fbe28a632 │ c12b4c0d1a59a050a20baa2b9d44396a8 │ 81F11C9E0B575E7ed2Ec1 │ 468b65fa9902387040283da6bf88ea4a9 │ │ │ ║ +╚═══════════════════════╧═══════════════════════════════════╧═══════════════════════╧═══════════════════════════════════╧════════════╧════════════╧════════════╝ +``` + +The script outputs a table with the plans' details: +- SPELL: Address of the spell (keep in mind this only works for compliant Spells, this field lists the plan scheduler address, which is the Spell on compliant spells, if non-compliant this field should be ignored) +- HASH: Hash of the plan +- USR: Address of the `DssSpellAction` related to the Spell +- TAG: `extcodehash` from the address of `DssSpellAction` +- FAX: `callcode` to be used when calling the Spell +- ETA: Timestamp of earliest execution time +- STATUS: Status of the plan: + - PENDING: The plan has been plotted (scheduled) on Pause, and is pending execution + - EXECUTED: The plan has already been executed + - DROPPED: The plan was scheduled and subsequently dropped \ No newline at end of file diff --git a/cli/list-pause-plans.js b/cli/list-pause-plans.js new file mode 100644 index 0000000..96db40b --- /dev/null +++ b/cli/list-pause-plans.js @@ -0,0 +1,144 @@ +import { ethers } from 'ethers'; +import { table } from 'table'; +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; +import pauseABI from './pause_abi.json' with { type: 'json' }; + +const argv = yargs(hideBin(process.argv)) + .option('pending', { + alias: 'p', + type: 'boolean', + description: 'Show only pending plans', + default: false + }) + .option('fromBlock', { + alias: 'b', + type: 'number', + description: 'Display spells from a given block', + default: 0 + }) + .help() + .alias('help', 'h') + .argv; + +const PLOT_TOPIC = "0x46d2fbbb00000000000000000000000000000000000000000000000000000000"; +const EXEC_TOPIC = "0x168ccd6700000000000000000000000000000000000000000000000000000000"; +const DROP_TOPIC = "0x162c7de300000000000000000000000000000000000000000000000000000000"; +const MCD_PAUSE = "0xbE286431454714F511008713973d3B053A2d38f3"; + +const tableConfig = { + columns: { + 0: { width: 21, wrapWord: true }, + 1: { width: 33, wrapWord: true }, + 2: { width: 21, wrapWord: true }, + 3: { width: 33, wrapWord: true }, + 4: { width: 10, wrapWord: true }, + 5: { width: 10, wrapWord: true }, + 6: { width: 10, wrapWord: true } + } +}; + +function getProvider() { + const url = process.env.ETH_RPC_URL || "mainnet"; + if (!process.env.ETH_RPC_URL) { + console.warn("ETH_RPC_URL not set, falling back to a public RPC provider. For improved results set ETH_RPC_URL to a trusted node."); + } + return ethers.getDefaultProvider(url); +} + +function decodeLogNote(log, contract) { + const eventFragment = contract.interface.getEvent('LogNote'); + return contract.interface.decodeEventLog(eventFragment, log.data, log.topics).toObject(); +} + +function decodeCallParams(sig, fax, contract) { + const functionFragment = contract.interface.getFunction(sig); + return contract.interface.decodeFunctionData(functionFragment, fax).toObject(); +} + +function hash(params) { + const abiCoder = new ethers.AbiCoder(); + const types = ["address", "bytes32", "bytes", "uint256"]; + const encoded = abiCoder.encode(types, [params.usr, params.tag, params.fax, params.eta]); + return ethers.keccak256(encoded); +} + +async function getFilteredEvents(contract, fromBlock) { + try { + return await contract.queryFilter([[PLOT_TOPIC, EXEC_TOPIC, DROP_TOPIC]], fromBlock); + } catch (error) { + console.error("Error fetching filtered events:", error); + throw error; + } +} + +function processEvent(event, contract) { + const decoded = decodeLogNote(event, contract); + const decodedCall = decodeCallParams(event.topics[0].slice(0, 10), decoded.fax, contract); + return { + ...event, + decoded, + decodedCall, + planHash: hash(decodedCall) + }; +} + +function prepareData(events, contract, filter) { + const decodedEvents = events.map(event => processEvent(event, contract)); + + const tableData = []; + const hashMap = new Map(); + + decodedEvents.forEach(event => { + const planHash = event.planHash; + + if (event.topics[0] === PLOT_TOPIC) { + const row = [event.decoded.guy, planHash, event.decodedCall.usr, event.decodedCall.tag, event.decodedCall.fax.trim(), event.decodedCall.eta, "PENDING"]; + tableData.push(row); + hashMap.set(planHash, row); + } else if (event.topics[0] === EXEC_TOPIC) { + const row = hashMap.get(planHash); + if (row) { + row[6] = "EXECUTED"; + } + } else if (event.topics[0] === DROP_TOPIC) { + const row = hashMap.get(planHash); + if (row) { + row[6] = "DROPPED"; + } + } + }); + + tableData.sort((a, b) => { + const etaA = BigInt(a[5]); + const etaB = BigInt(b[5]); + return etaB > etaA ? 1 : etaB < etaA ? -1 : 0; + }); + + if (filter) + return tableData.filter(row => row[6] === filter); + else + return tableData; +} + +async function main() { + try { + const provider = getProvider(); + const pause = new ethers.Contract(MCD_PAUSE, pauseABI, provider); + + const events = await getFilteredEvents(pause, argv.fromBlock); + let tableData = prepareData(events, pause, argv.pending ? "PENDING" : null); + + tableData.unshift(["SPELL", "HASH", "USR", "TAG", "FAX", "ETA", "STATUS"]); + + if (tableData.length === 1) { + console.log("No records to display."); + } else { + console.log(table(tableData, tableConfig)); + } + } catch (error) { + console.error("An error occurred:", error); + } +} + +main(); diff --git a/cli/package-lock.json b/cli/package-lock.json new file mode 100644 index 0000000..fd05c5b --- /dev/null +++ b/cli/package-lock.json @@ -0,0 +1,346 @@ +{ + "name": "scripts", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "ethers": "^6.13.1", + "table": "^6.8.2", + "yargs": "^17.7.2" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ethers": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.1.tgz", + "integrity": "sha512-hdJ2HOxg/xx97Lm9HdCWk949BfYqYWpyw4//78SiwOLgASyfrNszfMUNB2joKjvGUdwhHfaiMMFFwacVVoLR9A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/cli/package.json b/cli/package.json new file mode 100644 index 0000000..7203e4e --- /dev/null +++ b/cli/package.json @@ -0,0 +1,12 @@ +{ + "type": "module", + "scripts": { + "list": "node --no-warnings list-pause-plans --fromBlock", + "list-pending": "node --no-warnings list-pause-plans -pending --fromBlock" + }, + "dependencies": { + "ethers": "^6.13.1", + "table": "^6.8.2", + "yargs": "^17.7.2" + } +} diff --git a/cli/pause_abi.json b/cli/pause_abi.json new file mode 100644 index 0000000..1034b2b --- /dev/null +++ b/cli/pause_abi.json @@ -0,0 +1,315 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "delay_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "contract DSAuthority", + "name": "authority_", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": true, + "inputs": [ + { + "indexed": true, + "internalType": "bytes4", + "name": "sig", + "type": "bytes4" + }, + { + "indexed": true, + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "foo", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bar", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "fax", + "type": "bytes" + } + ], + "name": "LogNote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "authority", + "type": "address" + } + ], + "name": "LogSetAuthority", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "LogSetOwner", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "authority", + "outputs": [ + { + "internalType": "contract DSAuthority", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "delay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "tag", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "fax", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "drop", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "tag", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "fax", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "exec", + "outputs": [ + { + "internalType": "bytes", + "name": "out", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "plans", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "tag", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "fax", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "plot", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "proxy", + "outputs": [ + { + "internalType": "contract DSPauseProxy", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract DSAuthority", + "name": "authority_", + "type": "address" + } + ], + "name": "setAuthority", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "delay_", + "type": "uint256" + } + ], + "name": "setDelay", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file