dexe-mcp 0.5.8 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +641 -536
- package/README.md +289 -270
- package/SECURITY.md +96 -46
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +60 -0
- package/dist/config.js.map +1 -1
- package/dist/governor/adapter.d.ts +90 -0
- package/dist/governor/adapter.d.ts.map +1 -0
- package/dist/governor/adapter.js +169 -0
- package/dist/governor/adapter.js.map +1 -0
- package/dist/governor/configs/compound.json +32 -0
- package/dist/governor/configs/optimism.json +28 -0
- package/dist/governor/configs/uniswap.json +32 -0
- package/dist/governor/encoder.d.ts +59 -0
- package/dist/governor/encoder.d.ts.map +1 -0
- package/dist/governor/encoder.js +290 -0
- package/dist/governor/encoder.js.map +1 -0
- package/dist/governor/index.d.ts +11 -0
- package/dist/governor/index.d.ts.map +1 -0
- package/dist/governor/index.js +20 -0
- package/dist/governor/index.js.map +1 -0
- package/dist/governor/loader.d.ts +42 -0
- package/dist/governor/loader.d.ts.map +1 -0
- package/dist/governor/loader.js +103 -0
- package/dist/governor/loader.js.map +1 -0
- package/dist/governor/tally.d.ts +48 -0
- package/dist/governor/tally.d.ts.map +1 -0
- package/dist/governor/tally.js +103 -0
- package/dist/governor/tally.js.map +1 -0
- package/dist/governor/tools/build.d.ts +3 -0
- package/dist/governor/tools/build.d.ts.map +1 -0
- package/dist/governor/tools/build.js +137 -0
- package/dist/governor/tools/build.js.map +1 -0
- package/dist/governor/tools/extras.d.ts +4 -0
- package/dist/governor/tools/extras.d.ts.map +1 -0
- package/dist/governor/tools/extras.js +197 -0
- package/dist/governor/tools/extras.js.map +1 -0
- package/dist/governor/tools/read.d.ts +4 -0
- package/dist/governor/tools/read.d.ts.map +1 -0
- package/dist/governor/tools/read.js +174 -0
- package/dist/governor/tools/read.js.map +1 -0
- package/dist/governor/tools/simulate.d.ts +6 -0
- package/dist/governor/tools/simulate.d.ts.map +1 -0
- package/dist/governor/tools/simulate.js +191 -0
- package/dist/governor/tools/simulate.js.map +1 -0
- package/dist/lib/broadcastGuards.d.ts +41 -0
- package/dist/lib/broadcastGuards.d.ts.map +1 -0
- package/dist/lib/broadcastGuards.js +85 -0
- package/dist/lib/broadcastGuards.js.map +1 -0
- package/dist/lib/ethersProvider.d.ts +96 -0
- package/dist/lib/ethersProvider.d.ts.map +1 -0
- package/dist/lib/ethersProvider.js +170 -0
- package/dist/lib/ethersProvider.js.map +1 -0
- package/dist/lib/signer.d.ts +2 -0
- package/dist/lib/signer.d.ts.map +1 -1
- package/dist/lib/signer.js +4 -0
- package/dist/lib/signer.js.map +1 -1
- package/dist/tools/flow.d.ts.map +1 -1
- package/dist/tools/flow.js +13 -0
- package/dist/tools/flow.js.map +1 -1
- package/dist/tools/getConfig.d.ts.map +1 -1
- package/dist/tools/getConfig.js +17 -0
- package/dist/tools/getConfig.js.map +1 -1
- package/dist/tools/inbox.js +8 -8
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/predict.js +17 -17
- package/dist/tools/safe.d.ts +5 -0
- package/dist/tools/safe.d.ts.map +1 -0
- package/dist/tools/safe.js +264 -0
- package/dist/tools/safe.js.map +1 -0
- package/dist/tools/simulate.d.ts +7 -0
- package/dist/tools/simulate.d.ts.map +1 -1
- package/dist/tools/simulate.js +8 -0
- package/dist/tools/simulate.js.map +1 -1
- package/dist/tools/subgraph.js +162 -162
- package/dist/tools/txSend.d.ts.map +1 -1
- package/dist/tools/txSend.js +25 -0
- package/dist/tools/txSend.js.map +1 -1
- package/package.json +95 -92
package/SECURITY.md
CHANGED
|
@@ -1,46 +1,96 @@
|
|
|
1
|
-
# Security Policy
|
|
2
|
-
|
|
3
|
-
## Supported Versions
|
|
4
|
-
|
|
5
|
-
Only the latest published version on npm receives security updates. Pin to the latest minor (`^0.5`) in your MCP client config.
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
If you
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Only the latest published version on npm receives security updates. Pin to the latest minor (`^0.5`) in your MCP client config.
|
|
6
|
+
|
|
7
|
+
## Automated security checks
|
|
8
|
+
|
|
9
|
+
The repo runs four GitHub Actions security workflows continuously:
|
|
10
|
+
|
|
11
|
+
- **CI** (`ci.yml`) — typecheck and build on every push to `main` and every pull request, against Node 20 and 22, plus a `verify-lockfile` integrity job. The test step (`vitest`) runs whenever test files are present on the branch; it is currently a no-op via `--passWithNoTests` (the suite lives on `governor-adapter`) and becomes an enforcing gate once those tests merge. Read-only `GITHUB_TOKEN` scope.
|
|
12
|
+
- **Dependency Review** (`dependency-review.yml`) — every PR is checked against the GitHub Advisory Database. Fails the PR check if any added/updated dependency carries a `high` or `critical` CVE, or if it introduces a forbidden license (GPL/AGPL).
|
|
13
|
+
- **OSSF Scorecard** (`scorecard.yml`) — weekly + on push to `main`. Audits branch protection, signed releases, pinned dependencies, token permissions, and a dozen other supply-chain checks. Results uploaded to GitHub code-scanning (SARIF) and published as a public score at `https://api.securityscorecards.dev/projects/github.com/edward-arinin-web-dev/dexe-mcp/badge`.
|
|
14
|
+
- **CodeQL** (`codeql.yml`) — GitHub-native SAST with the `security-extended` query suite. Runs on every PR/main push and weekly. Scans for prototype pollution, command injection, ReDoS, unsafe deserialization, path traversal, and other CWE patterns. Findings land in the repo's Security tab.
|
|
15
|
+
|
|
16
|
+
## Release provenance
|
|
17
|
+
|
|
18
|
+
Every npm release from `v0.5.9` onwards is published via `.github/workflows/release.yml` with `npm publish --provenance`. The signed attestation links the tarball to the exact git commit and GitHub Actions run that produced it. Verify in three ways:
|
|
19
|
+
|
|
20
|
+
- The npmjs.com page for the package shows a "Provenance" badge with the source repo and workflow run.
|
|
21
|
+
- `npm view dexe-mcp dist.signatures` returns Sigstore signatures.
|
|
22
|
+
- `npm audit signatures` against an installed copy fails if the registry tarball was tampered with.
|
|
23
|
+
|
|
24
|
+
If you ever install a `dexe-mcp` version that lacks a provenance attestation (and is not a pre-`v0.5.9` historical release), treat it as suspect and report.
|
|
25
|
+
|
|
26
|
+
## Signed release tags
|
|
27
|
+
|
|
28
|
+
Every release tag is GPG-signed by the maintainer, and `release.yml` runs `git verify-tag "$GITHUB_REF_NAME"` **before** the publish step — an unsigned tag, an invalid signature, or a tag signed by an unknown key aborts the release, so a pushed tag can never publish to npm without a valid maintainer signature.
|
|
29
|
+
|
|
30
|
+
To verify a tag yourself after cloning the repo:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Import the maintainer's public key once (key id published alongside releases).
|
|
34
|
+
gpg --recv-keys <MAINTAINER_KEY_ID>
|
|
35
|
+
|
|
36
|
+
# Verify a specific tag — exits non-zero if unsigned or signed by an unknown key.
|
|
37
|
+
git verify-tag v0.5.9
|
|
38
|
+
# Equivalent shorthand:
|
|
39
|
+
git tag -v v0.5.9
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A clean `gpg: Good signature from "<maintainer>"` line is the only acceptable result. `error: ... no signature found` (unsigned) or `Can't check signature: No public key` (unknown signer) means do not trust the tag.
|
|
43
|
+
|
|
44
|
+
## Reporting a Vulnerability
|
|
45
|
+
|
|
46
|
+
If you find a vulnerability in `dexe-mcp` — whether in the calldata builders, the optional signer (`DEXE_PRIVATE_KEY`), IPFS upload paths, or the Hardhat bridge — please **do not** open a public GitHub issue.
|
|
47
|
+
|
|
48
|
+
Email: **edward.arinin@gmail.com**
|
|
49
|
+
|
|
50
|
+
Include:
|
|
51
|
+
|
|
52
|
+
- A description of the issue and its impact (what an attacker can do, under what conditions).
|
|
53
|
+
- A minimal reproduction: the tool call, env vars (redacted), and the resulting behavior.
|
|
54
|
+
- Affected version (`dexe-mcp --version` or check `package.json`).
|
|
55
|
+
- Suggested mitigation, if you have one.
|
|
56
|
+
|
|
57
|
+
You should expect an acknowledgement within 72 hours. A coordinated-disclosure timeline will be agreed before any public advisory is filed.
|
|
58
|
+
|
|
59
|
+
## Scope
|
|
60
|
+
|
|
61
|
+
In scope:
|
|
62
|
+
|
|
63
|
+
- Calldata-builder tools (`dexe_proposal_build_*`, `dexe_vote_build_*`, `dexe_dao_build_deploy`) that produce calldata that does not match the intended action.
|
|
64
|
+
- Signer mode (`dexe_tx_send`, auto-broadcast in `dexe_proposal_create` / `dexe_proposal_vote_and_execute`) leaking or misusing the configured private key.
|
|
65
|
+
- IPFS upload paths that exfiltrate non-public data or accept unsafe input.
|
|
66
|
+
- Hardhat bridge (`dexe_compile`, `dexe_test`, etc.) executing unintended shell commands.
|
|
67
|
+
- Dependency vulnerabilities reachable through `dexe-mcp`'s exposed tool surface.
|
|
68
|
+
|
|
69
|
+
Out of scope:
|
|
70
|
+
|
|
71
|
+
- Vulnerabilities in the on-chain DeXe Protocol contracts (report at <https://github.com/dexe-network>).
|
|
72
|
+
- Issues that require the operator to set obviously unsafe env values (e.g. `DEXE_PRIVATE_KEY=<a key the attacker already controls>`).
|
|
73
|
+
- General npm-registry / npm-cli / Node.js issues unrelated to this package.
|
|
74
|
+
|
|
75
|
+
## Threat Model
|
|
76
|
+
|
|
77
|
+
`dexe-mcp` runs **locally** alongside an MCP client (Claude Desktop, Claude Code, etc.). It does not bind a network port and does not expose itself to the public internet. The interesting attack surfaces are:
|
|
78
|
+
|
|
79
|
+
1. The operator's private key in signer mode — never logged, never sent off-host, only used by `ethers.Wallet` to sign payloads the operator has already approved at the agent level.
|
|
80
|
+
2. Calldata correctness — every `_build_*` tool emits a `TxPayload` the operator can decode (`dexe_decode_calldata`, `dexe_decode_proposal`) and sign-verify before broadcasting.
|
|
81
|
+
3. IPFS pinning credentials — keep `PINATA_JWT` scoped to a project-specific key.
|
|
82
|
+
|
|
83
|
+
If you believe any of the above is broken, please report per the process above.
|
|
84
|
+
|
|
85
|
+
## Signer broadcast guards
|
|
86
|
+
|
|
87
|
+
When signer mode is enabled (`DEXE_PRIVATE_KEY`), `dexe_tx_send` runs four opt-in guards before broadcasting (`src/lib/broadcastGuards.ts`). They narrow the blast radius of a compromised or runaway MCP host — the host can still *call* the tool, but cannot send to arbitrary destinations, drain arbitrary value, pay gas for reverting txs, or loop unbounded. Each is a no-op unless its env var is set; a failed guard returns `{ status: "rejected", guard, reason }` with **no gas spent**.
|
|
88
|
+
|
|
89
|
+
| Guard | Env var | What it blocks |
|
|
90
|
+
|-------|---------|----------------|
|
|
91
|
+
| **B6** destination allowlist | `DEXE_SIGNER_ALLOWLIST` | Broadcasts to any `to` not on the comma-separated list. |
|
|
92
|
+
| **B7** value cap | `DEXE_SIGNER_MAX_VALUE_WEI` | Broadcasts whose `value` (wei) exceeds the cap. |
|
|
93
|
+
| **B9** auto-simulation | _(always on in signer mode)_ | Doomed txs — `eth_call` preflight aborts with the decoded revert reason before gas is spent. |
|
|
94
|
+
| **B10** rate limit | `DEXE_SIGNER_MAX_BROADCASTS_PER_MIN` | More than N broadcasts in a rolling 60s window. |
|
|
95
|
+
|
|
96
|
+
These are defense-in-depth, **not** a substitute for keeping the key off-host. For prod governance/treasury actions, prefer calldata mode + Safe Multisig / Ledger. See `docs/ENVIRONMENT.md` §4 for the recommended config block.
|
package/dist/config.d.ts
CHANGED
|
@@ -34,6 +34,15 @@ export interface DexeConfig {
|
|
|
34
34
|
forkBlock?: number;
|
|
35
35
|
/** Private key for tx signing. When set, `dexe_tx_send` can broadcast. */
|
|
36
36
|
privateKey?: string;
|
|
37
|
+
/**
|
|
38
|
+
* B6 — destination allowlist for `dexe_tx_send`. Lowercased, checksummed-then-
|
|
39
|
+
* lowercased addresses. Undefined/empty = no restriction.
|
|
40
|
+
*/
|
|
41
|
+
signerAllowlist?: string[];
|
|
42
|
+
/** B7 — max wei value per broadcast. Undefined = no cap. */
|
|
43
|
+
signerMaxValueWei?: bigint;
|
|
44
|
+
/** B10 — max broadcasts per rolling minute. Undefined = no limit. */
|
|
45
|
+
signerMaxBroadcastsPerMin?: number;
|
|
37
46
|
}
|
|
38
47
|
/**
|
|
39
48
|
* Reads environment and returns a frozen config. **Fast and side-effect-free**
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,YAAY,EAAE,MAAM,CAAC;IAErB,uEAAuE;IACvE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACzC;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,YAAY,EAAE,MAAM,CAAC;IAErB,uEAAuE;IACvE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACzC;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAwMtD;AAcD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAW9E"}
|
package/dist/config.js
CHANGED
|
@@ -34,6 +34,20 @@ export async function loadConfig() {
|
|
|
34
34
|
if (rpcMainnet) {
|
|
35
35
|
chains.set(56, { chainId: 56, rpcUrl: rpcMainnet });
|
|
36
36
|
}
|
|
37
|
+
// Generic per-chain RPC: DEXE_RPC_URL_<chainId> (e.g. DEXE_RPC_URL_1,
|
|
38
|
+
// DEXE_RPC_URL_10). Enables chains beyond BSC — notably the external
|
|
39
|
+
// Governor DAOs, which live on Ethereum (1) and Optimism (10). The numeric
|
|
40
|
+
// suffix never collides with the named *_TESTNET / *_MAINNET vars above.
|
|
41
|
+
for (const [key, val] of Object.entries(process.env)) {
|
|
42
|
+
const m = /^DEXE_RPC_URL_(\d+)$/.exec(key);
|
|
43
|
+
if (!m)
|
|
44
|
+
continue;
|
|
45
|
+
const url = val?.trim();
|
|
46
|
+
if (!url)
|
|
47
|
+
continue;
|
|
48
|
+
const cid = Number(m[1]);
|
|
49
|
+
chains.set(cid, { chainId: cid, rpcUrl: url });
|
|
50
|
+
}
|
|
37
51
|
// Legacy single-chain env (still supported)
|
|
38
52
|
const legacyRpc = process.env.DEXE_RPC_URL?.trim() || undefined;
|
|
39
53
|
let legacyChainId;
|
|
@@ -106,6 +120,49 @@ export async function loadConfig() {
|
|
|
106
120
|
const addr = new Wallet(privateKey).address;
|
|
107
121
|
process.stderr.write(`[dexe-mcp] signing enabled for ${addr}\n`);
|
|
108
122
|
}
|
|
123
|
+
// ---- signer broadcast guard B6 (destination allowlist) -----------------
|
|
124
|
+
// Opt-in; only meaningful in signer mode. Parses to undefined when unset,
|
|
125
|
+
// leaving the default posture unchanged.
|
|
126
|
+
let signerAllowlist;
|
|
127
|
+
const allowlistRaw = process.env.DEXE_SIGNER_ALLOWLIST?.trim();
|
|
128
|
+
if (allowlistRaw) {
|
|
129
|
+
const { isAddress, getAddress } = await import("ethers");
|
|
130
|
+
const normalized = [];
|
|
131
|
+
for (const entry of allowlistRaw.split(",").map(s => s.trim()).filter(Boolean)) {
|
|
132
|
+
if (!isAddress(entry)) {
|
|
133
|
+
fatal(`DEXE_SIGNER_ALLOWLIST contains an invalid address: ${entry}`);
|
|
134
|
+
}
|
|
135
|
+
normalized.push(getAddress(entry).toLowerCase());
|
|
136
|
+
}
|
|
137
|
+
if (normalized.length > 0)
|
|
138
|
+
signerAllowlist = normalized;
|
|
139
|
+
}
|
|
140
|
+
// ---- signer broadcast guard B7 (value cap) -----------------------------
|
|
141
|
+
let signerMaxValueWei;
|
|
142
|
+
const maxValueRaw = process.env.DEXE_SIGNER_MAX_VALUE_WEI?.trim();
|
|
143
|
+
if (maxValueRaw) {
|
|
144
|
+
let parsed;
|
|
145
|
+
try {
|
|
146
|
+
parsed = BigInt(maxValueRaw);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
fatal(`DEXE_SIGNER_MAX_VALUE_WEI must be a non-negative integer (wei), got: ${maxValueRaw}`);
|
|
150
|
+
}
|
|
151
|
+
if (parsed < 0n) {
|
|
152
|
+
fatal(`DEXE_SIGNER_MAX_VALUE_WEI must be a non-negative integer (wei), got: ${maxValueRaw}`);
|
|
153
|
+
}
|
|
154
|
+
signerMaxValueWei = parsed;
|
|
155
|
+
}
|
|
156
|
+
// ---- signer broadcast guard B10 (rate limit) ---------------------------
|
|
157
|
+
let signerMaxBroadcastsPerMin;
|
|
158
|
+
const maxBroadcastsRaw = process.env.DEXE_SIGNER_MAX_BROADCASTS_PER_MIN?.trim();
|
|
159
|
+
if (maxBroadcastsRaw) {
|
|
160
|
+
const n = Number(maxBroadcastsRaw);
|
|
161
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
162
|
+
fatal(`DEXE_SIGNER_MAX_BROADCASTS_PER_MIN must be a positive integer, got: ${maxBroadcastsRaw}`);
|
|
163
|
+
}
|
|
164
|
+
signerMaxBroadcastsPerMin = n;
|
|
165
|
+
}
|
|
109
166
|
let forkBlock;
|
|
110
167
|
if (process.env.DEXE_FORK_BLOCK) {
|
|
111
168
|
const n = Number(process.env.DEXE_FORK_BLOCK);
|
|
@@ -128,6 +185,9 @@ export async function loadConfig() {
|
|
|
128
185
|
subgraphInteractionsUrl,
|
|
129
186
|
forkBlock,
|
|
130
187
|
privateKey,
|
|
188
|
+
signerAllowlist,
|
|
189
|
+
signerMaxValueWei,
|
|
190
|
+
signerMaxBroadcastsPerMin,
|
|
131
191
|
});
|
|
132
192
|
}
|
|
133
193
|
/**
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Contract, type JsonRpcProvider } from "ethers";
|
|
2
|
+
import type { GovernorConfig } from "./loader.js";
|
|
3
|
+
/**
|
|
4
|
+
* Read surfaces for the two Governor families we target.
|
|
5
|
+
*
|
|
6
|
+
* - **OZ v4 / v5** (Optimism, post-2022 OZ Governor deploys): `state`,
|
|
7
|
+
* `proposalSnapshot`, `proposalDeadline`, `proposalVotes`, `quorum(uint256)`,
|
|
8
|
+
* `proposalThreshold`, etc.
|
|
9
|
+
* - **Bravo v3** (Uniswap, Compound): `state`, `proposals(uint256)` returning a
|
|
10
|
+
* flat struct, `quorumVotes()` (fixed quorum, no per-block snapshot),
|
|
11
|
+
* `proposalThreshold`. No `proposalSnapshot` / `proposalDeadline` /
|
|
12
|
+
* `quorum(blockNumber)`.
|
|
13
|
+
*
|
|
14
|
+
* The canonical `ProposalState` enum order is identical across both families.
|
|
15
|
+
*/
|
|
16
|
+
export declare const GOVERNOR_OZ_READ_ABI: readonly ["function state(uint256 proposalId) view returns (uint8)", "function proposalSnapshot(uint256 proposalId) view returns (uint256)", "function proposalDeadline(uint256 proposalId) view returns (uint256)", "function proposalVotes(uint256 proposalId) view returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes)", "function proposalThreshold() view returns (uint256)", "function quorum(uint256 blockNumber) view returns (uint256)", "function votingDelay() view returns (uint256)", "function votingPeriod() view returns (uint256)", "function hasVoted(uint256 proposalId, address account) view returns (bool)", "function hashProposal(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) pure returns (uint256)", "function name() view returns (string)", "function version() view returns (string)"];
|
|
17
|
+
export declare const GOVERNOR_BRAVO_READ_ABI: readonly ["function state(uint256 proposalId) view returns (uint8)", "function proposals(uint256 proposalId) view returns (uint256 id, address proposer, uint256 eta, uint256 startBlock, uint256 endBlock, uint256 forVotes, uint256 againstVotes, uint256 abstainVotes, bool canceled, bool executed)", "function proposalThreshold() view returns (uint256)", "function quorumVotes() view returns (uint256)", "function votingDelay() view returns (uint256)", "function votingPeriod() view returns (uint256)", "function hasVoted(uint256 proposalId, address account) view returns (bool)", "function name() view returns (string)"];
|
|
18
|
+
export declare const IVOTES_ABI: readonly ["function getVotes(address account) view returns (uint256)", "function getPastVotes(address account, uint256 blockNumber) view returns (uint256)", "function delegates(address account) view returns (address)"];
|
|
19
|
+
/**
|
|
20
|
+
* Compound-style vote getters. Bravo voting tokens (COMP, UNI) expose
|
|
21
|
+
* `getCurrentVotes(address)` / `getPriorVotes(address, uint256)` instead of the
|
|
22
|
+
* OZ `getVotes` / `getPastVotes`. Routing is static by `votingToken.type`
|
|
23
|
+
* (see `readVotingPower`) — `ERC20VotesComp` always uses these getters; there is
|
|
24
|
+
* no runtime fallback between the two interfaces.
|
|
25
|
+
*/
|
|
26
|
+
export declare const IVOTES_COMP_ABI: readonly ["function getCurrentVotes(address account) view returns (uint96)", "function getPriorVotes(address account, uint256 blockNumber) view returns (uint96)", "function delegates(address account) view returns (address)"];
|
|
27
|
+
export declare const PROPOSAL_STATE: readonly string[];
|
|
28
|
+
export declare function stateName(stateIndex: number): string;
|
|
29
|
+
export declare function isBravo(cfg: GovernorConfig): boolean;
|
|
30
|
+
export declare function governorContract(provider: JsonRpcProvider, cfg: GovernorConfig): Contract;
|
|
31
|
+
export declare function votesContract(provider: JsonRpcProvider, cfg: GovernorConfig): Contract;
|
|
32
|
+
/**
|
|
33
|
+
* Family-agnostic voting-power read. ERC20VotesComp (UNI, COMP) exposes
|
|
34
|
+
* `getCurrentVotes` / `getPriorVotes`; ERC20Votes (OP, modern OZ) exposes
|
|
35
|
+
* `getVotes` / `getPastVotes`. Returns wei + the actual method invoked.
|
|
36
|
+
*/
|
|
37
|
+
export declare function readVotingPower(c: Contract, cfg: GovernorConfig, account: string, blockNumber: number | undefined): Promise<{
|
|
38
|
+
power: bigint;
|
|
39
|
+
method: string;
|
|
40
|
+
}>;
|
|
41
|
+
export interface ProposalReadout {
|
|
42
|
+
state: {
|
|
43
|
+
index: number;
|
|
44
|
+
name: string;
|
|
45
|
+
};
|
|
46
|
+
snapshotBlock: string;
|
|
47
|
+
deadlineBlock: string;
|
|
48
|
+
votes: {
|
|
49
|
+
against: string;
|
|
50
|
+
for: string;
|
|
51
|
+
abstain: string;
|
|
52
|
+
};
|
|
53
|
+
bravoExtra?: {
|
|
54
|
+
proposer: string;
|
|
55
|
+
eta: string;
|
|
56
|
+
canceled: boolean;
|
|
57
|
+
executed: boolean;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Family-agnostic proposal read. Maps Bravo's `proposals(uint256)` struct onto
|
|
62
|
+
* the OZ-style {snapshot, deadline, votes} shape so callers don't branch.
|
|
63
|
+
*/
|
|
64
|
+
export declare function readProposal(c: Contract, cfg: GovernorConfig, proposalId: bigint): Promise<ProposalReadout>;
|
|
65
|
+
/**
|
|
66
|
+
* Returns the active quorum value. For OZ v4+ this is `quorum(blockNumber)`;
|
|
67
|
+
* for Bravo it's the fixed `quorumVotes()` (blockNumber is ignored, surfaced
|
|
68
|
+
* as `latest` in the response).
|
|
69
|
+
*/
|
|
70
|
+
export declare function readQuorum(c: Contract, cfg: GovernorConfig, blockNumber: number): Promise<{
|
|
71
|
+
quorum: bigint;
|
|
72
|
+
method: "quorum(blockNumber)" | "quorumVotes()";
|
|
73
|
+
}>;
|
|
74
|
+
export interface VoteTally {
|
|
75
|
+
against: bigint;
|
|
76
|
+
for: bigint;
|
|
77
|
+
abstain: bigint;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Pure projection of a hypothetical vote onto current tallies. Quorum semantics
|
|
81
|
+
* branch by family: OZ `GovernorCountingSimple` counts `for + abstain` toward
|
|
82
|
+
* quorum, Bravo counts only `forVotes`. `willPass` requires quorum met AND
|
|
83
|
+
* strictly more For than Against. No I/O — unit-testable in isolation.
|
|
84
|
+
*/
|
|
85
|
+
export declare function projectVoteImpact(bravo: boolean, current: VoteTally, support: number, weight: bigint, quorum: bigint): {
|
|
86
|
+
projected: VoteTally;
|
|
87
|
+
quorumMet: boolean;
|
|
88
|
+
willPass: boolean;
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/governor/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,oBAAoB,60BAavB,CAAC;AAEX,eAAO,MAAM,uBAAuB,6mBAS1B,CAAC;AAEX,eAAO,MAAM,UAAU,4NAIb,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,kOAIlB,CAAC;AAEX,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EASlC,CAAC;AAEX,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,QAAQ,CAGzF;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,QAAQ,CAGtF;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,CAAC,EAAE,QAAQ,EACX,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAU5C;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,UAAU,CAAC,EAAE;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,CAAC,EAAE,QAAQ,EACX,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC,CAoC1B;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,CAAC,EAAE,QAAQ,EACX,GAAG,EAAE,cAAc,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAAA;CAAE,CAAC,CAO9E;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb;IAAE,SAAS,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAUjE"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { Contract } from "ethers";
|
|
2
|
+
/**
|
|
3
|
+
* Read surfaces for the two Governor families we target.
|
|
4
|
+
*
|
|
5
|
+
* - **OZ v4 / v5** (Optimism, post-2022 OZ Governor deploys): `state`,
|
|
6
|
+
* `proposalSnapshot`, `proposalDeadline`, `proposalVotes`, `quorum(uint256)`,
|
|
7
|
+
* `proposalThreshold`, etc.
|
|
8
|
+
* - **Bravo v3** (Uniswap, Compound): `state`, `proposals(uint256)` returning a
|
|
9
|
+
* flat struct, `quorumVotes()` (fixed quorum, no per-block snapshot),
|
|
10
|
+
* `proposalThreshold`. No `proposalSnapshot` / `proposalDeadline` /
|
|
11
|
+
* `quorum(blockNumber)`.
|
|
12
|
+
*
|
|
13
|
+
* The canonical `ProposalState` enum order is identical across both families.
|
|
14
|
+
*/
|
|
15
|
+
export const GOVERNOR_OZ_READ_ABI = [
|
|
16
|
+
"function state(uint256 proposalId) view returns (uint8)",
|
|
17
|
+
"function proposalSnapshot(uint256 proposalId) view returns (uint256)",
|
|
18
|
+
"function proposalDeadline(uint256 proposalId) view returns (uint256)",
|
|
19
|
+
"function proposalVotes(uint256 proposalId) view returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes)",
|
|
20
|
+
"function proposalThreshold() view returns (uint256)",
|
|
21
|
+
"function quorum(uint256 blockNumber) view returns (uint256)",
|
|
22
|
+
"function votingDelay() view returns (uint256)",
|
|
23
|
+
"function votingPeriod() view returns (uint256)",
|
|
24
|
+
"function hasVoted(uint256 proposalId, address account) view returns (bool)",
|
|
25
|
+
"function hashProposal(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) pure returns (uint256)",
|
|
26
|
+
"function name() view returns (string)",
|
|
27
|
+
"function version() view returns (string)",
|
|
28
|
+
];
|
|
29
|
+
export const GOVERNOR_BRAVO_READ_ABI = [
|
|
30
|
+
"function state(uint256 proposalId) view returns (uint8)",
|
|
31
|
+
"function proposals(uint256 proposalId) view returns (uint256 id, address proposer, uint256 eta, uint256 startBlock, uint256 endBlock, uint256 forVotes, uint256 againstVotes, uint256 abstainVotes, bool canceled, bool executed)",
|
|
32
|
+
"function proposalThreshold() view returns (uint256)",
|
|
33
|
+
"function quorumVotes() view returns (uint256)",
|
|
34
|
+
"function votingDelay() view returns (uint256)",
|
|
35
|
+
"function votingPeriod() view returns (uint256)",
|
|
36
|
+
"function hasVoted(uint256 proposalId, address account) view returns (bool)",
|
|
37
|
+
"function name() view returns (string)",
|
|
38
|
+
];
|
|
39
|
+
export const IVOTES_ABI = [
|
|
40
|
+
"function getVotes(address account) view returns (uint256)",
|
|
41
|
+
"function getPastVotes(address account, uint256 blockNumber) view returns (uint256)",
|
|
42
|
+
"function delegates(address account) view returns (address)",
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* Compound-style vote getters. Bravo voting tokens (COMP, UNI) expose
|
|
46
|
+
* `getCurrentVotes(address)` / `getPriorVotes(address, uint256)` instead of the
|
|
47
|
+
* OZ `getVotes` / `getPastVotes`. Routing is static by `votingToken.type`
|
|
48
|
+
* (see `readVotingPower`) — `ERC20VotesComp` always uses these getters; there is
|
|
49
|
+
* no runtime fallback between the two interfaces.
|
|
50
|
+
*/
|
|
51
|
+
export const IVOTES_COMP_ABI = [
|
|
52
|
+
"function getCurrentVotes(address account) view returns (uint96)",
|
|
53
|
+
"function getPriorVotes(address account, uint256 blockNumber) view returns (uint96)",
|
|
54
|
+
"function delegates(address account) view returns (address)",
|
|
55
|
+
];
|
|
56
|
+
export const PROPOSAL_STATE = [
|
|
57
|
+
"Pending",
|
|
58
|
+
"Active",
|
|
59
|
+
"Canceled",
|
|
60
|
+
"Defeated",
|
|
61
|
+
"Succeeded",
|
|
62
|
+
"Queued",
|
|
63
|
+
"Expired",
|
|
64
|
+
"Executed",
|
|
65
|
+
];
|
|
66
|
+
export function stateName(stateIndex) {
|
|
67
|
+
return PROPOSAL_STATE[stateIndex] ?? `Unknown(${stateIndex})`;
|
|
68
|
+
}
|
|
69
|
+
export function isBravo(cfg) {
|
|
70
|
+
return cfg.governorVersion === "bravo-v3";
|
|
71
|
+
}
|
|
72
|
+
export function governorContract(provider, cfg) {
|
|
73
|
+
const abi = isBravo(cfg) ? GOVERNOR_BRAVO_READ_ABI : GOVERNOR_OZ_READ_ABI;
|
|
74
|
+
return new Contract(cfg.governorAddress, abi, provider);
|
|
75
|
+
}
|
|
76
|
+
export function votesContract(provider, cfg) {
|
|
77
|
+
const abi = cfg.votingToken.type === "ERC20VotesComp" ? IVOTES_COMP_ABI : IVOTES_ABI;
|
|
78
|
+
return new Contract(cfg.votingToken.address, abi, provider);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Family-agnostic voting-power read. ERC20VotesComp (UNI, COMP) exposes
|
|
82
|
+
* `getCurrentVotes` / `getPriorVotes`; ERC20Votes (OP, modern OZ) exposes
|
|
83
|
+
* `getVotes` / `getPastVotes`. Returns wei + the actual method invoked.
|
|
84
|
+
*/
|
|
85
|
+
export async function readVotingPower(c, cfg, account, blockNumber) {
|
|
86
|
+
const isComp = cfg.votingToken.type === "ERC20VotesComp";
|
|
87
|
+
if (blockNumber === undefined) {
|
|
88
|
+
const method = isComp ? "getCurrentVotes" : "getVotes";
|
|
89
|
+
const power = await c.getFunction(method).staticCall(account);
|
|
90
|
+
return { power, method };
|
|
91
|
+
}
|
|
92
|
+
const method = isComp ? "getPriorVotes" : "getPastVotes";
|
|
93
|
+
const power = await c.getFunction(method).staticCall(account, blockNumber);
|
|
94
|
+
return { power, method };
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Family-agnostic proposal read. Maps Bravo's `proposals(uint256)` struct onto
|
|
98
|
+
* the OZ-style {snapshot, deadline, votes} shape so callers don't branch.
|
|
99
|
+
*/
|
|
100
|
+
export async function readProposal(c, cfg, proposalId) {
|
|
101
|
+
const stateIdx = Number(await c.getFunction("state").staticCall(proposalId));
|
|
102
|
+
if (isBravo(cfg)) {
|
|
103
|
+
const p = await c.getFunction("proposals").staticCall(proposalId);
|
|
104
|
+
return {
|
|
105
|
+
state: { index: stateIdx, name: stateName(stateIdx) },
|
|
106
|
+
snapshotBlock: p.startBlock.toString(),
|
|
107
|
+
deadlineBlock: p.endBlock.toString(),
|
|
108
|
+
votes: {
|
|
109
|
+
against: p.againstVotes.toString(),
|
|
110
|
+
for: p.forVotes.toString(),
|
|
111
|
+
abstain: p.abstainVotes.toString(),
|
|
112
|
+
},
|
|
113
|
+
bravoExtra: {
|
|
114
|
+
proposer: p.proposer,
|
|
115
|
+
eta: p.eta.toString(),
|
|
116
|
+
canceled: p.canceled,
|
|
117
|
+
executed: p.executed,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const [snapshot, deadline, votes] = await Promise.all([
|
|
122
|
+
c.getFunction("proposalSnapshot").staticCall(proposalId),
|
|
123
|
+
c.getFunction("proposalDeadline").staticCall(proposalId),
|
|
124
|
+
c.getFunction("proposalVotes").staticCall(proposalId),
|
|
125
|
+
]);
|
|
126
|
+
return {
|
|
127
|
+
state: { index: stateIdx, name: stateName(stateIdx) },
|
|
128
|
+
snapshotBlock: snapshot.toString(),
|
|
129
|
+
deadlineBlock: deadline.toString(),
|
|
130
|
+
votes: {
|
|
131
|
+
against: votes[0].toString(),
|
|
132
|
+
for: votes[1].toString(),
|
|
133
|
+
abstain: votes[2].toString(),
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Returns the active quorum value. For OZ v4+ this is `quorum(blockNumber)`;
|
|
139
|
+
* for Bravo it's the fixed `quorumVotes()` (blockNumber is ignored, surfaced
|
|
140
|
+
* as `latest` in the response).
|
|
141
|
+
*/
|
|
142
|
+
export async function readQuorum(c, cfg, blockNumber) {
|
|
143
|
+
if (isBravo(cfg)) {
|
|
144
|
+
const q = await c.getFunction("quorumVotes").staticCall();
|
|
145
|
+
return { quorum: q, method: "quorumVotes()" };
|
|
146
|
+
}
|
|
147
|
+
const q = await c.getFunction("quorum").staticCall(blockNumber);
|
|
148
|
+
return { quorum: q, method: "quorum(blockNumber)" };
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Pure projection of a hypothetical vote onto current tallies. Quorum semantics
|
|
152
|
+
* branch by family: OZ `GovernorCountingSimple` counts `for + abstain` toward
|
|
153
|
+
* quorum, Bravo counts only `forVotes`. `willPass` requires quorum met AND
|
|
154
|
+
* strictly more For than Against. No I/O — unit-testable in isolation.
|
|
155
|
+
*/
|
|
156
|
+
export function projectVoteImpact(bravo, current, support, weight, quorum) {
|
|
157
|
+
const projected = { ...current };
|
|
158
|
+
if (support === 0)
|
|
159
|
+
projected.against += weight;
|
|
160
|
+
else if (support === 1)
|
|
161
|
+
projected.for += weight;
|
|
162
|
+
else
|
|
163
|
+
projected.abstain += weight;
|
|
164
|
+
const quorumPool = bravo ? projected.for : projected.for + projected.abstain;
|
|
165
|
+
const quorumMet = quorumPool >= quorum;
|
|
166
|
+
const willPass = quorumMet && projected.for > projected.against;
|
|
167
|
+
return { projected, quorumMet, willPass };
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/governor/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "compound",
|
|
3
|
+
"chainId": 1,
|
|
4
|
+
"governorAddress": "0xc0Da02939E1441F497fd74F78cE7Decb17B66529",
|
|
5
|
+
"governorVersion": "bravo-v3",
|
|
6
|
+
"votingToken": {
|
|
7
|
+
"type": "ERC20VotesComp",
|
|
8
|
+
"address": "0xc00e94Cb662C3520282E6f5717214004A7f26888",
|
|
9
|
+
"symbol": "COMP",
|
|
10
|
+
"decimals": 18
|
|
11
|
+
},
|
|
12
|
+
"timelock": {
|
|
13
|
+
"address": "0x6d903f6003cca6255D85CcA4D3B5E5146dC33925",
|
|
14
|
+
"minDelay": 172800
|
|
15
|
+
},
|
|
16
|
+
"votingParams": {
|
|
17
|
+
"votingDelay": 13140,
|
|
18
|
+
"votingPeriod": 19710,
|
|
19
|
+
"proposalThreshold": "25000000000000000000000",
|
|
20
|
+
"quorumNumerator": 400000,
|
|
21
|
+
"quorumDenominator": 1
|
|
22
|
+
},
|
|
23
|
+
"executor": {
|
|
24
|
+
"type": "timelock",
|
|
25
|
+
"id": null
|
|
26
|
+
},
|
|
27
|
+
"explorer": {
|
|
28
|
+
"etherscanBase": "https://etherscan.io",
|
|
29
|
+
"tallyOrgSlug": "compound"
|
|
30
|
+
},
|
|
31
|
+
"notes": "Compound GovernorBravoDelegate. Bravo signatures, Compound-style votes interface (getPriorVotes / getCurrentVotes — NOT OZ getPastVotes). quorumVotes() is a fixed value (400k COMP); quorumNumerator/Denominator here are descriptive only."
|
|
32
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "optimism",
|
|
3
|
+
"chainId": 10,
|
|
4
|
+
"governorAddress": "0xcDF27F107725988f2261Ce2256bDfCdE8B382B10",
|
|
5
|
+
"governorVersion": "oz-v4",
|
|
6
|
+
"votingToken": {
|
|
7
|
+
"type": "ERC20Votes",
|
|
8
|
+
"address": "0x4200000000000000000000000000000000000042",
|
|
9
|
+
"symbol": "OP",
|
|
10
|
+
"decimals": 18
|
|
11
|
+
},
|
|
12
|
+
"votingParams": {
|
|
13
|
+
"votingDelay": 6646,
|
|
14
|
+
"votingPeriod": 46027,
|
|
15
|
+
"proposalThreshold": "0",
|
|
16
|
+
"quorumNumerator": 30,
|
|
17
|
+
"quorumDenominator": 100
|
|
18
|
+
},
|
|
19
|
+
"executor": {
|
|
20
|
+
"type": "governor-self",
|
|
21
|
+
"id": null
|
|
22
|
+
},
|
|
23
|
+
"explorer": {
|
|
24
|
+
"etherscanBase": "https://optimistic.etherscan.io",
|
|
25
|
+
"tallyOrgSlug": "optimism"
|
|
26
|
+
},
|
|
27
|
+
"notes": "Optimism's modified OZ Governor. ERC20Votes (OP token implements OZ-style getPastVotes). Custom ProposalTypesConfigurator is OUT OF SCOPE (research/06-execution-plan.md §6). Treated as vanilla oz-v4 surface for read+build tools."
|
|
28
|
+
}
|