Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

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

未关闭 适合新手
#82 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
76/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
rust
领域
api, backend

调研方向

阅读 ReportBase::encode_int192 和 ReportBase::encode_int64 的实现,然后检查现有的 test_decode_report_data_v12 测试。为负值添加往返测试,并检查编码后的 ABI 字是否使用符号扩展;当负数字段解码回原始值且两个编码器都输出规范字时,即为完成。

由索引模型根据 Issue 内容生成。

描述

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.

主要语言
TypeScript
星标
11
派生
16
平均合并
3 天 16 小时
30 天内合并 PR
2

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

smartcontractkit/data-streams-sdk 的其他 Issue

查看 smartcontractkit/data-streams-sdk 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。