diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5fbe6ea..da95100 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -36,3 +36,17 @@ jobs: steps: - uses: actions/checkout@v4 - run: cargo fmt --all -- --check + + verify-bytecode: + name: Verify Bytecode + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: curl -L https://foundry.paradigm.xyz | bash && foundryup + - run: forge build --contracts=contracts + - run: mkdir -p bytecode/Erc6492.sol + - run: jq -r .bytecode.object out/Erc6492.sol/ValidateSigOffchain.json | xxd -r -p > bytecode/Erc6492.sol/ValidateSigOffchain.bytecode + - run: mkdir -p bytecode/Erc1271Mock.sol + - run: jq -r .bytecode.object out/Erc1271Mock.sol/Erc1271Mock.json | xxd -r -p > bytecode/Erc1271Mock.sol/Erc1271Mock.bytecode + - run: git diff bytecode + - run: if [ -n "$(git diff bytecode)" ]; then exit 1; fi diff --git a/.gitignore b/.gitignore index ea8c4bf..1e949f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target +/out +/cache diff --git a/Cargo.lock b/Cargo.lock index 1eec1dd..b1c5608 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1138,9 +1138,7 @@ version = "0.1.0" dependencies = [ "alloy", "alloy-node-bindings", - "alloy-primitives 0.8.0", "regex", - "serde_json", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index ade7b5f..052f969 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,3 @@ alloy = { version = "0.3", features = ["signer-local"] } alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy.git", rev = "d68a6b7" } regex = "1" tokio = { version = "1", features = ["full"] } - -[build-dependencies] -alloy-primitives = { version = "0.8.0" } -serde_json = "1" diff --git a/build.rs b/build.rs deleted file mode 100644 index 1232c5c..0000000 --- a/build.rs +++ /dev/null @@ -1,104 +0,0 @@ -use { - serde_json::Value, - std::process::{Command, Stdio}, -}; - -fn main() { - build_contracts(); -} - -fn build_contracts() { - println!("cargo::rerun-if-changed=contracts"); - install_foundry(); - compile_contracts(); - extract_bytecodes(); -} - -fn format_foundry_dir(path: &str) -> String { - format!( - "{}/../../../../.foundry/{}", - std::env::var("OUT_DIR").unwrap(), - path - ) -} - -fn install_foundry() { - let bin_finished_flag = format_foundry_dir("bin/.finished"); - if std::fs::metadata(&bin_finished_flag).is_ok() { - return; - } - - let bin_folder = format_foundry_dir("bin"); - std::fs::remove_dir_all(&bin_folder).ok(); - std::fs::create_dir_all(&bin_folder).unwrap(); - let output = Command::new("bash") - .args(["-c", &format!("curl https://raw.githubusercontent.com/foundry-rs/foundry/e0ea59cae26d945445d9cf21fdf22f4a18ac5bb2/foundryup/foundryup | FOUNDRY_DIR={} bash", format_foundry_dir(""))]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .unwrap() - .wait_with_output() - .unwrap(); - println!("foundryup status: {:?}", output.status); - let stdout = String::from_utf8(output.stdout).unwrap(); - println!("foundryup stdout: {stdout:?}"); - let stderr = String::from_utf8(output.stderr).unwrap(); - println!("foundryup stderr: {stderr:?}"); - assert!(output.status.success()); - - std::fs::write(bin_finished_flag, "").unwrap(); -} - -fn compile_contracts() { - let output = Command::new(format_foundry_dir("bin/forge")) - .args([ - "build", - "--contracts=contracts", - "--cache-path", - &format_foundry_dir("forge/cache"), - "--out", - &format_foundry_dir("forge/out"), - ]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .unwrap() - .wait_with_output() - .unwrap(); - println!("forge status: {:?}", output.status); - let stdout = String::from_utf8(output.stdout).unwrap(); - println!("forge stdout: {stdout:?}"); - let stderr = String::from_utf8(output.stderr).unwrap(); - println!("forge stderr: {stderr:?}"); - assert!(output.status.success()); -} - -const ERC6492_FILE: &str = "forge/out/Erc6492.sol/ValidateSigOffchain.json"; -const ERC6492_BYTECODE_FILE: &str = "forge/out/Erc6492.sol/ValidateSigOffchain.bytecode"; -const ERC1271_MOCK_FILE: &str = "forge/out/Erc1271Mock.sol/Erc1271Mock.json"; -const ERC1271_MOCK_BYTECODE_FILE: &str = "forge/out/Erc1271Mock.sol/Erc1271Mock.bytecode"; -fn extract_bytecodes() { - extract_bytecode( - &format_foundry_dir(ERC6492_FILE), - &format_foundry_dir(ERC6492_BYTECODE_FILE), - ); - extract_bytecode( - &format_foundry_dir(ERC1271_MOCK_FILE), - &format_foundry_dir(ERC1271_MOCK_BYTECODE_FILE), - ); -} - -fn extract_bytecode(input_file: &str, output_file: &str) { - let contents = serde_json::from_slice::(&std::fs::read(input_file).unwrap()).unwrap(); - let bytecode = contents - .get("bytecode") - .unwrap() - .get("object") - .unwrap() - .as_str() - .unwrap() - .strip_prefix("0x") - .unwrap(); - let bytecode = alloy_primitives::hex::decode(bytecode).unwrap(); - std::fs::write(output_file, bytecode).unwrap(); -} diff --git a/bytecode/Erc1271Mock.sol/Erc1271Mock.bytecode b/bytecode/Erc1271Mock.sol/Erc1271Mock.bytecode new file mode 100644 index 0000000..fccd1d0 Binary files /dev/null and b/bytecode/Erc1271Mock.sol/Erc1271Mock.bytecode differ diff --git a/bytecode/Erc6492.sol/ValidateSigOffchain.bytecode b/bytecode/Erc6492.sol/ValidateSigOffchain.bytecode new file mode 100644 index 0000000..0692986 Binary files /dev/null and b/bytecode/Erc6492.sol/ValidateSigOffchain.bytecode differ diff --git a/devloop.sh b/devloop.sh index dc96892..7b4989b 100755 --- a/devloop.sh +++ b/devloop.sh @@ -1,6 +1,14 @@ #!/bin/bash set -e +forge build --contracts=contracts + +mkdir -p bytecode/Erc6492.sol +jq -r .bytecode.object out/Erc6492.sol/ValidateSigOffchain.json | xxd -r -p > bytecode/Erc6492.sol/ValidateSigOffchain.bytecode + +mkdir -p bytecode/Erc1271Mock.sol +jq -r .bytecode.object out/Erc1271Mock.sol/Erc1271Mock.json | xxd -r -p > bytecode/Erc1271Mock.sol/Erc1271Mock.bytecode + cargo fmt --all cargo clippy --workspace --all-features --all-targets -- -D warnings cargo test --workspace --all-features --all-targets diff --git a/src/lib.rs b/src/lib.rs index 4e02107..7f968a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,10 +13,8 @@ sol! { constructor (address _signer, bytes32 _hash, bytes memory _signature); } } -const VALIDATE_SIG_OFFCHAIN_BYTECODE: &[u8] = include_bytes!(concat!( - env!("OUT_DIR"), - "/../../../../.foundry/forge/out/Erc6492.sol/ValidateSigOffchain.bytecode" -)); +const VALIDATE_SIG_OFFCHAIN_BYTECODE: &[u8] = + include_bytes!("../bytecode/Erc6492.sol/ValidateSigOffchain.bytecode"); #[must_use] #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -374,10 +372,8 @@ mod test { ); } - const ERC1271_MOCK_BYTECODE: &[u8] = include_bytes!(concat!( - env!("OUT_DIR"), - "/../../../../.foundry/forge/out/Erc1271Mock.sol/Erc1271Mock.bytecode" - )); + const ERC1271_MOCK_BYTECODE: &[u8] = + include_bytes!("../bytecode/Erc1271Mock.sol/Erc1271Mock.bytecode"); const ERC6492_MAGIC_BYTES: [u16; 16] = [ 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492, 0x6492,