Skip to content

Commit

Permalink
🚧 Add compute selector helper
Browse files Browse the repository at this point in the history
* wip: poc compute selectors

* refactor: compute selectors  #6

* fix

* remove

* rm unused

* rm unused

* fix: redudant closure / put test back

* clippy

* accidentally broke the test, whoops
  • Loading branch information
willco-1 authored Nov 18, 2024
1 parent e9dbd5b commit 679a436
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
2 changes: 1 addition & 1 deletion crates/ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ mod util;

pub use ast::*;
pub use parser::parse;
pub use util::u256_as_push;
pub use util::*;
55 changes: 54 additions & 1 deletion crates/ast/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use alloy_primitives::U256;
use crate::Spanned;
use alloy_dyn_abi::DynSolType;
use alloy_primitives::{keccak256, FixedBytes, U256};
use evm_glue::opcodes::Opcode;

pub(crate) fn u256_as_push_data<const N: usize>(value: U256) -> Result<[u8; N], String> {
Expand Down Expand Up @@ -53,3 +55,54 @@ pub fn u256_as_push(value: U256) -> Opcode {
_ => unreachable!(),
}
}

pub fn compute_selector(name: &Spanned<&str>, args: Box<[&Spanned<DynSolType>]>) -> FixedBytes<4> {
let arg_types: Vec<String> = args.iter().map(|arg| arg.0.to_string()).collect();

let signature = format!("{}({})", name.0, arg_types.join(","));
let hash = keccak256(signature.as_bytes());
FixedBytes::<4>::from_slice(&hash[..4])
}

#[cfg(test)]
mod tests {
use super::*;
use crate::ast::{SolError, SolFunction};
use chumsky::span::Span;

#[test]

fn test_compute_selector() {
let func = SolFunction {
name: Spanned::new("transfer", 0..8),
args: Box::new([
Spanned::new(DynSolType::Address, 9..17),
Spanned::new(DynSolType::Uint(256), 18..26),
]),
rets: Box::new([]),
};

let err = SolError {
name: Spanned::new("TransferFailed", 0..15),
args: Box::new([
Spanned::new(DynSolType::String, 16..21),
Spanned::new(DynSolType::Uint(256), 22..30),
]),
};

let func_selector = compute_selector(&func.name, func.args.iter().collect::<Box<[_]>>());
let err_selector = compute_selector(&err.name, err.args.iter().collect::<Box<[_]>>());

let expected_func_signature = "transfer(address,uint256)";
let expected_err_signature = "TransferFailed(string,uint256)";

let expected_func_hash = keccak256(expected_func_signature.as_bytes());
let expected_err_hash = keccak256(expected_err_signature.as_bytes());

let expected_func_selector = FixedBytes::<4>::from_slice(&expected_func_hash[..4]);
let expected_err_selector = FixedBytes::<4>::from_slice(&expected_err_hash[..4]);

assert_eq!(func_selector, expected_func_selector);
assert_eq!(err_selector, expected_err_selector);
}
}

0 comments on commit 679a436

Please sign in to comment.