`encode_int192` zero-pads negative values, corrupting them on `abi_encode`
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 76/100
Hướng nghiên cứu
Đọc các phần triển khai của ReportBase::encode_int192 và ReportBase::encode_int64, sau đó kiểm tra bài kiểm thử test_decode_report_data_v12 hiện có. Bổ sung kiểm thử khứ hồi cho các giá trị âm và kiểm tra các từ ABI được mã hóa có sử dụng mở rộng dấu hay không; hoàn thành khi các trường âm được giải mã trở lại đúng giá trị ban đầu và cả hai bộ mã hóa đều xuất ra các từ chuẩn tắc.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- TypeScript
- Star
- 11
- Fork
- 16
- Merge trung bình
- 1 ngày 20 giờ
- Pull request đã merge (30 ngày)
- 4
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của smartcontractkit/data-streams-sdk
-
Add 'once' supportCó thể đã có người làm @ChrisWozniak đã nhận 50 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 55/100
smartcontractkit/data-streams-sdk#61 · 1 reaction ·
Tất cả issue của smartcontractkit/data-streams-sdk
Issue tương tự
-
Report: Mooz Dance SDĐang mởcheck:passed streams:remove
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug needs triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
actions/setup-node#1659 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
vercel-labs/wterm#267 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
microsoft/AI-Engineering-Coach#355 · 1 reaction ·
Maintainer thường phản hồi trong vòng 4 ngày
-
level1 nsoc26
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
GauravKarakoti/SecureFlow#1501 ·
Maintainer thường phản hồi trong vòng 1 ngày