Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

`encode_int192` zero-pads negative values, corrupting them on `abi_encode`

Abierto Apto para principiantes
#82 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
76/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
rust
Área
api, backend

Línea de trabajo

Lee las implementaciones de ReportBase::encode_int192 y ReportBase::encode_int64 y luego revisa la prueba existente test_decode_report_data_v12. Añade cobertura de ida y vuelta para valores negativos y comprueba que las palabras ABI codificadas usen extensión de signo; el trabajo estará hecho cuando los campos negativos se decodifiquen de nuevo a sus valores originales y ambos codificadores emitan palabras canónicas.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

encode_int192 zero-pads negative values, so abi_encode corrupts them and emits non-canonical ABI words.

ReportBase::encode_int192 right-aligns BigInt::to_signed_bytes_be() — the minimal two's-complement form — into a zero-filled 32-byte buffer. For a negative value that minimal form is shorter than 24 bytes, and the leading bytes are left 0x00 instead of 0xFF, so the sign is lost.

ReportBase::encode_int64 has the same zero-fill, but because i64::to_be_bytes() is always 8 bytes and read_int64 reads exactly those 8 bytes back, the value survives a round-trip through this crate. The word it emits is still not what an ABI encoder would produce.

Affects 1.2.0, 1.2.2 and 1.3.0 (current). decode is correct — it reads the low 24 bytes as signed — so bodies returned by a real verifier are unaffected. What breaks is anything that builds a report with abi_encode.

Reproduction

use chainlink_data_streams_report::{feed_id::ID, report::v12::ReportDataV12};
use num_bigint::BigInt;

let report = ReportDataV12 {
    feed_id: ID([0u8; 32]),
    valid_from_timestamp: 1,
    observations_timestamp: 1,
    native_fee: BigInt::ZERO,
    link_fee: BigInt::ZERO,
    expires_at: 2,
    nav_per_share: BigInt::from(-1),
    next_nav_per_share: BigInt::from(-1_000_000),
    nav_date: -1,
    ripcord: 0,
};
let decoded = ReportDataV12::decode(&report.abi_encode().unwrap()).unwrap();
assert_eq!(decoded.nav_per_share, BigInt::from(-1)); // fails: 255

Output:

nav_per_share      in: -1         out: 255
next_nav_per_share in: -1000000   out: 15777216
nav_date           in: -1         out: -1

The navPerShare word:

actual:   00000000000000000000000000000000000000000000000000000000000000ff
expected: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Impact

Any code that builds a report body with abi_encode gets a different value back than it put in, whenever a field is negative. This is easy to miss in a test: a case that encodes a negative value to prove the consumer rejects it still passes, because what reaches the consumer is a large positive number rejected for an unrelated reason.

The emitted word is also not valid ABI, so a body built with abi_encode and read by Solidity's abi.decode disagrees with this crate.

Suggested fix

Fill the buffer according to the sign before copying, in both encode_int192 and encode_int64:

pub(crate) fn encode_int192(value: &BigInt) -> Result<[u8; 32], ReportError> {
    let bytes_value = value.to_signed_bytes_be();
    let len = bytes_value.len();
    if len > 24 {
        return Err(ReportError::InvalidLength("int192"));
    }
    let fill = if value.sign() == Sign::Minus { 0xFF } else { 0x00 };
    let mut buffer = [fill; 32];
    buffer[32 - len..32].copy_from_slice(&bytes_value);
    Ok(buffer)
}

A round-trip test over negative values would catch both. The existing test_decode_report_data_v12 uses only positive mocks, which is why this is not caught today.

Lenguaje dominante
TypeScript
Estrellas
11
Forks
16
Merge medio
3 d 16 h
PR fusionados (30 d)
2

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de smartcontractkit/data-streams-sdk

Todos los issues de smartcontractkit/data-streams-sdk

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.