-
Notifications
You must be signed in to change notification settings - Fork 780
abi::encode_packed() returns incorrect value for U256s with leading zeroes #2704
Description
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
ethers-rs/ethers-core/src/abi/packed.rs
Line 118 in b730b74
| let start = if in_array { 0 } else { 32 - ((n.bits() + 7) / 8) }; |
n.bits() instead of n.bits() + n.trailing_zeroes().