Skip to content
This repository was archived by the owner on Jun 1, 2026. It is now read-only.

Commit b5e889a

Browse files
authored
fix(signer): sign extend EIP-712 int values (#1158)
1 parent 791df3d commit b5e889a

2 files changed

Lines changed: 22 additions & 10 deletions

File tree

crates/signer/src/eip712/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ mod tests {
4848
let json = include_str!("../../testdata/eip712_signed_integers.json");
4949

5050
let digest = hash_typed_data(json).expect("hash succeeds");
51-
let expected = <[u8; 32]>::from_hex("10e6c8b7c51b08488a421a5492d4524439470010eb2f8c80c22b9d918d79a5a9").unwrap();
51+
let expected = <[u8; 32]>::from_hex("c6bed7e6a1ec9d2737b1d7bbca1e966eff59e74e21d8e20a66351b2db82cfc6a").unwrap();
5252
assert_eq!(digest, expected);
5353
}
5454

crates/signer/src/eip712/parse.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,27 @@ pub fn adjust_signed_value(number: I256, bits: usize) -> Result<U256, SignerErro
118118
return SignerError::invalid_input_err(format!("Value out of range for signed integer with {bits} bits"));
119119
}
120120

121-
if bits == MAX_WORD_BYTES * 8 {
122-
return Ok(number.into_raw());
123-
}
121+
Ok(number.into_raw())
122+
}
123+
124+
#[cfg(test)]
125+
mod tests {
126+
use alloy_primitives::I256;
127+
128+
use super::{MAX_WORD_BYTES, adjust_signed_value};
129+
130+
#[test]
131+
fn test_adjust_signed_value() {
132+
let negative = adjust_signed_value(I256::try_from(-42).unwrap(), 32).unwrap().to_be_bytes::<MAX_WORD_BYTES>();
133+
assert_eq!(negative[..31], [0xff; 31]);
134+
assert_eq!(negative[31], 0xd6);
135+
136+
let positive = adjust_signed_value(I256::try_from(42).unwrap(), 32).unwrap().to_be_bytes::<MAX_WORD_BYTES>();
137+
assert_eq!(positive[..31], [0; 31]);
138+
assert_eq!(positive[31], 42);
124139

125-
if number.is_negative() {
126-
let abs = number.unsigned_abs();
127-
let modulus = U256::from(1u64) << bits;
128-
modulus.checked_sub(abs).ok_or_else(|| SignerError::invalid_input("Failed to encode signed integer"))
129-
} else {
130-
Ok(number.unsigned_abs())
140+
assert!(adjust_signed_value(I256::try_from(-(1i128 << 31)).unwrap(), 32).is_ok());
141+
assert!(adjust_signed_value(I256::try_from(1i128 << 31).unwrap(), 32).is_err());
142+
assert!(adjust_signed_value(I256::try_from(-(1i128 << 31) - 1).unwrap(), 32).is_err());
131143
}
132144
}

0 commit comments

Comments
 (0)