audit-a-dao-treasury-signer-set
Use when reviewing who can move a DAO treasury, or after a signer change. Compares the multisig's on-chain owners and threshold against the governance-approved roster.
- License 许可
- MIT
- 最近更新
- 2026-11-12
- Stars
- ★ 81
- Forks
- 17
01 前言 Front Matter
- name
- audit-a-dao-treasury-signer-set
- description
- Use when reviewing who can move a DAO treasury, or after a signer change. Compares the multisig's on-chain owners and threshold against the governance-approved roster.
02 资源文件 3
- 许可证LICENSE1.0 KB
- 参考文档SOURCE.md357 B
- 参考文档TRUST.auto.yaml2.1 KB
03 SKILL.md 正文
Audit a DAO treasury signer set
The treasury multisig is only as legitimate as the signer set governance approved. A signer silently swapped in, or a threshold lowered by one, changes who controls the funds without a vote.
Procedure
-
Read the current owners and threshold:
cast call $SAFE "getOwners()(address[])" --rpc-url $RPCcast call $SAFE "getThreshold()(uint256)" --rpc-url $RPC -
Fetch the governance-approved roster: the proposal that last set the signer set, decoded from its calldata.
cast call $GOV "getActions(uint256)(address[],uint256[],bytes[],bytes32)" $ID --rpc-url $RPC -
Diff the two sets: any owner not in the approved list, or a missing approved owner, is a finding.
-
Check no two owners are controlled by one key: compare against a known cluster map, and flag duplicate hardware-wallet addresses or an owner that is an EOA of a current signer's hot key.
-
Verify the threshold still matches the approved value; a threshold reduced from 4/7 to 3/7 is a governance change even if the owners are identical.
-
Confirm the Safe is the timelock's beneficiary, not a rogue parallel treasury: the address the governor pays must equal this Safe.
-
Re-run after every
AddedOwner/RemovedOwner/ChangedThresholdevent; alert on any that does not trace to an executed proposal. -
Check each owner is still an active signer, not a departed member or a revoked key; a stale owner is a standing point of compromise.
-
Confirm no owner is a contract that cannot sign (e.g. the governor's own timelock); a non-signing owner quietly lowers the effective threshold.
-
Record the audit block and the proposal id that last authorised the set, so the check is reproducible later.
Pitfalls
-
Auditing owners but not the threshold; the same owners with a lower threshold is a weaker control.
-
Assuming the owners are the governance council when the founding team holds the keys from before the DAO existed.
-
Missing a signer module: a Safe with an enabled module (e.g. a recovery or spending-limit module) can move funds without the normal threshold.
-
Treating the Safe address as canonical without checking the governor's target; a proposal to pay a different, similarly-named Safe is the attack.
-
Ignoring signer rotation history; a signer added and removed within a term may still hold a copy of the config.
-
A Safe whose owners include the deployer EOA from before governance existed still grants that key standing weight.
-
Trusting the Safe UI's owner list; read
getOwners()on-chain, since a pending owner change is not yet applied. -
A module-enabled Safe can be drained through the module without any owner signing; check
getModulesPaginated.
Verification
cast call $SAFE "getOwners()(address[])" --rpc-url $RPC && cast call $SAFE "getThreshold()(uint256)" --rpc-url $RPC
# owners set and threshold must equal the decoded roster from the executed proposal
Report the owner set, the threshold, the approved roster, and any diff or non-governance signer change, with the events cited.
04 同仓库更多 Skills
recipe-performance
Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold/warm/background-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout/paint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.
mexc-spot-websocket
MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.
mexc-spot-rest
MEXC Spot REST workflows for public data, signed account requests, orders, wallet/admin actions, and secure signing without exposing API keys.
mexc-futures-websocket
MEXC Futures WebSocket workflows for public streams, private account/order/position streams, ping/pong, subscriptions, and depth maintenance.
0xklen-version-and-refresh-sanctions-lists
暂无简介
verify-tests-cover-changed-lines
Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.