dexe-mcp 0.9.0 → 0.11.1

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +109 -20
  2. package/README.md +6 -6
  3. package/dist/config.d.ts +22 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +30 -0
  6. package/dist/config.js.map +1 -1
  7. package/dist/env/schema.d.ts +21 -0
  8. package/dist/env/schema.d.ts.map +1 -1
  9. package/dist/env/schema.js +21 -0
  10. package/dist/env/schema.js.map +1 -1
  11. package/dist/lib/controllingVoters.d.ts +44 -0
  12. package/dist/lib/controllingVoters.d.ts.map +1 -0
  13. package/dist/lib/controllingVoters.js +152 -0
  14. package/dist/lib/controllingVoters.js.map +1 -0
  15. package/dist/lib/dangerousSelectors.d.ts +1 -1
  16. package/dist/lib/dangerousSelectors.d.ts.map +1 -1
  17. package/dist/lib/dangerousSelectors.js +12 -22
  18. package/dist/lib/dangerousSelectors.js.map +1 -1
  19. package/dist/lib/decoders.d.ts +4 -4
  20. package/dist/lib/decoders.d.ts.map +1 -1
  21. package/dist/lib/decoders.js +2 -2
  22. package/dist/lib/govProposalView.d.ts +37 -0
  23. package/dist/lib/govProposalView.d.ts.map +1 -0
  24. package/dist/lib/govProposalView.js +42 -0
  25. package/dist/lib/govProposalView.js.map +1 -0
  26. package/dist/lib/protocolAdvisories.d.ts +12 -13
  27. package/dist/lib/protocolAdvisories.d.ts.map +1 -1
  28. package/dist/lib/protocolAdvisories.js +23 -16
  29. package/dist/lib/protocolAdvisories.js.map +1 -1
  30. package/dist/lib/quorumRisk.d.ts +92 -0
  31. package/dist/lib/quorumRisk.d.ts.map +1 -0
  32. package/dist/lib/quorumRisk.js +159 -0
  33. package/dist/lib/quorumRisk.js.map +1 -0
  34. package/dist/lib/time.d.ts +16 -0
  35. package/dist/lib/time.d.ts.map +1 -0
  36. package/dist/lib/time.js +24 -0
  37. package/dist/lib/time.js.map +1 -0
  38. package/dist/tools/daoDeploy.d.ts.map +1 -1
  39. package/dist/tools/daoDeploy.js +32 -0
  40. package/dist/tools/daoDeploy.js.map +1 -1
  41. package/dist/tools/flow.d.ts.map +1 -1
  42. package/dist/tools/flow.js +90 -1
  43. package/dist/tools/flow.js.map +1 -1
  44. package/dist/tools/gov.js +2 -2
  45. package/dist/tools/index.d.ts.map +1 -1
  46. package/dist/tools/index.js +2 -0
  47. package/dist/tools/index.js.map +1 -1
  48. package/dist/tools/otc.d.ts +20 -0
  49. package/dist/tools/otc.d.ts.map +1 -1
  50. package/dist/tools/otc.js +191 -58
  51. package/dist/tools/otc.js.map +1 -1
  52. package/dist/tools/proposalBuild.d.ts.map +1 -1
  53. package/dist/tools/proposalBuild.js +19 -5
  54. package/dist/tools/proposalBuild.js.map +1 -1
  55. package/dist/tools/proposalBuildComplex.d.ts.map +1 -1
  56. package/dist/tools/proposalBuildComplex.js +12 -1
  57. package/dist/tools/proposalBuildComplex.js.map +1 -1
  58. package/dist/tools/proposalBuildMore.d.ts.map +1 -1
  59. package/dist/tools/proposalBuildMore.js +8 -5
  60. package/dist/tools/proposalBuildMore.js.map +1 -1
  61. package/dist/tools/risk.d.ts +4 -0
  62. package/dist/tools/risk.d.ts.map +1 -0
  63. package/dist/tools/risk.js +255 -0
  64. package/dist/tools/risk.js.map +1 -0
  65. package/dist/tools/subgraph.d.ts.map +1 -1
  66. package/dist/tools/subgraph.js +22 -15
  67. package/dist/tools/subgraph.js.map +1 -1
  68. package/dist/tools/voteBuild.d.ts.map +1 -1
  69. package/dist/tools/voteBuild.js +16 -4
  70. package/dist/tools/voteBuild.js.map +1 -1
  71. package/package.json +2 -2
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Controlling-holder participation signal for the treasury-safety advisory.
3
+ *
4
+ * Resolves whether at least one member of a DAO's "controlling set" voted For a
5
+ * given proposal. The controlling set (a product decision) is:
6
+ * validators ∪ top-N token holders by voting weight.
7
+ * "Voted For" is lenient: ≥1 member among the For-voters ⇒ `true`.
8
+ *
9
+ * Posture: **fail-soft, never throws.** Any missing subgraph, non-mainnet chain,
10
+ * empty set, or subgraph/RPC error ⇒ `null` (unknown). Informational only — a
11
+ * `false` (set non-empty, nobody voted For) adds an advisory note; it never
12
+ * blocks. We only return `false` when we positively enumerated the set AND
13
+ * confirmed no member voted For on-chain.
14
+ *
15
+ * The set is enumerated via subgraph (cheap, but untrusted for vote direction);
16
+ * each member's vote direction is then confirmed ON-CHAIN via
17
+ * `GovPool.getTotalVotes` (authoritative). We OR across PersonalVote /
18
+ * MicropoolVote / DelegatedVote so a member who voted via delegation or a
19
+ * micropool is not mistaken for a non-voter.
20
+ */
21
+ import { Interface } from "ethers";
22
+ import { multicall } from "./multicall.js";
23
+ import { gqlRequest } from "./subgraph.js";
24
+ /**
25
+ * Identical to the fragment in src/tools/vote.ts / src/tools/inbox.ts. Kept
26
+ * local + exported so the unit test can assert ethers parses it (ethers
27
+ * silently drops malformed fragments — see govProposalView Phase-A gotcha).
28
+ */
29
+ export const GET_TOTAL_VOTES_FRAGMENT = "function getTotalVotes(uint256 proposalId, address voter, uint8 voteType) view returns (uint256 totalVoted, uint256 totalRawVoted, uint256 votesForNow, bool isVoteFor)";
30
+ /** PersonalVote=0, MicropoolVote=1, DelegatedVote=2 (TreasuryVote=3 omitted). */
31
+ const VOTE_TYPES = [0, 1, 2];
32
+ /** Default top-N token holders when neither arg nor config overrides it. */
33
+ const DEFAULT_TOP_N = 5;
34
+ /** Trimmed from src/tools/subgraph.ts VALIDATORS_QUERY (fields we need only). */
35
+ const VALIDATORS_QUERY = /* GraphQL */ `
36
+ query getDaoPoolValidators($offset: Int!, $limit: Int!, $address: String!) {
37
+ validatorInPools(
38
+ skip: $offset
39
+ first: $limit
40
+ orderBy: balance
41
+ orderDirection: desc
42
+ where: { pool: $address }
43
+ ) {
44
+ validatorAddress
45
+ }
46
+ }
47
+ `;
48
+ /** Trimmed from src/tools/subgraph.ts DAO_MEMBERS_QUERY (fields we need only). */
49
+ const DAO_MEMBERS_QUERY = /* GraphQL */ `
50
+ query getVotersInPool($poolId: String!, $offset: Int!, $limit: Int!) {
51
+ voterInPools(skip: $offset, first: $limit, where: { pool: $poolId }) {
52
+ receivedDelegation
53
+ voter {
54
+ id
55
+ totalVotes
56
+ }
57
+ }
58
+ }
59
+ `;
60
+ function toBig(s) {
61
+ try {
62
+ return s ? BigInt(s) : 0n;
63
+ }
64
+ catch {
65
+ return 0n;
66
+ }
67
+ }
68
+ /** Validator addresses for `pool` (lowercased). Fail-soft → []. */
69
+ async function fetchValidators(cfg, pool) {
70
+ try {
71
+ const data = await gqlRequest(cfg.subgraphValidatorsUrl, VALIDATORS_QUERY, { offset: 0, limit: 100, address: pool });
72
+ return (data.validatorInPools ?? [])
73
+ .map((v) => v.validatorAddress?.toLowerCase())
74
+ .filter((a) => !!a);
75
+ }
76
+ catch {
77
+ return [];
78
+ }
79
+ }
80
+ /** Top-N holders by (totalVotes + receivedDelegation), lowercased. Fail-soft → []. */
81
+ async function fetchTopHolders(cfg, pool, topN) {
82
+ try {
83
+ const data = await gqlRequest(cfg.subgraphPoolsUrl, DAO_MEMBERS_QUERY, { poolId: pool, offset: 0, limit: 50 });
84
+ const weighted = (data.voterInPools ?? [])
85
+ .map((r) => ({
86
+ addr: r.voter?.id?.toLowerCase(),
87
+ weight: toBig(r.voter?.totalVotes) + toBig(r.receivedDelegation),
88
+ }))
89
+ .filter((x) => !!x.addr);
90
+ weighted.sort((a, b) => (a.weight < b.weight ? 1 : a.weight > b.weight ? -1 : 0));
91
+ return weighted.slice(0, Math.max(0, topN)).map((x) => x.addr);
92
+ }
93
+ catch {
94
+ return [];
95
+ }
96
+ }
97
+ /**
98
+ * Did ≥1 controlling-set member vote For proposal `proposalId`?
99
+ * - `true` — at least one member voted For (any vote type).
100
+ * - `false` — set was enumerated, non-empty, and NONE voted For.
101
+ * - `null` — cannot determine (no subgraph / non-mainnet / empty set / error).
102
+ * Never throws.
103
+ */
104
+ export async function resolveControllingHoldersVotedFor(args) {
105
+ const { provider, govPool, proposalId, cfg, chainId } = args;
106
+ const topN = args.topN ?? cfg.controllingTopN ?? DEFAULT_TOP_N;
107
+ // Gate: subgraph exists only on mainnet (56). Testnet (97) ⇒ unknown.
108
+ if (chainId !== 56)
109
+ return null;
110
+ if (!cfg.subgraphValidatorsUrl || !cfg.subgraphPoolsUrl)
111
+ return null;
112
+ const pool = govPool.toLowerCase();
113
+ // Enumerate each source independently — a transient failure of one source
114
+ // only shrinks the set, which can only make `false` LESS likely (the safe
115
+ // direction: fewer wrongful refuses).
116
+ const [validators, holders] = await Promise.all([
117
+ fetchValidators(cfg, pool),
118
+ fetchTopHolders(cfg, pool, topN),
119
+ ]);
120
+ const members = [...new Set([...validators, ...holders])];
121
+ if (members.length === 0)
122
+ return null;
123
+ try {
124
+ const iface = new Interface([GET_TOTAL_VOTES_FRAGMENT]);
125
+ const calls = [];
126
+ for (const member of members) {
127
+ for (const vt of VOTE_TYPES) {
128
+ calls.push({
129
+ target: govPool,
130
+ iface,
131
+ method: "getTotalVotes",
132
+ args: [proposalId, member, vt],
133
+ allowFailure: true,
134
+ });
135
+ }
136
+ }
137
+ const results = await multicall(provider, calls);
138
+ for (const r of results) {
139
+ if (!r.success || r.value == null)
140
+ continue;
141
+ // getTotalVotes returns a 4-tuple: [totalVoted, totalRawVoted, votesForNow, isVoteFor]
142
+ const v = r.value;
143
+ if (v[2] > 0n && v[3] === true)
144
+ return true;
145
+ }
146
+ return false; // set non-empty, confirmed nobody voted For
147
+ }
148
+ catch {
149
+ return null; // RPC/decoding failure ⇒ unknown, never a refuse
150
+ }
151
+ }
152
+ //# sourceMappingURL=controllingVoters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controllingVoters.js","sourceRoot":"","sources":["../../src/lib/controllingVoters.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@ export declare function selectorOf(data: string): string | null;
11
11
  * denylisted, else null. `data` is raw calldata (0x-hex).
