Skip to content

Commit

Permalink
Adjust bytes conversion to match Solidity behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
danhper committed Sep 24, 2024
1 parent 4c0b9bc commit b83d1db
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 14 deletions.
40 changes: 31 additions & 9 deletions src/interpreter/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,9 @@ impl Type {
(Type::Address, Value::Int(_, _)) => {
bail!("cannot only cast cast zero address from int")
}
(Type::Address, Value::FixBytes(v, _)) => {
Ok(Value::Addr(Address::from_slice(&v.0[12..])))
}
(Type::String, Value::Bytes(v)) => {
Ok(Value::Str(String::from_utf8_lossy(v).to_string()))
}
Expand All @@ -471,17 +474,22 @@ impl Type {
(t @ Type::FixBytes(bytes_num), Value::Uint(v, bits_num))
if *bytes_num * 8 == *bits_num =>
{
let bytes = B256::from_slice(&v.to_be_bytes_vec());
t.cast(&Value::FixBytes(bytes, 32))
let bytes = to_fixed_bytes(&v.to_be_bytes_vec(), *bytes_num, true)?;
t.cast(&Value::FixBytes(bytes, *bytes_num))
}
(Type::Uint(bits_num), Value::FixBytes(v, bytes_num))
if *bytes_num * 8 == *bits_num =>
{
let num = U256::from_be_slice(v.as_slice());
Ok(Value::Uint(num, *bits_num))
}
(Type::FixBytes(size), Value::FixBytes(bytes, _)) => {
Ok(Value::FixBytes(to_fixed_bytes(&bytes.0, *size)?, *size))
(Type::FixBytes(size), Value::FixBytes(bytes, previous_size)) => Ok(Value::FixBytes(
to_fixed_bytes(&bytes.0[32 - *previous_size..], *size, false)?,
*size,
)),
(Type::FixBytes(size), Value::Addr(addr)) if *size == 20 => {
let bytes = to_fixed_bytes(&addr.0 .0, 20, false)?;
Ok(Value::FixBytes(bytes, 20))
}
(Type::Transaction, Value::FixBytes(v, 32)) => Ok(Value::Transaction(*v)),
(Type::Bytes, Value::Str(v)) => Ok(Value::Bytes(v.as_bytes().to_vec())),
Expand All @@ -490,7 +498,7 @@ impl Type {
Ok(Value::Bytes(v.0[v.0.len() - *s..].to_vec()))
}
(Type::FixBytes(size), Value::Bytes(bytes)) => {
Ok(Value::FixBytes(to_fixed_bytes(bytes, *size)?, *size))
Ok(Value::FixBytes(to_fixed_bytes(bytes, *size, false)?, *size))
}
(Type::NamedTuple(name, types_), Value::Tuple(values)) => {
let mut new_values = IndexMap::new();
Expand Down Expand Up @@ -609,7 +617,7 @@ mod tests {
use crate::interpreter::Value;
use alloy::{
hex::FromHex,
primitives::{I128, I256, I32, I64, I8, U128, U256, U32, U64, U8},
primitives::{B256, I128, I256, I32, I64, I8, U128, U256, U32, U64, U8},
};

use super::Type;
Expand Down Expand Up @@ -677,9 +685,23 @@ mod tests {
let b256_value =
Value::from_hex("0x00000000000000000000000000000000000000000000000000000000281dd5af")
.unwrap();
let b4_value = Value::from_hex("0x281dd5af").unwrap();
assert_eq!(Type::FixBytes(4).cast(&b256_value).unwrap(), b4_value);
assert_eq!(Type::FixBytes(32).cast(&b4_value).unwrap(), b256_value);

assert_eq!(
Type::FixBytes(4).cast(&b256_value).unwrap(),
Value::from_hex("0x00000000").unwrap()
);
let b4 =
B256::from_hex("0x00000000000000000000000000000000000000000000000000000000281dd5af")
.unwrap();
let b4_value = Value::FixBytes(b4, 4);

let padded_b256_value =
Value::from_hex("0x281dd5af00000000000000000000000000000000000000000000000000000000")
.unwrap();
assert_eq!(
Type::FixBytes(32).cast(&b4_value).unwrap(),
padded_b256_value
);
}

#[test]
Expand Down
20 changes: 15 additions & 5 deletions src/interpreter/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,16 @@ pub fn receipt_to_value(env: &Env, receipt: TransactionReceipt) -> Result<Value>
Ok(Value::from_receipt(receipt, transformed_logs))
}

pub fn to_fixed_bytes(bytes: &[u8], size: usize) -> Result<B256> {
pub fn to_fixed_bytes(bytes: &[u8], size: usize, pad_left: bool) -> Result<B256> {
let mut new_bytes = vec![0; 32];
let new_size = bytes.len().min(size);
new_bytes[32 - new_size..].copy_from_slice(&bytes[bytes.len() - new_size..]);
if pad_left {
let to_copy = &bytes[bytes.len() - new_size..];
new_bytes[32 - new_size..].copy_from_slice(to_copy);
} else {
let to_copy = &bytes[..new_size];
new_bytes[32 - size..32 - size + new_size].copy_from_slice(to_copy);
}
Ok(B256::from_slice(&new_bytes))
}

Expand Down Expand Up @@ -218,17 +224,21 @@ mod tests {
#[test]
fn test_to_fixed_bytes() {
assert_eq!(
to_fixed_bytes(&[18, 52], 2).unwrap(),
to_fixed_bytes(&[18, 52], 2, true).unwrap(),
B256::from(U256::from(4660).to_be_bytes())
);
assert_eq!(
to_fixed_bytes(&[18, 52], 4).unwrap(),
to_fixed_bytes(&[18, 52], 4, true).unwrap(),
B256::from(U256::from(4660).to_be_bytes())
);
assert_eq!(
to_fixed_bytes(&[18, 52], 1).unwrap(),
to_fixed_bytes(&[18, 52], 1, true).unwrap(),
B256::from(U256::from(52).to_be_bytes())
);
assert_eq!(
to_fixed_bytes(&[102, 111, 111], 8, false).unwrap(),
B256::from(U256::from(7381240360074215424u64).to_be_bytes()) // 0x666f6f0000000000
);
}

#[test]
Expand Down

0 comments on commit b83d1db

Please sign in to comment.