Fiducia - Onchain Trust Rules and Cosigning

Safe Research

Safe Research

Safe ResearchAug 21, 202512 min read
fiducia
Go beyond single‑purpose checks. Fiducia is a powerful Safe Guard that gives you fine‑grained, onchain control over who your Safe can interact with, what it can do, and when - plus optional cosigner support to verify sensitive actions.

From Guardrail to Fiducia:

Guardrail showed how a single, targeted check (e.g., blocking risky delegatecalls) can raise the baseline of just having owners do the tx parameter verification. But what if you want to control more aspects of your transactions? Enter Fiducia -Latin for “trust” - a fitting name, as it enforces trust and rules onchain. Fiducia is essentially a “Swiss Army knife” guard for Safe. Instead of one check, it lets you enforce rules across address, calldata (function selector), and operation type, and even adding an extra approval mechanism for sensitive actions.

This is the second step in our journey: while Guardrail tackled one vector (delegatecalls), Fiducia broadens the scope to multiple dimensions of a transaction.

What Fiducia Can Do

Fiducia introduces several features that collectively significantly tighten security:

  • Transaction Allowlist & Blocklist: You can specify allowed transaction patterns - essentially combinations of a target address, the function (identified by function selector in the call data), and the call type (regular call or delegatecall). By default, any transaction not pre-approved will be blocked. This means you could allow, for example, calls to a specific DeFi contract’s deposit() function, but everything else would require extra scrutiny. It’s like telling your Safe, “You’re free to interact with X in these ways, but for anything else, slow down and let me double-check.” If Guardrail was a simple gate, Fiducia is a bouncer with a list - and if you’re not on the list, you’re not getting in (at least not immediately).

  • Cosigner Support (Extra Eyes on Every Transaction): Perhaps the hallmark feature of Fiducia is support for cosigners. A cosigner is an additional entity that can cryptographically approve a transaction which is not in the allow list. Cosigners were initially introduced in Safenet by Safe. Fiducia lets you designate a cosigner’s address. When active, this means every transaction which is not in the allowlist, needs a signature from that cosigner in addition to the usual Safe owner signatures. Why is this powerful? Because the cosigner can run independent checks offchain to verify the transaction’s safety or adherence to policy before signing. It’s like having an automated security analyst review each transaction in real time. If the cosigner approves (signature provided), Fiducia allows the transaction to bypass the delay and execute immediately (since presumably the cosigner did the necessary verification). If the cosigner does not approve, the transaction either has to be in the allow list or won’t execute at all. We’ll dive a bit more into cosigners below, because they’re worth a special discussion.

  • Token Transfer Limits: Fiducia can put per-token limits on transfers. For instance, you might configure it so the Safe can send at most 1,000 of Token ABC per transaction to any approved address. This is a safeguard against large withdrawals in a single transaction. If someone tries to transfer 10,000 tokens and that exceeds the set limit, Fiducia will block it (TokenTransferExceedsLimit error). You can fine-tune limits for each token and even specific recipient addresses if needed (setAllowedTokenTransfer() in the contract lets you whitelist certain token+recipient combos with higher limits). Note: This is per transaction limit, in a future iteration, it can be configured to have per day limit or certain time period limit, etc.

  • Guard Removal Protection: One obvious attack vector on any security system is trying to disable it. Fiducia anticipates this by requiring a secure process to remove or disable the guard itself. If the Safe owners decide to remove Fiducia, that action is also subject to a delay (i.e., you schedule a guard removal and can only finalize it after the delay). This way, an attacker who somehow got partial control of your Safe can’t instantly strip away the guard. You’d notice a scheduled removal and have time to react. Fiducia’s internal logic includes a scheduleGuardRemoval() function, ensuring removal follows the rules (attempting to remove it too early triggers an InvalidTimestamp() error). In short, Fiducia won’t fall for the “turn off the alarms” trick without ringing the bell itself.

On top of these core features, Fiducia supports Safe modules and MultiSendCallOnly transactions just like Guardrail. Under the hood, Fiducia implements both required guard interfaces from Safe (for regular and module transactions), so it truly watches everything going through your Safe.

The Role of Cosigners - Your Safe’s Best Friend 🚨👬

