Skip to content

Confirm load fails on a missing balance row it never reads #1292

Description

@DRadmir

Impact: iOS + Android. Any transaction whose asset has no stored balance row ends on the confirm screen's error card with only Try Again, even when the amount rules never look at that balance. The user cannot proceed and has no way to understand why. Perpetuals were one instance of this (fixed in #1291 by asking for the right asset); the failure mode itself stays.

Where:

  • core/gemstone/src/services/confirm/rules.rs:265build_metadata
  • core/gemstone/src/services/confirm/rules.rs:273asset_balance, raises BalanceMissing
  • core/gemstone/src/services/confirm/mod.rs:335input_metadata
  • core/crates/primitives/src/transfer_amount.rs:100spends_balance
  • core/crates/primitives/src/transfer_amount.rs:128required is ZERO when it is false

Root cause: build_metadata resolves a balance row for the transaction asset and for the fee asset, and turns a missing row into a load-blocking BalanceMissing. Whether that row is used is decided elsewhere: TransferAmountInput::calculate sets required = BigInt::ZERO when spends_balance() is false, so the transaction asset's balance is never compared against anything for Perpetual, TokenApprove, Account, TransferNft and the non-spending stake types. The load demands data the rules will not read, and a row that is absent only because a balance has not synced yet is indistinguishable from one that can never exist.

Confirmed: the perpetual instance was reproduced — test_perpetual_metadata_reads_the_collateral_balance_the_wallet_stores fails without #1291 with BalanceMissing { hypercore / perpetual::ETH }, and both apps showed the error card. The remaining cases are read off the rules above, not reproduced — no other input type has been observed reaching confirm without a row.

Note on the fix: the cheap version (missing row -> zero) is wrong here: for a real spend it would turn "balances not synced" into a false "insufficient balance". The row should be required only when the rule reads it, which means build_metadata has to know the input type.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions