Skip to content
This repository was archived by the owner on Oct 19, 2024. It is now read-only.
This repository was 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

@nanaknihal

Description

@nanaknihal

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().

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions