7Block Labs
Decentralized Finance

ByAUJay

“DAO Treasury Multisig” GetFindings Version-Utils: Tuning AlertID Rules for ExecutionFailure

Decision-Makers’ Summary

When you're managing Safe (formerly Gnosis Safe) treasuries, it’s easy to overlook execution failures. This often happens because the external transaction looks like it went through, but the internal call could still trip up and fail. In this guide, we’ll show you how to set up Forta’s oz-gnosis events feed and use some smart, version-aware rules to catch and manage ExecutionFailures without too much noise in Safe versions 1.3.0 and 1.4.1. We’ll dive into everything from the coding side to fine-tuning alerts and even crafting operational runbooks. To help you out, you can reference this link: polygonscan.com.


Why this matters now

  • Safe is still your top choice for a DAO treasury smart account. Since mid-2024, the core version has been 1.3.0 across various chains, and the 1.4.x series is being actively maintained and rolled out throughout 2025. Upgrading your treasury is a breeze with SafeMigration, so it's really important to keep track of which version you’re using now and what’s coming down the pipeline. Take a look at everything over on GitHub!
  • Safe triggers ExecutionSuccess and ExecutionFailure events from execTransaction. Here's the twist: a blockchain explorer might display "Success" even if the internal call ended up reverting. But don’t worry--Safe still logs an ExecutionFailure and even dishes out a refund to the executor. So if you’re only glancing at receipt.status, you could easily overlook actual failures. It's super important to pay attention to the details! You can check out what’s going on over at Polygonscan.

This article will guide you through a straightforward way to subscribe to Forta alerts. You’ll discover how to identify the ExecutionFailure signal for your multisigs and minimize those annoying false positives by using version-aware rules.


ExecutionFailure 101 (for Safe treasuries)

What the Safe Contract Does on Execution:

When you run a Safe contract, several key things take place:

  1. Transaction Validation: The contract makes sure that the transaction has all its ducks in a row, like getting signatures from the right number of owners.
  2. Funds Management: This system takes care of the funds based on established guidelines. Whether it's moving assets around or carrying out a particular function, it only moves forward once everything's confirmed and in order.
  3. Event Logging: Every action you take gets logged as an event. This makes it super easy to keep tabs on everything happening with the contract.
  4. Reverts on Failure: If anything goes awry, the contract will roll back any changes it made. This way, your assets stay protected, and you can be sure that nothing surprising occurs.
  5. Notification: After everything's gone off without a hitch, the contract can shoot out notifications to keep everyone updated.

The Safe contract handles all the important details securely and reliably, ensuring everything operates as smoothly as it can.

  • Triggers one of these events:

    • ExecutionSuccess(bytes32 txHash, uint256 payment)
    • ExecutionFailure(bytes32 txHash, uint256 payment)
  • It sets aside some gas to manage event emissions (plus a little pre and post work) and uses guards GS010/GS013 to make sure everything stays secure during execution and estimation. So here’s the scoop: you could have an outer transaction that seems to go off without a hitch, but if there's an issue happening behind the scenes, the event is where you'll find the real story. Take a peek here: (polygonscan.com)

Common DAO Scenarios That Trigger ExecutionFailure:

When you're dealing with DAOs (Data Access Objects), there are a few typical situations that can trigger an ExecutionFailure. Check out some of these scenarios:

  1. Database Connection Issues:

    • Every now and then, you might run into trouble connecting to the database. This can be a real headache, often caused by network glitches or settings that just aren’t quite right.
  2. Invalid Queries:

    • If your SQL queries have mistakes or don’t quite fit the database schema, you’re probably going to hit an ExecutionFailure. So, it’s a good idea to give your syntax another glance!
  3. Data Integrity Violations:

    • When you attempt to insert or update data that clashes with what's already in the database--like duplicate keys or foreign key issues--the operation just won’t go through.
  4. Transaction Failures:

    • You might run into this kind of exception if something goes wrong when trying to commit a transaction, like a timeout or if someone requests a rollback.
  5. Insufficient Resources:

    • There are times when the database simply runs out of resources, whether it's memory or disk space. When that happens, it can stop everything in its tracks and result in an ExecutionFailure.
  6. Concurrency Problems:

    • When several processes are trying to access the same data at the same time, it can lead to some conflicts and, ultimately, an execution error.
  7. Timeouts:

    • If a query runs for too long, it could hit a timeout limit and you'll end up with an ExecutionFailure.
  8. Schema Changes:

    • Changing up the database schema (you know, like switching things around in your tables) while everything's still running can lead to a world of headaches. It's really smart to map out these changes ahead of time.

