linera-io/linera-protocol · error

deposit amount exceeds u128

Error message

deposit amount exceeds u128

What it means

process_deposit converts the parsed deposit amount from a 256-bit integer to u128 (Linera's Amount/U128) and expects success. The panic means the on-chain DepositInitiated event carried an amount larger than 2^128-1, which the wrapped-fungible token cannot represent. The transaction aborts, so no Mint is issued.

Source

Thrown at linera-bridge/contracts/evm-bridge/src/contract.rs:298

            .processed_deposits
            .insert(&deposit_hash)
            .expect("failed to insert deposit hash");

        // 5b. Cache the verified block hash so subsequent deposits from the same
        //     block skip the RPC finality check.
        if !self.state.rpc_endpoint.get().is_empty() {
            self.state
                .verified_block_hashes
                .insert(&block_hash.0)
                .expect("failed to cache verified block hash");
        }

        // 6. Convert deposit fields to Linera types and call Mint
        let amount = U128(
            deposit
                .amount
                .try_into()
                .expect("deposit amount exceeds u128"),
        );

        let mint_op = WrappedFungibleOperation::MintAndTransfer {
            target_account: Account {
                chain_id: deposit.target_chain_id,
                owner: deposit.target_account_owner,
            },
            amount,
        };

        // Forward authenticated signer (chain owner = minter) to the fungible app.
        let fungible_app_id = params.fungible_app_id.with_abi::<WrappedFungibleTokenAbi>();
        self.runtime
            .call_application(true, fungible_app_id, &mint_op);
    }

    /// Drives a user-initiated burn. Runs on the *user's* chain: moves `amount`
    /// of the authenticated signer's wrapped tokens into the signer's own escrow

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. In the relayer, filter deposits before submission: skip and alert on amount > u128::MAX
  2. Fix or avoid the source contract that emits such amounts (cap at mint time on the EVM side)
  3. If you maintain the bridge, add a configurable per-deposit cap assert before the conversion for a clearer rejection message
  4. For legitimate huge supplies, bridge a scaled representation (e.g. 18-decimal normalization) rather than raw wei

Example fix

// before
submit(ProcessDeposit { .. }); // contract aborts: deposit amount exceeds u128

// after — relayer-side filter
let amount: u128 = deposit.amount
    .try_into()
    .map_err(|_| anyhow!("deposit {} exceeds u128 — skipping and alerting", deposit.amount))?;
if amount > MAX_BRIDGEABLE {
    notify_ops("oversized deposit", deposit);
    return Ok(());
}
submit(ProcessDeposit { .. });
Defensive patterns

Strategy: validation

Validate before calling

// Filter oversized deposits before submission:
match u128::try_from(deposit.amount) {
    Ok(amount) if amount <= max_bridgeable => submit(ProcessDeposit { .. }),
    _ => { alert_ops(format!("oversized deposit {} skipped", deposit.amount)); }

Type guard

fn deposit_amount_representable(amount: alloy_primitives::U256) -> bool {
    amount <= alloy_primitives::U256::from(u128::MAX)
}

Try / catch

// The contract aborts atomically; there is no partial mint. Relayer-side,
// route oversized amounts to an exception queue for manual review instead of
// retrying.

Prevention

When it happens

Trigger: A malicious or buggy source contract emits DepositInitiated with an amount >= 2^128 (e.g. type-cast from uint256 max, or a wei-amount with absurd decimals); a relayer relays such an event instead of filtering it; fuzzed deposit fixtures with U256::MAX.

Common situations: Bridging from contracts that mint 2^256-ish supply tokens or use unscaled wei amounts; testnets with deliberately extreme values; token decimals mismatches where the feeder multiplies instead of divides.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/6cc93e724e50ca51. Report an issue: GitHub.