migration · Safe → LSP0

Migrate from Safe (Gnosis Safe) to Universal Profile

quotable answer

Moving custody from a Safe multisig to a LUKSO Universal Profile maps the multisig-signer model to LSP6 Key Manager controllers. Each Safe owner becomes an LSP6 controller address with a permission bitfield (CALL, SETDATA, TRANSFERVALUE, ADDCONTROLLER, SIGN); threshold semantics become LSP6 policy or an inline verifier via LSP20. Assets and ENS transfer as normal (Universal Profiles are contracts, so ownership transfers change the account behind the address). Recovery is redesigned end-to-end — Safe's owner-management model doesn't map to LSP11 guardian-voting directly.

Step 1 — model the Safe as permissions

Take your Safe’s owner set and threshold and translate it into LSP6 vocabulary. A threshold of “3 of 5” doesn’t directly exist in LSP6 (controllers are individual, not aggregated). Two patterns:

  • Recovery contract — deploy a contract that enforces the threshold and is itself registered as the controller with EDITPERMISSIONS on the profile. Day-to-day controllers do day-to-day work; the recovery contract handles ownership-level changes.
  • Day-to-day single controller + cold multisig — flatten the daily workflow to one controller; keep the Safe (or a new threshold contract) as the cold recovery layer.

Step 2 — deploy the Universal Profile

Use the standard lsp-factory.js or equivalent deploy script. Set LSP3 profile metadata. Add controllers per the design from step 1.

Step 3 — transfer assets

For each asset class:

  • Native LYXSafe.execTransaction → profile.execute(0, profile, value, "")
  • ERC-20 / LSP7Safe → token.transfer(profile, balance)
  • NFTsSafe → token.safeTransferFrom(safe, profile, id) (or LSP8 equivalent)

If the Safe holds many assets, write a sweep contract that batches the transfers.

Step 4 — update integrations

Identify every protocol that knows the Safe’s address: vesting contracts, multi-sig DAOs, subscriptions, allowance grants. Update each one to point to the new profile address.

Step 5 — sunset the Safe

Once nothing material lives in the Safe, transfer its remaining gas dust out and consider it historical. Leave it deployed — destroying multisig contracts is unsupported and dangerous.

Gotchas.

  • Multi-sig threshold semantics don't map 1:1 to LSP6 — model it as a recovery controller contract that enforces the threshold and is itself registered as an LSP6 controller with EDITPERMISSIONS.
  • Asset transfer is many separate transactions unless the Safe owns the assets through a sweep contract that batches outbound moves.
  • Anything connected to the Safe's address (vesting schedules, allowance grants, on-chain memberships) needs to be re-pointed to the new profile address — addresses don't migrate, the references do.
  • Safe modules have their own permission shape; LSP6 controllers + LSP17 extensions are the LSP-side equivalents. Map each module to its closest LSP primitive deliberately.

Verify before ship.

  • All assets transferred to the Universal Profile
  • Old Safe paused (no longer holds material assets)
  • Controllers + permissions configured on the new profile
  • Recovery policy in place — at least one cold controller with EDITPERMISSIONS
  • Off-chain integrations updated to the new address

Continue at docs.lukso.tech.