ByAUJay
“ExecutionFromModuleSuccess” and “ExecutionFromModuleFailure” in DAO‑Multisig: What the Alerts Really Mean
Description: These two Safe (previously known as Gnosis Safe) events aren’t your typical “success/fail” logs -- they’re specific signals showing that a whitelisted module has executed (or tried to execute) a transaction from your Safe account. In this guide, we’ll break down what these events mean on L1 versus L2, how to look into them, and tips to strengthen your setup against any potential risks.
TL;DR for decision‑makers
- With Safe-based DAO multisigs, modules have the ability to skip the usual n-of-m signature process and automate actions instead. When a module kicks in, the Safe will send out either an ExecutionFromModuleSuccess or ExecutionFromModuleFailure message. This acts as your audit trail to show that “automation interacted with the treasury.” (docs.safe.global)
- If you’re working on L2 networks (or using SafeL2), you’ll benefit from a detailed SafeModuleTransaction event that includes the target, value, and operation. This makes incident response way simpler. On L1, though, you usually have to dig into traces or use the Safe Transaction Service API to piece together what happened. (scrollscan.com)
Why your SIEM keeps flagging these two events
Safe’s ModuleManager contract has this handy function called execTransactionFromModule(...). Basically, any enabled module (think of it as an automation plug-in) can use it to have the Safe perform a call or a delegatecall without needing to gather signatures from the owners. After that, the Safe lets you know what happened by emitting one of two events:
- event ExecutionFromModuleSuccess(address indexed module)
- event ExecutionFromModuleFailure(address indexed module)
These events are built right into the Safe contracts and trigger as soon as the low-level call gives a true/false response. They only log one piece of information: the module that kicked off the execution. You can check it out on gnosisscan.io.
Key point for executives: Success means “a whitelisted module just moved or changed something for your treasury,” rather than just “a UI action succeeded.” On the flip side, a Failure happens when the module attempted to act, but the call returned false (which can be harmless or sometimes just a warning). (gnosisscan.io)
Where these alerts come from in the code
Inside ModuleManager.execTransactionFromModule, Safe first makes sure that msg.sender is an enabled module. After that, it goes ahead and executes the requested operation, which then leads to one of the two events being emitted:
- success = execute(to, value, data, operation, gasleft());
if (success) {
emit ExecutionFromModuleSuccess(msg.sender);
} else {
emit ExecutionFromModuleFailure(msg.sender);
}
That info comes right from trusted Safe sources (Safe v1.3.x/1.4.x family); it’s the go-to behavior across networks. (gnosisscan.io)
On SafeL2 (the event-packed version that's commonly used on most L2s), the contract sends out a SafeModuleTransaction(module, to, value, data, operation) notification before it logs the success or failure event. This makes it super easy for indexers to piece together everything that went down. You can check it out here.
L1 vs L2: why your forensics experience differs
- L1 (Safe.sol): This version keeps things minimalist with its events to help save on gas fees. You’ll get notifications like ExecutionFromModuleSuccess/Failure, but you won’t get the full details like to/value/data. If you want to piece everything together, you’ll usually need to rely on transaction tracing or the Safe Transaction Service (STS). Check it out here.
- L2 (SafeL2.sol): Here, we’ve got some added bonus events for better indexing. One standout is SafeModuleTransaction, which gives you all those juicy details you need for quick troubleshooting. That’s why dashboards on Arbitrum, Optimism, Base, and Scroll feel super snappy and informative compared to L1, where things can be slower unless you’re running traces. Want to know more? Dive in here.
The Safe Transaction Service lays it all out clearly: it keeps track of Safe activity using traces on L1 and events on L2. Plus, it offers module transaction endpoints that standardize details like “isSuccessful,” module address, target, value, data, and operation. You can find more info in the documentation.
Real on‑chain examples to recognize
- You’ll often spot
ExecutionFromModuleSuccesspopping up with modules like the ERC‑4337 Safe adapter (for instance, Safe7579). This tag shows that something is happening with a module in the account-abstraction flows. If you check out the Etherscan receipts, you'll see the Success event from the Safe, along with a nearby SafeModuleTransaction on L2. (etherscan.io) - The Topic 0 (event signature) for
ExecutionFromModuleSuccessiskeccak256("ExecutionFromModuleSuccess(address)"), which you'll see represented as 0x6895…becb8 in logs. If your tools don’t handle ABI-based decoding, make sure to use this topic in your filters. (etherscan.io)
Just a heads up: the event only confirms that “a module did something.” To figure out the specifics, you’ll want to check out SafeModuleTransaction (L2) or grab the module transaction from the STS API or node traces (L1). You can find more info here.
What actually triggers “Failure”?
Failure happens when the inner call or delegatecall gives back a false result. Here are some usual, harmless reasons for that:
- The target call is purposely set to roll back during a “dry run” when a module tests its capabilities.
- An action got rejected because of a rate-limit or roles modifier (like the Roles/Delay modifiers in Zodiac setups).
- A dependency wasn’t available yet (missing allowance; the target got paused).
Since execTransactionFromModule gives you a boolean response and triggers events rather than rolling back the entire transaction, you'll end up logging a Failure event without necessarily causing the whole outer transaction to fail. This approach is intentional, allowing modules to handle their own control flow. Check it out on gnosisscan.io!
When you're setting up alerts, think of isolated failures as something to "investigate" rather than jumping straight to calling it a "breach." Keep an eye out for recurring failures from a new or unfamiliar module, especially if they show up alongside any configuration changes. Check it out here: (docs.safe.global)
Mapping alerts back to real actions (step‑by‑step)
Three-Step Playbook for Handling ExecutionFromModuleSuccess/Failure
Whenever you encounter an ExecutionFromModuleSuccess or ExecutionFromModuleFailure, just follow these three straightforward steps:
- Assess the Situation
Take a moment to understand what's going on. Look at the logs and any relevant information to figure out what triggered the success or failure. - Implement the Fix
Based on your assessment, apply the necessary changes or fixes. If it’s a failure, determine if it’s a configuration issue, a bug, or something else entirely. - Verify the Outcome
After you’ve made adjustments, test to confirm everything is back on track. Check to see if the ExecutionFromModule is running smoothly now, ensuring that everything's working as it should.
Keep these steps handy for when issues pop up; they can help streamline your troubleshooting process!
- Identify the module and check if it's still enabled
- Grab the Safe’s module registry (you can do this on-chain using
getModulesPaginatedor through the API) to make sure the module is authorized. If it’s not enabled, raise the alarm right away (this could be a spoofed event or an indexer that's not set up properly). (gnosisscan.io)
2) Reconstruct the Call Details
- L2: Start by parsing the
SafeModuleTransactionevent within the same transaction. Look for the module,to,value,data, andoperation, and then decode the calldata. You can check it out here: scrollscan.com. - L1: Next, dive into the Safe Transaction Service and use the “Get Module Transaction” feature by using the transaction hash or by listing module transactions for your Safe. The STS will leverage traces to help you piece together “to/value/data/operation” and whether it was “isSuccessful.” For more details, head over to docs.safe.global.
3) Classify the Operation Risk
- Operation
1 (DELEGATE_CALL)is considered high risk since it changes the Safe’s storage. It's best to avoid using it in modules unless it's absolutely essential. Consider implementing a Module Guard or a Roles/Delay chain to either block or safeguard these operations. You can check out more details here.
- A DAO’s “automation” module doing a token transfer on L2
- Look out for SafeModuleTransaction(module, to=token, value=0, data=transfer(...), operation=CALL) followed by ExecutionFromModuleSuccess. Double-check the token address and recipient against your policy allowlist. (scrollscan.com)
- An ERC‑4337 userOp routed through a Safe module
- When you check the receipt, you'll see EntryPoint events, the Safe’s ExecutionFromModuleSuccess, and usually the module address of a 7579 adapter. This is totally expected for AA-powered Safe accounts, so make sure to whitelist these modules in your monitoring. (etherscan.io)
3) A Failure from a Roles+Delay pipeline (Zodiac)
- The Delay Modifier works by queuing up tasks and executing them later. If you encounter a Failure, it might mean that the queued call either expired or got invalidated. Before you escalate the issue, take a look at your Delay queue and the Roles ruleset. You can dive deeper here.
The most common misunderstandings (and how to avoid them)
- “Success means owners approved it.” Not exactly -- it actually means a module ran without needing any owner signatures. That’s really what modules are all about! You just need to confirm the module's legitimacy and then decode what it did. Check it out here: (docs.safe.global)
- “Failure means we were attacked.” Not always the case! A lot of modules have their own ways of probing or protect themselves using revert-on-unexpected-state patterns. It’s good to look for patterns like repeated attempts, new modules showing up, or sensitive operations (like delegatecall or owner/threshold changes). You can take a closer look at this on (gnosisscan.io).
- “Events look different across networks.” That’s true! On L1, the base Safe tends to emit fewer events because it’s cheaper, while on L2, SafeL2 generates more indexing events. So, make sure to tailor your monitoring strategy based on that! More info can be found here: (docs.safe.global)
Monitoring recipes your team can deploy this week
- Minimal Event Filter (All Chains)
Use this filter to track ExecutionFromModuleSuccess/Failure events by topic0, while keeping it focused on your specific Safe(s):
// ethers.js v6
import { ethers } from 'ethers';
const iface = new ethers.Interface([
'event ExecutionFromModuleSuccess(address indexed module)',
'event ExecutionFromModuleFailure(address indexed module)'
]);
const filter = {
address: SAFE_ADDRESS, // your Safe
topics: [
// topic0 = either Success or Failure signature
[iface.getEvent('ExecutionFromModuleSuccess').topicHash,
iface.getEvent('ExecutionFromModuleFailure').topicHash]
]
};
provider.on(filter, async (log) => {
const parsed = iface.parseLog(log);
const module = parsed.args.module;
// Step 1: verify module is enabled; Step 2: fetch details (see below)
});
For custom pipelines that work based on topic hash, you'll find that ExecutionFromModuleSuccess uses the topic 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. If you need to compute other topics, just run keccak256("EventName(types)"). You can check out more details on this transaction here: (etherscan.io).
2) Auto‑enrichment for details
- L2: Check out the
SafeModuleTransactionright in the receipt; you can decode the “data” to get the function and parameters. You can find more info here. - L1: To get a list of transactions, just call the Safe Transaction Service: use
GET /api/v1/module-transactions?safe=0x…. If you already have themoduleTransactionId, you can go withGET /api/v1/module-transactions/{id}. TheisSuccessfulanddataDecodedfields will give you instant clarity! Check out the details here.
3) Detection Rules That Actually Surface Risk
- High Priority:
- Success from a module that’s not on your allowlist.
- Success when the operation is
DELEGATE_CALL. - Any Success that comes right after a
ChangedModuleGuard/EnabledModuleevent. (docs.safe.global)
- Medium Priority:
- Repeated Failures from a new module.
- Failures that line up with guard/roles changes. (docs.safe.global)
Governance and security guardrails that reduce alert noise
- Always use a Module Guard with your modules. These guards do a pre-check on any calls made by the module, enforcing things like allowlisted targets, value caps, and “no delegatecall” rules. You can set this up using
setModuleGuard(address). Check out the details here. - Consider adding Zodiac modifiers in front of your Safe:
- Roles Modifier: This gives you super fine-grained control with selector-level permissions for your modules. It allows you to specify “only these functions on these contracts.” More info can be found here.
- Delay/Timelock Modifier: This sets up a cooldown period, giving you time to react before any funds are moved. Transactions are put on hold and executed later. Check out the details here.
- Treat your modules like they’re superusers. The Safe documentation points out that modules have the potential to take over your Safe. So, it’s crucial to enable only those modules that are audited and follow the least-privilege principle. Review them just like you would a sensitive production microservice. More info can be found here.
How to triage a “Failure” like a pro (10‑minute drill)
- First, make sure the module's still enabled on the Safe. If it's not, dive into why that might be and check for any indexing drift. (gnosisscan.io)
- Next up, let’s reconstruct what’s going on with the target/action:
- L2: check out the SafeModuleTransaction event.
- L1: grab the module transaction from the STS; if you can’t find it, run a trace on the tx. (docs.safe.global)
- Now, time to classify what we’re dealing with: is it just a harmless probe, a policy block, or a genuine issue (like repeated attempts to switch up the owner set)?
- If things look a bit fishy, consider temporarily disabling the module (the owners can sign off on a standard Safe transaction) or raise the threshold while you dig deeper.
- Finally, do a post-mortem: tighten up the Module Guard or Roles policy so that we don’t keep getting spammed with the same failure pattern.
Notes on ERC‑4337 and modules (why you’ll see more of these)
Account-abstraction adapters for Safe, like Safe7579, work as modules and call execTransactionFromModule during the validation and execution of user operations. If you're diving into AA, be ready for those regular ExecutionFromModuleSuccess logs. Make sure to allowlist the adapter module and keep your detections focused on the target/selector and delegatecall usage, rather than just looking for the event itself. Check it out here: github.com
The difference from owner‑signed multisig executions
Owner-signed multisig transactions generate ExecutionSuccess or ExecutionFailure events, rather than the standard module events. It's a good idea to keep these streams separate in your SIEM. This way, you can easily spot the “human-approved” actions versus those that were kicked off by automation at a glance. Check it out here: (gist.github.com)
Implementation snippet: enrich an alert with STS (TypeScript)
import SafeApiKit from '@safe-global/api-kit';
const api = new SafeApiKit({ chainId: 1n }); // mainnet, adjust per chain
async function enrichModuleTx(txHash: string) {
// List module txs for this Safe, filter by hash
const list = await api.getModuleTransactions({ safe: SAFE_ADDRESS, transactionHash: txHash });
if (list.results.length === 0) return null;
const t = list.results[0];
return {
isSuccessful: t.isSuccessful,
module: t.module,
to: t.to,
value: t.value,
operation: t.operation, // 0=CALL, 1=DELEGATE_CALL, 2=CREATE
dataDecoded: t.dataDecoded
};
}
STS makes those tricky bits a lot easier for you, particularly on L1 since you miss out on the more detailed L2 events. Make sure to incorporate this enrichment into your alert pipeline. Check it out here: docs.safe.global
Emerging best practices we recommend in 2026
- Make sure to enforce the policy on both fronts: use a classic Guard for transactions that are owner-signed and a Module Guard for transactions that are initiated by modules. Remember to double-check both after any Safe upgrade. You can find more details here.
- Default to denying DELEGATE_CALL from modules unless there's a solid reason documented for it. Take a good look at any Success with operation==1. More info is available here.
- Introduce a 24-72 hour Delay modifier before any module actions that might affect the treasury; serialize those high-risk executions so you’re ready to respond if needed. Check it out here.
- Keep an eye on configuration drift: set up alerts for EnabledModule/DisabledModule and ChangedModuleGuard events, not just for executions. This way, you can catch any supply-chain changes before any funds start moving. More details can be found here.
- Opt for SafeL2 when it's available for richer event monitoring. If you're stuck on L1, make sure to run STS with tracing enabled and treat that as your go-to source of truth. You can check it out here.
Executive summary to share with your board
- ExecutionFromModuleSuccess and ExecutionFromModuleFailure are basically the Safe contract’s way of saying “hey, automation just interacted with the treasury.” These messages pop up whenever an enabled module carries out a transaction. If you're on L2, you can check out the full call details right from the events; on L1, you'll need to dig into traces or use the Safe Transaction Service. It’s a good idea to put Module Guards, Roles, and Delay in front of those modules, and keep an eye out for any policy-breaking patterns (like unknown modules, delegate calls, or configuration drift) instead of bombarding you with alerts for every single failure. Check out more at (gnosisscan.io).
Appendix: exact references you can hand to your engineers
- You've got module events in Safe that handle the behavior of
execTransactionFromModule, which emits either Success or Failure. Check it out here! - Over on SafeL2, you'll find it emits
SafeModuleTransaction, giving you richer L2 indexing. Take a look here! - If you're looking for the nitty-gritty on
execTransactionFromModuleandexecTransactionFromModuleReturnData, the documentation is right here. - Don't miss out on the STS indexing model--comparing L1 traces with L2 events, plus some insights into module transaction APIs. You can find all the details here.
- Just a heads-up: modules can skip signatures, so think of them as high-privilege components. More info can be found here.
If you're looking for a thorough review of your current Safe setup and need us to craft those Module Guard/Delay/Roles policies specifically for your treasury operations, look no further! At 7Block Labs, we can tackle this in just a week. By the end of our time together, you'll have a tailored monitoring ruleset that only triggers on the important stuff.
Like what you're reading? Let's build together.
Get a free 30-minute consultation with our engineering team.
Related Posts
ByAUJay
Building a Donation-Based Crowdfunding Platform That Gives Tax Receipts
**Summary:** Donation-based crowdfunding that includes tax receipts has become quite the complex puzzle across different regions. You've got to navigate IRS Pub 1771/526 rules, UK Gift Aid declarations, Canada’s CRA receipting, and the new eIDAS/OpenID4VCI wallets--all while keeping everything running smoothly.
ByAUJay
Why 'Full-Lifecycle Advisory' Beats Just Coding
**Summary:** Engineering teams that focus solely on “writing Solidity” often find themselves caught off guard by shifts in protocols, the need for composable security, and the procurement hurdles that are now impacting real ROI. Our full-lifecycle advisory service bridges the gap by connecting EIP-7702 smart accounts, modular decentralized applications (DA), and ZK-based compliance solutions.
ByAUJay
Why Your Project Could Really Use a 'Protocol Economist
Summary: A lot of Web3 teams are missing a crucial player: the “protocol economist.” And you can really see the impact--value slips away through MEV routing, token incentives that are all out of whack, and those sneaky changes to wallets after Pectra that end up messing with the unit economics. In this playbook, we’ll explore what a protocol economist can do to tackle these issues head-on.