While you're working on your development, make sure to watch out for these issues. They can help you avoid ExecutionFailure from throwing you off track.

  • Every now and then, when you're using the multisend batch step, it can revert due to a hiccup in a downstream call. But here’s the silver lining: the main Safe transaction can still succeed! This is what we call a classic “success with internal failure.” If you want to dive deeper into this, check it out here.
  • Don’t forget about safeTxGas! If you end up with too little or accidentally miscalculate the gas for an inner call, Safe has you covered with a stipend. They might even give a little something to the executor, even if that inner call doesn’t go as planned. You can take a peek at it on Polygon Scan.
  • Lastly, keep in mind that execution might stumble when modules trigger it, such as with Zodiac/roles/delay or any custom operations module you’re using. If you're diving into modules, it’s smart to watch out for ExecutionFromModuleFailure too. You can get more info here.

Key takeaway: Make sure you're keeping an eye on event-level monitoring for ExecutionFailure on every treasury Safe you manage across all the chains you’re working with.


The monitoring stack you’ll use

  • Forta oz‑gnosis events bot: This nifty tool keeps you in the loop by sending alerts for events occurring in OpenZeppelin and Safe repositories, such as ExecutionFailure. Let's take a closer look at it, sign up, and then narrow things down to just your treasury addresses and chains. You can check it out here.
  • Forta SDK v2: This version lets you tap into initialize, handleAlert, and getAlerts for backfills or calibration. Make sure to pay attention to the AlertEvent fields like alertId/name, chainId, and addresses. You can find more details here.
  • Optional correlation feeds:

    • There's this handy template called “Successful transactions with internal failures.” It’s perfect for when you see a receipt saying “success,” but something went sideways with some internal calls. You can check it out here.
    • If you’re looking for a broader perspective, you might find the Attack/Scam combiners or governance kits useful. They help you catch those bigger patterns, like a failure that happens right after a parameter change. For more info, take a look here.

Version‑Utils: a pragmatic pattern to keep rules in sync with Safe versions

In the real world, you’ll likely find yourself juggling a bunch of Safes, each running different versions across various chains. That’s where our handy “Version‑Utils” pattern comes into play. It’s basically a straightforward configuration and helper that:

  1. When it boots up, it figures out the Safe version by checking the VERSION constant or looking through safe-deployments based on the address.
  2. It sets up the right alertId/name filters for each version since, you know, bots and event signatures can shift over time.
  3. It also considers the specific edge cases for each version--like the differences in gas semantics between 1.3.0 and how guarding works in 1.4.1--to help you with your severity logic. (github.com)

Why should you avoid hard-coding? A lot of DAOs are gearing up to move from version 1.3.0 to 1.4.1 using SafeMigration. When you tie your rules to just one version, they can become outdated pretty quickly, which can create some avoidable headaches down the line. If you want to dive deeper, take a look at the documentation here: (docs.safe.global).


Concrete example: subscribing to ExecutionFailure for your treasury Safes

We'll kick things off by pulling alerts from the oz‑gnosis events feed. We'll use initialize/handleAlert to do this, and then we'll zero in on the ones that show ExecutionFailure.

Step 1: Define Your Treasury Set and Chains

Before we jump into the details, let's take a moment to clarify what your treasury setup is all about and the chains you plan to use. This is your base, so let’s unpack it:

  1. Treasury Set: You can think of this as your stash of assets--like your own treasure chest! It's super important to know exactly what’s inside--whether you’re dealing with cash, stocks, bonds, or cryptocurrencies. Having a solid grasp of your holdings is key to making smarter choices down the line.
  2. Chains: Alright, let’s dive into chains! Here, we’re chatting about the various blockchain networks you’ll be engaging with. Each of these chains comes with its own unique features and perks. So, take a moment to consider which chains fit best with your goals and your approach to managing your treasury.

Once you’ve got your treasury set and chains figured out, you’re ready to dive into the next steps!

// config/treasuries.ts
export const TREASURIES = {
  1: [ // Ethereum mainnet
    "0xYourMainnetSafe",
    "0xAnotherMainnetSafe"
  ],
  137: [ // Polygon
    "0xYourPolygonSafe"
  ],
  42161: [ // Arbitrum One
    "0xYourArbitrumSafe"
  ]
};

Step 2: Minimal Version-Utils

Getting Started with version-utils

In this step, we’re going to explore the essentials of version-utils. This awesome tool makes it super easy to handle and tweak version numbers without breaking a sweat. Let’s get into the details you need to kick things off!

What is Version-Utils?

Version-utils is a handy library that makes dealing with version numbers a breeze. Whether you need to bump a version, compare different versions, or just want to keep everything organized, this tool is here to help you out.

Key Features

  • Bumping Versions: Quickly raise the major, minor, or patch version numbers with ease.
  • Comparing Versions: Find out which version is more recent or if they’re actually the same.
  • Parsing Versions: Transform version strings into manageable objects that are easy to work with.

Getting Started

To kick things off with version-utils, you'll need to install it first. Simply pop this command into your terminal:

npm install version-utils

Basic Usage

Here’s a handy guide on how to incorporate version-utils into your project:

const versionUtils = require('version-utils');

// Bumping a version
let newVersion = versionUtils.bump('1.0.0', 'patch'); // returns '1.0.1'

// Comparing versions
let comparison = versionUtils.compare('1.0.0', '1.0.1'); // returns -1 (meaning the first version is older)

Documentation

If you’re looking to explore all the cool features and functionalities, you should definitely take a look at the official documentation.

Conclusion

And that's a wrap on the minimal version-utils! With just a handful of commands, you'll be able to handle your version numbers like a champ. If you have any questions or run into any bumps along the way, feel free to reach out!

// utils/version-utils.ts
import { ethers } from "ethers";
import deployments from "@safe-global/safe-deployments"; // JSON addresses/abis

export type SafeVersion = "1.3.0" | "1.4.1" | "unknown";

export async function getSafeVersion(provider: ethers.providers.Provider, safeAddr: string): Promise<SafeVersion> {
  // Try read VERSION() from the Safe proxy via ABI, else fall back to deployments lookup
  const abi = ["function VERSION() view returns (string)"];
  try {
    const c = new ethers.Contract(safeAddr, abi, provider);
    const v: string = await c.VERSION();
    if (v.startsWith("1.3.0")) return "1.3.0";
    if (v.startsWith("1.4.1")) return "1.4.1";
  } catch {}
  // Fallback: heuristic via bytecode hash against known deployments (left as exercise)
  return "unknown";
}

Take a look at the Safe contracts repo for everything you need to know about the supported versions and how to migrate. It’s super handy for managing your logic--like adjusting the severity levels for failures with version 1.4.1 after you upgrade. You can check it out here: (github.com).

Step 3: Subscribe to oz‑gnosis Events and Filter for ExecutionFailure

Now, let’s go ahead and subscribe to those oz‑gnosis events and set up a filter for the ExecutionFailure. This way, we can easily track any bumps that might come up while we’re executing things. Here’s how to get it done:

  1. Sign up for oz-gnosis events.
  2. Configure the filter for ExecutionFailure: Ensure that you’re focusing solely on those annoying failures rather than getting bogged down with every single event.

With this setup, you’ll be ready to spot and tackle any issues the moment they pop up.

// src/agent.ts
import {
  AlertEvent, Finding, FindingSeverity, FindingType, HandleAlert, Initialize, InitializeResponse
} from "forta-agent";
import { TREASURIES } from "../config/treasuries";
import { getSafeVersion } from "../utils/version-utils";

const OZ_GNOSIS_EVENTS_BOT = "oz-gnosis-events"; // use actual botId from Forta app once verified in staging

// store run-time cache of safe versions
const versionCache = new Map<string, string>();

export const initialize: Initialize = async (): Promise<void | InitializeResponse> => {
  // Build Forta subscriptions: one for the OZ/Gnosis bot; keep alertIds empty until we discover them from staging
  return {
    alertConfig: [
      { botIds: [OZ_GNOSIS_EVENTS_BOT] } // we'll filter in code by alert.name and addresses
    ]
  };
};

function isTreasury(chainId: number, addr: string): boolean {
  return (TREASURIES[chainId] || []).some(a => a.toLowerCase() === addr.toLowerCase());
}

export const handleAlert: HandleAlert = async (alertEvent: AlertEvent) => {
  const f: Finding[] = [];

  // quick chain/address filter
  const chainId = alertEvent.chainId;
  const addrHit = (alertEvent.alert.addresses || []).find(a => isTreasury(chainId, a));
  if (!addrHit) return f;

  // normalize by alert.name when alertId is unknown/changes across versions
  const name = (alertEvent.name || alertEvent.alert.name || "").toLowerCase();
  if (!name.includes("executionfailure")) return f;

  // fetch Safe version for added context (cached)
  if (!versionCache.has(addrHit)) {
    // supply a provider here or ask a sibling bot
    versionCache.set(addrHit, "unknown");
  }
  const version = versionCache.get(addrHit) || "unknown";

  // severity tuning: stricter on 1.4.1 post-migration, lower on known-estimation-flows
  const severity = version.startsWith("1.4") ? FindingSeverity.High : FindingSeverity.Medium;

  f.push(Finding.from({
    name: "Safe ExecutionFailure observed",
    description: `ExecutionFailure on treasury ${addrHit} (v${version})`,
    alertId: "SAFE-EXECUTION-FAILURE",
    severity,
    type: FindingType.Suspicious,
    addresses: [addrHit],
    metadata: {
      chainId: String(chainId),
      botId: alertEvent.botId,
      txHash: alertEvent.transactionHash || "",
    }
  }));
  return f;
};

export default { initialize, handleAlert };

Notes

Important Reminders

  • Remember to double-check those deadlines!
  • Stay on top of any feedback you get from various sources.
  • And hey, don't forget to plug in new appointments into your calendar!

Upcoming Events

Workshop on Digital Marketing

  • Date: March 10, 2024
  • Time: 9:00 AM - 3:00 PM
  • Location: Downtown Conference Center
  • RSVP: Please let us know by February 28, 2024

Team Meeting

  • Date: March 15, 2024
  • Time: 2:00 PM
  • Location: Zoom Meeting Room
  • Agenda: Let’s chat about project updates and what our next steps will be!

Resources

Tips for Staying Organized

  1. Grab a planner or pop open a digital calendar to stay on top of your tasks.
  2. Don't forget to set up reminders for those important deadlines - they can really sneak up on you!
  3. Take those big tasks and chop them down into smaller, more manageable pieces.

Final Thoughts

Make sure you take some breaks and take care of yourself while you’re juggling everything! Keeping a good work-life balance is super important for staying productive. You've totally got this!

  • You can find all the details about Forta’s AlertEvent fields like alertId, name, chainId, and addresses in the documentation. If the oz‑gnosis bot ever decides to change up the alertId format, no sweat! The code above will keep working by matching on the alert name instead. While you're in staging, definitely remember to log those incoming alertId values and save them in your config to keep everything running smoothly when you go live. (docs.forta.network)
  • If you're looking to keep things breezy, just ask for specific alertIds during the initialization phase once you’ve got the green light. This way, you'll get less volume and save on costs. (docs.forta.network)

Calibrating the exact AlertID: a safe way to “learn” IDs

