SlowMist Analysis: Safe Dilemma, Can Guard Reconstruct the Contract Babel?

This article is machine translated
Show original
Here is the English translation of the text, with the specified terms retained and not translated:

The future of digital asset management will be a co-evolutionary process of smart contract security mechanisms and the continuous evolution of attack and defense.

Author: flush, kong, Slow Fog Security Team

Editor: Liz

Background

On February 21, 2025, the cryptocurrency industry experienced the most severe asset management crisis in history. The on-chain multi-signature wallet of the trading platform Bybit was breached in a targeted attack, and nearly $1.5 billion in assets quietly disappeared through a "legally signed" transaction. Subsequent on-chain analysis showed that the attacker obtained multi-signature privileges through a sophisticated social engineering attack, used the delegatecall function of the Safe contract to inject malicious logic, and ultimately bypassed the multi-signature verification mechanism to transfer the funds to an anonymous address.

This incident exposed a cruel reality: "Multi-signature" does not mean "absolute security". Even the Safe multi-signature wallet, a security mechanism, still faces the risk of being breached if it lacks additional protective measures. This is not the first attack case targeting the Safe multi-signature wallet. Last year, WazirX (lost $230 million) and Radiant Capital (lost $50 million) also encountered similar attack methods. As analyzed in the article Slow Fog: The Hacking Techniques and Questions Behind the $1.5 Billion Theft from Bybit, the Safe multi-signature wallet attack events exhibit the following technical commonalities:

  • Over-reliance on the signature mechanism: Placing all security responsibilities on private key management.
  • Lack of dynamic defense: Absence of real-time risk scanning before transaction execution.
  • Coarse-grained permission control: Failure to establish a whitelist mechanism for high-risk operations like delegatecall.
(Bybit Theft Process: Using Safe v1.1.1)

The core issue of this series of events is not the Safe contract itself, but the security vulnerabilities in the integration process of the entire system, especially in the front-end verification link. This prompts us to consider: How can we strengthen the protective capabilities of multi-signature wallets through additional security mechanisms of Safe?

Safe

Safe is a multi-signature (Multi-Sig) wallet, primarily used for the secure storage and transfer of high-value assets and cryptocurrencies. As the infrastructure for decentralized asset management, it ensures the security of fund operations through a multi-party verification mechanism, preventing a single administrator or hacker from exploiting single points of failure to conduct malicious operations. It is widely used in DAO governance, corporate fund custody, decentralized fund pools, and other scenarios. The contract is developed by the Safe (formerly Gnosis Safe) team and is the current industry standard on-chain asset management solution. The contract implements structured data signing based on the EIP-712 standard, which enhances the security and verifiability of transaction data.

Core Usage

  • Secure Fund Management: The contract requires multiple pre-set owners (Owners) to jointly confirm transactions before execution, effectively preventing single-point failures or malicious operations, and ensuring fund security.
  • Transaction Execution and Management: Through the built-in multi-signature verification mechanism, the contract can execute outbound transfers, call other contracts, or handle complex business logic when the signature threshold conditions are met, supporting token and native coin payments and fee compensation.
  • Modular Expansion: The contract adopts a modular design, inheriting and combining multiple management modules (such as OwnerManager, ModuleManager, GuardManager, FallbackManager, etc.), making its functionality flexible and easy to extend, and providing customized support for different application scenarios.

Function Analysis

The execTransaction function executes transactions that have undergone multi-signature verification:

  • Calculates the unique hash value of the transaction (combining transaction parameters, nonce, etc.);
  • Verifies the validity of all signatures, ensuring that each signature comes from a legitimate owner or pre-approved address;
  • Calls the business logic of the target address, and records the success or failure status through events after the transaction is executed;
  • Supports flexible gas fee handling to ensure accurate calculation of transaction costs when paying compensation.

The checkContractSignatures & checkNSignatures functions verify the signature data of transactions or messages:

  • Separately handle EOA account signatures, contract signatures (EIP-1271), and pre-approved hashes;
  • Ensure that the signatures are arranged in the order of the owners, and that each signature comes from a valid address, to prevent replay attacks and signature tampering.

The getTransactionHash function generates the transaction hash, which is used for signature verification and to prevent replay attacks:

  • Utilize the EIP-712 standard to structurally hash the transaction data;
  • Use inline assembly to optimize memory operations and improve computational efficiency;
  • Combine the current nonce value to ensure the uniqueness of each transaction.

The handlePayment function handles the gas compensation payment during the execution of the transaction:

  • Calculate the payment amount based on the actual gas consumed and the base fee;
  • Support payment in ETH and other tokens to ensure accurate fee compensation.


