---
id: TIP-1113
title: In-Place Account Migration
description: Lets an existing account adopt configurable ownership while retaining its address and permissions.
authors: Tanishk Goyal (@legion2002), Jake Moxey (@jxom)
status: Draft
related: TIP-1114, TIP-1107, TIP-1108, TIP-1109, TIP-1111, TIP-1112, TIP-1137
protocolVersion: T14
---

# TIP-1113: In-Place Account Migration

## Abstract

This TIP lets an existing account adopt configurable ownership at the same address. The original root key authorises a sole-call migration that installs a version-one configuration and permanently disables bare root authority at T14.

Migration preserves balances, application storage and permissions, and nonce state apart from normal transaction effects. Access keys granted by the migrating account retain their permissions and spending state. The new owners can later rotate through TIP-1109 without changing the account address.

The account must have no code, EIP-7702 delegation, or existing configuration. Grants it received as a primitive delegate become unusable under the current key-type checks. Migration does not provide the CREATE2 recovery guarantee of newly derived accounts, or retire the root on other chains.

## Motivation

Existing users need key rotation while keeping their balances, allowances, roles, and application history at the same address. [TIP-1104](https://github.com/tempoxyz/tempo/pull/7445) proposed in-place migration; this TIP carries that capability into the configurable-account design.

## Assumptions

| Assumption | Consequence if violated |
|---|---|
| TIP-1108 commitments, TIP-1109 updates, TIP-1111 access keys, and TIP-1114 configurable account authorisation activate with migration at T14. | A migrated account could lack storage, signing, rotation, or delegation support. |
| TIP-1112 root disablement activates at the same fork. | The original root could bypass the new owners after migration. |

# Specification

## Overview

**Migration** installs the first owner configuration on an existing account. The root authorises the transition; the configuration controls subsequent direct transactions.

1. **Prepare:** choose the owners and threshold, and check that the account is eligible.
2. **Approve:** the original root signs a transaction whose only call is `upgradeAccount`.
3. **Migrate:** validate the configuration, store its version-one commitment, and emit `AccountUpgraded`.
4. **Confirm:** verify the commitment in canonical state and use the new owners for subsequent direct transactions.

| State | Before migration | After successful migration |
|---|---|---|
| Configuration commitment | Zero | Nonzero, at version one |
| Direct authority | Primitive root key | Current owner quorum |
| Address and application state | Existing account | Preserved |
| Grants made by this account | Existing permissions and spending state | Preserved |
| Primitive grants received from others | Usable if otherwise valid | Unusable under the current type checks |

For example, a user migrates to a 1-of-1 configuration with their existing key at weight one and threshold one. The key then signs through a version-one multisig witness. A later owner update can replace it. If migration fails, the commitment and event roll back and the original root remains authoritative.

Migration covers this chain's account authority. It provides no CREATE2 recovery guarantee on another chain and does not disable the root there.

## Migration transition

### Who can migrate

- `upgradeAccount` must be the only top-level call.
- Require `msg.sender == tx.origin == tx.from`.
- Require a primitive outer signature from the root key.
- Do not allow access-key authority.
- Reject an authorization list or `key_authorization` in the same transaction. Migration must not hide simultaneous delegation changes.
- Allow ordinary fee sponsorship.

The account must have empty code, no EIP-7702 delegation, and a zero configuration commitment.

### Installing the configuration

Construct the initial migrated configuration as follows:

```text
salt = keccak256("tempo:configurable-account:upgrade" || account)
config = (salt, version = 1, threshold, owners)
```

1. Encode the domain as raw ASCII and `account` as 20 bytes.
2. Validate the configuration using TIP-1114.
3. Require its TIP-1108 hash to be nonzero.
4. Store that hash and emit `AccountUpgraded`.

Later updates follow TIP-1109.

The original root MAY be an explicit owner.

The root's signed calldata authorizes the chosen configuration. No additional owner signature is required onchain.

| Outcome | Authority and state | Next action |
|---|---|---|
| Migration succeeds | Version-one commitment and `AccountUpgraded` remain. Bare root authority is disabled. | Use the current owner configuration; the account cannot migrate again. |
| Migration call fails | Revert the commitment and event. The original root authority remains unchanged. Normal transaction fee and nonce rules still apply. | Recheck eligibility, configuration, and nonce before resubmitting with the root. |

### Errors and gas

Check failures in this order:

1. Sole-call and authorization restrictions: `UpgradeMustBeOnlyCall`.
2. Root authority: `PrimitiveRootRequired`.
3. Code or delegation: `AccountHasCode`.
4. Existing commitment: `AccountAlreadyConfigurable`.
5. Configuration validity: `InvalidConfig`.

Charge:

- Ordinary precompile, input, and event costs.
- Standard Keccak gas for the salt and commitment.
- TIP-1108 account access and the zero-to-nonzero commitment write.
- TIP-1000's new-account cost, including its state-gas portion, if the commitment write creates the sender.

The commitment write creates the sender if the sender is empty (zero nonce, zero balance, no code) at the write. A TIP-20 balance does not make the sender nonempty. The cost is the one TIP-1114 registration charges, but `upgradeAccount` charges it during execution rather than in intrinsic gas.

- With `nonce_key == 0`, or a transaction type without a nonce key, charge nothing more. The protocol nonce write creates the sender before the call, and the `nonce == 0` charge pays for it.
- With a 2D or expiring nonce, charge it. The sender is still empty at the write. The `nonce == 0` charge pays for the new nonce-key slot, and expiring-nonce gas pays for replay protection.

Fee sponsorship does not change this charge.

## Changes to other components

Migration preserves the account's:

- Address and balances.
- Application storage and permissions.
- Nonce state, apart from normal transaction effects.

Existing access keys granted by the migrating account keep their expiry, limits, scopes, spending counters, and revocation state.

- [TIP-1137](https://github.com/tempoxyz/tempo/pull/8204) removes admin key-management authority at T14. The proposal retains unrestricted spending for pre-T14 admin grants until revoked. Migration does not restore their key-management authority.
- Delegates whose own root authority is retired still follow TIP-1111 and TIP-1112.

From the next transaction, direct signing requires a matching witness at version one or later. TIP-1112 rejects bare root signatures.

## Delegation compatibility

Migration makes primitive grants received from other accounts unusable under the current rules. Owner rotation of an already configurable account does not have this effect.

For example, treasury A grants B $100/day, recording B's address and primitive signature type. B migrates at the same address: its root is retired, but the grant does not accept its configured owners' signatures. A cannot reauthorise B at that address because AccountKeychain rejects reused key IDs, even after revocation.

The proposed resolution is to make grants independent of key type:

- Remove the onchain check that the signature type matches the type stored in the grant.
- Bind the grant to B's address and validate its current authority. A nonzero configuration hash requires its configured owners' approvals.
- Keep the grant's permissions, expiry, spending counters, and revocation state unchanged.

Adoption requires updating TIP-1111's signature-type checks and migration rules.

## Interfaces

Extend the TIP-1109 precompile at the same address with:

```solidity
interface IConfigurableAccountUpgrade {
    struct ConfigurableAccountOwner {
        address owner;
        uint8 weight;
    }

    /// Migrate msg.sender using threshold and sorted owners.
    /// Return the stored hash.
    /// Only a direct primitive-root transaction with upgradeAccount as its sole
    /// call may invoke this. Reverts if already configured, code-bearing,
    /// unauthorized, or given an invalid configuration. Access keys are retained.
    function upgradeAccount(
        uint8 threshold,
        ConfigurableAccountOwner[] calldata owners
    ) external returns (bytes32 commitment);

    event AccountUpgraded(
        address indexed account,
        bytes32 indexed commitment,
        bytes32 salt,
        uint8 threshold,
        ConfigurableAccountOwner[] owners
    );

    error PrimitiveRootRequired();
    error UpgradeMustBeOnlyCall();
    error AccountAlreadyConfigurable();
    error AccountHasCode();
    error InvalidConfig();
}
```

# Tooling

- Show the new owners, threshold, retained access keys, and permanent root disablement before migration.
- Check that the proposed quorum can sign locally before submission. This is a wallet check, not an additional onchain signature.
- Disclose if access-key enumeration is incomplete. Users wanting quorum-only control must revoke unwanted grants separately.
- Show that primitive grants received from other accounts become unusable under the current [delegation rules](#delegation-compatibility).
- Show that outstanding permits signed by the retiring root become invalid under TIP-1112, including signatures created before migration. Vouchers on channels it already funded stay redeemable, but those channels cannot be topped up, and new channels need a non-retired authorized signer.
- If the retiring root may be compromised, prompt the user to close channels it funded, because the old key can still sign vouchers against their remaining deposits.
- Warn that migration does not retire the root key on zones. Funds the account holds on zones stay under the old key, so move them before migrating if that key may be compromised.
- Verify the expected commitment in finalized canonical state and retain the configuration from `AccountUpgraded`.
- Then use TIP-1114 for direct signing and keep valid access-key flows available.

# Observability

`AccountUpgraded` records a successful migration's configuration and commitment. Later `ConfigurableAccountConfigUpdated` events extend the configuration history. Match the latest configuration to the account's commitment in finalized canonical state.

A failed migration call leaves no configuration write or migration event. An absent event alone does not distinguish a pending transaction from a failed one; check the transaction result and current commitment before retrying.

# Threat Model

Migration transfers direct account authority from the original root to the chosen owner configuration.

| Actor | Trust |
| --- | --- |
| Original root holder | Trusted until migration succeeds. A compromised root can race the intended migration or install attacker-controlled owners. |
| Migration wallet | Trusted to show the chosen owners, threshold, and retained grants. The root's signed calldata authorises the transition; no additional on-chain approval from the new owners is required. |
| New owners | Trusted to retain usable keys sufficient to meet the threshold. Configuration validation cannot prove that they still possess those keys. |
| Existing delegates | Retain the grants made by the migrating account, including spending counters and revocation state. They cannot authorise migration or acquire owner authority through those grants. |

An inaccessible quorum can lock the account after migration. Bare root authority is permanently disabled, including when the old key remains an explicit owner. Migration does not end unwanted outgoing grants; they need separate revocation.

# Invariants

- Successful migration always leaves a nonzero configuration hash.
- Migration preserves outgoing access-key grants, spending counters, and revocation state, including legacy, revoked, and expired grants.
- Migration does not restore key-management authority removed by TIP-1137.
- The original root may remain an explicit owner or be omitted from the new configuration.
- Successful migration disables bare root authority regardless of whether the original root remains an owner.
- Failed migration rolls back the configuration write and event.
- Failed migration follows normal transaction fee and nonce rules.
- An account that already has a configuration cannot migrate again.
- Later transactions in the same block cannot use the migrated account's bare root authority.
- A transaction that migrates an empty sender pays TIP-1000's new-account cost exactly once, including its state-gas portion, under every nonce type, with or without fee sponsorship.
- Migration adds no new-account cost for a nonempty sender.