12
12
  */
13
13
  export declare function findForbiddenSelector(data: string): ForbiddenSelector | null;
14
- /** Human-readable hard-refusal explaining why the selector is blocked (C-2). */
14
+ /** Human-readable hard-refusal explaining why the selector is blocked. */
15
15
  export declare function dangerousSelectorError(match: ForbiddenSelector, target?: string): string;
16
16
  /** The full denylist — for docs, tests, and introspection. */
17
17
  export declare function forbiddenSelectors(): ForbiddenSelector[];
@@ -1 +1 @@
1
- {"version":3,"file":"dangerousSelectors.d.ts","sourceRoot":"","sources":["../../src/lib/dangerousSelectors.ts"],"names":[],"mappings":"AAyCA,MAAM,WAAW,iBAAiB;IAChC,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,SAAS,EAAE,MAAM,CAAC;CACnB;AAaD,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGtD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAI5E;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAYxF;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,IAAI,iBAAiB,EAAE,CAExD"}
1
+ {"version":3,"file":"dangerousSelectors.d.ts","sourceRoot":"","sources":["../../src/lib/dangerousSelectors.ts"],"names":[],"mappings":"AAiCA,MAAM,WAAW,iBAAiB;IAChC,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,SAAS,EAAE,MAAM,CAAC;CACnB;AAaD,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGtD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAI5E;AAED,0EAA0E;AAC1E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAUxF;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,IAAI,iBAAiB,EAAE,CAExD"}
@@ -1,27 +1,19 @@
1
1
  import { id } from "ethers";