onBeforeExecTransaction is an internal virtual hook function, called before the execTransaction function is executed. The purpose of this function is to allow child contracts that inherit the Safe contract to perform custom logic processing before the transaction is executed. The received parameter set includes:

  • to: target address - the contract or account address that the transaction is calling
  • value: Ether value - the amount of Ether sent with the transaction
  • data: data payload - the call data containing the function selector and parameters
  • operation: operation type - determines whether it is a CALL or DELEGATECALL
  • safeTxGas: transaction gas limit - the amount of gas reserved for the transaction execution
  • baseGas: base gas - the gas cost independent of the transaction execution
  • gasPrice: gas price - the gas price used to calculate the transaction fee compensation
  • gasToken: gas token - the token address used to pay the transaction fee
  • refundReceiver: refund receiver - the address that receives the transaction fee compensation
  • signatures: signature collection - the owner's signature data for the transaction


Although the multi-signature wallet contract, with its rigorous security design and flexible modular structure, provides an efficient and secure solution for digital asset management, realizing end-to-end security control from transaction initialization to final execution, and has become an important tool for blockchain security management, it is also worth noting that victims often rely on hardware wallets for signing, and some hardware devices have poor display effects for structured data signing, which can easily lead to users being unable to accurately identify transaction data in a short period of time, resulting in the risk of "blind signing". In addition to optimizing hardware and its data display effects, measures such as adding multi-confirmation, smart prompts, and enhancing signature verification tools can also be explored to further reduce the security risks brought by blind signing.

Safe Guard

The important security feature introduced in the 1.3.0 version of the Safe contract - the Safe Guard mechanism. This mechanism aims to provide additional restrictive conditions for the standard n-out-of-m multi-signature scheme, further enhancing transaction security. The core value of Safe Guard lies in its ability to perform security checks at different stages of transaction execution:

  • Pre-transaction check (checkTransaction): The Guard mechanism can programmatically check all parameters of the transaction before execution, ensuring that the transaction complies with the pre-set security rules.
  • Post-execution check (checkAfterExecution): After the transaction is executed, the Guard will also perform additional security verification, checking whether the final state of the Safe wallet is as expected.

Architectural Analysis

In Safe, multi-signature transactions are generally executed through the execTransaction function. When the Safe Guard is enabled, when the user executes a multi-signature transaction, the Safe contract will call the checkTransaction function of the Guard contract to perform a pre-transaction check, and when the multi-signature transaction is completed, the Safe contract will call the checkAfterExecution function of the Guard contract to check the execution result of the transaction. The specific implementation is as follows:

