Crypto Training
Safe Smart Account Evolution: v1.0.0 to v1.5.0, Feature Growth vs Security Surface
A deep, code-first analysis of Safe version evolution from v1.0.0 to v1.5.0: what changed, why it changed, what risks were introduced, and how audits and fixes shifted the security posture over time.
Safe is one of the most battle-tested smart account systems in production, but battle-tested does not mean static. It means repeated exposure, repeated stress, repeated fixes, and repeated redesign when assumptions change.
This post is a code-first analysis of Safe from v1.0.0 to v1.5.0, built from release tags, changelog entries, audit artifacts, and Safe docs. The goal is not a marketing timeline. The goal is to understand security posture drift: what each feature bought, what each feature cost, and which old classes of bugs were actually eliminated versus reshaped.
Primary references:
- Safe smart account repo: https://github.com/safe-fndn/safe-smart-account
- Changelog (
v1.5.0includes change history fromv1.3.0onward): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/CHANGELOG.md - Guidelines: https://github.com/safe-fndn/safe-smart-account/blob/main/docs/guidelines.md
- Safe docs home: https://docs.safe.global/home/what-is-safe
- Smart account overview: https://docs.safe.global/advanced/smart-account-overview
- Smart account concepts: https://docs.safe.global/advanced/smart-account-concepts
- Modules docs: https://docs.safe.global/advanced/smart-account-modules
- Guards docs: https://docs.safe.global/advanced/smart-account-guards
- Fallback handler docs: https://docs.safe.global/advanced/smart-account-fallback-handler
- Signatures docs: https://docs.safe.global/advanced/smart-account-signatures
- Migrations docs: https://docs.safe.global/advanced/migrations
- Audits docs page: https://docs.safe.global/advanced/smart-account-audits
Evolution map: capabilities vs attack surface#
The key pattern across all releases:
- security fixes reduced specific known bug classes
- extensibility added new composition risks
- migration and operational tooling improved UX while adding control-plane complexity
That is normal for a modular smart account architecture.
What stayed constant across all versions#
Across all versions analyzed, the foundational trust skeleton remained the same:
- proxy delegates to singleton implementation
- owners and threshold control transaction authorization
- nonce-based replay protection anchors ordering
- modules and fallback handlers provide extension points
- execution path is still fundamentally
verify signatures -> enforce policy -> execute external call
Core code anchors by version:
v1.0.0contracts/GnosisSafe.sol: https://github.com/safe-fndn/safe-smart-account/blob/v1.0.0/contracts/GnosisSafe.solv1.3.0contracts/GnosisSafe.sol: https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/GnosisSafe.solv1.4.0contracts/Safe.sol: https://github.com/safe-fndn/safe-smart-account/blob/v1.4.0/contracts/Safe.solv1.5.0contracts/Safe.sol: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/Safe.sol
Because this shape stayed stable, most security evolution happened in the edges: signature encoding details, gas semantics, setup/deployment constraints, callback handling, migration helpers, and policy hooks.
Version by version: what changed, why, and what new risk arrived#
v1.0.0: strong baseline, but critical classes discovered during verification#
Code:
GnosisSafe.sol(v1.0.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.0.0/contracts/GnosisSafe.solProxyFactory.sol(v1.0.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.0.0/contracts/proxies/ProxyFactory.sol
Audit artifact:
- Formal verification report: https://github.com/safe-fndn/safe-smart-account/blob/v1.0.0/docs/Gnosis_Safe_Formal_Verification_Report_1_0_0.pdf
Key takeaways from the formal verification cycle:
- critical issue classes were identified in execution and transaction safety logic
- high-value classes included reentrancy around transaction execution and gas/refund abuse paths
- the release quality improved by fixing those classes before finalizing that release line
Interpretation:
v1.0.0is not “perfect from day one”; it is “formal methods found hard bugs, then the protocol hardened”- this is exactly how formal verification should improve production software
v1.1.0 and v1.1.1: deployment and lifecycle hardening#
Code:
GnosisSafe.sol(v1.1.1): https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/contracts/GnosisSafe.solFallbackManager.sol(v1.1.1): https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/contracts/base/FallbackManager.solMultiSend.sol(v1.1.1): https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/contracts/libraries/MultiSend.sol
Audit artifacts:
1.1.0report: https://github.com/safe-fndn/safe-smart-account/blob/v1.1.0/docs/Gnosis_Safe_Audit_Report_1_1_0.pdf1.1.1amended review: https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/docs/Gnosis_Safe_Audit_Report_1_1_1.pdf
What was emphasized:
- delegatecall-induced state integrity risk was explicitly documented as a design hazard
- master copy must be non-operable by construction, to reduce upgrade/deployment trust accidents
- Istanbul gas repricing made legacy assumptions around
send/transferbehavior fragile - MultiSend hardening reduced accidental misuse and self-destruct style lifecycle risk
New risk introduced by architecture evolution:
- fallback routing gives flexibility, but any fallback route becomes a permanent selector-level trust boundary
If handler assumptions are weak, the path above becomes a policy bypass vector.
v1.2.0: EIP-150 gas overhead fix under relayer threat model#
Code:
GnosisSafe.sol(v1.2.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.2.0/contracts/GnosisSafe.sol
Audit artifact:
- gas validation adjustment report: https://github.com/safe-fndn/safe-smart-account/blob/v1.2.0/docs/Gnosis_Safe_Audit_Report_1_2_0.pdf
Issue class fixed:
- incorrect gas overhead calculation under EIP-150 could allow a relayer to force internal failure while consuming nonce progression
Practical impact:
- this is not a cosmetic gas bug
- nonce consumption plus relayer execution is an authorization and liveness problem
Relevant behavior notes:
- safe transaction gas semantics are documented here: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/safe_tx_gas.md
The high-value lesson: gas math errors in account abstraction flows are often security bugs, not just UX bugs.
v1.3.0: major security architecture pivot#
Code:
GnosisSafe.sol(v1.3.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/GnosisSafe.solGuardManager.sol(v1.3.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/base/GuardManager.solCompatibilityFallbackHandler.sol(v1.3.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/handler/CompatibilityFallbackHandler.solHandlerContext.sol(v1.3.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/handler/HandlerContext.solStorageAccessible.sol(v1.3.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/common/StorageAccessible.solGnosisSafeL2.sol(v1.3.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/GnosisSafeL2.sol
Audit artifacts:
- April 2021 review (
no serious issues): https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/docs/GnosisSafeApr2021.pdf - May 2021 review (
no serious issues): https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/docs/GnosisSafeMay2021.pdf
Feature gains:
- chain-aware transaction hashing (
chainIdin EIP-712 domain) - transaction guards (
checkTransaction,checkAfterExecution) - fallback context improvements (
msg.senderforwarding semantics) - EIP-1271 compatibility logic shifted to handler layer
- L2 event-rich execution model (
GnosisSafeL2) - better simulation support via
StorageAccessible
Why it was done:
- split core account logic from compatibility and observability concerns
- make policy hooks explicit and auditable
- support richer integrations without forcing core bloat
New risks introduced:
- guards can lock accounts if guard logic is buggy or misconfigured
- fallback handlers became even more central to message/signature workflows
- simulation and compatibility paths introduced more “advanced user footguns”
v1.3.0 is where Safe became a clearer policy platform, not just a multisig executor.
v1.4.0: factory hardening, signature integrity checks, and naming cleanup#
Code:
Safe.sol(v1.4.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.0/contracts/Safe.solSafeProxyFactory.sol(v1.4.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.0/contracts/proxies/SafeProxyFactory.solGuardManager.sol(v1.4.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.0/contracts/base/GuardManager.solCompatibilityFallbackHandler.sol(v1.4.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.0/contracts/handler/CompatibilityFallbackHandler.sol
Audit artifact:
v1.4.0report: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/Safe_Audit_Report_1_4_0.pdf
Important changes:
- contract namespace changed from
Gnosis*toSafe* - factory removed risky/legacy APIs like
createProxy - setup path added stricter singleton existence checks
createChainSpecificProxyWithNonceadded to avoid cross-chain address replay where unwanted- contract-signature validation tightened by enforcing
dataHashconsistency - guard assignment now checks ERC-165 support
- event indexing improved for operational monitoring
Why it mattered:
- this release focused on reducing operational mistakes and ambiguous deployment behavior
New risks and caveats:
- callback-based deployment flows still had race assumptions
- guard and module design still had acknowledged liveness and front-running trade-offs
v1.4.1 and 1.4.1-x: ERC-4337 compatibility fix plus migration libraries#
Code:
ModuleManager.sol(v1.4.1): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.1/contracts/base/ModuleManager.solSafeMigration.sol(v1.4.1-2): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.1-2/contracts/libraries/SafeMigration.solSafeToL2Setup.sol(v1.4.1-2): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.1-2/contracts/libraries/SafeToL2Setup.solSafeToL2Migration.sol(v1.4.1-2): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.1-2/contracts/libraries/SafeToL2Migration.sol
What changed:
setupModulesremovedgasleft()dependency and used full forwarding semantics for compatibility in ERC-4337 contexts- migration helper contracts introduced to move between singleton variants and L2 compatible setups
Why it mattered:
- smart account infra had to coexist with ERC-4337 style constraints and cross-network replay/deployment workflows
New risks:
- migration helpers are power tools; assumptions around nonce/version/singleton must stay explicit
- indexers and backends can misinterpret migration event context if they assume more than what code guarantees
v1.5.0: extensible fallback, module guarding, cleanup of unsafe deployment assumptions#
Code:
Safe.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/Safe.solModuleManager.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/base/ModuleManager.solFallbackManager.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/base/FallbackManager.solExtensibleFallbackHandler.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/handler/ExtensibleFallbackHandler.solHandlerContext.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/handler/HandlerContext.solSafeProxyFactory.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/proxies/SafeProxyFactory.solSafeProxy.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/proxies/SafeProxy.sol
Audit artifacts:
- Ackee report: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/Safe_Audit_Report_1_5_0_Ackee.pdf
- Certora report: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/Safe_Audit_Report_1_5_0_Certora.pdf
Major feature and policy changes:
- extensible fallback handler subsystem introduced
- module guard interface introduced and wired
- overloaded
checkNSignaturesadded with executor context support - internal revert reason propagation improved
- legacy
sendandtransferusage removed in favor ofcall createProxyWithCallbackdeprecated and removed- EraVM specific support path deprecated as EVM compatibility strategy evolved
SafeToL2Migrationdeprecated in favor of updated setup/migration posture
Why it mattered:
- Safe expanded from a guarded smart account into a richer programmable policy substrate
What new risk came with that power:
- higher policy graph complexity means more misconfiguration states
- fallback method maps and domain verifiers create additional trust configuration vectors
- module guard logic can protect execution or accidentally deadlock it
The security trajectory is clear: stronger controls, but more moving parts to reason about.
Function-level evolution that changed the threat model#
Below is the practical diff map that matters most when auditing systems pinned to specific Safe versions.
| Version jump | Function or component | Why it changed | Security consequence |
|---|---|---|---|
v1.0.0 -> v1.1.1 | fallback and master-copy lifecycle controls | Istanbul and deployment trust concerns | reduced unsafe lifecycle assumptions, but introduced persistent fallback trust boundaries |
v1.1.1 -> v1.2.0 | gas overhead math in execution checks | EIP-150 correctness under relayers | closed nonce-burning relayer griefing vector |
v1.2.0 -> v1.3.0 | checkSignatures and checkNSignatures visibility and use | make signature logic reusable for modules/handlers | improved composability, but increased misuse blast radius if callers pass wrong context |
v1.2.0 -> v1.3.0 | guard hooks (checkTransaction, checkAfterExecution) | policy extensibility | policy enforcement became explicit, but guard DoS became a real liveness class |
v1.2.0 -> v1.3.0 | EIP-1271 moved to fallback compatibility layer | decouple evolving standard from core | improved upgrade agility, but handler correctness became critical |
v1.3.0 -> v1.4.0 | setGuard ERC-165 checks | reject malformed guard contracts | reduced accidental bricking by non-conforming guard targets |
v1.3.0 -> v1.4.0 | setupModules stricter target checks | prevent uninitialized or invalid setup flows | reduced setup-time misconfiguration risk |
v1.4.0 -> v1.4.1 | setupModules no gasleft() dependency | ERC-4337 compatibility | better bundler semantics, fewer gas-opcode edge assumptions |
v1.4.x -> v1.5.0 | createProxyWithCallback removed | callback bypass/front-run class | removed an API with known race assumptions |
v1.4.x -> v1.5.0 | module guard interface path | policy controls over module execution | better defense-in-depth, but more liveness complexity |
v1.4.x -> v1.5.0 | overloaded checkNSignatures with executor | safe use of pre-approved signatures from modules | less logic duplication and fewer context bugs |
v1.4.x -> v1.5.0 | send and transfer removed in favor of call | future gas schedule resilience | avoids stipend fragility, but reentrancy analysis burden increases |
Representative code links for this diff map:
v1.3.0core: https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/GnosisSafe.solv1.4.0core: https://github.com/safe-fndn/safe-smart-account/blob/v1.4.0/contracts/Safe.solv1.5.0core: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/Safe.solv1.5.0factory: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/proxies/SafeProxyFactory.solv1.5.0extensible handler: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/handler/ExtensibleFallbackHandler.sol
Why some features were removed, not fixed#
A recurring pattern in mature security engineering is feature retirement. Safe did this in multiple places:
- removing
createProxyWithCallbackrather than iterating forever on nonce/callback race subtleties - deprecating paths that made migration or cross-network assumptions brittle
- removing dependence on gas stipend behavior (
transferandsend) when protocol-level gas schedules can change
This is the right trade-off when:
- the feature is low usage
- the exploit or misuse class is persistent
- equivalent safer paths already exist
Safe’s v1.5.0 release clearly uses this strategy.
Release rationale in one sentence per major change#
This subsection is intentionally direct so engineers can map design intent to threat model updates.
- Chain-aware transaction hash domain was added so signatures are not accidentally replayable across chain domains.
- Transaction guards were added so teams can enforce policy before and after account execution, rather than relying purely on signer behavior.
- Compatibility fallback handler split was introduced so evolving standards logic can move faster than core execution logic.
- L2 event-heavy variant was added because indexing and observability requirements differ by gas market and execution environment.
- Factory API cleanup was done because deterministic deployment mistakes are a major source of operator error.
- ERC-165 guard checks were added because malformed guard contracts can brick systems even without malicious intent.
- Migration helpers were introduced because the ecosystem needed explicit operational paths between singleton and network compatibility variants.
- Module guard support was added because module execution had become large enough to require dedicated policy controls.
- Extensible fallback handler was added because teams needed richer programmable flows without forcing permanent core-contract growth.
Risk ledger by component, not by release#
A release-centric view is useful for chronology. A component-centric view is better for active audits.
| Component | Typical historical bug class | Best current control | Residual risk |
|---|---|---|---|
| Signature decoding and checks | malformed encoding assumptions, context mismatches | explicit signature type handling, executor-aware checkNSignatures | integration-layer misuse of packed signatures and domain context |
| Nonce and gas semantics | relayer griefing and nonce burn edge cases | corrected EIP-150 overhead handling and documented safeTxGas semantics | operational errors in off-chain gas estimation and relay strategy |
| Guard system | incorrect guard implementations causing liveness failure | ERC-165 interface checks and clearer guard hooks | accepted trade-off: broken guard can still DoS execution |
| Module execution path | privilege overreach and module front-run assumptions | module guard support and stricter governance process | high blast radius if module trust model is weak |
| Fallback dispatch | selector confusion and handler trust boundary flaws | explicit fallback handler contracts and context helpers | policy complexity in extensible handler maps |
| Factory and setup | uninitialized proxies, callback race assumptions | stricter setup checks and callback path deprecation | deployment script quality remains critical |
| Migration helpers | version/nonce/event assumption drift | explicit migration contracts and guarded preconditions | migration scripts and backend interpretation drift |
Gas semantics and safeTxGas are still often misunderstood#
Safe’s gas model changed for good reasons, and misunderstanding it still causes integration bugs.
Reference:
The core point:
- with refunds (
gasPrice > 0),safeTxGasbehaves as a strict cap-like execution budget for internal execution economics - without refunds (
gasPrice == 0),safeTxGascan behave more like a minimum-availability guard and failure semantics differ based onsafeTxGasandgasPrice
This is one of the most practical examples of how account abstraction UX and protocol security intertwine.
A note on docs and implementation drift#
One useful lesson from multiple audits is that documentation mismatches can produce security misunderstandings even when bytecode is correct.
Examples from the v1.5.0 cycle include:
- signature description mismatches fixed in docs
- event indexing and interpretation clarifications
- behavior notes added where a direct code change was not the right move
This is not paperwork. For high-value account systems, docs are part of the security surface, because most failures happen at integration boundaries.
Version delta matrix for operational teams#
If your team operates Safes across networks and vintages, this matrix is practical for migration planning.
| Area | Pre-1.3.0 bias | 1.3.x and 1.4.x bias | 1.5.0 bias |
|---|---|---|---|
| Signature strategy | core-heavy logic | core plus compatibility split | richer compatibility and extensibility with clearer context APIs |
| Deployment strategy | easier accidental divergence | stronger deterministic patterns | deterministic plus deprecated callback race paths |
| Policy controls | owners and modules | owners/modules plus tx guard | owners/modules plus tx guard plus module guard |
| Fallback behavior | basic callbacks and compatibility | richer context and compatibility | extensible routing and domain verifier model |
| Migration posture | ad hoc and painful | explicit migration helpers | migration helpers plus deprecations for old paths |
Practical exploit-path thought model for modern Safe stacks#
When you audit protocols integrating Safe as an admin or treasury account, this sequence catches real bugs:
If you threat-model only Safe core and not the integration code around it, you miss the bug class that currently causes the most real losses.
Chronological closure notes from audit cycles#
To avoid vague statements like “audited and secure,” this timeline maps concrete findings to concrete closure behavior:
v1.0.0formal verification cycle surfaced critical classes including execution reentrancy and gas/refund abuse concerns. These were treated as release-blocking classes and fixed before finalization.v1.1.0andv1.1.1reviews found no immediately exploitable direct vulnerability in reviewed deltas, but emphasized that delegatecall-capable account systems require strict provenance and deployment discipline.v1.2.0gas-validation review identified the EIP-150 overhead miscalculation that could let malicious relayers force internal failure and burn nonce progress. The report states the issue was fixed.v1.3.0April/May 2021 reviews reported no serious issues, with mostly optimization and ergonomic notes.v1.4.0report highlighted medium and warning classes such as broken guard DoS and operational caveats around module/front-run behavior. Some issues were fixed, some acknowledged as design trade-offs.v1.5.0Ackee report captured a medium-severity callback bypass front-running path and multiple lower-severity correctness issues; most were fixed and some were acknowledged/documented.v1.5.0Certora report contributed medium/low findings around ERC-777 behavior assumptions, dirty-bit handling, fallback semantics, and documentation consistency, with most fixes merged and a small set explicitly accepted.
This closure pattern is what mature security engineering looks like in high-value account software:
- detect real classes through multiple methods (manual review, formal properties, integration-driven audits)
- fix what is code-fixable
- document what is architectural trade-off
- remove APIs that are structurally fragile
Teams integrating Safe should copy this mindset: do not just consume release notes. Build internal upgrade playbooks that map each release delta to your exact module, guard, and fallback configuration.
Audit-fix ledger by version#
This table consolidates what was added and what had to be fixed or acknowledged.
| Version | Feature intent | Security issue class observed | Typical outcome |
|---|---|---|---|
v1.0.0 | reliable multisig baseline | reentrancy and gas/refund abuse classes surfaced in verification | critical classes fixed during formal verification cycle |
v1.1.x | lifecycle and deployment hardening | delegatecall state integrity caveats, master copy deployment trust, Istanbul gas behavior | mitigations, stronger deployment guidance, constructor hardening |
v1.2.0 | gas correctness under relayers | EIP-150 overhead miscalc enabled nonce-burning griefing | medium severity fix applied |
v1.3.0 | policy and compatibility architecture | guard liveness and fallback complexity became first-class risk domains | no serious findings in reviewed deltas, but stronger integration obligations |
v1.4.0 | deployment API cleanup and validation hardening | callback race assumptions, guard DoS risk, module front-run realities | mixed fixed and acknowledged trade-offs |
v1.4.1 | ERC-4337 setup and migration support | migration assumptions and helper misuse risk | bugfix + migration utilities, then iterative hardening |
v1.5.0 | extensibility and modernized interfaces | callback bypass class, dirty bits and fallback/method-map correctness, handler semantics | most findings fixed; some documented or explicitly accepted |
Audit references:
- Formal verification (
v1.0.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.0.0/docs/Gnosis_Safe_Formal_Verification_Report_1_0_0.pdf v1.1.0/v1.1.1: https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/docs/Gnosis_Safe_Audit_Report_1_1_1.pdfv1.2.0: https://github.com/safe-fndn/safe-smart-account/blob/v1.2.0/docs/Gnosis_Safe_Audit_Report_1_2_0.pdfv1.3.0Apr: https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/docs/GnosisSafeApr2021.pdfv1.3.0May: https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/docs/GnosisSafeMay2021.pdfv1.4.0: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/Safe_Audit_Report_1_4_0.pdfv1.5.0Ackee: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/Safe_Audit_Report_1_5_0_Ackee.pdfv1.5.0Certora: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/Safe_Audit_Report_1_5_0_Certora.pdf
Deep technical slices that matter in real audits#
1) Signature engine evolution and why checkNSignatures overload matters#
Relevant code:
Safe.solsignature checks (v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/Safe.sol- signature docs: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/signatures.md
The overloaded method that accepts executor context solves a real integration pain point: pre-approved hash flows from modules and guards.
Without executor context, modules either duplicate logic or make brittle assumptions around msg.sender-coupled approval semantics.
Risk that remains:
- integrators can still misuse signature packing, ordering, or context assumptions and accidentally widen authority.
2) Guard and module guard are security controls and liveness risks#
Relevant code:
GuardManager.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/base/GuardManager.solModuleManager.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/base/ModuleManager.solIModuleGuard.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/base/ModuleManager.sol
Guards are not “just checks.” They are externally programmable policy engines invoked in critical execution paths.
If check* logic reverts unexpectedly, governance and operations can halt.
3) Fallback handler evolution increased power and review burden#
Relevant code:
FallbackManager.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/base/FallbackManager.solCompatibilityFallbackHandler.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/handler/CompatibilityFallbackHandler.solExtensibleFallbackHandler.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/handler/ExtensibleFallbackHandler.sol
Fallback logic moved from basic token callback compatibility to a richer extensible method and domain verification system.
Security implication:
- policy mistakes in method registration or domain binding can produce subtle auth bugs
- this is now a must-review surface in any Safe-based protocol audit
4) Factory and setup remain critical trust boundaries#
Relevant code:
SafeProxyFactory.sol(v1.4.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.0/contracts/proxies/SafeProxyFactory.solSafeProxyFactory.sol(v1.5.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/contracts/proxies/SafeProxyFactory.sol
The createProxyWithCallback deprecation in v1.5.0 is a textbook case of retiring a fragile API surface once a front-running class is understood.
This was directly captured and then closed in the v1.5.0 audit/fix cycle.
5) Migration tooling improves ops while increasing assumption load#
Relevant code:
SafeMigration.sol(v1.4.1-2): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.1-2/contracts/libraries/SafeMigration.solSafeToL2Setup.sol(v1.4.1-2): https://github.com/safe-fndn/safe-smart-account/blob/v1.4.1-2/contracts/libraries/SafeToL2Setup.sol
Migration helpers make upgrades and cross-network normalization feasible, but migrations are state surgery. They are never low-risk by default.
You should treat migration code as privileged maintenance logic with same scrutiny as upgrade admin contracts.
6) Storage layout discipline and hashed slots reduced collision risk#
Relevant guidance:
Safe’s hashed slot guidance is a practical defense against storage collisions in evolving proxy layouts.
This is not a silver bullet, but it is a strong pattern when extensions and migrations keep expanding.
Battle-tested vs fixed all old problems#
The short answer:
- Safe is battle-tested
- Safe has not fixed all old and future problems forever
The longer answer:
What battle-tested means in Safe’s case#
- many years of production use with high-value wallets
- repeated external audits across major and patch releases
- formal verification integration for critical properties
- demonstrated willingness to deprecate or remove fragile APIs
What it does not mean#
- every extension composition is automatically safe
- every guard/module/fallback combo is liveness-safe
- migration pathways are impossible to misuse
- operational assumptions cannot drift
This cycle is healthy engineering maturity. It is not a terminal state.
Practical checklist for auditing modern Safe integrations#
If you audit a protocol that depends on Safe v1.4.x or v1.5.x, these checks produce real findings:
- Guard liveness and recovery paths
- Can a broken guard permanently freeze execution?
- Is there a safe fallback recovery process tested in scripts, not only documented?
- Module authority boundaries
- Are module permissions scoped, monitored, and revocable?
- Could a module front-run disable/removal workflows?
- Fallback handler method/domain correctness
- Which selectors are routed where?
- Are domain verifiers aligned with actual message domain intent?
- Signature context usage
- Are integrations using the executor-aware signature checks where needed?
- Are pre-approved hash semantics constrained to expected callers?
- Deployment flow assumptions
- Does system logic rely on callback behavior from deprecated factory paths?
- Is singleton existence and initialization success validated in deployment scripts?
- Migration assumptions
- Are version and nonce preconditions enforced on-chain and re-validated off-chain?
- Are events used as hints or as authority?
- Token and callback edge behavior
- Are token callback handlers intentionally enabled?
- Can token callback semantics lock assets or create implicit trust edges?
- Event-based indexer dependence
- Are downstream systems robust to ordering and semantic nuance?
- Do alerts watch state, not just event text?
Final verdict on Safe evolution#
Safe’s evolution from v1.0.0 to v1.5.0 is a strong case study in real security engineering:
- core transaction integrity got much stronger
- deployment and compatibility hazards were steadily reduced
- extensibility increased practical utility and ecosystem reach
- each extensibility step introduced fresh policy and composition risk
The right way to think about modern Safe is:
- core is mature
- extensions are powerful
- integration quality is the deciding factor
In other words, Safe is no longer just a multisig contract. It is an account platform. Treat every enabled extension as part of your protocol’s trusted computing base.
Source map by version and docs#
Code tags:
v1.0.0: https://github.com/safe-fndn/safe-smart-account/tree/v1.0.0/contractsv1.1.1: https://github.com/safe-fndn/safe-smart-account/tree/v1.1.1/contractsv1.2.0: https://github.com/safe-fndn/safe-smart-account/tree/v1.2.0/contractsv1.3.0: https://github.com/safe-fndn/safe-smart-account/tree/v1.3.0/contractsv1.4.0: https://github.com/safe-fndn/safe-smart-account/tree/v1.4.0/contractsv1.4.1: https://github.com/safe-fndn/safe-smart-account/tree/v1.4.1/contractsv1.4.1-2migration libs: https://github.com/safe-fndn/safe-smart-account/tree/v1.4.1-2/contracts/librariesv1.5.0: https://github.com/safe-fndn/safe-smart-account/tree/v1.5.0/contracts
Docs and design notes:
- What is Safe: https://docs.safe.global/home/what-is-safe
- Smart account overview: https://docs.safe.global/advanced/smart-account-overview
- Smart account concepts: https://docs.safe.global/advanced/smart-account-concepts
- Modules: https://docs.safe.global/advanced/smart-account-modules
- Guards: https://docs.safe.global/advanced/smart-account-guards
- Fallback handler: https://docs.safe.global/advanced/smart-account-fallback-handler
- Signatures: https://docs.safe.global/advanced/smart-account-signatures
- Migrations: https://docs.safe.global/advanced/migrations
- Audits page: https://docs.safe.global/advanced/smart-account-audits
- Guidelines: https://github.com/safe-fndn/safe-smart-account/blob/main/docs/guidelines.md
Audit PDFs:
- Formal verification (
v1.0.0): https://github.com/safe-fndn/safe-smart-account/blob/v1.0.0/docs/Gnosis_Safe_Formal_Verification_Report_1_0_0.pdf v1.1.0: https://github.com/safe-fndn/safe-smart-account/blob/v1.1.0/docs/Gnosis_Safe_Audit_Report_1_1_0.pdfv1.1.1: https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/docs/Gnosis_Safe_Audit_Report_1_1_1.pdfv1.2.0: https://github.com/safe-fndn/safe-smart-account/blob/v1.2.0/docs/Gnosis_Safe_Audit_Report_1_2_0.pdfv1.3.0April: https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/docs/GnosisSafeApr2021.pdfv1.3.0May: https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/docs/GnosisSafeMay2021.pdfv1.4.0: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/Safe_Audit_Report_1_4_0.pdfv1.5.0Ackee: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/Safe_Audit_Report_1_5_0_Ackee.pdfv1.5.0Certora: https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/docs/Safe_Audit_Report_1_5_0_Certora.pdf