0xMiden / 0xMiden/bridge-portal
bug: Number(amount) precision loss in createBridgeP2IDNote can silently send wrong amount
- Lenguaje dominante
- TypeScript
- Estrellas
- 0
- Forks
- 3
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Descripción
### Packages versions
@miden-sdk/miden-sdk (latest)
@miden-sdk/miden-wallet-adapter-base (latest)
@epoch-protocol/epoch-intents-sdk (latest)
### Bug description
In `src/app/lib/epoch/miden-note.ts:80`, the bigint `amount` parameter from the Epoch SDK is converted to `number` via `Number(amount)`. For values exceeding `Number.MAX_SAFE_INTEGER` (2^53 - 1 = 9007199254740991), this silently loses precision the P2IDE collateral note is minted with a different amount than intended, with no error thrown.
The existing guard (`Number.isFinite` + `> 0`) does not detect precision loss:
```ts
const amountUnits = Number(amount);
if (!Number.isFinite(amountUnits) || amountUnits <= 0) {
throw new Error(`Invalid Miden bridge amount: "${amount}".`);
}
```
This causes a silent fund mismatch: the collateral note amount differs from what the intent declared, causing the allocator to reject the fill or the user to lose the difference.
Additionally, `src/app/lib/epoch/bridge.ts` has inconsistent `TaskType` usage:
- Line 151: `taskType: "gettokenout" as TaskType` (hardcoded string cast)
- Line 210: `taskType: TaskType.GetTokenOut` (proper enum)
If the SDK renames the enum value, the Miden→EVM path silently breaks.
### How can this be reproduced?
```ts
const amount = 9007199254740993n; // bigint from Epoch SDK
const amountUnits = Number(amount);
console.log(amountUnits); // 9007199254740992 — 1 unit silently lost
Number.isFinite(amountUnits); // true — guard passes
amountUnits > 0; // true — guard passes
```
Any bigint in the range (2^53, 2^64) will silently round to the nearest IEEE 754 double. The P2IDE note is then minted with the wrong amount.
Suggested fix — add a MAX_SAFE_INTEGER guard before conversion:
```ts
if (amount > BigInt(Number.MAX_SAFE_INTEGER)) {
throw new Error(
`Miden bridge amount ${amount} exceeds Number.MAX_SAFE_INTEGER and cannot be safely converted.`
);
}
const amountUnits = Number(amount);
```
Longer term, `MidenSendTransaction.amount` should accept `bigint`.
### Relevant log output
```shell
No error logged the conversion succeeds silently with wrong value.
```
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.