0xMiden / 0xMiden/wallet

Seed-recovered Guardian account can be permanently locked behind its own rotation gate

未關閉
#805 0 則留言 1 個 reaction 已指派 0 人 在 GitHub 檢視
主要語言
TypeScript
星號
5
分支
28
平均合併
9 小時 50 分鐘
30 天內合併 PR
123

描述

**Trigger:** [protocol#3765](https://github.com/0xMiden/protocol/pull/3765) · **Status:** research / design decision needed
**Not reachable in production today** — see "When this lands".

## Symptom

Recovering a Guardian wallet from its seed phrase on a fee-charging chain can leave the
wallet permanently unusable when the recovered account's vault holds no native asset.

## Why

Three things are individually reasonable and together form a cycle:

1. A seed-only recovery cannot recover the device-bound hot key, so the recovered account
always carries `requiresHotKeyRotation` (`HotKeyRotationGate.tsx`).
2. That gate is a **full-app blocking overlay**. Its own doc: accounts carrying the flag
*"have no usable local hot key and cannot sign, sync, or transact until a `replace_signer`
rotation lands"*, and the gate *"paints a full-screen overlay that blocks all wallet
interaction"*.
3. Since protocol 0.16 the fee is paid inside the auth procedure from the acting account's
own vault. With protocol#3765 the guarded-multisig auth calls `fee::pay_fee`, so the
rotation is a **paid** transaction.

An account with an empty vault therefore cannot pay for the one transaction it is allowed to
make, and cannot make any other transaction to fund itself.

The usual escape from Miden's empty-vault bootstrap — consuming a note credits the vault
before `pay_fee` withdraws, so a claim funds itself — does **not** apply: claiming needs the
hot key, which is exactly what is missing.

## Observed

`guardian-seed-backup-verify` on a localnet at `verification_base_fee = 10000`:

failure

```
[replace-hot-key 8760567b stage=creating-proposal]
Error: failed to execute transaction at anchor: transaction execution failed:
failed to execute transaction kernel program:
assertion failed with error code: 644413868907058392
```

`644413868907058392` decodes to *"failed to remove the fungible asset from the vault since
the amount of the asset in the vault is less than the amount to remove"* — i.e. the fee
withdrawal, against an empty vault. The conversion info IS committed correctly; the account
simply cannot pay.

## When this lands

Not reachable today. The **published** guarded-multisig auth component contains no
`exec.fee::pay_fee`, so a guarded rotation currently moves no assets and costs nothing. This
becomes reachable the moment protocol#3765 ships, which makes it a question to settle
**before** that merges rather than after.

## Verified vs. inferred

Verified: the gate blocks all interaction (source); seed recovery always sets the flag
(source); the rotation fails with a vault-insufficient kernel assertion on a fee-charging
chain (observed, decoded); published guarded multisig has no `pay_fee` (source).

**Inferred, not tested:** that a user cannot escape by having someone send them MIDEN — it
follows from "no hot key ⇒ cannot sign a claim" plus the blocking overlay, but no one has
driven that path. **That is the first thing to check**, because if a background auto-consume
can claim while gated, the severity drops from "locked out" to "confusing wait".

## Directions (unevaluated)

- Let the gate expose receive/claim before the rotation, if a claim is signable without the
hot key. Cheapest if the inference above is wrong.
- Defer the gate: allow read-only use, and prompt for the rotation once the vault can pay.
- Sponsor the rotation, as `fees::collect_sponsored_fees` already does for network accounts —
a protocol/standards decision, not a wallet one.
- Have the guardian pay or co-fund the rotation.
- Detect the unpayable case and say so. Today the wallet surfaces the raw kernel string;
`TRANSACTION_FEE_UNPAYABLE_ERROR` exists but this path does not route through it, so the
user is told nothing actionable even in the recoverable case.

## Reviewers

The inference in "Verified vs. inferred" is the load-bearing part — if a gated account can
still claim, most of this dissolves.

貢獻指南

開啟貢獻指南

研究方向

First, verify if a gated account can still claim notes without the hot key by examining the claim signing logic in the wallet code. Look at the HotKeyRotationGate component and the guarded-multisig auth flow. Check the fee payment mechanism in the protocol, especially after protocol#3765. The goal is to confirm whether the account is permanently locked or can receive funds to pay the rotation fee.

由索引模型根據 Issue 內容生成。

評估

技術堆疊
rust, typescript
領域
backend, blockchain, security
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
活躍
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。