Skip to content

Instantly share code, notes, and snippets.

@frangio
Created November 14, 2025 12:08
Show Gist options
  • Select an option

  • Save frangio/0b20c337ffafdb880f881d7073c01580 to your computer and use it in GitHub Desktop.

Select an option

Save frangio/0b20c337ffafdb880f881d7073c01580 to your computer and use it in GitHub Desktop.
use alloy::{primitives::{hex, Bytes, FixedBytes, U256}};
const DYN_PREFIX: &[u8] = &hex! {
"0000000000000000000000000000000000000000000000000000000000000040"
"0000000000000000000000000000000000000000000000000000000000000060"
"0000000000000000000000000000000000000000000000000000000000000000"
};
const ZERO: &[u8] = &hex! {
"0000000000000000000000000000000000000000000000000000000000000000"
};
fn aggregate(selector: FixedBytes<4>, pre_encoded_args: &[Bytes]) -> Bytes {
let mut args: Vec<(Bytes, bool)> = Vec::new();
for pre_arg in pre_encoded_args {
assert_eq!(pre_arg.len() % 32, 0);
if pre_arg.starts_with(DYN_PREFIX) {
let enc_arg = pre_arg.slice(DYN_PREFIX.len()..);
assert!(!enc_arg.is_empty());
args.push((enc_arg, true));
} else {
let static_size = U256::from_be_slice(&pre_arg[..32]).to::<usize>();
assert_eq!(pre_arg.len(), static_size + 32);
assert_eq!(&pre_arg[pre_arg.len() - 32..], ZERO);
let enc_arg = pre_arg.slice(32..pre_arg.len() - 32);
args.push((enc_arg, false));
}
}
let mut heads = Vec::new();
let mut tails = Vec::new();
let mut next_dyn_head: usize = args
.iter()
.map(|(enc, is_dyn)| if *is_dyn { 32 } else { enc.len() })
.sum();
for (enc_arg, is_dyn) in args {
if is_dyn {
tails.extend_from_slice(&enc_arg);
heads.extend_from_slice(&U256::from(next_dyn_head).to_be_bytes::<32>());
next_dyn_head += enc_arg.len();
} else {
heads.extend_from_slice(&enc_arg);
}
}
let mut result = Vec::with_capacity(4 + heads.len() + tails.len());
result.extend_from_slice(selector.as_slice());
result.extend_from_slice(&heads);
result.extend_from_slice(&tails);
result.into()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment