ByAUJay
“DAO Treasury Multisig” “AddedOwner” and “AddedOwner” Forta Alerts: Governance Risk Signals to Watch
A concise, expert guide for startup and enterprise leaders on how to treat “AddedOwner”/owner‑change activity in DAO treasury multisigs as actionable governance risk signals, and how to wire Forta alerts into your incident response and compliance workflows in 2026. We include concrete event signatures, alert patterns, runbooks, and example queries you can use today.
TL;DR (description)
Owner changes on a DAO’s Gnosis Safe are among the highest-signal governance events. Monitoring AddedOwner and related events with Forta, and automating runbooks on top of those alerts, materially reduces treasury compromise risk and speeds incident response.
Why “AddedOwner” alerts matter more than you think
- “Owners” of a Safe can:
- Propose and co-sign transactions that move funds, install/uninstall modules, change guards, or even lower thresholds in a follow-up tx.
- Cascade privileges into governance modules (e.g., SafeSnap, Roles), where a single mis-scoped change can enable policy bypass.
- The Safe emits canonical events for owner/threshold changes:
- AddedOwner(address)
- RemovedOwner(address)
- ChangedThreshold(uint256) (docs.safe.global)
- Forta’s real-time detection network can surface these events (via custom or community bots) and correlate them with higher-order threat intel like Tornado Cash funding, suspicious contract creation, and exploit patterns. This is ideal for wiring owner-change alerts to an emergency runbook. (docs.forta.network)
The Compound DAO’s operations illustrate the pattern: they use Forta to monitor a community multisig for “adding/removing owners” and other privileged changes—treating them as operational risk signals that demand review. (forta.org)
The events you must watch (and their exact signatures)
When building or tuning detection bots, you’ll want the event topics and ABI functions that touch signer sets:
- Events
- AddedOwner(address): topic0 = keccak256("AddedOwner(address)")
- RemovedOwner(address): topic0 = keccak256("RemovedOwner(address)")
- ChangedThreshold(uint256): topic0 = keccak256("ChangedThreshold(uint256)") (docs.safe.global)
- Functions that emit those events
- addOwnerWithThreshold(address owner, uint256 _threshold)
- removeOwner(address prevOwner, address owner, uint256 _threshold)
- changeThreshold(uint256 _threshold) (docs.safe.global)
Practical tip: also watch for guard/module changes because they reshape enforcement:
- ChangedGuard(address)
- ChangedModuleGuard(address) (docs.safe.global)
What to consider a “critical” AddedOwner alert
Treat an AddedOwner alert as Critical if any of these co-conditions hold (example heuristics you can encode in your bot or your responder):
- The new owner address:
- Received funds from a sanctioned mixer or known exploiter label in the prior 7 days. Forta’s Attack Detector and base bots expose these signals and labels. (docs.forta.network)
- Was contract-created “just in time” (same hour/day) before addition. Correlate with “suspicious contract creation” base alerts in Forta. (docs.forta.network)
- Has zero or near-zero prior on-chain history, or belongs to an unvetted custodian.
- The AddedOwner transaction also sets a lower threshold (ChangedThreshold) than historical policy, or is closely followed by a threshold decrease within N blocks. (docs.safe.global)
- Any concurrent event that weakens defense-in-depth:
- ChangedGuard to an unknown address,
- ChangedModuleGuard,
- EnabledModule for a new, broad-privilege module. (docs.safe.global)
For each matched condition, escalate severity/urgency and widen the blast radius of your runbook (e.g., freeze high-value Safes via spend caps, pause modules, raise timeouts).
Forta alert plumbing that actually works in 2026
- Subscribe to bot alerts and route to Slack/Telegram/webhooks directly from the Forta App. Use this for human-in-the-loop channels and for webhooks that trigger your automations. (docs.forta.network)
- Use Forta’s GraphQL API to query historical or streaming alerts in your backend, enrich, and drive automated response. The schema and example queries (by bot IDs, time range, addresses) are production-ready. (docs.forta.network)
- Build composable bots that consume other alerts via handleAlert to correlate multisig events with attack stages (funding → prep → exploit → laundering). This is a high-signal pattern that reduces noise. (docs.forta.network)
Note on operations: OpenZeppelin Defender is being sunset July 1, 2026; plan migrations to open-source Monitor/Relayer or another stack if your Forta → action pipeline currently depends on Defender. (blog.openzeppelin.com)
Example: a minimal detection rule for “AddedOwner”
This is the shape of a Forta bot rule you can implement in TypeScript:
- Listen for logs on Safe singleton(s) across your chains with topic0 of AddedOwner.
- Decode the owner address from topic1/data.
- Query Forta labels/alerts for the new owner and its funders in the last 7 days (e.g., “attacker”, Tornado Cash funded, suspicious creation).
- Emit a finding like SAFE-OWNER-ADDED with severity based on the conditions.
Reference APIs and patterns:
- Safe ABI events/functions (for decoding). (docs.safe.global)
- Forta SDK Finding/Alert schema and getAlerts/getLabels queries. (docs.forta.network)
Example GraphQL queries you can paste into the Forta API Sandbox
- Fetch recent alerts tied to a specific Safe address (works when you constrain to your bot IDs that produce AddedOwner/RemovedOwner findings):
query todaysAlerts($input: AlertsInput) { alerts(input: $input) { alerts { alertId name description severity addresses createdAt source { transactionHash block { number chainId timestamp } } labels { label entity confidence } metadata } pageInfo { hasNextPage endCursor { blockNumber alertId } } } }
Variables example:
{ "input": { "addresses": ["0xYourSafeAddress"], "bots": ["0xyour-bot-id-here"], "first": 50, "afterCreatedAtDate": "2026-01-01T00:00:00Z" } }
See the Forta GraphQL reference and example queries for field details and paging. (docs.forta.network)
What “good” looks like: severity tiers for AddedOwner and friends
Recommended default policy (tune to your risk appetite):
- Critical
- AddedOwner and threshold decreased by ≥1 within the same change set
- AddedOwner whose address is Tornado-funded, attacker-labeled, or created in last 24h
- RemovedOwner reducing the signer set below an established quorum without an on-chain proposal or off-chain announcement
- High
- AddedOwner without threshold change but in combination with ChangedGuard or EnabledModule
- ChangedThreshold to <= M-1 relative to policy, or back-to-back threshold changes within 1 day
- Medium
- AddedOwner or RemovedOwner aligned with a public governance rotation, vetted address, threshold constant or increased
- Low
- Spurious, repeated alerts due to backfills or redundant bot coverage; still acknowledge, but auto-resolve
Correlate with higher-level detectors (Attack Detector 2.0) to auto-escalate if any stage of an exploit is simultaneously detected near the owner change. (docs.forta.network)
End-to-end runbook for treasury safety
Map Forta alert types to specific, deterministic actions:
- AddedOwner + risk co-signal → immediate
- Set spending limits near-zero on the treasury Safe; lock large transfers to “allowlisted” recipients for 24–72h
- Raise timelock delays on governance-controlled contracts (e.g., TimelockController) while investigating
- Assign a “ProtocolGuardian” or “GovernanceGuardian” Safe to veto or pause under strict scope until cleared (implement hard constraints so guardians can pause but not unpause) (7blocklabs.com)
- ChangedGuard/ChangedModuleGuard → verification gate
- Confirm guard/module address against an allowlist; if unknown, temporarily disable module execution on downstream Safes or pause sensitive flows. (docs.safe.global)
- RemovedOwner or threshold decrease → out-of-band confirmation
- Require a second-channel human confirmation for signer rotations (e.g., through board ops) before lifting temporary spending caps
Implementation details that save you time
- Owner list is a linked list
- When removing an owner, prevOwner must be correct; malformed removal can brick the owner list. Validate calldata in your bots and CI pipelines. (docs.safe.global)
- Bulk, safe signer rotations
- Use automation to generate correct, minimal transaction bundles across chains and to maintain list integrity for large councils. Simulate on Tenderly before execution. (github.com)
- Delegates vs owners
- Safe Transaction Service “delegates” are off-chain convenience signers for the service API, not on-chain owners. Don’t confuse delegate additions with AddedOwner events. Monitor both surfaces if you use the service. (docs.safe.global)
- Delivery plumbing beyond polling
- Safe’s Events Service can stream webhook/SSE notifications (e.g., EXECUTED_MULTISIG_TRANSACTION), which you can join with Forta alerts to reduce MTTD without heavy polling. (github.com)
Building your own AddedOwner Forta bot (outline)
- Detector inputs
- Chain log scanner on Safe singleton addresses (per chain)
- Forta getAlerts/getLabels to enrich entities
- Conditions
- Trigger on AddedOwner, RemovedOwner, ChangedThreshold; attach correlated guard/module events if found nearby
- Pull the last N blocks’ alerts for the new owner’s funders; if TORNADO‑CASH‑FUNDED or ATTACKER labels appear, set severity Critical
- Outputs
- alertId: "SAFE-OWNER-ADDED" | "SAFE-OWNER-REMOVED" | "SAFE-THRESHOLD-CHANGED"
- severity: Info/Low/Medium/High/Critical
- metadata: { newOwner, thresholdAfter, txHash, chainId, anomalyScore, correlatedAlertIds, guardChanged, moduleChanged, policyHash }
SDK and docs you’ll use:
- Forta bot SDK (Finding/Alert schema, handleAlert, getAlerts/getLabels) (docs.forta.network)
- Forta API GraphQL (pagination, filter by bots/addresses/time) (docs.forta.network)
- Safe reference for ABI and events to decode logs correctly (docs.safe.global)
Production patterns from leading protocols
- Monitor the DAO/community multisig as a first-class asset, not just product contracts. Compound’s public write-ups note dedicated Forta coverage for their community multisig, including owner changes and role assignments. Adopt the same stance for your treasury Safe(s). (forta.org)
- Reduce noise with correlation
- Compose your AddedOwner bot with Forta’s Attack Detector 2.0 signals. It improves precision via stage correlation and ML-driven anomaly scores, which is critical if you plan automated responses. (docs.forta.network)
- Plan your monitoring platform migration
- If you rely on Defender’s Sentinels for alert routing and Autotasks for reactions, schedule a move to open-source Monitor/Relayer or an alternative before July 1, 2026. Keep the same Forta subscriptions; only the downstream runner changes. (blog.openzeppelin.com)
Quick-start checklist (copy/paste)
- Inventory every Safe that can move treasury funds or install modules; track current owners and threshold.
- Subscribe to AddedOwner/RemovedOwner/ChangedThreshold detections for each Safe (your bot or a community bot) in Forta App; deliver to Slack and to a webhook URL you control. (docs.forta.network)
- Add enrichment: on AddedOwner, query Forta labels and Attack Detector proximity; compute severity. (docs.forta.network)
- Write a runbook:
- Critical → set spend caps to near-zero, increase timelock delays, and require out-of-band validation
- High → manual review within 2 hours, temporary caps, publish a status note
- Medium/Low → log + weekly audit
- Guard/module monitoring:
- Alert on ChangedGuard/ChangedModuleGuard/EnabledModule/DisabledModule to catch control plane changes. (docs.safe.global)
- Simulate owner changes in CI (Tenderly/Anvil) before execution; verify linked-list invariants and threshold bounds. (github.com)
- Prepare for Defender sunset; ensure your webhook → automation path does not break. (blog.openzeppelin.com)
Appendix: worked examples
- Safe signer rotation with risk flag
- Situation: Treasury Safe 5/9 rotates one signer. AddedOwner fires; threshold unchanged (5).
- Enrichment: New owner created 2 hours ago; funded by a Tornado Cash–funded address 90 minutes ago.
- Action: Critical severity.
- Freeze large transfers by setting per-tx and 24h spend caps in your Guard or via Safe spending limits; temporarily block unknown recipients until a named allowlist is confirmed. (7blocklabs.com)
- Escalate to core governance for verification and rotate the signer again if compromised.
- Threshold decrease with benign owner addition
- Situation: AddedOwner + ChangedThreshold from 5→4 during council expansion.
- Enrichment: New owner is a known custodian; no hostile intel.
- Action: High severity pending policy check.
- Require explicit approval from treasury policy owners; if within the approved “expansion” window, downgrade to Medium and document.
- Guard swapped quietly
- Situation: ChangedGuard emitted; no owner change.
- Enrichment: Guard not on allowlist.
- Action: High severity.
- Pause module-originated calls via Module Guard; require dual approval to re-enable. If the guard is legitimate (e.g., upgraded Roles Modifier), update allowlists after code review. (docs.safe.global)
The bottom line
- AddedOwner/RemovedOwner/ChangedThreshold are “governance tripwires.” Treat them like prod access changes in a regulated environment, not like routine wallet ops.
- Forta gives you the substrate—alerts, labels, correlation—to turn those tripwires into low-latency decisions and, where appropriate, safe automation. (docs.forta.network)
- Make the detection actionable with a runbook, spend caps, and guard/module policy—and keep your monitoring stack future-proof as platform tooling evolves. (blog.openzeppelin.com)
Sources and docs to bookmark
- Safe events/functions for owners/threshold/guards: AddedOwner, RemovedOwner, ChangedThreshold, setGuard/setModuleGuard. (docs.safe.global)
- Forta Attack Detector 2.0 overview and docs; labels; API and queries; subscriptions; SDK. (docs.forta.network)
- Compound’s Forta-backed community multisig monitoring (owner changes, pause guardian, etc.). (forta.org)
- Defender sunset and migration to open-source Monitor/Relayer (plan before July 1, 2026). (blog.openzeppelin.com)
Like what you're reading? Let's build together.
Get a free 30‑minute consultation with our engineering team.