As mentioned before, a cosigner is an offchain agent that provides a second signature on transactions. But unlike a human co-owner, this agent’s “approval” is typically automated and based on predefined security checks. Think of it as a smoke detector for your Safe - it won’t stop you from lighting a candle (safe action), but it will blare if it detects something burning (dangerous transaction).

Every time you or anyone submits a transaction from the Safe, the cosigner service is expected to inspect that transaction and, if all looks good, produce a signature that Fiducia recognizes. If the signature is present and valid, Fiducia lets the transaction skip the delay and execute immediately. If not, the transaction will either fail or be checked against the allowlist. Essentially, cosigners introduce a verified check for every transaction. They can run much more complex analysis than an onchain guard alone could, because they’re not always limited by gas. They might simulate the transaction, compare it against known attack patterns, check an allowlist of safe destinations, or even require human confirmation for high-value actions. We highlight cosigners as “an essential layer of verified checks” that act as an independent signer confirming the transaction’s safety.

For more information about Cosigners, we have already written an article on it with our project Varangian. Fiducia is compatible with the Varangian cosigner, so you can check how things work when multiple security options (guard + cosigner) comes together.

Using Fiducia in Plain English

Setting up Fiducia is a bit more involved than Guardrail but still manageable, especially for developers:

  1. Deploy the Fiducia Guard contract (just like deploying Guardrail, using a tool like Forge). You can configure the initial delay (e.g., instantiate it with a 1-day or 12-hour delay as default). Let’s say we deploy it with a 24-hour delay.

  2. Attach it to your Safe: Execute a Safe transaction to set this new contract as the Safe’s guard (safe.setGuard(guardAddress)). Since Fiducia covers module transactions too, you also call safe.setModuleGuard(guardAddress) - effectively the Safe will route all transaction executions through Fiducia.

  3. Initial Configuration: Now you can configure allowed transactions and limits using Fiducia’s setup functions (these are done via transactions from the Safe owners to the guard contract):

    • Use setAllowedTx(target, functionSelector, operation) to allow specific calls with no delay. For example, you might allow UniswapRouter.swapExactTokensForTokens() (identified by its function selector and the router’s address) as an allowed transaction type. After this, any swap on that router won’t be delayed or blocked by Fiducia.

    • Use setAllowedTokenTransfer(tokenAddress, recipient, amountLimit) to whitelist certain token transfers. For instance, allow up to 1000 USDC to a specific business partner’s address per transaction.

    • Use setCosigner(cosignerAddress) to register your cosigner. If you don’t want a cosigner, you could leave it unset (address 0), in which case all non-allowed transactions will be rejected. If you do set one, Fiducia will from now on expect that cosigner’s signature on transactions for immediate execution.

  4. Ongoing Operation: Now the Safe works under Fiducia’s watch. Let’s walk through two scenarios:

    • Scenario A: Allowed Transaction. Say you pre-allowed calls to a certain DeFi protocol. A Safe owner submits a transaction that matches one of those allowed patterns (correct destination and function). That transaction can be executed immediately once the required owner signatures are collected. Fiducia sees it, matches it to an allowed pattern, and essentially says “This is fine.”. This is great for regular operations you trust since your Safe doesn’t get bottlenecked.

    • Scenario B: New or Unapproved Transaction. Now consider a transaction that is not on any allowlist - e.g., sending funds to a brand new address or calling a function you haven’t allowed. When a Safe owner submits this, if you have a cosigner, one of two things happens:

      • (i) The cosigner reviews it. If it’s actually something the cosigner finds safe (maybe your cosigner is programmed to approve any outgoing ETH transfer under 0.1 ETH, for example), it signs and includes its signature. Fiducia sees the cosigner’s blessing and lets the transaction proceed immediately despite not being pre-allowed

      • (ii) If the cosigner does not provide a signature (meaning it flagged the tx or simply wasn’t programmed to approve it), then Fiducia will not execute the tx immediately. Instead, it requires it to be added to the allowlist first. The owners will need to wait the 24 hours (or whatever delay) and then replay the transaction after the time has passed (FirstTimeTx() error is thrown if one tries to execute immediately without cosigner on a new pattern). This delay period is your chance to investigate the transaction. Finally, after the delay, the transaction can be executed.

  5. Removal/Changes: If you ever need to disable Fiducia (hopefully not, unless you’re upgrading to a different guard), you don’t just flip it off instantly. You would call scheduleGuardRemoval() which starts the timer to remove the guard. Only after the delay can you actually remove it with a follow-up call. This ensures an attacker who compromised a couple of owners can’t immediately remove Fiducia to perform evil acts - you’d get an early warning. Also, you can update cosigner or allowed lists at any time via Safe transactions to the guard contract.