2
2
  /**
3
- * C-2 guardrailforbidden proposal-action selectors.
3
+ * Forbidden proposal-action selectorshard guard.
4
4
  *
5
5
  * Every function below lives on `GovUserKeeper` and is `onlyOwner` (the owner is
6
6
  * the GovPool). GovPool invokes them internally on behalf of users through its
7
7
  * own deposit/withdraw/delegate entrypoints — they are NOT meant to be the
8
8
  * `executor` + `data` of a raw governance proposal action.
9
9
  *
10
- * They are dangerous as proposal targets because the `payer` / `delegator`
11
- * argument is decoupled from the funds' owner: e.g.
12
- * `withdrawTokens(payer, receiver, amount)` debits `_usersInfo[payer]` and pays
13
- * `receiver`. A proposal can therefore name an arbitrary victim as `payer` and
14
- * the attacker as `receiver`.
15
- *
16
- * The DeXe protocol's INTERNAL allowlist
17
- * (`GovPoolCreate._handleDataForInternalProposal`) is supposed to make these
18
- * unreachable-by-proposal, but it only runs when the *last* action's executor is
19
- * a registered INTERNAL executor. A proposal whose trailing action routes to
20
- * DEFAULT skips the allowlist entirely, so these selectors slip through —
21
- * finding C-2. This guard refuses to build any proposal action carrying one of
22
- * them, regardless of routing. It is harm-reduction at the MCP layer ONLY: the
23
- * root cause is in the protocol contracts, and an attacker can still hand-craft
24
- * the calldata. See docs/security/C2-default-routing-bypass.md.
10
+ * They are unsafe as proposal targets because the `payer` / `delegator`
11
+ * argument is decoupled from the funds' owner (e.g. `withdrawTokens(payer,
12
+ * receiver, amount)` debits `payer` and pays `receiver`), so a proposal could
13
+ * name an account other than the proposer. This guard refuses to build any
14
+ * proposal action carrying one of these selectors. Defense-in-depth at the MCP
15
+ * layer; users deposit/withdraw/delegate their OWN funds through the GovPool
16
+ * entrypoints, never via a proposal.
25
17
  */
26
18
  const FORBIDDEN_SIGNATURES = [
27
19
  "withdrawTokens(address,address,uint256)",
@@ -61,17 +53,15 @@ export function findForbiddenSelector(data) {
61
53
  return null;
62
54
  return FORBIDDEN_BY_SELECTOR.get(sel) ?? null;
63
55
  }
64
- /** Human-readable hard-refusal explaining why the selector is blocked (C-2). */
56
+ /** Human-readable hard-refusal explaining why the selector is blocked. */
65
57
  export function dangerousSelectorError(match, target) {
66
58
  return (`Refusing to build: calldata selector ${match.selector} is ` +
67
59
  `GovUserKeeper.${match.signature}, a privileged onlyOwner accounting function ` +
68
60
  `that must never be a governance proposal action` +
69
61
  (target ? ` (target ${target})` : "") +
70
- `. Encoding it enables finding C-2: a DEFAULT-routed proposal bypasses the ` +
71
- `GovPoolCreate INTERNAL allowlist and can drain an arbitrary depositor's ` +
72
- `unlocked balance the function takes a free 'payer'/'delegator' decoupled ` +
73
- `from the caller. Users deposit/withdraw/delegate their OWN funds through the ` +
74
- `GovPool entrypoints, never via a proposal. Hard block, no override.`);
62
+ `. These functions take a 'payer'/'delegator' argument decoupled from the ` +
63
+ `caller; users deposit/withdraw/delegate their OWN funds through the GovPool ` +
64
+ `entrypoints, never via a proposal. Hard block, no override.`);
75
65
  }
76
66
  /** The full denylist — for docs, tests, and introspection. */
