Overview
As the smart account ecosystem evolves, Safe periodically releases new versions of the Safe Singleton contract. Each Safe Smart Account is implemented as a SafeProxy, which delegates all logic to a Singleton contract whose address is stored in storage slot0.
Existing SafeProxy contracts can be upgraded to point to a newer Singleton implementation. This process preserves the Safe’s address, owners, and configuration, but requires an explicit migration transaction approved by the Safe owners. The migration is performed via delegatecall and must be executed with care.
This guide walks through a step-by-step example of migrating an existing SafeProxy to a newer Singleton using the SafeMigration contract and the Safe Protocol Kit.
Migration process
The first step in any migration is identifying the address of the target Singleton contract. Safe provides the SafeMigration contract, which updates the Singleton address stored in a SafeProxy.- SafeMigration source:
https://github.com/safe-fndn/safe-smart-account/blob/main/contracts/libraries/SafeMigration.sol - Official SafeMigration deployments are listed in the
Safe Deployments repository
SafeMigration contract methods
The currently available SafeMigration contract supports upgrades to Safe Singleton v1.4.1.migrateSingleton()
Updates the SafeProxy to point to the new L1 Singleton implementation.
migrateWithFallbackHandler()
Updates both the Singleton implementation and the fallback handler.
migrateL2Singleton()
Updates the SafeProxy to point to the L2 Singleton implementation.
migrateL2WithFallbackHandler()
Updates the L2 Singleton implementation and the fallback handler.
Requirements
- An already deployed SafeProxy contract
- Compatibility between the existing SafeProxy and Singleton v1.4.1
- For simplicity, this example assumes a Safe with a threshold of 1
Migration tutorial
1
Setup a new project
2
Add script commands in package.json
The
SafeMigration contract provides four methods for migration. Update the package.json to add the following script commands:
The migration script will read the argument and choose the appropriate method to execute.3
Create a migration script
Create a new file
src/migrate.ts and add the following code:4
Define variables
Define the constants required for the migration script. Replace the placeholders with the actual values.
5
Build `calldata` for the migration
6
Initialize the Protocol Kit
7
Create and execute transaction
8
Final script
9
Run the migration script
Run one of the below commands:
Further actions
- The migration script can be extended to support Safe Account migration with a threshold of more than one. Users can use the Safe API Kit to propose the transactions, fetch transaction data, and sign them.
- The source code for this script is available in the Safe Migration Script repository.