Skip to content

Commit

Permalink
chore: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
chris13524 committed Sep 23, 2024
1 parent 6e24481 commit 85054cb
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 308 deletions.
18 changes: 8 additions & 10 deletions crates/yttrium/build.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
use {
// serde_json::Value,
std::process::{Command, Stdio},
};
use std::process::{Command, Stdio};

fn main() {
build_contracts();
// build_contracts();
}

#[allow(unused)]
fn build_contracts() {
install_foundry();
compile_contracts("crates/yttrium/safe-smart-account/contracts/proxies/SafeProxyFactory.sol", );
compile_contracts("crates/yttrium/safe-smart-account/contracts/Safe.sol");
compile_contracts(
"crates/yttrium/safe-smart-account/contracts/libraries/MultiSend.sol",
"safe-smart-account/contracts/proxies/SafeProxyFactory.sol",
);
compile_contracts("safe-smart-account/contracts/Safe.sol");
compile_contracts("safe-smart-account/contracts/libraries/MultiSend.sol");
compile_contracts(
"safe-modules/modules/4337/contracts/SafeModuleSetup.sol",
);

{
println!("cargo::rerun-if-changed=safe7579");
println!("cargo::rerun-if-changed=safe7579/pnpm-lock.yaml");
let output = Command::new("pnpm")
.current_dir("safe7579")
.args(["install"])
Expand All @@ -46,7 +44,7 @@ fn build_contracts() {
);

{
println!("cargo::rerun-if-changed=src/contracts");
println!("cargo::rerun-if-changed=src/contracts/yarn.lock");
let output = Command::new("yarn")
.current_dir("src/contracts")
.args(["install"])
Expand Down
6 changes: 3 additions & 3 deletions crates/yttrium/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl Signer {
chain_id: u64,
sign_service: &MutexGuard<SignService>,
) -> eyre::Result<UserOperationV07> {
let hash = uo.hash(ep, chain_id)?;
let hash = uo.hash(ep, chain_id);
let message_bytes = hash.0.to_vec();
println!("message_bytes: {:?}", message_bytes.clone());

Expand Down Expand Up @@ -152,7 +152,7 @@ pub fn sign_user_operation_v07_with_ecdsa_and_sign_service(
signer: PrivateKeySigner,
sign_service: &Arc<Mutex<SignService>>,
) -> eyre::Result<UserOperationV07> {
let hash = uo.hash(ep, chain_id)?;
let hash = uo.hash(ep, chain_id);

println!("hash: {:?}", hash.clone());

Expand Down Expand Up @@ -204,7 +204,7 @@ pub fn sign_user_operation_v07_with_ecdsa(
chain_id: u64,
signer: PrivateKeySigner,
) -> eyre::Result<UserOperationV07> {
let hash = uo.hash(ep, chain_id)?;
let hash = uo.hash(ep, chain_id);

println!("hash: {:?}", hash.clone());

Expand Down
162 changes: 148 additions & 14 deletions crates/yttrium/src/smart_accounts/safe.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::transaction::Transaction;
use alloy::{
dyn_abi::DynSolValue,
primitives::{address, keccak256, Address, Bytes, Uint, U256},
primitives::{
address, bytes, keccak256, Address, Bytes, FixedBytes, Uint, U256,
},
providers::ReqwestProvider,
sol,
sol_types::{SolCall, SolValue},
Expand Down Expand Up @@ -36,18 +39,6 @@ sol!(
".foundry/forge/out/Safe7579.sol/Safe7579.json"
);

// Had to copy from safe7579/artifacts/interfaces/IERC7579Account.json
// This struct doesn't seem to be in generated ABIs
sol!(
#[allow(missing_docs)]
#[sol(rpc, abi)]
struct Execution {
address target;
uint256 value;
bytes callData;
}
);

// https://github.com/WalletConnect/secure-web3modal/blob/f1d16f973a313e598d124a0e4751aee12d5de628/src/core/SmartAccountSdk/utils.ts#L180
pub const SAFE_ERC_7579_LAUNCHPAD_ADDRESS: Address =
address!("EBe001b3D534B9B6E2500FB78E67a1A137f561CE");
Expand Down Expand Up @@ -93,7 +84,7 @@ sol!(
".foundry/forge/out/MultiSend.sol/MultiSend.json"
);

pub const DUMMY_SIGNATURE_HEX: &str = "0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
pub const DUMMY_SIGNATURE: Bytes = bytes!("000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");

// https://github.com/WalletConnect/secure-web3modal/blob/c19a1e7b21c6188261728f4d521a17f94da4f055/src/core/SmartAccountSdk/constants.ts#L10
// const APPKIT_SALT: U256 = U256::from_str("zg3ijy0p46");
Expand Down Expand Up @@ -190,3 +181,146 @@ pub async fn get_account_address(
);
SAFE_PROXY_FACTORY_ADDRESS.create2(salt, keccak256(deployment_code))
}

pub fn get_call_data(execution_calldata: Vec<Transaction>) -> Bytes {
let batch = execution_calldata.len() != 1;
let revert_on_error = false;
let selector = [0u8; 4];
let context = [0u8; 22];

let mode = DynSolValue::Tuple(vec![
DynSolValue::Uint(Uint::from(if batch { 0x01 } else { 0x00 }), 8), // DelegateCall is 0xFF
DynSolValue::Uint(Uint::from(revert_on_error as u8), 8),
DynSolValue::Bytes(vec![0u8; 4]),
DynSolValue::Bytes(selector.to_vec()),
DynSolValue::Bytes(context.to_vec()),
])
.abi_encode_packed();

let execution_calldata = encode_calls(execution_calldata);

Safe7579::executeCall {
mode: FixedBytes::from_slice(&mode),
executionCalldata: execution_calldata,
}
.abi_encode()
.into()
}

sol! {
function executionBatch((address, uint256, bytes)[]);
}

fn encode_calls(calls: Vec<Transaction>) -> Bytes {
fn call(call: Transaction) -> (Address, U256, Bytes) {
(call.to, call.value, call.data)
}

let tuples = calls.into_iter().map(call).collect::<Vec<_>>();
if tuples.len() == 1 {
tuples.abi_encode_packed()
} else {
let call = executionBatchCall { _0: tuples };

// encode without selector
let mut out = Vec::with_capacity(call.abi_encoded_size());
call.abi_encode_raw(&mut out);
out
}
.into()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn empty_execution_call_data() {
assert_eq!(encode_calls(vec![]), bytes!("00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"));
}

#[test]
fn single_execution_call_data_value() {
assert_eq!(
encode_calls(vec![Transaction {
to: address!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
value: U256::from(19191919),
data: bytes!(""),
}]),
bytes!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000000000000000000000000000000000000124d86f")
);
}

#[test]
fn single_execution_call_data_data() {
assert_eq!(
encode_calls(vec![Transaction {
to: address!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
value: U256::ZERO,
data: bytes!("7777777777777777"),
}]),
bytes!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000000000000000000000000000007777777777777777")
);
}

#[test]
fn two_execution_call_data() {
assert_eq!(
encode_calls(vec![Transaction {
to: address!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
value: U256::from(19191919),
data: bytes!(""),
}, Transaction {
to: address!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
value: U256::ZERO,
data: bytes!("7777777777777777"),
}]),
bytes!("00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000000000000000000000000000000000000124d86f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000087777777777777777000000000000000000000000000000000000000000000000")
);
}

#[test]
fn empty_call_data() {
assert_eq!(get_call_data(vec![]), bytes!("e9ae5c5301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"));
}

#[test]
fn single_call_data_value() {
assert_eq!(
get_call_data(vec![Transaction {
to: address!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
value: U256::from(19191919),
data: bytes!(""),
}]),
bytes!("e9ae5c53000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000034aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000000000000000000000000000000000000124d86f000000000000000000000000")
);
}

#[test]
fn single_call_data_data() {
assert_eq!(
get_call_data(vec![Transaction {
to: address!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
value: U256::ZERO,
data: bytes!("7777777777777777"),
}]),
bytes!("e9ae5c5300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000000000000000000000000000777777777777777700000000")
);
}

#[test]
fn two_call_data() {
assert_eq!(
get_call_data(vec![Transaction {
to: address!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
value: U256::from(19191919),
data: bytes!(""),
}, Transaction {
to: address!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
value: U256::ZERO,
data: bytes!("7777777777777777"),
}]),
bytes!("e9ae5c530100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000000000000000000000000000000000000124d86f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000087777777777777777000000000000000000000000000000000000000000000000")
);
}
}
3 changes: 2 additions & 1 deletion crates/yttrium/src/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use alloy::primitives::{address, Address, Bytes, U256};
use serde::{Deserialize, Serialize};

pub mod send;

#[derive(Debug, Clone, PartialEq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Transaction {
pub to: Address,
pub value: U256,
Expand Down
7 changes: 1 addition & 6 deletions crates/yttrium/src/transaction/send.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::smart_accounts::safe::Execution;
use crate::transaction::send::simple_account_test::send_transaction_with_signer;
use crate::{
config::Config, transaction::Transaction, user_operation::UserOperationV07,
Expand Down Expand Up @@ -89,11 +88,7 @@ pub async fn send_transaction_with_private_key_signer(

let user_operation_hash = if safe {
safe_test::send_transaction(
vec![Execution {
target: transaction.to,
value: transaction.value,
callData: transaction.data,
}],
vec![transaction],
signer,
None,
None,
Expand Down
Loading

0 comments on commit 85054cb

Please sign in to comment.