77
67
  export function forbiddenSelectors() {
@@ -1 +1 @@
1
- {"version":3,"file":"dangerousSelectors.js","sourceRoot":"","sources":["../../src/lib/dangerousSelectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,oBAAoB,GAAG;IAC3B,yCAAyC;IACzC,wCAAwC;IACxC,yCAAyC;IACzC,2CAA2C;IAC3C,yCAAyC;IACzC,2CAA2C;IAC3C,yCAAyC;IACzC,wCAAwC;IACxC,yCAAyC;IACzC,2CAA2C;IAC3C,yCAAyC;IACzC,2CAA2C;CACnC,CAAC;AASX;;;GAGG;AACH,MAAM,qBAAqB,GAA2C,IAAI,GAAG,CAC3E,oBAAoB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;IACrC,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1D,OAAO,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAU,CAAC;AACtD,CAAC,CAAC,CACH,CAAC;AAEF,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IACxF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,OAAO,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;AAChD,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,sBAAsB,CAAC,KAAwB,EAAE,MAAe;IAC9E,OAAO,CACL,wCAAwC,KAAK,CAAC,QAAQ,MAAM;QAC5D,iBAAiB,KAAK,CAAC,SAAS,+CAA+C;QAC/E,iDAAiD;QACjD,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,4EAA4E;QAC5E,0EAA0E;QAC1E,6EAA6E;QAC7E,+EAA+E;QAC/E,qEAAqE,CACtE,CAAC;AACJ,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB;IAChC,OAAO,CAAC,GAAG,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"dangerousSelectors.js","sourceRoot":"","sources":["../../src/lib/dangerousSelectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,oBAAoB,GAAG;IAC3B,yCAAyC;IACzC,wCAAwC;IACxC,yCAAyC;IACzC,2CAA2C;IAC3C,yCAAyC;IACzC,2CAA2C;IAC3C,yCAAyC;IACzC,wCAAwC;IACxC,yCAAyC;IACzC,2CAA2C;IAC3C,yCAAyC;IACzC,2CAA2C;CACnC,CAAC;AASX;;;GAGG;AACH,MAAM,qBAAqB,GAA2C,IAAI,GAAG,CAC3E,oBAAoB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;IACrC,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1D,OAAO,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAU,CAAC;AACtD,CAAC,CAAC,CACH,CAAC;AAEF,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IACxF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,OAAO,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;AAChD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,sBAAsB,CAAC,KAAwB,EAAE,MAAe;IAC9E,OAAO,CACL,wCAAwC,KAAK,CAAC,QAAQ,MAAM;QAC5D,iBAAiB,KAAK,CAAC,SAAS,+CAA+C;QAC/E,iDAAiD;QACjD,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,2EAA2E;QAC3E,8EAA8E;QAC9E,6DAA6D,CAC9D,CAAC;AACJ,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB;IAChC,OAAO,CAAC,GAAG,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAAC;AAC7C,CAAC"}
@@ -10,12 +10,12 @@ export interface DecodedCall {
10
10
  args: Record<string, unknown>;
11
11
  /** Raw positional args — useful for agents that want the tuple directly. */
12
12
  argsArray: unknown[];
13
- /** True if this selector is a C-2-class privileged accounting function. */
13
+ /** True if this selector is a privileged accounting function (unsafe as a proposal action). */
14
14
  privileged?: boolean;
15
15
  /**
16
16
  * Calls discovered inside this call's calldata args — e.g. the inner calls of
17
17
  * a `multicall(bytes[])`, or the actions of a nested `createProposal`. Lets a
18
- * reviewer see hidden privileged calls instead of just the wrapper (C-1).
18
+ * reviewer see hidden privileged calls instead of just the wrapper.
19
19
  */
20
20
  nested?: DecodedCall[];
21
21
  }
@@ -41,8 +41,8 @@ export declare class CalldataDecoder {
41
41
  * Decode calldata and recursively unwrap any well-formed nested calldata
42
42
  * found in its arguments — `multicall(bytes[])`, a nested `createProposal`'s
43
43
  * `ProposalAction[]`, `tryExecute`, etc. The decoded `primary` carries a
44
- * `privileged` flag for C-2-class selectors and a `nested` tree so a reviewer
45
- * reading the text sees hidden inner calls, not just the wrapper (C-1).
44
+ * `privileged` flag for privileged-class selectors and a `nested` tree so a
45
+ * reviewer reading the text sees hidden inner calls, not just the wrapper.
46
46
  */
47
47
  decodeCalldata(data: string, contractName?: string): {
48
48
  primary: DecodedCall | null;
@@ -1 +1 @@
1
- {"version":3,"file":"decoders.d.ts","sourceRoot":"","sources":["../../src/lib/decoders.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,MAAM,WAAW,WAAW;IAC1B,iGAAiG;IACjG,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,mGAAmG;IACnG,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,4EAA4E;IAC5E,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;CAC7B;AAED,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,aAAa;IAG3C;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,cAAc,KAAK;IAEnC;;;;;;OAMG;IACH,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GACpB;QAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;QAAC,YAAY,EAAE,WAAW,EAAE,CAAA;KAAE;IAI/D,OAAO,CAAC,cAAc;IAiBtB,qFAAqF;IACrF,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,UAAU;IA+ClB;;;;;;;;OAQG;IACH,oBAAoB,CAAC,MAAM,EAAE;QAC3B,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;KACzB,GAAG,qBAAqB;CAU1B"}
1
+ {"version":3,"file":"decoders.d.ts","sourceRoot":"","sources":["../../src/lib/decoders.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,MAAM,WAAW,WAAW;IAC1B,iGAAiG;IACjG,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,mGAAmG;IACnG,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,4EAA4E;IAC5E,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;CAC7B;AAED,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,aAAa;IAG3C;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,cAAc,KAAK;IAEnC;;;;;;OAMG;IACH,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GACpB;QAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;QAAC,YAAY,EAAE,WAAW,EAAE,CAAA;KAAE;IAI/D,OAAO,CAAC,cAAc;IAiBtB,qFAAqF;IACrF,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,UAAU;IA+ClB;;;;;;;;OAQG;IACH,oBAAoB,CAAC,MAAM,EAAE;QAC3B,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;KACzB,GAAG,qBAAqB;CAU1B"}
@@ -17,8 +17,8 @@ export class CalldataDecoder {
17
17
  * Decode calldata and recursively unwrap any well-formed nested calldata
18
18
  * found in its arguments — `multicall(bytes[])`, a nested `createProposal`'s
19
19
  * `ProposalAction[]`, `tryExecute`, etc. The decoded `primary` carries a
20
- * `privileged` flag for C-2-class selectors and a `nested` tree so a reviewer
21
- * reading the text sees hidden inner calls, not just the wrapper (C-1).
20
+ * `privileged` flag for privileged-class selectors and a `nested` tree so a
21
+ * reviewer reading the text sees hidden inner calls, not just the wrapper.
22
22
  */
23
23
  decodeCalldata(data, contractName) {
24
24
  return this.decodeEnriched(data, contractName, 0);
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Canonical IGovPool.getProposals fragment + a fail-soft ProposalView decoder.
3
+ *
4
+ * Shared by the flow execute-gate (src/tools/flow.ts) and the risk-assess tool
5
+ * (src/tools/risk.ts) so the deeply-nested struct is declared and decoded in
6
+ * exactly one place. The nested `validatorProposal`
7
+ * (IGovValidators.ExternalProposal) MUST stay byte-exact with the deployed
8
+ * contract or ethers decoding throws — verified against DeXe-Protocol
9
+ * interfaces/gov/IGovPool.sol + interfaces/gov/validators/IGovValidators.sol.
10
+ */
11
+ export declare const GET_PROPOSALS_FRAGMENT = "function getProposals(uint256 offset, uint256 limit) view returns (tuple(tuple(tuple(tuple(bool earlyCompletion, bool delegatedVotingAllowed, bool validatorsVote, uint64 duration, uint64 durationValidators, uint64 executionDelay, uint128 quorum, uint128 quorumValidators, uint256 minVotesForVoting, uint256 minVotesForCreating, tuple(address rewardToken, uint256 creationReward, uint256 executionReward, uint256 voteRewardsCoefficient) rewardsInfo, string executorDescription) settings, uint64 voteEnd, uint64 executeAfter, bool executed, uint256 votesFor, uint256 votesAgainst, uint256 rawVotesFor, uint256 rawVotesAgainst, uint256 givenRewards) core, string descriptionURL, tuple(address executor, uint256 value, bytes data)[] actionsOnFor, tuple(address executor, uint256 value, bytes data)[] actionsOnAgainst) proposal, tuple(tuple(bool executed, uint56 snapshotId, uint64 voteEnd, uint64 executeAfter, uint128 quorum, uint256 votesFor, uint256 votesAgainst) core) validatorProposal, uint8 proposalState, uint256 requiredQuorum, uint256 requiredValidatorsQuorum)[])";
12
+ export interface DecodedProposalView {
13
+ actionsOnFor: {
14
+ executor: string;
15
+ value: string;
16
+ data: string;
17
+ }[];
18
+ actionsOnAgainst: {
19
+ executor: string;
20
+ value: string;
21
+ data: string;
22
+ }[];
23
+ /** settings.quorum — a fraction of 1e27 (pct × 1e25). */
24
+ quorumRaw: bigint;
25
+ votesFor: bigint;
26
+ votesAgainst: bigint;
27
+ /** getProposals' requiredQuorum view field — absolute token-weight. */
28
+ requiredQuorum: bigint;
29
+ proposalState: number;
30
+ descriptionURL: string;
31
+ }
32
+ /**
33
+ * Decode one element of the getProposals return (a ProposalView tuple). Returns
34
+ * null on any structural surprise — callers fail soft rather than throw.
35
+ */
36
+ export declare function decodeProposalView(view: unknown): DecodedProposalView | null;
37
+ //# sourceMappingURL=govProposalView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"govProposalView.d.ts","sourceRoot":"","sources":["../../src/lib/govProposalView.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,sBAAsB,kjCAC8gC,CAAC;AAEljC,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClE,gBAAgB,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtE,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,mBAAmB,GAAG,IAAI,CAyB5E"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Canonical IGovPool.getProposals fragment + a fail-soft ProposalView decoder.
3
+ *
4
+ * Shared by the flow execute-gate (src/tools/flow.ts) and the risk-assess tool
5
+ * (src/tools/risk.ts) so the deeply-nested struct is declared and decoded in
6
+ * exactly one place. The nested `validatorProposal`
7
+ * (IGovValidators.ExternalProposal) MUST stay byte-exact with the deployed
8
+ * contract or ethers decoding throws — verified against DeXe-Protocol
9
+ * interfaces/gov/IGovPool.sol + interfaces/gov/validators/IGovValidators.sol.
10
+ */
11
+ export const GET_PROPOSALS_FRAGMENT = "function getProposals(uint256 offset, uint256 limit) view returns (tuple(tuple(tuple(tuple(bool earlyCompletion, bool delegatedVotingAllowed, bool validatorsVote, uint64 duration, uint64 durationValidators, uint64 executionDelay, uint128 quorum, uint128 quorumValidators, uint256 minVotesForVoting, uint256 minVotesForCreating, tuple(address rewardToken, uint256 creationReward, uint256 executionReward, uint256 voteRewardsCoefficient) rewardsInfo, string executorDescription) settings, uint64 voteEnd, uint64 executeAfter, bool executed, uint256 votesFor, uint256 votesAgainst, uint256 rawVotesFor, uint256 rawVotesAgainst, uint256 givenRewards) core, string descriptionURL, tuple(address executor, uint256 value, bytes data)[] actionsOnFor, tuple(address executor, uint256 value, bytes data)[] actionsOnAgainst) proposal, tuple(tuple(bool executed, uint56 snapshotId, uint64 voteEnd, uint64 executeAfter, uint128 quorum, uint256 votesFor, uint256 votesAgainst) core) validatorProposal, uint8 proposalState, uint256 requiredQuorum, uint256 requiredValidatorsQuorum)[])";
12
+ /**
13
+ * Decode one element of the getProposals return (a ProposalView tuple). Returns
14
+ * null on any structural surprise — callers fail soft rather than throw.
15
+ */
16
+ export function decodeProposalView(view) {
17
+ try {
18
+ const v = view;
19
+ const proposal = v[0];
20
+ const core = proposal[0];
21
+ const settings = core[0];
22
+ const mapActions = (raw) => raw.map((a) => ({
23
+ executor: a[0],
24
+ value: a[1].toString(),
25
+ data: a[2],
26
+ }));
27
+ return {
28
+ actionsOnFor: mapActions(proposal[2]),
29
+ actionsOnAgainst: mapActions(proposal[3]),
30
+ quorumRaw: settings[6],
31
+ votesFor: core[4],
32
+ votesAgainst: core[5],
33
+ requiredQuorum: v[3],
34
+ proposalState: Number(v[2]),
35
+ descriptionURL: proposal[1],
36
+ };
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ //# sourceMappingURL=govProposalView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"govProposalView.js","sourceRoot":"","sources":["../../src/lib/govProposalView.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GACjC,+iCAA+iC,CAAC;AAeljC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAa;IAC9C,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAiB,CAAC;QAC5B,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAc,CAAC;QACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAc,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAc,CAAC;QACtC,MAAM,UAAU,GAAG,CAAC,GAAY,EAAE,EAAE,CACjC,GAAuC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnD,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;YACd,KAAK,EAAG,CAAC,CAAC,CAAC,CAAY,CAAC,QAAQ,EAAE;YAClC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;SACX,CAAC,CAAC,CAAC;QACN,OAAO;YACL,YAAY,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACrC,gBAAgB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACzC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAW;YAChC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAW;YAC3B,YAAY,EAAE,IAAI,CAAC,CAAC,CAAW;YAC/B,cAAc,EAAE,CAAC,CAAC,CAAC,CAAW;YAC9B,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAW;SACtC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1,26 +1,25 @@
1
1
  /**
2
- * Advisory warnings for proposal configurations whose root cause is a DeXe
3
- * *contract* property the MCP cannot fix it can only flag them (the full
4
- * write-up for the protocol team is docs/ESCALATION-DEXE.md). These surface in
5
- * the relevant builder's human-readable output so a reviewer/agent doesn't
6
- * unknowingly ship a degraded-governance configuration.
2
+ * Advisory warnings for proposal/DAO configurations that are governance-safety
3
+ * risks. These surface in the relevant builder's human-readable output so a
4
+ * reviewer/agent doesn't unknowingly ship a degraded-governance configuration.
5
+ * Advisory only verify settings against your DAO's policy.
7
6
  */
8
- /** Seconds. A validator phase beyond this is almost certainly a mistake — and freezes deposits (H-11). */
7
+ /** Seconds. A validator phase beyond this is almost certainly a mistake — and keeps deposits locked. */
9
8
  export declare const DURATION_VALIDATORS_SANITY_CAP = 2592000n;
10
9
  /**
11
10
  * Flag degraded-governance GovSettings: zero-delay execution (no timelock),
12
- * auto-defeating validator quorum, and an unbounded validator phase that
13
- * freezes every voter's deposit. All three are unfixable in the MCP — the
14
- * deployed contracts enforce no such bounds (H-11, executionDelay=0).
11
+ * auto-defeating validator quorum, and an unbounded validator phase that can
12
+ * keep deposits locked for its duration. Configure these against your DAO's policy.
15
13
  */
16
14
  export declare function settingsAdvisories(s: {
17
15
  validatorsVote: boolean;
18
16
  durationValidators: string;
19
17
  executionDelay: string;
20
18
  quorumValidators: string;
21
- }): string[];
19
+ quorum?: string;
20
+ }, floorPct?: number): string[];
22
21
  /** changeVotePower swaps the DAO's vote-power math contract — a privileged, governance-wide change. */
23
- export declare const CHANGE_VOTE_POWER_ADVISORY = "\u26A0 changeVotePower swaps the DAO's entire vote-power math contract \u2014 a privileged, governance-wide change (reversible only by another passed proposal). Verify the new VotePower address before proposing. [protocol-property \u2014 see docs/ESCALATION-DEXE.md]";
24
- /** custom_abi can encode ANY call; the C-2 surface is privileged selectors routed via DEFAULT. */
25
- export declare const CUSTOM_ABI_DEFAULT_ROUTING_ADVISORY = "\u26A0 custom_abi encodes an arbitrary call with no semantic validation. If the LAST proposal action routes to an unregistered executor (settingsId=DEFAULT), the INTERNAL allowlist is skipped for ALL earlier actions \u2014 the C-2 amplifier. (Privileged GovUserKeeper selectors are hard-refused by the C-2 guard.) Keep the last action's executor a registered one. [protocol-property \u2014 see docs/ESCALATION-DEXE.md]";
22
+ export declare const CHANGE_VOTE_POWER_ADVISORY = "\u26A0 changeVotePower swaps the DAO's entire vote-power math contract \u2014 a privileged, governance-wide change (reversible only by another passed proposal). Verify the new VotePower address before proposing. [governance-safety advisory]";
23
+ /** custom_abi can encode ANY call; ensure actions route to registered executors. */
24
+ export declare const CUSTOM_ABI_DEFAULT_ROUTING_ADVISORY = "\u26A0 custom_abi encodes an arbitrary call with no semantic validation. Ensure every proposal action routes to a properly registered executor so the DAO's internal access controls apply, and keep the final action's executor a registered one. Privileged accounting selectors are refused by the MCP's selector guard. [governance-safety advisory]";
26
25
  //# sourceMappingURL=protocolAdvisories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocolAdvisories.d.ts","sourceRoot":"","sources":["../../src/lib/protocolAdvisories.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,0GAA0G;AAC1G,eAAO,MAAM,8BAA8B,WAAa,CAAC;AAEzD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,EAAE,CAqBX;AAED,uGAAuG;AACvG,eAAO,MAAM,0BAA0B,+QACwN,CAAC;AAEhQ,kGAAkG;AAClG,eAAO,MAAM,mCAAmC,uaACuW,CAAC"}
1
+ {"version":3,"file":"protocolAdvisories.d.ts","sourceRoot":"","sources":["../../src/lib/protocolAdvisories.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,wGAAwG;AACxG,eAAO,MAAM,8BAA8B,WAAa,CAAC;AAEzD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,EAAE;IACD,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,EACD,QAAQ,SAAK,GACZ,MAAM,EAAE,CA6BV;AAED,uGAAuG;AACvG,eAAO,MAAM,0BAA0B,qPACmM,CAAC;AAE3O,oFAAoF;AACpF,eAAO,MAAM,mCAAmC,6VACuS,CAAC"}
@@ -1,39 +1,46 @@
1
1
  /**
2
- * Advisory warnings for proposal configurations whose root cause is a DeXe
3
- * *contract* property the MCP cannot fix it can only flag them (the full
4
- * write-up for the protocol team is docs/ESCALATION-DEXE.md). These surface in
5
- * the relevant builder's human-readable output so a reviewer/agent doesn't
6
- * unknowingly ship a degraded-governance configuration.
2
+ * Advisory warnings for proposal/DAO configurations that are governance-safety
3
+ * risks. These surface in the relevant builder's human-readable output so a
4
+ * reviewer/agent doesn't unknowingly ship a degraded-governance configuration.
5
+ * Advisory only verify settings against your DAO's policy.
7
6
  */
7
+ import { quorumPctFromRaw, judgeQuorum, lowQuorumAdvisory } from "./quorumRisk.js";
8
8
  function toBig(s) {
9
9
  return /^[0-9]+$/.test(s) ? BigInt(s) : null;
10
10
  }
11
- /** Seconds. A validator phase beyond this is almost certainly a mistake — and freezes deposits (H-11). */
11
+ /** Seconds. A validator phase beyond this is almost certainly a mistake — and keeps deposits locked. */
12
12
  export const DURATION_VALIDATORS_SANITY_CAP = 2592000n; // 30 days
13
13
  /**
14
14
  * Flag degraded-governance GovSettings: zero-delay execution (no timelock),
15
- * auto-defeating validator quorum, and an unbounded validator phase that
16
- * freezes every voter's deposit. All three are unfixable in the MCP — the
17
- * deployed contracts enforce no such bounds (H-11, executionDelay=0).
15
+ * auto-defeating validator quorum, and an unbounded validator phase that can
16
+ * keep deposits locked for its duration. Configure these against your DAO's policy.
18
17
  */
19
- export function settingsAdvisories(s) {
18
+ export function settingsAdvisories(s, floorPct = 50) {
20
19
  const out = [];
20
+ // Low quorum reduces the participation required to pass a proposal — a
21
+ // governance-safety risk for treasury-moving proposals.
22
+ if (s.quorum !== undefined) {
23
+ const pct = quorumPctFromRaw(s.quorum);
24
+ if (judgeQuorum(pct, floorPct) !== "SAFE") {
25
+ out.push(lowQuorumAdvisory(pct, floorPct));
26
+ }
27
+ }
21
28
  if (toBig(s.executionDelay) === 0n) {
22
- out.push("executionDelay=0 → no timelock: a passed proposal executes immediately, leaving no window to react to a malicious-but-passed action (amplifies C-2). DeXe contracts enforce no minimum set a non-zero delay.");
29
+ out.push("executionDelay=0 → no timelock: a passed proposal executes immediately, leaving no window to review it before it takes effect. Set a non-zero execution delay (a 1-day minimum is recommended for standard governance).");
23
30
  }
24
31
  if (s.validatorsVote) {
25
32
  if (toBig(s.quorumValidators) === 0n) {
26
- out.push("quorumValidators=0 with validatorsVote=true → every validator proposal auto-defeats (governance DoS). DeXe contracts enforce no lower bound.");
33
+ out.push("quorumValidators=0 with validatorsVote=true → every validator proposal auto-defeats (governance stalls). Set a non-zero validator quorum.");
27
34
  }
28
35
  const dv = toBig(s.durationValidators);
29
36
  if (dv !== null && dv > DURATION_VALIDATORS_SANITY_CAP) {
30
- out.push(`durationValidators=${s.durationValidators}s (> 30 days) → GovSettings has NO upper bound and deposits stay LOCKED for the whole validator phase (GovPoolUnlock excludes ValidatorVoting), so a huge value freezes every voter's funds (H-11).`);
37
+ out.push(`durationValidators=${s.durationValidators}s (> 30 days) → deposits stay locked for the whole validator phase, so a very large value can lock voters' funds for an extended period. Use a sane validator duration.`);
31
38
  }
32
39
  }
33
40
  return out;
34
41
  }
35
42
  /** changeVotePower swaps the DAO's vote-power math contract — a privileged, governance-wide change. */
36
- export const CHANGE_VOTE_POWER_ADVISORY = "⚠ changeVotePower swaps the DAO's entire vote-power math contract — a privileged, governance-wide change (reversible only by another passed proposal). Verify the new VotePower address before proposing. [protocol-property — see docs/ESCALATION-DEXE.md]";
37
- /** custom_abi can encode ANY call; the C-2 surface is privileged selectors routed via DEFAULT. */
38
- export const CUSTOM_ABI_DEFAULT_ROUTING_ADVISORY = "⚠ custom_abi encodes an arbitrary call with no semantic validation. If the LAST proposal action routes to an unregistered executor (settingsId=DEFAULT), the INTERNAL allowlist is skipped for ALL earlier actions the C-2 amplifier. (Privileged GovUserKeeper selectors are hard-refused by the C-2 guard.) Keep the last action's executor a registered one. [protocol-property — see docs/ESCALATION-DEXE.md]";
43
+ export const CHANGE_VOTE_POWER_ADVISORY = "⚠ changeVotePower swaps the DAO's entire vote-power math contract — a privileged, governance-wide change (reversible only by another passed proposal). Verify the new VotePower address before proposing. [governance-safety advisory]";
44
+ /** custom_abi can encode ANY call; ensure actions route to registered executors. */
45
+ export const CUSTOM_ABI_DEFAULT_ROUTING_ADVISORY = "⚠ custom_abi encodes an arbitrary call with no semantic validation. Ensure every proposal action routes to a properly registered executor so the DAO's internal access controls apply, and keep the final action's executor a registered one. Privileged accounting selectors are refused by the MCP's selector guard. [governance-safety advisory]";
39
46
  //# sourceMappingURL=protocolAdvisories.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocolAdvisories.js","sourceRoot":"","sources":["../../src/lib/protocolAdvisories.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,SAAS,KAAK,CAAC,CAAS;IACtB,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED,0GAA0G;AAC1G,MAAM,CAAC,MAAM,8BAA8B,GAAG,QAAU,CAAC,CAAC,UAAU;AAEpE;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAKlC;IACC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;QACnC,GAAG,CAAC,IAAI,CACN,gNAAgN,CACjN,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;QACrB,IAAI,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,EAAE,CAAC;YACrC,GAAG,CAAC,IAAI,CACN,8IAA8I,CAC/I,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;QACvC,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,GAAG,8BAA8B,EAAE,CAAC;YACvD,GAAG,CAAC,IAAI,CACN,sBAAsB,CAAC,CAAC,kBAAkB,qMAAqM,CAChP,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uGAAuG;AACvG,MAAM,CAAC,MAAM,0BAA0B,GACrC,6PAA6P,CAAC;AAEhQ,kGAAkG;AAClG,MAAM,CAAC,MAAM,mCAAmC,GAC9C,qZAAqZ,CAAC"}
1
+ {"version":3,"file":"protocolAdvisories.js","sourceRoot":"","sources":["../../src/lib/protocolAdvisories.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEnF,SAAS,KAAK,CAAC,CAAS;IACtB,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED,wGAAwG;AACxG,MAAM,CAAC,MAAM,8BAA8B,GAAG,QAAU,CAAC,CAAC,UAAU;AAEpE;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,CAMC,EACD,QAAQ,GAAG,EAAE;IAEb,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,uEAAuE;IACvE,wDAAwD;IACxD,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,MAAM,EAAE,CAAC;YAC1C,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC;QACnC,GAAG,CAAC,IAAI,CACN,yNAAyN,CAC1N,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;QACrB,IAAI,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,EAAE,CAAC;YACrC,GAAG,CAAC,IAAI,CACN,2IAA2I,CAC5I,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;QACvC,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,GAAG,8BAA8B,EAAE,CAAC;YACvD,GAAG,CAAC,IAAI,CACN,sBAAsB,CAAC,CAAC,kBAAkB,yKAAyK,CACpN,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uGAAuG;AACvG,MAAM,CAAC,MAAM,0BAA0B,GACrC,wOAAwO,CAAC;AAE3O,oFAAoF;AACpF,MAAM,CAAC,MAAM,mCAAmC,GAC9C,qVAAqV,CAAC"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Low-quorum governance-safety advisories — pure logic, no RPC.
3
+ *
4
+ * Treasury-moving proposals (ERC20 approve/transfer or native value) should pass
5
+ * under an adequate quorum so a true majority is required. This module flags when
6
+ * a DAO's quorum setting is low for such proposals, so an operator/agent verifies
7
+ * the quorum and stakeholder participation before executing. Advisory only — the
8
+ * durable control is an adequate on-chain quorum threshold configured per DAO.
9
+ */
10
+ export type RiskLevel = "SAFE" | "CAUTION" | "DANGER";
11
+ /** Worst (most dangerous) of a set of risk levels. Empty → SAFE. */
12
+ export declare function worstRisk(...levels: RiskLevel[]): RiskLevel;
13
+ /** Convert a raw quorum setting (pct × 1e25) to a human percentage. 5e26 → 50. */
14
+ export declare function quorumPctFromRaw(raw: bigint | string): number;
15
+ /** SAFE ≥ floor; CAUTION ≥ 0.8×floor; DANGER below. NaN → DANGER (unparseable). */
16
+ export declare function judgeQuorum(pct: number, floorPct: number): RiskLevel;
17
+ export type TreasuryHitKind = "approve" | "transfer" | "transferFrom" | "increaseAllowance" | "nftTransfer" | "nativeValue";
18
+ export interface TreasuryHit {
19
+ /** Index of the action in the proposal's action array. */
20
+ index: number;
21
+ /** Target contract of the action. */
22
+ executor: string;
23
+ /** 0x 4-byte selector, or null for a pure native-value transfer. */
24
+ selector: string | null;
25
+ kind: TreasuryHitKind;
26
+ /** Best-effort decoded recipient (spender / `to`), or null when undecodable. */
27
+ recipient: string | null;
28
+ /** Best-effort decoded amount / tokenId as a decimal string, or null. */
29
+ amount: string | null;
30
+ }
31
+ /** Decimal selectors of every treasury-touching function (for docs/tests). */
32
+ export declare function treasurySelectors(): string[];
33
+ /**
34
+ * Scan a proposal's actions and report every one that moves treasury value or
35
+ * grants an allowance. Best-effort recipient/amount decode — NEVER throws.
36
+ * A single action can yield two hits (native value + an ERC20 call).
37
+ */
38
+ export declare function classifyTreasuryActions(actions: {
39
+ executor: string;
40
+ value: string;
41
+ data: string;
42
+ }[]): TreasuryHit[];
43
+ export interface QuorumConcentration {
44
+ /** Absolute voting weight needed to clear quorum, or null when unknown. */
45
+ requiredWeight: bigint | null;
46
+ /** Token total supply used as the denominator, or null when unknown. */
47
+ totalSupply: bigint | null;
48
+ /**
49
+ * Share of total supply required to meet quorum. INDICATIVE: ignores VotePower
50
+ * math, NFT multipliers, and delegation, and uses minted supply as the
51
+ * denominator. Null when supply/weight unknown. A low value indicates a DAO
52
+ * whose decisions need only a small share of supply — a governance-safety flag.
53
+ */
54
+ pctOfSupplyForQuorum: number | null;
55
+ verdict: RiskLevel;
56
+ }
57
+ /**
58
+ * Estimate the share of token supply required to meet a proposal's quorum.
59
+ * Prefers the on-chain `requiredWeight` (getProposalRequiredQuorum); otherwise
60
+ * derives it from `quorumPct × totalVoteWeight`. When the percentage cannot be
61
+ * computed the verdict is CAUTION (unknown is never SAFE).
62
+ */
63
+ export declare function quorumConcentration(args: {
64
+ quorumPct: number;
65
+ floorPct?: number;
66
+ totalSupply?: bigint;
67
+ requiredWeight?: bigint;
68
+ totalVoteWeight?: bigint;
69
+ }): QuorumConcentration;
70
+ /** Flag a below-floor quorum SETTING (deploy / change-voting-settings). */
71
+ export declare function lowQuorumAdvisory(pct: number, floorPct: number): string;
72
+ /** Flag a treasury-touching proposal at build time (static, no RPC needed). */
73
+ export declare const TREASURY_RISK_ADVISORY: string;
74
+ /**
75
+ * Build-time advisory for any builder whose actions move treasury value.
76
+ * Returns the static advisory string when there is at least one treasury hit
77
+ * and the guard is enabled, else null. Build-time is WARN-only — it never
78
+ * blocks (refusing would just route users to hand-crafted custom_abi).
79
+ */
80
+ export declare function buildTimeTreasuryAdvisory(actions: {
81
+ executor: string;
82
+ value: string;
83
+ data: string;
84
+ }[], guard: "off" | "warn"): string | null;
85
+ /**
86
+ * Advisory message for the vote_and_execute treasury alert. `reasons` are the
87
+ * failing checks (below-floor quorum, no controlling-member participation).
88
+ * Advisory ONLY — the guard never blocks; it surfaces this and proceeds. The
89
+ * durable control is an adequate on-chain quorum threshold configured per DAO.
90
+ */
91
+ export declare function treasuryExecuteAdvisory(reasons: string[]): string;
92
+ //# sourceMappingURL=quorumRisk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quorumRisk.d.ts","sourceRoot":"","sources":["../../src/lib/quorumRisk.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtD,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAI3D;AAQD,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAS7D;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAKpE;AAID,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,UAAU,GACV,cAAc,GACd,mBAAmB,GACnB,aAAa,GACb,aAAa,CAAC;AAElB,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,eAAe,CAAC;IACtB,gFAAgF;IAChF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,yEAAyE;IACzE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AA6BD,8EAA8E;AAC9E,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GAC3D,WAAW,EAAE,CAsCf;AAID,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,wEAAwE;IACxE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;OAKG;IACH,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,OAAO,EAAE,SAAS,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,mBAAmB,CAoBtB;AAMD,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQvE;AAED,+EAA+E;AAC/E,eAAO,MAAM,sBAAsB,QAG6C,CAAC;AAEjF;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EAC5D,KAAK,EAAE,KAAK,GAAG,MAAM,GACpB,MAAM,GAAG,IAAI,CAGf;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAOjE"}