function execTransaction(        ...    ) external payable override returns (bool success) {        ...        address guard = getGuard();        {            if (guard != address(0)) {                ITransactionGuard(guard).checkTransaction(                    // Transaction info                    to,                    value,                    data,                    operation,                    safeTxGas,                    // Payment info                    baseGas,                    gasPrice,                    gasToken,                    refundReceiver,                    // Signature info                    signatures,                    msg.sender                );            }        }        ...        {            ...            success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);            ...        }        {            if (guard != address(0)) {                ITransactionGuard(guard).checkAfterExecution(txHash, success);            }        }    }

When the Safe contract executes a multi-signature transaction pre-check through the Guard mechanism, its checkTransaction function will receive the complete transaction context data, including the target contract address, call method, execution data (such as delegatecall), owner signature information, Gas configuration and payment information. This mechanism allows developers to implement multi-dimensional risk control strategies, such as contract whitelist management (restricting interactable addresses), function-level permission management (disabling high-risk function selectors), transaction frequency limits, and dynamic rules based on fund flows. By reasonably configuring the Guard strategy, the attack path of attackers exploiting non-contract-level attacks can be effectively blocked.

Against the backdrop of the continuous emergence of security incidents, various parties are increasingly concerned about the security of multi-signature wallet contracts. Hardware wallet providers such as KeyStone, OneKey, and RigSec have called for enhancing the parsing and protection capabilities of the Safe contract to prevent similar risks from occurring again. After the Bybit incident, many projects have begun to focus on the Safe contract and explore upgrade and extension solutions based on the Guard mechanism. Among them, there are innovative applications based on the Guard mechanism, building a middle-layer security solution based on the Safe multi-signature wallet, providing additional security guarantees between the underlying assets and user assets. Its core function is to achieve fine-grained transaction checks by passing the target contract, call method, execution data, owner signature information, payment information, and gas information involved in the Safe multi-signature transaction into the checkTransaction function, including whitelist contract calls, whitelist function operations, whitelist transfer targets, transaction frequency control, and other permission control.

It is worth noting that Safe itself only provides Guard management and callback functions, and the actual multi-signature transaction check logic is implemented by the user, and its security depends on the quality of the Guard implementation. For example, Solv Guardian has expanded on this idea, configuring a dedicated Guardian for each Vault to specify the allowed target addresses and operation permissions, realizing the three key permission control elements of specifying allowed contracts, defining allowed function operations, and ACL verification. At the same time, a separated governance mechanism is adopted, with the Vault Guardian responsible for execution and the Governor controlling the governance rights, ensuring that even if the Guardian has problems, remedial measures can be taken in time to protect user assets. A similar design concept is also applied in the SecurityControlModule of Elytro, where the preExecute function intercepts critical operations and uses a whitelist mechanism to perform fine-grained control over high-risk operations such as module installation, hook setting, and validator management, ensuring that only trusted contracts can be added to the system, providing persistent security guarantees for the wallet.

In the attack chain of the Bybit incident, if the Safe contract had deployed a reasonably configured Guard mechanism, the malicious delegatecall initiated by the attacker through execTransaction would have been intercepted by multiple strategies in the pre-check stage: the Guard's checkTransaction function would first identify the delegatecall operation type and trigger the disable rule (such as forcibly limiting the operation to be a normal call), then parse the data field to detect the unusual contract address (0x4622...7242) and high-risk function selector, and directly roll back the transaction through the pre-set contract whitelist and function blacklist strategy, ultimately forming a "strategy interception → logic blocking" defense system, completely blocking the path of storage tampering and fund transfer.

(When using Safe version ≥ v1.3.0, the verification operation of the Safe Guard module https://excalidraw.com/#room=fd1df67dd09b3dab6bd8,Q1jeb1MZW7vwbY4NuxaV5A)

In general, Safe only provides the Guard function after version 1.3.0, although Guard can provide extremely fine-grained multi-signature transaction checks, users have a relatively high threshold when using the Guard function. They need to implement the Guard check logic themselves, and a rough or defective Guard implementation may not help users improve the security of their Safe wallet, so security auditing of the Guard implementation is necessary. Undoubtedly, a secure and appropriate Guard implementation can greatly improve the security of the Safe wallet.

Conclusion and Outlook

The attack on Bybit highlights the importance of timely updating security infrastructure. Bybit used the v1.1.1 (<1.3.0) version of the Safe contract, which means they could not use the Guard mechanism, a key security feature. If Bybit had upgraded to the 1.3.0 or higher version of the Safe contract and implemented appropriate Guard mechanisms, such as specifying a whitelist of addresses to receive funds and performing strict access control verification of contract functions, they might have avoided this loss. Although this is just a hypothesis, it provides important ideas for future asset security management.

The Safe Guard mechanism is like a smart security check system installed on the digital asset safe, and its effectiveness depends on the rigor of the rule design and the quality of the implementation. Faced with increasingly sophisticated attack methods, we need:

  • Automated verification: Establish an automated transaction verification mechanism
  • Dynamic policy adjustment: Adjust security policies in real-time based on threat intelligence
  • Multi-layer defense: Build a deep defense system by combining multiple security mechanisms
  • Continuous auditing: Regularly conduct security audits of the Guard implementation

The future of digital asset management will be a co-evolutionary process of smart contract security mechanisms and the ongoing attack-defense evolution. Only by integrating security concepts into every link can we build a real security barrier in the "spear" of hackers and the "shield" of defenders.

References

[1] https://github.com/safe-global/safe-smart-account/blob/v1.3.0/CHANGELOG.md[2] https://docs.safe.global/advanced/smart-account-guards[3] https://docs.solv.finance/security/solv-guard[4] https://github.com/safe-global/safe-smart-account/tree/main/contracts/examples/guards[5] https://github.com/Elytro-eth/soul-wallet-contract/blob/v0.6/contracts/modules/securityControlModule/SecurityControlModule.sol

Disclaimer: As a blockchain information platform, the articles published on this site only represent the personal views of the authors and guests, and are not related to the position of Web3Caff. The information in the articles is for reference only and does not constitute any investment advice or offer, and please comply with the relevant laws and regulations of your country or region.

Source
Disclaimer: The content above is only the author's opinion which does not represent any position of Followin, and is not intended as, and shall not be understood or construed as, investment advice from Followin.
Like
Add to Favorites
Comments
Followin logo