Skip to content

Commit

Permalink
fix: simulation forbid recursive call
Browse files Browse the repository at this point in the history
  • Loading branch information
zsluedem committed May 29, 2023
1 parent 20e58c2 commit 371f0b8
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 13 deletions.
15 changes: 15 additions & 0 deletions crates/uopool/src/canonical/simulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,21 @@ impl<M: Middleware + 'static> UoPool<M> {
let mut calls: Vec<CallEntry> = vec![];
self.parse_call_stack(trace, &mut calls)?;

// check recursive call entrypoint method
let call_into_entry_point = calls.iter().find(|call| {
call.to.unwrap_or_default() == self.entry_point.address()
&& call.from.unwrap_or_default() != self.entry_point.address()
&& (call.method.is_some()
&& call.method.clone().unwrap_or_default() != *"depositTo")
});
if call_into_entry_point.is_some() {
return Err(SimulateValidationError::CallStackValidation {
message: format!(
"illegal call into EntryPoint during validation {call_into_entry_point:?}"
),
});
}

for (index, stake_info) in stake_info_by_entity.iter().enumerate() {
if LEVEL_TO_ENTITY[index] == "paymaster" {
let call = calls.iter().find(|call| {
Expand Down
14 changes: 1 addition & 13 deletions tests/src/validate_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ async fn fail_with_bad_opcode_in_paymaster() -> anyhow::Result<()> {
context.opcodes_factory.address,
)
.await;
println!("{res:?}");
assert!(matches!(
res,
Err(SimulateValidationError::OpcodeValidation { entity, opcode }) if entity=="paymaster" && opcode == "COINBASE"
Expand All @@ -354,7 +353,6 @@ async fn fail_with_bad_opcode_in_validation() -> anyhow::Result<()> {
context.opcodes_factory.address,
)
.await;
println!("{res:?}");
assert!(matches!(
res,
Err(SimulateValidationError::OpcodeValidation { entity, opcode }) if entity=="account" && opcode == "BLOCKHASH"
Expand All @@ -377,7 +375,6 @@ async fn fail_if_create_too_many() -> anyhow::Result<()> {
context.opcodes_factory.address,
)
.await;
println!("{res:?}");
assert!(matches!(
res,
Err(SimulateValidationError::OpcodeValidation { entity, opcode }) if entity=="account" && opcode == "CREATE2"
Expand All @@ -400,7 +397,6 @@ async fn fail_referencing_self_token() -> anyhow::Result<()> {
context.storage_factory.address,
)
.await;
println!("{res:?}");
assert!(matches!(
res,
Err(SimulateValidationError::StorageAccessValidation { .. })
Expand All @@ -411,14 +407,12 @@ async fn fail_referencing_self_token() -> anyhow::Result<()> {
#[tokio::test]
async fn account_succeeds_referecing_its_own_balance() {
let res = test_existing_user_op("balance-self".to_string(), "".to_string()).await;
println!("{res:?}");
assert!(matches!(res, Ok(..)));
}

#[tokio::test]
async fn account_fail_to_read_allowance_of_address() {
let res = test_existing_user_op("allowance-self-1".to_string(), "".to_string()).await;
println!("{res:?}");
assert!(matches!(
res,
Err(SimulateValidationError::StorageAccessValidation { .. })
Expand All @@ -428,21 +422,18 @@ async fn account_fail_to_read_allowance_of_address() {
#[tokio::test]
async fn account_can_reference_its_own_allowance_on_other_contract_balance() {
let res = test_existing_user_op("allowance-1-self".to_string(), "".to_string()).await;
println!("{res:?}");
assert!(matches!(res, Ok(..)));
}

#[tokio::test]
async fn access_self_struct_data() {
let res = test_existing_user_op("struct-self".to_string(), "".to_string()).await;
println!("{res:?}");
assert!(matches!(res, Ok(..)));
}

#[tokio::test]
async fn fail_to_access_other_address_struct_data() {
let res = test_existing_user_op("struct-1".to_string(), "".to_string()).await;
println!("{res:?}");
assert!(matches!(
res,
Err(SimulateValidationError::StorageAccessValidation { .. })
Expand All @@ -464,7 +455,6 @@ async fn fail_if_referencing_other_token_balance() -> anyhow::Result<()> {
context.storage_factory.address,
)
.await;
println!("{res:?}");
assert!(matches!(
res,
Err(SimulateValidationError::StorageAccessValidation { .. })
Expand All @@ -475,7 +465,6 @@ async fn fail_if_referencing_other_token_balance() -> anyhow::Result<()> {
#[tokio::test]
async fn fail_if_referencing_self_token_balance_after_wallet_creation() {
let res = test_existing_user_op("balance-self".to_string(), "".to_string()).await;
println!("{res:?}");
assert!(matches!(res, Ok(..)));
}

Expand Down Expand Up @@ -534,10 +523,9 @@ async fn fail_with_validation_recursively_calls_handle_ops() -> anyhow::Result<(
signature: Bytes::from("handleOps".as_bytes().to_vec()),
};
let res = validate(&context, user_op).await;
println!("{res:?}");
assert!(matches!(
res,
Err(SimulateValidationError::StorageAccessValidation { .. })
Err(SimulateValidationError::CallStackValidation { .. })
));
Ok(())
}
Expand Down

0 comments on commit 371f0b8

Please sign in to comment.