Since alertId strings are set by bots, it's a good idea to do a quick "learning" pass in a non-production environment:

  1. Run getAlerts to grab the oz‑gnosis alerts for your treasury addresses from the past N days, and don’t forget to group them by alertId or name.
  2. Dive into the alertIds that keep popping up as ExecutionFailure across various chains and versions.
  3. Store those IDs in a ruleset file, and make sure to version it according to the Safe version and the chain.

Example GraphQL Query to Explore Recent oz-gnosis Alerts and Extract Names/IDs

If you want to get the scoop on the latest oz-gnosis alerts and snag some names and IDs, you’ve come to the right spot. Check out this handy GraphQL query you can use:

{
  alerts(first: 10, where: { status: "recent" }) {
    edges {
      node {
        id
        name
      }
    }
  }
}

Breaking it Down

  • alerts: This is your go-to spot for fetching all the alerts.
  • first: 10: We're keeping it simple by only grabbing the first 10 alerts.
  • where: { status: "recent" }: We're focusing on the most recent ones only.
  • edges: Here’s where you'll find the real data.
  • node: Each alert's details hang out in this section.
  • id & name: These are the crucial bits of info we're extracting.

Go ahead and adjust the parameters however you like to fit your needs and explore the data further!

# POST https://api.forta.network/graphql
query recentAlerts($input: AlertsInput) {
  alerts(input: $input) {
    pageInfo { hasNextPage endCursor }
    alerts {
      name
      alertId
      chainId
      addresses
      source { bot { id } transactionHash }
    }
  }
}

Make sure to use variables for your bot IDs and addresses. For instance, you might want to set createdSince=600000 to capture alerts from the last 10 minutes, and you can always widen that time frame if you need to. If you’re looking for some great examples and the fields you'll need, definitely check out Forta’s documentation. You can find it here: (forta-network.github.io).


Reducing noise: five precision levers that actually work

  1. Request several proofs for raising severity
    • Combine oz-gnosis ExecutionFailure with “Successful txn with internal failures” to eliminate any confusion in explorers and make it clear which operations are actually failing. (docs.forta.network)

2. Version-aware Severities

  • In version 1.3.0, some teams might intentionally trigger an inner revert while they’re estimating gas or running dry tests. If safeTxGas=0 fits into what you’re doing, feel free to mark it as Informational. However, starting from version 1.4.1, any ExecutionFailure post-upgrade needs to be classified as Medium or High unless it’s on the whitelist. You can check it out here: (polygonscan.com).

3. Module-aware filtering

  • If you’re working with modules like Delay, Roles, or SafeSnap/Reality, don’t forget to subscribe to ExecutionFromModuleFailure too. It’s a great way to catch those pesky automation failures that might slip through the cracks during owner-initiated executions. You can check it out here: (pkg.go.dev)

4. Chain and Bot Confirmation Filters

  • Keep an eye on your active chainIds and remember to set scanNodeConfirmations to at least 2 in getAlerts for those backfills. This little tweak helps to filter out those annoying transient anomalies. For more details, take a look at the docs!

5. Address Scoping and Allowlists

  • Keep access restricted to only verified treasury Safe addresses and trusted module addresses. It’s a good idea to set up a separate staging environment for testing to avoid any operational noise messing up your production channels. You can explore more on GitHub!

Ops runbook: what to do when ExecutionFailure fires

  • Triage within 10 minutes:

    • First up, dive into the Safe transaction hash and event logs to hunt for any instances of ExecutionFailure. If there's an inner revert reason hanging around, give that a look too. The Safe code references GS013 (“require success or non‑zero safeTxGas/gasPrice”), and checking out the gas accounting might just provide some clarity on what went wrong. (polygonscan.com)
    • After that, see if the transaction included Multisend. If it did, try to pinpoint which specific step stumbled and then attempt to re-execute just that failed action, making sure to adjust the gas settings appropriately. (ethereum.stackexchange.com)
  • Governance Linkage:

    • If you're working with Snapshot/SafeSnap or Reality modules, it's a good idea to verify the proposal ID. Make sure that the on-chain execution aligns with the approved payload. If something goes wrong, you may need to put forward another proposal or implement an emergency fix. (forum.gnosis.io)
  • Post-mortem checklist:

    • Did you hit the wrong target, use an old ABI, or run into some module permission problem?
    • Were you short on safeTxGas? If that’s the case, increase it and try again.
    • If you're facing a module-level revert, take a look at ExecutionFromModuleFailure and dive into those module logs. (pkg.go.dev)

