Kupmios/Kupo: 64-bit UTxO amounts decoded as JS number, rounding values above 2^53
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 58/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Tranquilo
- Stack tecnológico
- typescript
Línea de trabajo
Comienza en packages/evolution/src/sdk/provider/internal/Kupo.ts y sigue las respuestas de Kupo a través de HttpUtils.get y los esquemas antes de leer KupmiosEffects.ts. Reproduce el problema con las cantidades grandes de lovelace y assets especificadas y, después, verifica la ruta de regresión a través de CoreAssets. La tarea está terminada cuando ambos valores siguen siendo valores bigint exactos al decodificar y consumir la respuesta de Kupo.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
The Kupo provider decodes on-chain lovelace and asset quantities as JS numbers, but a JS
number is exact only to 2^53-1. Cardano amounts are uint64, so any value above 2^53 is
silently rounded. Kupo returns these amounts as unquoted JSON integers, so the rounding
happens at JSON.parse time — before the schema — and the later BigInt(...) conversion just
preserves the already-corrupted value. Blockfrost and Koios avoid this on decode by typing the
same fields as strings. Fail closed: no fund loss; a consumer can display a wrong balance, and a
corrupted UTxO fed into evaluation produces a tx that is rejected on-chain.
Affected
packages/evolution/src/sdk/provider/internal/Kupo.ts
- L4 ValueSchema coins: S.Number
- L5 ValueSchema assets value: S.Number
- L49-50 Delegation rewards/deposit lovelace: S.Number
packages/evolution/src/sdk/provider/internal/KupmiosEffects.ts
- L79 BigInt(value.coins) // wraps an already-rounded number
- L85 BigInt(value.assets[unit]) // wraps an already-rounded number
transport: HttpUtils.get -> response.json -> JSON.parse truncates above 2^53 before the schema runs.
Kupo API: value.coins and asset quantities are type: integer (unquoted JSON numbers), per the Kupo OpenAPI spec.
contrast (correct): Blockfrost.ts inbound quantity: Schema.String -> BigInt; Koios.ts value/quantity: Schema.String -> BigInt.
Fix
Because JSON.parse rounds before the schema, changing S.Number to a bigint schema is not
enough — the inbound amount fields need a big-int-aware JSON parser on the Kupo response
(json-bigint style, or parse coins/assets from the raw text), then carry them as bigint into
CoreAssets.fromLovelace / addByHex (drop the intermediate JS number entirely).
Regression test
- given: a Kupo matches response with coins = 2^53+1 and an asset quantity = 2^64-1 as raw JSON integers
- before fix: decoded amounts are corrupted (2^53+1 -> 2^53, 2^64-1 -> 18446744073709552000)
- after fix: CoreAssets holds the exact bigint values, round-tripping unchanged
Must FAIL on main today and PASS after the fix.
Reference
Reported informally (large-value UTxO precision loss). Related: #406 (same bug class, Ogmios outbound path).
Correction to the original triage: the report also named Blockfrost, and that is partly right —
Blockfrost is safe on decode (amounts are strings) but IS affected on its OUTBOUND evaluate
serialization (BlockfrostEffect.ts toBlockfrostValue, Number() at L89/L98). That Blockfrost
outbound path is a separate finding, tracked in its own issue.
- Lenguaje dominante
- TypeScript
- Estrellas
- 22
- Forks
- 33
- Merge medio
- 2 d 12 h
- PR fusionados (30 d)
- 36
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de IntersectMBO/evolution-sdk
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
IntersectMBO/evolution-sdk#601 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
IntersectMBO/evolution-sdk#559 ·
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
IntersectMBO/evolution-sdk#557 ·
Los mantenedores suelen responder en 1 día
-
dependencies good first issue
Dificultad 1/5 Menos de una hora Aptitud para principiantes 93/100
IntersectMBO/evolution-sdk#541 ·
Los mantenedores suelen responder en 1 día
-
bug external-review
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
IntersectMBO/evolution-sdk#530 ·
Los mantenedores suelen responder en 1 día
Todos los issues de IntersectMBO/evolution-sdk
Issues similares
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
Small-tailqwq/dsh-deep-whale#187 ·
Los mantenedores suelen responder en 1 día
-
Tela Marca manda conferir o campo "Razão social", que em Portugal se chama "Denominação social"Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
melgarafael/DeskcommCRM#2503 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
0x80/isolate-package#218 ·
-
bug via-triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
pingdotgg/t3code#16859 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
Los mantenedores suelen responder en 1 día