`encode_int192` zero-pads negative values, corrupting them on `abi_encode`
まだ誰も着手していません。
評価
調査の方向性
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
- 平均マージ
- 1日 20時間
- マージ済み PR(30日)
- 4
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
smartcontractkit/data-streams-sdk のほかの issue
-
Add 'once' support対応中かも @ChrisWozniak が 49 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 55/100
smartcontractkit/data-streams-sdk#61 · リアクション 1 件 ·
smartcontractkit/data-streams-sdk の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
Northeastern-Electric-Racing/FinishLine#4660 ·
メンテナーはふだん 2 日以内に返信
-
BeOS .json missingオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
mihaip/infinite-mac#475 ·
-
Let TypeScript accept an initial object in ReactiveDict対応中かも @yograj-vijay-yadav が今日担当しました。 オープンbug good first issue help wanted workshop
難易度 2/5 1〜3時間 初心者へのやさしさ 92/100
meteor/meteor#14919 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
marmelab/atomic-crm#401 ·
メンテナーはふだん 1 日以内に返信
-
account: profile
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
メンテナーはふだん 5 日以内に返信