Safe version nuances that change how you alert

  • 1.3.0 Behavior: We've rolled out some cool updates regarding ExecutionFailure/Success events. Now, we're clearing those events and setting aside gas just for them. A little heads-up: sometimes an outer success can hide an inner revert, so it's good to stay alert. Also, refund semantics are now linked with tx.origin and refundReceiver. To keep everything running smoothly, just ensure your rules avoid paging on those pesky “estimation reverts.” You can check it out on PolygonScan.
  • 1.4.1 Line: This update introduces some exciting new features to support ERC‑4337, plus a few guard checks and broader L2 coverage. If your team just went through SafeMigration, keep an eye out for any ExecutionFailure messages you encounter in the first week--they should be a top priority. You'll want to identify any misconfigured fallback handlers or modules right away. For more info, check out GitHub.

Keep your “version‑utils” mapping fresh with the safe‑deployments package! This repo is fantastic at tracking deployments and ABIs for every chain, so you can trust that your address and version detection remains accurate. Take a look here: (github.com)


Forta deployment hygiene (so you don’t miss real failures)

  • SLA and publishing: Keep an eye on event.batch‑publish.error in your scanners. If a publisher gets hung up, it can throw a wrench in your SLA and might even cause alerts to drop. So, it’s a good idea to set up some alerts in your pipeline to notify you if your SLA KPIs start to veer off course. Check it out here: (docs.forta.network)
  • To effectively handle bot alerts, make sure to use paid API keys along with the v2 SDK’s handleAlert. It’s also smart to throttle your getAlerts backfills and opt for cursor-based pagination whenever you can. Check it out here: (docs.forta.network)
  • Consider incorporating Nethermind’s governance and security bots into your setup. They’re great at monitoring any changes to Safe admins and upgrades, which helps you understand the relationship between "config drift" and possible failures. Check it out here: (forta.org)

Production checklist for “DAO Treasury Multisig: ExecutionFailure” monitoring

  • Scope:

    • Compile a list of all the treasury Safes for each chain. Don’t forget to include the owner threshold, modules, and fallback handler details.
    • When booting up, make sure to check and save the Safe version. Plus, set up a weekly task to verify it. (github.com)
  • Subscriptions:

    • Check out the Forta oz‑gnosis events bot! It’s also a good idea to watch out for “Successful txn with internal failures.” You can find more info in the Forta docs.
  • Rules:

    • Maintain an allowlist of addresses that only includes your safes and modules.
    • For the AlertId/name, stick with ExecutionFailure; be sure to verify the exact bot alertId in staging before finalizing it.
    • Create a severity policy that’s aware of different versions; ramp it up after migration or if there are any changes made by admins.
  • Correlations:

    • Keep an eye on any module failure events (ExecutionFromModuleFailure).
    • Make sure to track governance proposal IDs (SafeSnap/Reality) when it makes sense. (pkg.go.dev)
  • Ops:

    • Only use PagerDuty/Slack for high alerts; keep the medium alerts on the triage board.
    • Make sure the post-mortem template has safeTxGas and the failing step from Multisend. (ethereum.stackexchange.com)
  • Resilience:

    • Stay on top of the scanner SLA and make sure everything’s publishing smoothly. It’s a good idea to set up a canary alert that goes off once a day from a trusted lab Safe. Check out the details here: (docs.forta.network)

Bonus: Backfill and governance reporting

Run a Weekly Backfill to Quantify the “Failed-to-Executed” Ratio:

