Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

abi::encode_packed() returns incorrect value for U256s with leading zeroes #2704

Open
nanaknihal opened this issue Dec 31, 2023 · 1 comment
Labels
bug Something isn't working

Comments

@nanaknihal
Copy link
Contributor

Version
Since the formatting below got a bit weird: TLDR everything is v2.0.11
├── ethers v2.0.11
│ ├── ethers-addressbook v2.0.11
│ │ ├── ethers-core v2.0.11
│ ├── ethers-contract v2.0.11
│ │ ├── ethers-contract-abigen v2.0.11
│ │ │ ├── ethers-core v2.0.11 ()
│ │ ├── ethers-contract-derive v2.0.11 (proc-macro)
│ │ │ ├── ethers-contract-abigen v2.0.11 (
)
│ │ │ ├── ethers-core v2.0.11 ()
│ │ ├── ethers-core v2.0.11 (
)
│ │ ├── ethers-providers v2.0.11
│ │ │ ├── ethers-core v2.0.11 ()
│ ├── ethers-core v2.0.11 (
)
│ ├── ethers-etherscan v2.0.11
│ │ ├── ethers-core v2.0.11 ()
│ ├── ethers-middleware v2.0.11
│ │ ├── ethers-contract v2.0.11 (
)
│ │ ├── ethers-core v2.0.11 ()
│ │ ├── ethers-etherscan v2.0.11 (
)
│ │ ├── ethers-providers v2.0.11 ()
│ │ ├── ethers-signers v2.0.11
│ │ │ ├── ethers-core v2.0.11 (
)
│ ├── ethers-providers v2.0.11 ()
│ └── ethers-signers v2.0.11 (
)
Platform
Darwin Kernel Version 21.6.0 (arm64, MacOS Monterey)

Description
abi::encode_packed removes all leading zeroes from all uint256 (and I assume the same for all uint types). To be consistent with solidity and ethers-js it should keep these.

I expected to see this happen:
solidity (0.8.0)

uint256 abc = 123;
bytes32 xyz = keccak256("test");
abi.encodePacked(abc, xyz);

returns 0x9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658000000000000000000000000000000000000000000000000000000000000007b.

Instead, this happened:
ethers-rs

let abc = 123;
let xyz = keccak256("test".as_bytes());
let ep = abi::encode_packed(&[Token::Uint(U256::from(abc)), Token::FixedBytes(xyz.into())]).unwrap()
hex::encode(ep)

returns 9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb6587b

It is likely because this line

let start = if in_array { 0 } else { 32 - ((n.bits() + 7) / 8) };
subtracts n.bits() instead of n.bits() + n.trailing_zeroes().

@nanaknihal nanaknihal added the bug Something isn't working label Dec 31, 2023
@harpocryptes
Copy link
Contributor

This past issue seems relevant: #2225

If I understand correctly, the answer is that it's the intended behavior in ethers-rs, right?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants