ByAUJay
Summary:
Just keeping tabs on your token balances isn’t enough to safeguard your DAO treasury. The main on-chain signal you should be paying attention to is the ChangedFallbackHandler on your Safe (formerly known as Gnosis Safe) multisig. In this post, I’ll break down why this is crucial, guide you on how to effectively track it across different chains, and share a useful incident playbook along with an allowlist for approved handler changes.
DAO Treasury Multisig: From “DAO Treasury Multisig - Token Balance Changed” to “ChangedFallbackHandler”
A lot of treasuries are fixated on “Token Balance Changed” alerts as their key health indicator, but let’s be real--that's mostly just background noise. The bigger concern for a Safe-based treasury actually lies in those configuration changes. This is especially true when you have a fallback handler rotation happening.
When your Safe gets a fresh contract that deals with those mysterious function calls and token callbacks, it kicks off an on-chain event called ChangedFallbackHandler. You really want to give this your top priority (P0). As for the rest--like individual transfers, dust, or spam--just keep an eye on them with some solid config monitoring. If you need more info, take a look at the docs.safe.global.
Understanding the Fallback Handler
What’s a Fallback Handler?
Alright, let’s break it down. A fallback handler is a unique function found in smart contracts, mainly on Ethereum. It kicks in whenever a contract gets plain Ether or when someone tries to call a function that doesn’t actually exist. Think of it as a safety net designed to deal with unexpected scenarios.
Why Attackers Target the Fallback Handler
So, why would someone want to tamper with it? Well, if an attacker gets in there and tweaks the fallback function, they can actually change how the contract works when it gets Ether or when it calls a function that isn't recognized. This could open the door to unauthorized actions or even financial losses, which is why it’s a hot target for shady characters.
Legitimate Changes to the Fallback Handler
Not every change is a bad one! In fact, there are some great reasons why developers might want to adjust the fallback handler. Here are a few examples:
- Giving functionality a boost
- Beefing up security measures
- Making the user experience better
Monitoring and Responding Quickly
Keeping an eye on your contracts is super important for spotting any shady activities as soon as they pop up. Here’s a handy guide on how to do that with logs, Safe Transaction/Event Services, and security networks like Forta:
- Logs: Make sure to keep a record of all transactions and interactions. When you dive into these logs, you'll be able to catch any weird patterns that might pop up.
- Safe Transaction/Event Services: These handy tools let you keep an eye on important events and alerts tied to your contracts, so you can easily stay in the loop.
- Forta: This network is all about keeping an eye on threats in real-time. It’s designed to help you spot any potential vulnerabilities or breaches before they become big problems.
Implementation Example
Here’s a handy little code snippet to kick off your journey in monitoring your fallback handler:
fallback() external payable {
// Your custom logic here
emit FallbackCalled(msg.sender, msg.value);
}
Addresses and Severity Matrix
Make sure to swing by these links for even more great insights:
Here’s a straightforward severity matrix you can start using this week to classify potential issues by their impact and likelihood:
| Severity Level | Description | Action Required |
|---|---|---|
| High | Immediate threat detected | Investigate + patch ASAP |
| Medium | Potential vulnerability | Monitor closely |
| Low | Informational alert | No immediate action needed |
Stay alert and make sure your contracts are safe!
Why “Token Balance Changed” is the wrong north star
- Balance movements are often noisy and can feel overwhelming. You've got things like dusting, airdrops, NFT spam, and MEV swaps constantly shuffling balances around without actually changing who’s in charge of the treasury. Even block explorers are jumping on the bandwagon and now hide zero-value token transfers by default to reduce that spam and annoying address poisoning clutter. If your alerts still flag these as top-priority, it might just burn out your on-call team. (coindesk.com)
- When you’re looking at balance diffs, remember to treat them as effects rather than causes. By the time you get that balance alert, the permission change that led to the drain could be 1-N blocks in the past. The real culprits are usually structural changes--things like owners, thresholds, guards, modules, and the fallback handler. So, it makes sense to keep an eye on those elements first. Safe has some pretty straightforward and stable emitted events: AddedOwner, RemovedOwner, ChangedThreshold, EnabledModule, DisabledModule, ChangedGuard, and ChangedFallbackHandler. Check them out in the docs.safe.global.
The fallback handler, in 60 seconds
A Safe can hand off any unknown function calls to a flexible "fallback handler" contract. This handler is pretty handy because it adds some features that the main Safe doesn’t have by default, such as token receive hooks for ERC‑721, ERC‑1155, and ERC‑777, as well as ERC‑1271 contract signature checks, simulation helpers, and ERC‑4337 entrypoint validation. If you ever feel like switching up the handler, it’s considered a top-tier Safe transaction and will trigger a ChangedFallbackHandler event. Want to dig deeper? Check it out here.
How It Works, Exactly:
- The Safe's FallbackManager is pretty neat; it monitors the handler address and forwards any calls it doesn’t recognize to that handler, all while including the original caller's info in the calldata for context. Just so you know, there are some security measures here--like you can’t set the handler to point back to itself. If you want to dive deeper, check it out here.
- Most Safes come with a standard handler known as CompatibilityFallbackHandler. This handy little tool manages ERC‑1271’s
isValidSignatureand takes care of token callbacks. Plus, if you're on Safe version 1.4.1 or newer, you’ve got the ExtensibleFallbackHandler and the Safe4337Module, which can step in as a fallback for Account Abstraction (AA). You can dive deeper into this here.
Why Attackers Care
- A malicious handler can make the Safe behave as if it supports certain interfaces or signatures that it shouldn’t, kind of like how custom ERC‑1271 behaviors work. This can mislead outside applications into accepting approvals or signatures that aren’t legitimate. While the Safe team has done a pretty good job at securing this aspect, the handler still wields enough power that using one without a proper vetting process is just asking for trouble. Nowadays, Safe’s own documentation even warns that fallback handlers could pose a danger if they haven’t been audited or included in the allowlist. (alchemy.com)
Bottom line: as soon as your handler changes, you’ll need to check what contract it switched to--and see if that address is on the allowlist for your network and Safe version.
Legitimate reasons your fallback handler might change
- We're upgrading from CompatibilityFallbackHandler v1.3.0 to v1.4.1 on the Ethereum mainnet. Check out these canonical addresses you'll need:
- v1.3.0: 0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4
- v1.4.1: 0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99
These came from Safe, and you can see them in the safe-eth-py/safe-deployments. Just a heads up--make sure to allowlist these addresses on your monitor! You can find more info here.
- If you want to enable ERC‑4337 on a Safe that’s version ≥ v1.4.1, make sure to check out the Safe4337Module. In some setups, this module works as both the Module and the Fallback Handler to handle validateUserOp calls from the EntryPoint. Just make sure to confirm that your EntryPoint address matches the supported version on your network and that you're on v1.4.1 or higher. You can find more info here.
- Lastly, if you're looking to dive into some advanced interface multiplexing, switching to the ExtensibleFallbackHandler is a great option. It's perfect for routing based on specific functions, but just a heads-up: you'll still need to stick to strict allowlisting and keep a solid audit trail in place. If you want to learn more, check out this page: docs.safe.global.
If you find any other handler address, just treat it as unknown until you can verify it.
What to monitor: from spammy balance diffs to Safe config events
Absolutely! Here’s a quick overview of the Safe events sorted by how severe they are:
- P0 (page the team): We've got a few updates to talk about. The
ChangedFallbackHandleris now linked to a non-allowlisted address, which is a bit concerning. Also, the status ofChangedGuardis still a mystery, and we’ve activated a module that we don’t know much about yet. To top it off, there’s a notable drop in theChangedThreshold, or maybe aRemovedOwner, which might lead to some redundancy problems. You can check out more details here. - P1: It seems like there’s a new
AddedOwner, but the threshold hasn’t changed or might have actually gone up. Plus, we’ve spotted aDisabledModulefrom a familiar protection module. On top of that, there are some unusual spikes inApproveHashandSignMsgactions that don’t align with our governance process. You can find more details here. - P2: Great news! We’ve achieved
ExecutionSuccesswithsetFallbackHandler, even when it's on the allowlist--this really helps us confirm the intent. Plus, it looks like the owner rotations are syncing up well with our planned calendar CABs. You can check out more details here. - P3: We’ve spotted some shifts in token balances that don’t seem to connect to any verified items in the governance queue. It could be worth considering using anomaly detectors to keep an eye on numeric thresholds.
Keep an eye on the differences between L1 and L2: SafeL2 is all about throwing more events into the mix to enhance event-based indexing. Meanwhile, the Safe Transaction Service might rely on traces for L1 and switch to events for L2. This can really affect how quickly things go down and how complete your data ends up being. You can expect some indexing delays that can stretch from 15 to 120 seconds, and don’t worry about any reorg waits when it comes to webhooks--just make sure to double-check with the API. (github.com)
How to detect ChangedFallbackHandler reliably (three ways)
1) Raw Log Subscription (Any EVM RPC)
When you're diving into any EVM-compatible network, it’s really useful to use raw log subscriptions to keep an eye on events. This way, you can listen in on specific logs that your smart contracts kick out, all through JSON-RPC.
Here’s a quick rundown on how to get it done:
- Connect to an EVM RPC: Alright, let’s kick things off by connecting to an Ethereum node or any EVM-compatible network. You can use platforms like Infura or Alchemy for this--just don’t forget to grab your API key beforehand!
- Set up a log subscription: To get this going, you can use a JSON-RPC call. Check out this straightforward format you can use:
{
"jsonrpc": "2.0",
"method": "eth_subscribe",
"params": ["logs", {
"address": "0xYourSmartContractAddress",
"topics": ["0xYourEventSignature"]
}],
"id": 1
}
- Handle incoming logs: After you get this sorted out, you'll start seeing log updates coming in immediately! Just be sure to manage these logs correctly in your app.
If you want some in-depth examples and extra resources, don’t forget to check out the official documentation or swing by the community forums for some great insights. Happy coding!
To get your filter up and running, just grab the Safe's address and pair it with the event signature hash for ChangedFallbackHandler(address). Here’s a quick guide on how to do that with ethers.js:
const { ethers } = require("ethers");
// Replace with your Safe address
const safeAddress = "YOUR_SAFE_ADDRESS";
// This is the event signature hash for ChangedFallbackHandler(address)
const eventSignature = "ChangedFallbackHandler(address)";
const eventSignatureHash = ethers.utils.id(eventSignature);
// Set up your filter
const filter = {
address: safeAddress,
topics: [eventSignatureHash],
};
// Now you can use this filter to listen for events!
Just make sure to replace "YOUR_SAFE_ADDRESS" with your Safe's actual address. That way, you'll be able to track the events you really want to see!
import { ethers } from 'ethers'
// 1) RPC and contract
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL)
const safe = '0xYourSafeAddress'
// 2) Event topic for ChangedFallbackHandler(address)
const topic0 = ethers.id('ChangedFallbackHandler(address)') // keccak256
// If you also want to filter to a specific handler, include it as topic[1], 32-byte left-padded.
provider.on({
address: safe,
topics: [topic0]
}, (log) => {
const handler = ethers.getAddress('0x' + log.topics[1].slice(26))
console.log(`[P0] Fallback handler changed to ${handler} in tx ${log.transactionHash}`)
})
Solidity takes care of verifying the event name and signature, and you'll notice that topic[1] refers to the new handler. Just a heads-up: make sure to include an allowlist check before you send anything over to PagerDuty. If you want to dive deeper, check out the Kalychain documentation for more info.
2) Safe Transaction Service + Events Service
The Safe Transaction Service and Events Service team up to form a robust toolkit that not only manages secure transactions but also makes it super easy to track the events linked to those transactions. Here’s a quick rundown of how they work hand-in-hand:
Safe Transaction Service
This service offers a solid framework for safely managing transactions. It guarantees that every transaction is handled with top-notch security, keeping sensitive info under wraps and lowering the chances of fraud.
Events Service
On the flip side, the Events Service is focused on keeping tabs on and reacting to different events that pop up during transactions. Whether it's confirming a payment, updating order statuses, or sending out notifications to users, the Events Service ensures everything flows seamlessly and that users are always in the know.
How They Work Together
When you combine the Safe Transaction Service with the Events Service, you create a smooth experience that not only keeps your transactions safe but also boosts communication and engagement. Here’s what you can look forward to:
- Real-Time Notifications: Users receive immediate updates on their transaction status, which really helps to foster trust and transparency.
- Fraud Prevention: Keeping an eye on transaction-related events allows you to swiftly spot and tackle any suspicious activities.
- Enhanced User Experience: With these timely updates, users feel way more connected to the service, resulting in higher satisfaction levels.
In a nutshell, bringing these two services together not only enhances the security of your transactions but also makes for a more lively and engaging user experience.
- Jump on the Safe Events Service SSE/webhooks train! When you receive an
EXECUTED_MULTISIG_TRANSACTION, simply pull the transaction details from the Transaction Service and see if it was asetFallbackHandlercall. These services are designed for this, so you'll skip the hassle of constant node polling. Just remember, they’ll send updates your way as soon as they happen (no more waiting around for confirmations), and your system should take care of reconciling everything through the API. Dive deeper here: (github.com)
3) Forta Network
The Forta Network is a cool solution aimed at boosting the security of decentralized applications (dApps). It serves as a live monitoring layer that watches over blockchain networks, making sure everything operates smoothly and securely.
Key Features:
- Real-Time Monitoring: Forta is always on the lookout for any unusual behavior, so it can spot suspicious activities that might put your assets at risk super fast.
- Decentralization: This whole thing runs on a network of independent agents collaborating to build transparency and trust--super important in the crypto world.
- Integration: You can seamlessly integrate Forta into your current dApps, ensuring they stay secure without any fuss.
Use Cases:
- DeFi Security: Forta keeps an eye on decentralized finance platforms, helping to shield users from possible exploits and hacks.
- NFT Protection: NFT markets can be a bit of a wild ride, but Forta steps in to add an extra layer of security. It helps keep transactions safe, so both creators and collectors can breathe a little easier.
- DAOs: Decentralized Autonomous Organizations can really take advantage of Forta’s monitoring capabilities, protecting their decision-making processes from any malicious attacks.
If you want to dive deeper into what Forta is all about and how it can help you out, head over to their official website: Forta Network.
- Don't forget to sign up for the Governance Threat Detection Kit! You can easily set up a custom bot or template that will help you monitor your Safe for any changes to the ChangedFallbackHandler and other key governance events. Plus, if you pair this with the Attack Detector 2.0 feeds, you can really minimize those annoying false positives. This combo gives you a solid grasp of the threats out there in the ecosystem, including any shady interactions with sanctioned or exploiter addresses and MEV routes tied to changes in your Safe. Check it out here: (docs.forta.network)
Important Update on OpenZeppelin Defender
Just a quick note: OpenZeppelin Defender is going to be phased out on July 1, 2026. If you’ve been relying on Defender Sentinels, now’s a great time to switch your monitors over to either OpenZeppelin Monitor or Forta. You might also want to consider self-hosting your event listeners. Don’t leave it until the last minute to make this transition! For all the details, take a look at the OpenZeppelin blog post.
Allowlist known-good fallback handler addresses
Hardcoding some key canonical addresses can really be a lifesaver when things go sideways:
- Ethereum Mainnet:
- CompatibilityFallbackHandler v1.3.0:
0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4 - CompatibilityFallbackHandler v1.4.1:
0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99
- CompatibilityFallbackHandler v1.3.0:
You can easily keep this list current by using either @safe-global/safe-deployments or safe-eth-py, which links versions to specific networks. Make sure your detector is always verifying new handler addresses against this allowlist, plus any custom handlers that have been given the green light internally. If you want to dive deeper, check out the safe-eth-py documentation.
For your ERC‑4337 deployments, don't forget to allowlist these:
- Make sure you have the Safe4337Module address that corresponds to your specific chain and release line.
- Don’t forget to check the EntryPoint address family you’re using (like the 0.8 or 0.9 series). It's also a good idea to look at your bundler’s
eth_supportedEntryPointsoutput when it kicks off. For more details, you can dive into the docs.safe.global.
Production-ready monitor: 30-line rules plus paging
Policy sketch for a single Safe per chain:
- If a
ChangedFallbackHandlerpops up and the handler isn’t part ofALLOWLIST[chainId], then let’s trigger the P0 page. - If a
ChangedFallbackHandlerappears and the handler is in theALLOWLIST, but the change isn’t noted in the current CAB/Jira ticket, feel free to trigger the P1 alert. - Don't forget to add the decoded transaction, proposer, and confirmations every time.
Using the Safe Events Service (SSE) is a breeze! Just grab your event as the signal and then jump right into using the Transaction Service to decode and verify it with this method:
# Pseudocode flow
on EXECUTED_MULTISIG_TRANSACTION for address == mySafe:
tx = GET /api/v1/multisig-transactions/{safeTxHash}
if tx.data decodes to setFallbackHandler(address handler):
if handler not in ALLOWLIST[chainId]: page P0
else alert P1 with CAB link
Indexing expectations and managing reorganizations are all clearly outlined for you. Just a quick reminder, though: it’s best not to rely completely on webhooks as your go-to source of truth. Instead, consider them more like a gentle push to fetch data from the API. For more details, take a look here: (github.com)
Incident playbook: What to do when ChangedFallbackHandler fires
- Locate the new handler contract.
- Extract it from the log topic and enhance the details by adding the code verification status, the creator’s info, its age, and any pertinent references. If it’s either unverified or a newbie in the space, mark it as critical. (etherscan.io)
- Lock down your Safe in just a few easy steps:
- First, raise the threshold to N-of-N, or at the very least +1, to avoid complications from another risky change.
- Next, activate a Guard (if you have a “safe-allow” Guard, this will prevent setFallbackHandler from running unless it’s targeting addresses on your allowlist).
- Lastly, make sure to turn off any unfamiliar modules.
Example Using Safe Protocol Kit:
The Safe Protocol Kit is a great resource for developers aiming to create secure applications. Let’s take a look at a real-world example to see how it all comes together.
Setting Up the Environment
First up, let’s get Node.js installed. You can grab it from the Node.js Official Website. Once that’s all set and done, we can dive into setting up your project.
Fire up your terminal and type in these commands:
mkdir my-safe-protocol-app
cd my-safe-protocol-app
npm init -y
npm install safe-protocol-kit
This command will set up a fresh directory for your app, kick off a new Node.js project, and install the Safe Protocol Kit.
Basic Usage
Setting Up a Safe Communication Channel: A Simple Example
Alright, let’s dive into a straightforward example of how to establish a secure communication channel. This is essential for protecting your information and ensuring that your conversations stay private. Here's how you can do it!
Step 1: Choose Your Tools
First things first, you need to pick the right tools for your communication. There are several options out there that prioritize security:
- Signal: A popular choice known for its end-to-end encryption.
- Telegram: Offers secret chats with solid encryption features.
- WhatsApp: Widely used with good encryption practices.
Pick one that feels right for you!
Step 2: Set Up Your Account
Once you’ve settled on the app that suits your needs, it’s time to create an account. Just follow the instructions provided by the app, usually involving:
- Downloading the app from the App Store or Google Play.
- Registering with your phone number.
- Verifying your account with a code sent via SMS.
Pretty simple, right?
Step 3: Enable Security Features
Next, you'll want to beef up your security settings. Here's a quick checklist for you:
- Enable Two-Factor Authentication (2FA): This adds an extra layer of protection.
- Use Strong Passwords: If your app allows it, create a unique and complex password.
- Check Privacy Settings: Go through the app's privacy settings to control who can contact you.
Step 4: Start Communicating Securely
Now that you’re all set up, it's time to start chatting! Here’s how to ensure your conversations stay safe:
- Only Message Other Trusted Users: Stick to talking with people you know and trust.
- Avoid Sharing Sensitive Info: Be cautious about discussing personal details or confidential information.
- Use Timed Messages: Some apps allow you to send messages that disappear after a certain time.
Conclusion
And there you have it! Setting up a safe communication channel doesn’t have to be complicated. By following these steps and using the right tools, you can ensure that your chats remain private and secure. Happy communicating!
Create a new file named app.js and toss in this code:
const { SafeProtocol } = require('safe-protocol-kit');
const myProtocol = new SafeProtocol();
myProtocol.on('message', (message) => {
console.log('Received:', message);
});
myProtocol.send('Hello, safe world!');
In this code snippet, we're bringing in the Safe Protocol Kit and spinning up a new protocol instance. We also set up a listener to catch incoming messages and send out our very first message.
Running the Application
To get your application up and running, just pop back over to your terminal and run:
node app.js
You’ll want to check out the message that shows up in the console!
Conclusion
And there you go! You've successfully set up a basic communication channel with the Safe Protocol Kit. If you're looking to explore more advanced features or dive deeper into the details, don’t forget to take a look at the Safe Protocol Kit Documentation.
Don't hesitate to play around even more! Try adding features like error handling or connect with more clients!
import Safe, { EthersAdapter } from '@safe-global/protocol-kit'
import { ethers } from 'ethers'
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL)
const signer = new ethers.Wallet(process.env.KEY, provider)
const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: signer })
const safe = await Safe.create({ ethAdapter, safeAddress: '0xYourSafe' })
// 1) Temporarily raise threshold by +1
const current = await safe.getThreshold()
const inc = await safe.createChangeThresholdTx({ threshold: current + 1 })
await safe.executeTransaction(inc)
// 2) Optionally enable a Guard you’ve pre-deployed
// const guardTx = await safe.createEnableGuardTx({ guardAddress: '0xYourGuard' })
// await safe.executeTransaction(guardTx)
// 3) Disable suspicious modules (loop list from getModules())
Confirmations still have to reach the current threshold. Don’t forget to pinpoint who your “rapid responders” are among the owners. (docs.safe.global)
3) Revoke approvals and pause treasury programs.
- If you're in charge of an AA, take a moment to review your EntryPoint/Paymaster policies and consider pausing any sponsorships until you can figure out what's causing the issue. For ERC‑4337 stacks, make sure your Safe4337Module is still marked as the fallback and that the EntryPoint is matched up with the correct version. (docs.safe.global)
- Communicate externally.
- Shoot out an update to the handler address and give everyone a heads-up on whether it's the canonical version. Make sure to include a list of the functions that are affected (like the ERC‑1271 signature verification paths) and any steps you’ve taken to help fix things.
5) Forensics
- Start by collecting the multisig proposal details. Take a look at the proposer’s wallet and grab the set of signatures. If you suspect that the proposer might have been compromised, it’s a good idea to rotate the owners right away. Don’t forget to keep that Forta subscription active to keep an eye on any shady funding or laundering activities, just in case the assets start moving around. For more info, check out this link.
- EVM log filter (low-level) for ChangedFallbackHandler(address):
- Topic0:
keccak256("ChangedFallbackHandler(address)") - Topic1: This one’s optional! You can use a 32-byte handler address if you want to zero in on dependable upgrades.
- Topic0:
This method is budget-friendly, quick, and compatible with various networks. Take a look at the details in the Kalychain docs!
- Safe API + webhooks (super user-friendly):
- Simply subscribe to EXECUTED_MULTISIG_TRANSACTION, then fetch and decode to catch any calls to setFallbackHandler(handler). Latency is usually under a minute, but during busy times, it could stretch to 1-2 minutes. Just a heads-up, your endpoint should respond in under 2 seconds. You can dive into the details on (github.com).
- Forta Policy Layer (Threat Intelligence):
- Be sure to sign up for the Governance Threat Detection Kit and Attack Detector 2.0. These handy tools let you keep tabs on your Safe’s changes while also checking for any shady exploiter activities or Tornado funding trends. If you ever come across any P0s, just shoot them straight to the incident channel. (docs.forta.network)
- Event noise suppression:
- Let's keep “Token Balance Changed” as a P3 informational alert. Just a heads-up, zero-value transfer spam is automatically hidden on major explorers, so it doesn’t really indicate any kind of compromise. Rather than relying solely on a simple “balance changed” trigger, it’s smarter to use an anomaly detector to keep an eye on those big ERC‑20/721/1155 outflows. For more details, check out this article on Coindesk.
ERC‑4337 interplay: extra checks when your Safe is AA‑enabled
If you’re using Safe as an ERC‑4337 account, here are some important things to remember:
- First things first, make sure your Safe is updated to version v1.4.1 or later.
- The Safe4337Module usually covers both the Module and the Fallback Handler roles, so it’s crucial to double-check the address of the fallback handler. You also want to confirm that the EntryPoint version is either 0.8 or 0.9. If you slip up here, you might end up bricking validation or running into some quirky issues. Here’s what your monitor should keep an eye on:
- The handler’s address should match the Safe4337Module address for the chain release you’re working with.
- The entryPoint needs to be included in eth_supportedEntryPoints.
- Lastly, make sure the module is still enabled, which means the status should be set to true.
If you want to dive deeper, take a look at the documentation here.
Reference addresses and how to keep them up-to-date
- First up, you'll want to grab the CompatibilityFallbackHandler and ExtensibleFallbackHandler addresses for each chain and version in CI using @safe-global/safe-deployments. Once you've got those, don’t forget to publish an internal allowlist artifact so your bots can refer to it while they're running. For the Ethereum mainnet, here’s what you need to know:
- v1.3.0 CFH: 0xf48f…fe5e4
- v1.4.1 CFH: 0xfd07…9c99
Make sure to check in regularly with the safe-eth-py docs and the deployments repo to keep everything up to date. You can find all the good stuff here: (safe-eth-py.readthedocs.io).
A minimal risk matrix you can copy
- P0: So, it looks like ChangedFallbackHandler isn't on the allowlist. ChangedGuard is a bit of a head-scratcher, ChangedThreshold has dropped, and we still don’t know much about EnabledModule.
- P1: Good news--ChangedFallbackHandler is allowed, but it’s not in CAB. Also, AddedOwner slid in without raising the threshold, and we're seeing some unexpected bursts of ApproveHash/SignMsg that are a bit out of sync.
- P2: DisabledModule is tied to a module we know, and we’re just seeing some harmless owner rotations happening within the CAB window.
- P3: We’ve spotted a change in the token balance, but there haven’t been any adjustments to the structural configuration.
Event Names and Documentation
Here’s a quick overview of some key event names you should definitely remember:
- ApproveHash
- SignMsg
- Added/Removed Owner
- Changed Threshold
- Enabled/Disabled Module
- Changed Fallback Handler
If you want to dive deeper into the details, take a look at the official documentation here.
Implementation notes and emerging best practices
- Jump on those alerts right away--no need to wait for confirmations! Safe’s event/webhook system shoots out notifications super fast, so your main task is to page out quickly and handle the details later. (github.com)
- Just a heads-up, chain differences can really make an impact. For L2s, event-based indexing is the way to go; but for L1, you’ll be dealing with trace-based indexing, which can get tricky and potentially add some latency. Keep this in mind when you’re figuring out your SLAs. (github.com)
- Thinking about moving on from Defender? If you're still on OZ Defender Sentinels, be sure to switch over to OpenZeppelin Monitor or Forta before July 1, 2026. Keep an eye out for Safe config events and governance timelocks. (blog.openzeppelin.com)
- Make sure to keep tabs on handler provenance. It's super important for any non-standard handler to document audit links, code hashes, deployment transactions, and the owner's keys. Remember, you'll need CAB approval for any changes to handlers, even if it's just an upgrade. (docs.safe.global)
What 7Block Labs ships for clients
- Check out our ready-to-use "Safe Config Guardrail" that takes care of a few important things:
- It monitors ChangedFallbackHandler/Guard/Module/Owner/Threshold events happening across all your chains.
- It keeps an accurate allowlist updated, thanks to safe-deployments and your CAB.
- If anything goes awry, it can quickly alert P0 in just seconds, provide decoded transaction details, and even has the capability to automatically submit a "raise threshold" transaction from a designated emergency owner.
- Forta offers subscriptions and custom bots that link treasury configuration changes with patterns of attacker funding and exfiltration. This really helps minimize those pesky false positives. You can dive into more details here: (docs.forta.network)
- On top of that, our AA-aware monitors are hard at work checking the Safe4337Module and EntryPoint versions for every chain. If you're curious, you can check out more details right here: (docs.safe.global)
The takeaway
- Chill out about the “Token Balance Changed” notifications. It’s just noise in the background. (coindesk.com)
- Instead, keep your eyes peeled for the ChangedFallbackHandler and its sidekicks like ChangedGuard, EnabledModule, and ChangedThreshold. This is where you can spot treasury takeovers before they even start or stop them in their tracks. The Safe’s event surface is pretty solid, so your monitoring can be really effective. (docs.safe.global)
- Get that allowlist, log filter, and incident playbook wrapped up this week. Seriously, your future self--and your token holders--will thank you for it!
Sources and further reading
- Swing by the Safe Fallback Handler docs to get the lowdown on setFallbackHandler, events, and learn a bit about compatibility and extensible handlers. Oh, and don’t skip the security note! (docs.safe.global)
- If you’re curious about the ins and outs of FallbackManager, you can uncover the risks involved, like event emission and that pesky "cannot set to self" rule. (pkqs90.github.io)
- Want to know more about canonical handler addresses and how Safe deployments roll? Check it out here! (safe-eth-py.readthedocs.io)
- Take a deep dive into ERC‑4337 with Safe, including the details about Safe4337Module and the latest updates on EntryPoint releases. (docs.safe.global)
- Explore the Safe Transaction/Event Services, along with all the cool stuff about their webhook and SSE behavior. (github.com)
- Fun fact: Etherscan actually hides zero-value token transfers! It’s all about keeping things tidy and filtering out the junk. (coindesk.com)
- Check out the Forta Governance kit and see what exciting features are coming with Attack Detector 2.0. (docs.forta.network)
- And finally, get the latest scoop on OpenZeppelin Defender as it winds down and transitions into Monitor. (blog.openzeppelin.com)
If you need us to take care of the wiring for your treasury, we’re on it! You can expect to have the monitors, allowlists, and runbooks all set up for you in under two weeks. We’ll make sure to include all the AA/4337 checks and any specifics that relate to the chain.
Like what you're reading? Let's build together.
Get a free 30-minute consultation with our engineering team.
Related Posts
ByAUJay
Creating a Yield Aggregator for RWA Tokens: A Step-by-Step Guide
### Summary So, you’re looking to create a serious RWA yield aggregator in 2026? Well, things have definitely stepped up a notch technically! You'll need to manage a few crucial elements like ERC‑4626/7540 vault flows, permissioned token standards (ERC‑3643/1404), NAV and reserve oracles, and cross‑chain DvP. It’s going to be a challenging but exciting ride!
ByAUJay
Building 'Policy-Based' DeFi Wallets for Corporate Treasuries When it comes to managing corporate funds, efficiency and security are top priorities. That's where 'policy-based' DeFi wallets come in. These wallets not only allow businesses to tap into decentralized finance but also ensure there's a robust framework in place to manage their assets according to specific guidelines. What exactly do we mean by 'policy-based'? Well, it's all about tailoring the wallet's functionality to fit the unique needs of a company's treasury operations. With these kinds of wallets, companies can set rules and policies that dictate how funds are accessed, spent, and invested. So, if you're worried about security or compliance, these wallets can be a big help. These wallets can be designed to handle everything from regular transactions to more complex financial maneuvers, like yield farming or liquidity provision. Plus, the ability to automate certain processes means that businesses can save time and reduce the risk of human error. In a nutshell, 'policy-based' DeFi wallets are game-changers for corporate treasuries. They provide a smart, efficient way to manage crypto assets while keeping everything in check with rules that align with the company's financial strategy. It's a win-win!
**Summary:** Hey there! Corporate treasuries now have a great opportunity to explore the world of DeFi with some robust controls. Thanks to EIP-7702 smart accounts, along with policy modules like ERC-7579 and ERC-6900, they can ensure everything runs smoothly. Plus, with features like MPC signing, on-chain sanctions checks, and Travel Rule workflows, security is top-notch. This guide is here to take you through how 7Bl can help make it all happen!
ByAUJay
The 'Dual-Market' DeFi Setup: Merging Speed with Flexibility
**Summary:** A lot of DeFi stacks make you choose between super-fast execution and a whole bunch of features. But with a Dual‑Market architecture, you don’t have to pick one over the other anymore! It combines a low-latency “Fast Market” for quick trades with an intent-driven “Flexible Market” that offers versatility, bringing them together in a seamless way.