Here’s a simple way to keep an eye on the “failed-to-executed” ratio by doing a weekly backfill:

  1. Set the Time Frame: Pick a specific day each week for your backfill. This way, you can easily track and compare your data over time.
  2. Collect Data: Gather all the transaction data from the week. Don’t forget to include both the successful and the failed transactions so you can really see what’s going on.
  3. Calculate the Ratio:

    • Go ahead and plug in the numbers using this formula:
      Failed-to-Executed Ratio = (Number of Failed Transactions) / (Total Executed Transactions)
  4. Analyze Results: Once you've got the ratio calculated, take a moment to dig into those results. Check out the patterns or trends in the data--these could help you figure out why certain transactions didn’t go through.
  5. Adjust Strategies: After looking into your findings, consider what changes you can implement to cut down on those pesky failed transactions. This could mean fine-tuning your processes or upgrading your tools for better performance.
  6. Report Findings: It's time to share what you've discovered with the team! You could whip up a straightforward report or put together a presentation that highlights the ratio and includes any suggestions stemming from your analysis.

Stick to this process, and you'll be able to keep an eye on how your transactions are doing, which will help you make smart choices down the line!

  • Take a look at the oz‑gnosis alerts for any ExecutionFailure issues that popped up in your safes over the past week.
  • Mix in some data from your proposal metadata--like the amount, beneficiary, and module--to identify any patterns in the problems (you might find some misconfigured modules or per-chain gas policies). Forta offers some great examples of GraphQL queries and filtering options, including severities and scanNodeConfirmations. Check it out here!

Deliver an Exec-Ready Dashboard KPI:

Creating a dashboard that stands out to the execs is all about blending clarity, relevance, and a sprinkle of creativity. Here’s how you can put together an impressive KPI dashboard that will definitely catch their eye:

1. Define Your Audience

Before you jump in, take a moment to consider who will actually be using this dashboard. What are they hoping to achieve? How much detail do they need? Getting a good grasp on this will really help you customize the dashboard to fit their needs perfectly.

2. Select Key Performance Indicators (KPIs)

Choose the KPIs that truly resonate with your audience. Here are a few favorites to consider:

  • Revenue Growth: What’s the latest on our income?
  • Customer Satisfaction Score: Are our customers satisfied with what we offer?
  • Employee Engagement: How’s the overall morale within the team?

Ensure that these KPIs are in sync with our overall business goals.

3. Choose a Visualization Tool

Based on what your team likes and how much you want to spend, there are quite a few tools to choose from. Here are some fan favorites:

  • Tableau: Awesome for creating interactive dashboards that really pop.
  • Power BI: A strong pick for digging deep into data insights.
  • Google Data Studio: Ideal if you’re just stepping into the world of data visualization.

4. Design the Dashboard

  • Keep It Simple: Avoid cramming in too much info. Go for a clean layout that really shines a light on the key data.
  • Use Visuals: Spice things up with charts, graphs, and some color coding to make your data stand out.
  • Interactive Elements: If you can, add filters so users can really dig into the data.

5. Regular Updates

Keep your dashboard up to date with the freshest data. Set a schedule for updates that works best, whether that’s weekly, monthly, or even in real-time, based on what your execs require.

6. Provide Context

Instead of just bombarding them with numbers, try to provide some context or insights that can really bring the data to life. It might be a good idea to add a section for notes or interpretations to help clarify things.

7. Gather Feedback

Once you've pulled your dashboard together, it's a great idea to get some feedback from your audience. What do they love? What do they feel is missing? Use their thoughts to tweak and elevate your dashboard.

Conclusion

Creating a dashboard for execs boils down to making sure it's clear and relevant. Just follow these steps, and you'll be on track to deliver a dashboard that's not only engaging but also helps your audience make informed decisions.


Check out these awesome links to dive deeper:

  • Tableau
  • Power BI
  • Google Data Studio
  • For each chain, we're checking out: the count of ExecutionFailures, the percentage that got retried successfully within 24 hours, and the key reasons for reverts.
  • Following the upgrade window for version 1.4.1 (migration), let’s take a closer look at any persistent failures. (docs.safe.global)

