`encode_int192` zero-pads negative values, corrupting them on `abi_encode`
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 76/100
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
- 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 smartcontractkit/data-streams-sdk
-
Add 'once' supportPosiblemente ocupada @ChrisWozniak la tomó hace 49 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 55/100
smartcontractkit/data-streams-sdk#61 · 1 reacción ·
Todos los issues de smartcontractkit/data-streams-sdk
Issues similares
-
Add: Disco Mix SDAbiertocheck:passed streams:add
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
level2 nsoc26
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
GauravKarakoti/SecureFlow#1488 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
deltachat/deltachat-desktop#6914 ·
Los mantenedores suelen responder en 2 días
-
area:cli bug P4
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
bug from-studio
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
esengine/DeepSeek-Reasonix#14868 ·
Los mantenedores suelen responder en 1 día