Practical Benefits and Use Cases

Fiducia is ideal for those who have a good handle on their typical transaction activity and want to lock down everything else. For example, suppose you run a crypto treasury for a project: you regularly transfer stablecoins to your payroll provider and interact with a couple of DeFi protocols for yield. With Fiducia, you can allow those specific actions (addresses/functions) and they’ll go through smoothly. If a hacker tricks one of your officers into trying to transfer funds to an unknown address, Fiducia will step in: if you’ve set up a cosigner, it likely won’t sign that; at worst, the transfer will sit in limbo forever. This gives you a chance to react (perhaps the officer says “Uh, I didn’t initiate that!” and you realize an attack is happening). In a standard multisig without guards, if enough signers are compromised or fooled, that transaction would have executed and the funds gone whereas here, the guard provides an additional hurdle for the attacker.

For a less technical audience, you can compare this to spending limits and approvals on a bank account or corporate treasury, combined with an automated auditor watching every payment. It might sound complex, but the idea is to automate “Are we sure we want to do this?” checks that responsible humans would ask if they could scrutinize every transaction (which in practice, they might not - people click “Approve” quickly, or time zones differ, etc.). Fiducia enforces those “Are you sure?” checkpoints in code. It embodies the principle “Trust, but verify” - hence the name Fiducia (trust) - because it won’t just trust even your owners’ signatures blindly; it will verify conditions and possibly require a trusted cosigner’s second approval too.

Cosigner Advantages Recap

With cosigners in particular, we get a friendly synergy between tx analysis and on-chain enforcement. Cosigners can use sophisticated logic (even AI or external data) to decide if a transaction is safe, something we can’t fully do inside a smart contract due to certain limitations. But once the cosigner is happy, the onchain guard (Fiducia) will honor that by letting the tx pass. If the cosigner is unhappy or offline, the guard falls back to delays - meaning your security still holds. Many in the crypto security community view cosigned transactions as the future: even we note that cosigners add verified transaction approvals that greatly reduce vulnerabilities from blind signing.

A Quick Note on User Experience

Security features sometimes add friction. Fiducia does add a bit, for instance, initial setup and possibly occasional delays. However, used wisely (with a cosigner and well-set allowlists), it can be configured such that 90% of your routine transactions see no noticeable change, while 10% (the risky/unusual ones) get flagged. It’s a trade-off: a bit of inconvenience for a lot of peace of mind. For most crypto-savvy folks and devs (which, as per our audience, is a majority), this is a welcome trade. For newcomers, concepts like cosigner might be new, but the takeaway is: you have a robot buddy double-checking everything.

What’s next?

With Fiducia covering so much ground, you might wonder what’s left to improve. As powerful as it is, there’s still one more step in our Safe Guards journey. Fiducia, while flexible, is a single guard contract that you configure with various rules. What if you wanted to plug in entirely separate policy or have an easily extensible system where multiple policies can be developed independently and then attached to your Safe? That’s where the Policy Engine comes in which is the next (and major) evolution. It will take the concept of Safe Guards to a new level by allowing multiple concurrent policies and a more modular approach to defining them. Intrigued? Let’s move on to the grand finale: Safe’s Policy Engine.

About Safe Research

Safe Research is the applied R&D arm of Safe, dedicated to advancing the self custody stack. Our work is grounded in the cypherpunk principles of security, censorship resistance, and privacy, and we focus on building trustless, user centric infrastructure for smart accounts and wallets.

Let’s make Ethereum’s original cypherpunk vision real, one commit at a time.


Get the Alpha

Sign up to hear the latest from Safe in your inbox