Security footnotes for leaders

  • When it comes to Safe event semantics, don’t treat them as optional. Just counting on the outer transaction status isn’t safe at all. Your teams should really focus on ExecutionFailure/Success to understand what went down inside execTransaction. You can check out the Etherscan-verified source to see exactly where these events are triggered and why explorers might incorrectly show “success” even when there are inner failures. (polygonscan.com)
  • If you're automating using modules, make sure to include the failure events in your Service Level Objectives (SLOs). A module that doesn’t report can mess up payroll or market operations, and you definitely don't want that. The getamis Gnosis kit has those event types available, so you can easily index or set up bots. (pkg.go.dev)
  • Looking to save some time? Forta’s curated kits come with an “internal failures” detector and an oz-gnosis events feed. It’s way more efficient to use those rather than creating raw log parsers from scratch. This way, you’ll cover more ground faster and worry less about maintenance. (docs.forta.network)

What good looks like in 2026

  • We're keeping tabs on every treasury Safe across all the active chains to catch any ExecutionFailures using Forta oz‑gnosis events.
  • With our version-aware ruleset, we ensure that the AlertID/name filters stay aligned as you upgrade to 1.4.1+ and introduce new modules.
  • Each week, we compile a report to track failure rates, retries, and governance connections.
  • We've found a good balance when it comes to pager fatigue: only new, high-risk failures trigger alerts for the on-call team, while those “expected” estimation reverts get automatically suppressed.

If you're planning to integrate this with your existing SIEM, we can easily set up the Forta consumer as an external bot using your logging format and RBAC. Forta is designed to work with external bots and alert submissions, making it super convenient for you to boost your findings down the line. For more info, take a look here.


References and further reading

  • Take a peek at the Safe contract source (1.3.0) which goes into detail about ExecutionFailure/Success and guards GS010/GS013. It does a great job explaining the “outer success, inner failure” idea. You can check it out here: (polygonscan.com)
  • If you're curious about the Forta SDK, there's a solid rundown on using alert consumption (initialize, handleAlert, getAlerts). Everything's clearly laid out for you right here: (docs.forta.network)
  • For those new to Forta, don't miss the starter kits! They dive into oz‑gnosis events and discuss “Successful transactions with internal failures.” Perfect for getting your feet wet! Check it out: (docs.forta.network)
  • If you’re keeping an eye on Safe releases, make sure to look at the migration guidance for version 1.4.1. All the info you need is packed into one spot! (github.com)
  • And finally, you'll want to familiarize yourself with Module failure events (ExecutionFromModuleFailure) in the Safe tooling. It’s a really useful resource to have on hand. Check it out here: (pkg.go.dev)

TL;DR implementation kit

  • Make sure to subscribe to Forta's oz‑gnosis events! You can easily filter these events by:
    • The addresses that you've got on your treasury/module allowlist,
    • Names that have “ExecutionFailure” in them (just remember to pin the exact alertIds after staging),
    • The chainId that corresponds to your active networks. Check out the details over at docs.forta.network.
  • Keep a version‑utils map close by--using VERSION() or deployments will help you tweak severity and suppression rules based on your Safe version. You can find it on GitHub.
  • Don’t forget to link up with the “internal failures” bot for even more accuracy. Plus, if you’re thinking about automation, be sure to monitor those module failure events! More info is available at docs.forta.network.

Stick to this pattern, and you’ll find that ExecutionFailure won’t catch you by surprise during your treasury retros anymore. Instead, it’ll just be a straightforward signal that you can actually take action on.

Like what you're reading? Let's build together.

Get a free 30-minute consultation with our engineering team.

Related Posts

Decentralized Finance

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!

Decentralized Finance

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!

Decentralized Finance

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.

7BlockLabs

Full-stack blockchain product studio: DeFi, dApps, audits, integrations.

7Block Labs is a trading name of JAYANTH TECHNOLOGIES LIMITED.

Registered in England and Wales (Company No. 16589283).

Registered Office address: Office 13536, 182-184 High Street North, East Ham, London, E6 2JA.

© 2026 7BlockLabs. All rights reserved.