diff --git a/Cargo.lock b/Cargo.lock index ca3a63fa4e59..14f2b5ff2138 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3009,6 +3009,8 @@ dependencies = [ "tempfile", "thiserror", "tokio", + "toml 0.8.12", + "toml_edit 0.21.1", "tower-http", "tracing", "tracing-subscriber", @@ -3477,7 +3479,6 @@ dependencies = [ "proptest", "rand 0.8.5", "revm", - "rustc-hash", "serde", "thiserror", "tracing", diff --git a/crates/anvil/core/src/eth/serde_helpers.rs b/crates/anvil/core/src/eth/serde_helpers.rs index 311b3a9f27e8..5fda8ef49eb6 100644 --- a/crates/anvil/core/src/eth/serde_helpers.rs +++ b/crates/anvil/core/src/eth/serde_helpers.rs @@ -27,7 +27,7 @@ pub mod sequence { return Err(serde::de::Error::custom(format!( "expected params sequence with length 1 but got {}", seq.len() - ))) + ))); } Ok(seq.remove(0)) } @@ -75,7 +75,7 @@ pub mod empty_params { return Err(serde::de::Error::custom(format!( "expected params sequence with length 0 but got {}", seq.len() - ))) + ))); } Ok(()) } diff --git a/crates/anvil/core/src/eth/transaction/mod.rs b/crates/anvil/core/src/eth/transaction/mod.rs index 10de5f80e7f0..058d77f958b4 100644 --- a/crates/anvil/core/src/eth/transaction/mod.rs +++ b/crates/anvil/core/src/eth/transaction/mod.rs @@ -67,7 +67,7 @@ pub fn transaction_request_to_typed(tx: TransactionRequest) -> Option("isSystemTx")?.ok()?, input: input.into_input().unwrap_or_default(), - })) + })); } match ( @@ -81,8 +81,8 @@ pub fn transaction_request_to_typed(tx: TransactionRequest) -> Option { + (Some(0), _, None, None, None, None, None, None) + | (None, Some(_), None, None, None, None, None, None) => { Some(TypedTransactionRequest::Legacy(TxLegacy { nonce: nonce.unwrap_or_default().to::(), gas_price: gas_price.unwrap_or_default().to::(), @@ -97,8 +97,8 @@ pub fn transaction_request_to_typed(tx: TransactionRequest) -> Option { + (Some(1), _, None, None, _, None, None, None) + | (None, _, None, None, Some(_), None, None, None) => { Some(TypedTransactionRequest::EIP2930(TxEip2930 { nonce: nonce.unwrap_or_default().to::(), gas_price: gas_price.unwrap_or_default().to(), @@ -114,10 +114,10 @@ pub fn transaction_request_to_typed(tx: TransactionRequest) -> Option { + (Some(2), None, _, _, _, _, None, None) + | (None, None, Some(_), _, _, _, None, None) + | (None, None, _, Some(_), _, _, None, None) + | (None, None, None, None, None, _, None, None) => { // Empty fields fall back to the canonical transaction schema. Some(TypedTransactionRequest::EIP1559(TxEip1559 { nonce: nonce.unwrap_or_default().to::(), @@ -214,7 +214,7 @@ impl MaybeImpersonatedTransaction { #[cfg(feature = "impersonated-tx")] pub fn recover(&self) -> Result { if let Some(sender) = self.impersonated_sender { - return Ok(sender) + return Ok(sender); } self.transaction.recover() } @@ -227,7 +227,7 @@ impl MaybeImpersonatedTransaction { pub fn hash(&self) -> B256 { if self.transaction.is_impersonated() { if let Some(sender) = self.impersonated_sender { - return self.transaction.impersonated_hash(sender) + return self.transaction.impersonated_hash(sender); } } self.transaction.hash() @@ -994,31 +994,31 @@ pub enum TypedReceipt { impl TypedReceipt { pub fn gas_used(&self) -> U256 { match self { - TypedReceipt::Legacy(r) | - TypedReceipt::EIP1559(r) | - TypedReceipt::EIP2930(r) | - TypedReceipt::EIP4844(r) | - TypedReceipt::Deposit(r) => U256::from(r.receipt.cumulative_gas_used), + TypedReceipt::Legacy(r) + | TypedReceipt::EIP1559(r) + | TypedReceipt::EIP2930(r) + | TypedReceipt::EIP4844(r) + | TypedReceipt::Deposit(r) => U256::from(r.receipt.cumulative_gas_used), } } pub fn logs_bloom(&self) -> &Bloom { match self { - TypedReceipt::Legacy(r) | - TypedReceipt::EIP1559(r) | - TypedReceipt::EIP2930(r) | - TypedReceipt::EIP4844(r) | - TypedReceipt::Deposit(r) => &r.bloom, + TypedReceipt::Legacy(r) + | TypedReceipt::EIP1559(r) + | TypedReceipt::EIP2930(r) + | TypedReceipt::EIP4844(r) + | TypedReceipt::Deposit(r) => &r.bloom, } } pub fn logs(&self) -> &Vec { match self { - TypedReceipt::Legacy(r) | - TypedReceipt::EIP1559(r) | - TypedReceipt::EIP2930(r) | - TypedReceipt::EIP4844(r) | - TypedReceipt::Deposit(r) => &r.receipt.logs, + TypedReceipt::Legacy(r) + | TypedReceipt::EIP1559(r) + | TypedReceipt::EIP2930(r) + | TypedReceipt::EIP4844(r) + | TypedReceipt::Deposit(r) => &r.receipt.logs, } } } @@ -1026,11 +1026,11 @@ impl TypedReceipt { impl From for ReceiptWithBloom { fn from(val: TypedReceipt) -> Self { match val { - TypedReceipt::Legacy(r) | - TypedReceipt::EIP1559(r) | - TypedReceipt::EIP2930(r) | - TypedReceipt::EIP4844(r) | - TypedReceipt::Deposit(r) => r, + TypedReceipt::Legacy(r) + | TypedReceipt::EIP1559(r) + | TypedReceipt::EIP2930(r) + | TypedReceipt::EIP4844(r) + | TypedReceipt::Deposit(r) => r, } } } diff --git a/crates/anvil/server/src/ipc.rs b/crates/anvil/server/src/ipc.rs index 97ec0709887d..1091fc85b07c 100644 --- a/crates/anvil/server/src/ipc.rs +++ b/crates/anvil/server/src/ipc.rs @@ -48,7 +48,7 @@ impl IpcEndpoint { Ok(connections) => connections, Err(err) => { error!(%err, "Failed to create IPC listener"); - return Err(err) + return Err(err); } }; @@ -156,7 +156,7 @@ impl tokio_util::codec::Decoder for JsonRpcCodec { return match String::from_utf8(bts.as_ref().to_vec()) { Ok(val) => Ok(Some(val)), Err(_) => Ok(None), - } + }; } } Ok(None) diff --git a/crates/anvil/server/src/pubsub.rs b/crates/anvil/server/src/pubsub.rs index 3c9be85bce6d..a1abfb153a91 100644 --- a/crates/anvil/server/src/pubsub.rs +++ b/crates/anvil/server/src/pubsub.rs @@ -70,7 +70,7 @@ impl PubSubContext { let mut subscriptions = self.subscriptions.lock(); if let Some(idx) = subscriptions.iter().position(|(i, _)| id == i) { trace!(target: "rpc", ?id, "removed subscription"); - return Some(subscriptions.swap_remove(idx).1) + return Some(subscriptions.swap_remove(idx).1); } None } @@ -178,7 +178,7 @@ where error!(target: "rpc", ?err, "Failed to send message"); } } else { - break + break; } } @@ -187,7 +187,7 @@ where if let Poll::Ready(Err(err)) = pin.connection.poll_flush_unpin(cx) { trace!(target: "rpc", ?err, "websocket err"); // close the connection - return Poll::Ready(()) + return Poll::Ready(()); } loop { @@ -199,25 +199,25 @@ where Err(err) => match err { RequestError::Axum(err) => { trace!(target: "rpc", ?err, "client disconnected"); - return Poll::Ready(()) + return Poll::Ready(()); } RequestError::Io(err) => { trace!(target: "rpc", ?err, "client disconnected"); - return Poll::Ready(()) + return Poll::Ready(()); } RequestError::Serde(err) => { pin.process_request(Err(err)); } RequestError::Disconnect => { trace!(target: "rpc", "client disconnected"); - return Poll::Ready(()) + return Poll::Ready(()); } }, _ => {} }, Poll::Ready(None) => { trace!(target: "rpc", "socket connection finished"); - return Poll::Ready(()) + return Poll::Ready(()); } Poll::Pending => break, } @@ -260,7 +260,7 @@ where } if !progress { - return Poll::Pending + return Poll::Pending; } } } diff --git a/crates/anvil/src/anvil.rs b/crates/anvil/src/anvil.rs index 8ce75751c7f1..214139a4fa88 100644 --- a/crates/anvil/src/anvil.rs +++ b/crates/anvil/src/anvil.rs @@ -53,7 +53,7 @@ async fn main() -> eyre::Result<()> { &mut std::io::stdout(), ), } - return Ok(()) + return Ok(()); } let _ = fdlimit::raise_fd_limit(); diff --git a/crates/anvil/src/cmd.rs b/crates/anvil/src/cmd.rs index 9cde54553120..276ac0246849 100644 --- a/crates/anvil/src/cmd.rs +++ b/crates/anvil/src/cmd.rs @@ -577,7 +577,7 @@ impl Future for PeriodicStateDumper { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); if this.dump_state.is_none() { - return Poll::Pending + return Poll::Pending; } loop { @@ -588,7 +588,7 @@ impl Future for PeriodicStateDumper { } Poll::Pending => { this.in_progress_dump = Some(flush); - return Poll::Pending + return Poll::Pending; } } } @@ -598,7 +598,7 @@ impl Future for PeriodicStateDumper { let path = this.dump_state.clone().expect("exists; see above"); this.in_progress_dump = Some(Box::pin(PeriodicStateDumper::dump_state(api, path))); } else { - break + break; } } @@ -628,7 +628,7 @@ impl StateFile { } let mut state = Self { path, state: None }; if !state.path.exists() { - return Ok(state) + return Ok(state); } state.state = Some(SerializableState::load(&state.path).map_err(|err| err.to_string())?); @@ -663,14 +663,14 @@ impl FromStr for ForkUrl { fn from_str(s: &str) -> Result { if let Some((url, block)) = s.rsplit_once('@') { if block == "latest" { - return Ok(ForkUrl { url: url.to_string(), block: None }) + return Ok(ForkUrl { url: url.to_string(), block: None }); } // this will prevent false positives for auths `user:password@example.com` if !block.is_empty() && !block.contains(':') && !block.contains('.') { let block: u64 = block .parse() .map_err(|_| format!("Failed to parse block number: `{block}`"))?; - return Ok(ForkUrl { url: url.to_string(), block: Some(block) }) + return Ok(ForkUrl { url: url.to_string(), block: Some(block) }); } } Ok(ForkUrl { url: s.to_string(), block: None }) diff --git a/crates/anvil/src/eth/api.rs b/crates/anvil/src/eth/api.rs index 402bf4b751c7..62314f647aa6 100644 --- a/crates/anvil/src/eth/api.rs +++ b/crates/anvil/src/eth/api.rs @@ -333,7 +333,7 @@ impl EthApi { if time >= U256::from(u64::MAX) { return ResponseResult::Error(RpcError::invalid_params( "The timestamp is too big", - )) + )); } let time = time.to::(); self.evm_set_next_block_timestamp(time).to_rpc_result() @@ -342,7 +342,7 @@ impl EthApi { if timestamp >= U256::from(u64::MAX) { return ResponseResult::Error(RpcError::invalid_params( "The timestamp is too big", - )) + )); } let time = timestamp.to::(); self.evm_set_time(time).to_rpc_result() @@ -433,13 +433,13 @@ impl EthApi { false, ) .unwrap(); - return build_typed_transaction(request, nil_signature) + return build_typed_transaction(request, nil_signature); } _ => { for signer in self.signers.iter() { if signer.accounts().contains(from) { let signature = signer.sign_transaction(request.clone(), from)?; - return build_typed_transaction(request, signature) + return build_typed_transaction(request, signature); } } } @@ -605,7 +605,7 @@ impl EthApi { if let BlockRequest::Number(number) = block_request { if let Some(fork) = self.get_fork() { if fork.predates_fork(number) { - return Ok(fork.get_balance(address, number).await?) + return Ok(fork.get_balance(address, number).await?); } } } @@ -762,7 +762,7 @@ impl EthApi { if let BlockRequest::Number(number) = block_request { if let Some(fork) = self.get_fork() { if fork.predates_fork(number) { - return Ok(fork.get_code(address, number).await?) + return Ok(fork.get_code(address, number).await?); } } } @@ -787,7 +787,7 @@ impl EthApi { if let BlockRequest::Number(number) = block_request { if let Some(fork) = self.get_fork() { if fork.predates_fork_inclusive(number) { - return Ok(fork.get_proof(address, keys, Some(number.into())).await?) + return Ok(fork.get_proof(address, keys, Some(number.into())).await?); } } } @@ -982,7 +982,7 @@ impl EthApi { "not available on past forked blocks".to_string(), )); } - return Ok(fork.call(&request, Some(number.into())).await?) + return Ok(fork.call(&request, Some(number.into())).await?); } } } @@ -1029,7 +1029,7 @@ impl EthApi { if let BlockRequest::Number(number) = block_request { if let Some(fork) = self.get_fork() { if fork.predates_fork(number) { - return Ok(fork.create_access_list(&request, Some(number.into())).await?) + return Ok(fork.create_access_list(&request, Some(number.into())).await?); } } } @@ -1171,7 +1171,7 @@ impl EthApi { self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?; if let Some(fork) = self.get_fork() { if fork.predates_fork_inclusive(number) { - return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?) + return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?); } } // It's impossible to have uncles outside of fork mode @@ -2160,7 +2160,7 @@ impl EthApi { "not available on past forked blocks".to_string(), )); } - return Ok(fork.estimate_gas(&request, Some(number.into())).await?) + return Ok(fork.estimate_gas(&request, Some(number.into())).await?); } } } diff --git a/crates/anvil/src/eth/backend/cheats.rs b/crates/anvil/src/eth/backend/cheats.rs index 0dc3189b07eb..251bd271add0 100644 --- a/crates/anvil/src/eth/backend/cheats.rs +++ b/crates/anvil/src/eth/backend/cheats.rs @@ -30,7 +30,7 @@ impl CheatsManager { // which does not check that list when auto impersonation is enabeld. if state.impersonated_accounts.contains(&addr) { // need to check if already impersonated, so we don't overwrite the code - return true + return true; } state.impersonated_accounts.insert(addr) } diff --git a/crates/anvil/src/eth/backend/executor.rs b/crates/anvil/src/eth/backend/executor.rs index 5e68924c95c3..aaece8279fc7 100644 --- a/crates/anvil/src/eth/backend/executor.rs +++ b/crates/anvil/src/eth/backend/executor.rs @@ -155,18 +155,18 @@ impl<'a, DB: Db + ?Sized, Validator: TransactionValidator> TransactionExecutor<' } TransactionExecutionOutcome::Exhausted(tx) => { trace!(target: "backend", tx_gas_limit = %tx.pending_transaction.transaction.gas_limit(), ?tx, "block gas limit exhausting, skipping transaction"); - continue + continue; } TransactionExecutionOutcome::Invalid(tx, _) => { trace!(target: "backend", ?tx, "skipping invalid transaction"); invalid.push(tx); - continue + continue; } TransactionExecutionOutcome::DatabaseError(_, err) => { // Note: this is only possible in forking mode, if for example a rpc request // failed trace!(target: "backend", ?err, "Failed to execute transaction due to database error"); - continue + continue; } }; let receipt = tx.create_receipt(); @@ -270,7 +270,7 @@ impl<'a, 'b, DB: Db + ?Sized, Validator: TransactionValidator> Iterator // check that we comply with the block's gas limit let max_gas = self.gas_used.saturating_add(U256::from(env.tx.gas_limit)); if max_gas > env.block.gas_limit { - return Some(TransactionExecutionOutcome::Exhausted(transaction)) + return Some(TransactionExecutionOutcome::Exhausted(transaction)); } // validate before executing @@ -280,7 +280,7 @@ impl<'a, 'b, DB: Db + ?Sized, Validator: TransactionValidator> Iterator &env, ) { warn!(target: "backend", "Skipping invalid tx execution [{:?}] {}", transaction.hash(), err); - return Some(TransactionExecutionOutcome::Invalid(transaction, err)) + return Some(TransactionExecutionOutcome::Invalid(transaction, err)); } let nonce = account.nonce; diff --git a/crates/anvil/src/eth/backend/genesis.rs b/crates/anvil/src/eth/backend/genesis.rs index 14197b63d9ba..19ec37fa65aa 100644 --- a/crates/anvil/src/eth/backend/genesis.rs +++ b/crates/anvil/src/eth/backend/genesis.rs @@ -110,14 +110,14 @@ impl<'a> DatabaseRef for AtGenesisStateDb<'a> { type Error = DatabaseError; fn basic_ref(&self, address: Address) -> DatabaseResult> { if let Some(acc) = self.accounts.get(&(address)).cloned() { - return Ok(Some(acc)) + return Ok(Some(acc)); } self.db.basic_ref(address) } fn code_by_hash_ref(&self, code_hash: B256) -> DatabaseResult { if let Some((_, acc)) = self.accounts.iter().find(|(_, acc)| acc.code_hash == code_hash) { - return Ok(acc.code.clone().unwrap_or_default()) + return Ok(acc.code.clone().unwrap_or_default()); } self.db.code_by_hash_ref(code_hash) } @@ -127,7 +127,7 @@ impl<'a> DatabaseRef for AtGenesisStateDb<'a> { if let Some(storage) = acc.storage.as_ref() { return Ok(U256::from_be_bytes( storage.get(&B256::from(index)).copied().unwrap_or_default().0, - )) + )); } } self.db.storage_ref(address, index) diff --git a/crates/anvil/src/eth/backend/mem/mod.rs b/crates/anvil/src/eth/backend/mem/mod.rs index a60ba56408fa..65b24bb59a7d 100644 --- a/crates/anvil/src/eth/backend/mem/mod.rs +++ b/crates/anvil/src/eth/backend/mem/mod.rs @@ -614,7 +614,7 @@ impl Backend { /// Returns an error if op-stack deposits are not active pub fn ensure_op_deposits_active(&self) -> Result<(), BlockchainError> { if self.is_optimism() { - return Ok(()) + return Ok(()); } Err(BlockchainError::DepositTransactionUnsupported) } @@ -1381,7 +1381,7 @@ impl Backend { } if let Some(fork) = self.get_fork() { - return Ok(fork.block_by_hash_full(hash).await?) + return Ok(fork.block_by_hash_full(hash).await?); } Ok(None) @@ -1435,7 +1435,7 @@ impl Backend { if let Some(fork) = self.get_fork() { let number = self.convert_block_number(Some(number)); if fork.predates_fork_inclusive(number) { - return Ok(fork.block_by_number(number).await?) + return Ok(fork.block_by_number(number).await?); } } @@ -1454,7 +1454,7 @@ impl Backend { if let Some(fork) = self.get_fork() { let number = self.convert_block_number(Some(number)); if fork.predates_fork_inclusive(number) { - return Ok(fork.block_by_number_full(number).await?) + return Ok(fork.block_by_number_full(number).await?); } } @@ -1818,7 +1818,7 @@ impl Backend { } if let Some(fork) = self.get_fork() { - return Ok(fork.trace_transaction(hash).await?) + return Ok(fork.trace_transaction(hash).await?); } Ok(vec![]) @@ -1862,7 +1862,7 @@ impl Backend { } if let Some(fork) = self.get_fork() { - return Ok(fork.debug_trace_transaction(hash, opts).await?) + return Ok(fork.debug_trace_transaction(hash, opts).await?); } Ok(GethTrace::Default(Default::default())) @@ -1888,7 +1888,7 @@ impl Backend { if let Some(fork) = self.get_fork() { if fork.predates_fork(number) { - return Ok(fork.trace_block(number).await?) + return Ok(fork.trace_block(number).await?); } } @@ -2085,7 +2085,9 @@ impl Backend { if let Some(fork) = self.get_fork() { let number = self.convert_block_number(Some(number)); if fork.predates_fork(number) { - return Ok(fork.transaction_by_block_number_and_index(number, index.into()).await?) + return Ok(fork + .transaction_by_block_number_and_index(number, index.into()) + .await?); } } @@ -2102,7 +2104,7 @@ impl Backend { } if let Some(fork) = self.get_fork() { - return Ok(fork.transaction_by_block_hash_and_index(hash, index.into()).await?) + return Ok(fork.transaction_by_block_hash_and_index(hash, index.into()).await?); } Ok(None) @@ -2141,7 +2143,10 @@ impl Backend { } if let Some(fork) = self.get_fork() { - return fork.transaction_by_hash(hash).await.map_err(BlockchainError::AlloyForkProvider) + return fork + .transaction_by_hash(hash) + .await + .map_err(BlockchainError::AlloyForkProvider); } Ok(None) @@ -2284,7 +2289,7 @@ fn get_pool_transactions_nonce( .max() { let tx_count = highest_nonce.saturating_add(U256::from(1)); - return Some(tx_count) + return Some(tx_count); } None } @@ -2314,8 +2319,8 @@ impl TransactionValidator for Backend { if chain_id.to::() != tx_chain_id { if let Some(legacy) = tx.as_legacy() { // - if env.handler_cfg.spec_id >= SpecId::SPURIOUS_DRAGON && - !meets_eip155(chain_id.to::(), legacy.signature().v()) + if env.handler_cfg.spec_id >= SpecId::SPURIOUS_DRAGON + && !meets_eip155(chain_id.to::(), legacy.signature().v()) { warn!(target: "backend", ?chain_id, ?tx_chain_id, "incompatible EIP155-based V"); return Err(InvalidTransactionError::IncompatibleEIP155); diff --git a/crates/anvil/src/eth/backend/mem/storage.rs b/crates/anvil/src/eth/backend/mem/storage.rs index 0e2ac2b636ad..0732dbc9cf85 100644 --- a/crates/anvil/src/eth/backend/mem/storage.rs +++ b/crates/anvil/src/eth/backend/mem/storage.rs @@ -164,7 +164,7 @@ impl InMemoryBlockStates { if let Some(state) = self.on_disk_states.get_mut(hash) { if let Some(cached) = self.disk_cache.read(*hash) { state.init_from_snapshot(cached); - return Some(state) + return Some(state); } } None diff --git a/crates/anvil/src/eth/backend/time.rs b/crates/anvil/src/eth/backend/time.rs index ce6900eb48f9..2e4d11b6a66d 100644 --- a/crates/anvil/src/eth/backend/time.rs +++ b/crates/anvil/src/eth/backend/time.rs @@ -75,7 +75,7 @@ impl TimeManager { if timestamp <= *self.last_timestamp.read() { return Err(BlockchainError::TimestampError(format!( "{timestamp} is lower than or equal to previous block's timestamp" - ))) + ))); } self.next_exact_timestamp.write().replace(timestamp); Ok(()) diff --git a/crates/anvil/src/eth/fees.rs b/crates/anvil/src/eth/fees.rs index ef2d38eca87f..e950e370dc52 100644 --- a/crates/anvil/src/eth/fees.rs +++ b/crates/anvil/src/eth/fees.rs @@ -125,7 +125,7 @@ impl FeeManager { // It means it was set by the user deliberately and therefore we treat it as a constant. // Therefore, we skip the base fee calculation altogether and we return 0. if self.base_fee().is_zero() { - return 0 + return 0; } calculate_next_block_base_fee( gas_used.to::(), @@ -140,22 +140,22 @@ pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u6 let gas_target = gas_limit / EIP1559_ELASTICITY_MULTIPLIER; if gas_used == gas_target { - return base_fee + return base_fee; } if gas_used > gas_target { let gas_used_delta = gas_used - gas_target; let base_fee_delta = std::cmp::max( 1, - base_fee as u128 * gas_used_delta as u128 / - gas_target as u128 / - BASE_FEE_CHANGE_DENOMINATOR as u128, + base_fee as u128 * gas_used_delta as u128 + / gas_target as u128 + / BASE_FEE_CHANGE_DENOMINATOR as u128, ); base_fee + (base_fee_delta as u64) } else { let gas_used_delta = gas_target - gas_used; - let base_fee_per_gas_delta = base_fee as u128 * gas_used_delta as u128 / - gas_target as u128 / - BASE_FEE_CHANGE_DENOMINATOR as u128; + let base_fee_per_gas_delta = base_fee as u128 * gas_used_delta as u128 + / gas_target as u128 + / BASE_FEE_CHANGE_DENOMINATOR as u128; base_fee.saturating_sub(base_fee_per_gas_delta as u64) } @@ -288,7 +288,7 @@ impl FeeHistoryService { for (gas_used, effective_reward) in transactions.iter().cloned() { sum_gas += gas_used; if target_gas <= sum_gas { - return Some(effective_reward) + return Some(effective_reward); } } None @@ -401,7 +401,7 @@ impl FeeDetails { if let Some(max_priority) = max_priority { let max_fee = max_fee.unwrap_or_default(); if max_priority > max_fee { - return Err(BlockchainError::InvalidFeeInput) + return Err(BlockchainError::InvalidFeeInput); } } Ok(FeeDetails { diff --git a/crates/anvil/src/eth/miner.rs b/crates/anvil/src/eth/miner.rs index 2199a5061351..414b1d1dbd87 100644 --- a/crates/anvil/src/eth/miner.rs +++ b/crates/anvil/src/eth/miner.rs @@ -163,7 +163,7 @@ impl FixedBlockTimeMiner { fn poll(&mut self, pool: &Arc, cx: &mut Context<'_>) -> Poll>> { if self.interval.poll_tick(cx).is_ready() { // drain the pool - return Poll::Ready(pool.ready_transactions().collect()) + return Poll::Ready(pool.ready_transactions().collect()); } Poll::Pending } @@ -195,7 +195,7 @@ impl ReadyTransactionMiner { } if self.has_pending_txs == Some(false) { - return Poll::Pending + return Poll::Pending; } let transactions = @@ -205,7 +205,7 @@ impl ReadyTransactionMiner { self.has_pending_txs = Some(transactions.len() >= self.max_transactions); if transactions.is_empty() { - return Poll::Pending + return Poll::Pending; } Poll::Ready(transactions) diff --git a/crates/anvil/src/eth/otterscan/api.rs b/crates/anvil/src/eth/otterscan/api.rs index ac092f36c7f7..ce09bf67d0e6 100644 --- a/crates/anvil/src/eth/otterscan/api.rs +++ b/crates/anvil/src/eth/otterscan/api.rs @@ -69,7 +69,7 @@ impl EthApi { if let Some(receipt) = self.backend.mined_transaction_receipt(hash) { if receipt.inner.status_code == Some(U64::ZERO) { - return Ok(receipt.out.map(|b| b.0.into())) + return Ok(receipt.out.map(|b| b.0.into())); } } @@ -164,7 +164,7 @@ impl EthApi { res.extend(hashes); if res.len() >= page_size { - break + break; } } } @@ -223,7 +223,7 @@ impl EthApi { res.extend(hashes); if res.len() >= page_size { - break + break; } } } @@ -248,7 +248,7 @@ impl EthApi { if let Some(txs) = self.backend.mined_transactions_by_block_number(n.into()).await { for tx in txs { if U256::from(tx.nonce) == nonce && tx.from == address { - return Ok(Some(tx)) + return Ok(Some(tx)); } } } diff --git a/crates/anvil/src/eth/pool/mod.rs b/crates/anvil/src/eth/pool/mod.rs index 34a75c205ade..edae99b260c4 100644 --- a/crates/anvil/src/eth/pool/mod.rs +++ b/crates/anvil/src/eth/pool/mod.rs @@ -216,7 +216,7 @@ impl PoolInner { /// Returns `None` if the transaction does not exist in the pool fn get_transaction(&self, hash: TxHash) -> Option { if let Some(pending) = self.pending_transactions.get(&hash) { - return Some(pending.transaction.pending_transaction.clone()) + return Some(pending.transaction.pending_transaction.clone()); } Some( self.ready_transactions.get(&hash)?.transaction.transaction.pending_transaction.clone(), @@ -249,7 +249,7 @@ impl PoolInner { fn add_transaction(&mut self, tx: PoolTransaction) -> Result { if self.contains(&tx.hash()) { warn!(target: "txpool", "[{:?}] Already imported", tx.hash()); - return Err(PoolError::AlreadyImported(Box::new(tx))) + return Err(PoolError::AlreadyImported(Box::new(tx))); } let tx = PendingPoolTransaction::new(tx, self.ready_transactions.provided_markers()); @@ -259,7 +259,7 @@ impl PoolInner { if !tx.is_ready() { let hash = tx.transaction.hash(); self.pending_transactions.add_transaction(tx)?; - return Ok(AddedTransaction::Pending { hash }) + return Ok(AddedTransaction::Pending { hash }); } self.add_ready_transaction(tx) } @@ -299,7 +299,7 @@ impl PoolInner { if is_new_tx { debug!(target: "txpool", "[{:?}] Failed to add tx: {:?}", current_hash, err); - return Err(err) + return Err(err); } else { ready.discarded.push(current_hash); } @@ -313,7 +313,7 @@ impl PoolInner { // the pending queue if ready.removed.iter().any(|tx| *tx.hash() == hash) { self.ready_transactions.clear_transactions(&ready.promoted); - return Err(PoolError::CyclicTransaction) + return Err(PoolError::CyclicTransaction); } Ok(AddedTransaction::Ready(ready)) @@ -354,7 +354,7 @@ impl PoolInner { pub fn remove_invalid(&mut self, tx_hashes: Vec) -> Vec> { // early exit in case there is no invalid transactions. if tx_hashes.is_empty() { - return vec![] + return vec![]; } trace!(target: "txpool", "Removing invalid transactions: {:?}", tx_hashes); @@ -372,7 +372,7 @@ impl PoolInner { self.transactions_by_sender(sender).map(move |tx| tx.hash()).collect::>(); if tx_hashes.is_empty() { - return vec![] + return vec![]; } trace!(target: "txpool", "Removing transactions: {:?}", tx_hashes); diff --git a/crates/anvil/src/eth/pool/transactions.rs b/crates/anvil/src/eth/pool/transactions.rs index 312bde4818bf..9527a66c7c6f 100644 --- a/crates/anvil/src/eth/pool/transactions.rs +++ b/crates/anvil/src/eth/pool/transactions.rs @@ -157,7 +157,7 @@ impl PendingTransactions { warn!(target: "txpool", "pending replacement transaction underpriced [{:?}]", tx.transaction.hash()); return Err(PoolError::ReplacementUnderpriced(Box::new( tx.transaction.as_ref().clone(), - ))) + ))); } } @@ -343,7 +343,7 @@ impl Iterator for TransactionsIterator { } } - return Some(best.transaction) + return Some(best.transaction); } } } @@ -463,7 +463,7 @@ impl ReadyTransactions { // early exit if we are not replacing anything. if remove_hashes.is_empty() { - return Ok((Vec::new(), Vec::new())) + return Ok((Vec::new(), Vec::new())); } // check if we're replacing the same transaction and if it can be replaced @@ -480,7 +480,7 @@ impl ReadyTransactions { // check if underpriced if tx.pending_transaction.transaction.gas_price() <= to_remove.gas_price() { warn!(target: "txpool", "ready replacement transaction underpriced [{:?}]", tx.hash()); - return Err(PoolError::ReplacementUnderpriced(Box::new(tx.clone()))) + return Err(PoolError::ReplacementUnderpriced(Box::new(tx.clone()))); } else { trace!(target: "txpool", "replacing ready transaction [{:?}] with higher gas price [{:?}]", to_remove.transaction.transaction.hash(), tx.hash()); } diff --git a/crates/anvil/src/filter.rs b/crates/anvil/src/filter.rs index 60dce6b66956..3cf81bc523e2 100644 --- a/crates/anvil/src/filter.rs +++ b/crates/anvil/src/filter.rs @@ -54,7 +54,7 @@ impl Filters { .await .unwrap_or_else(|| ResponseResult::success(Vec::<()>::new())); *deadline = self.next_deadline(); - return resp + return resp; } } warn!(target: "node::filter", "No filter found for {}", id); @@ -65,7 +65,7 @@ impl Filters { pub async fn get_log_filter(&self, id: &str) -> Option { let filters = self.active_filters.lock().await; if let Some((EthFilter::Logs(ref log), _)) = filters.get(id) { - return log.filter.filter.clone() + return log.filter.filter.clone(); } None } @@ -94,7 +94,7 @@ impl Filters { active_filters.retain(|id, (_, deadline)| { if now > *deadline { trace!(target: "node::filter",?id, "Evicting stale filter"); - return false + return false; } true }); diff --git a/crates/anvil/src/pubsub.rs b/crates/anvil/src/pubsub.rs index b0b8b33bbecd..73d1c28b7e3d 100644 --- a/crates/anvil/src/pubsub.rs +++ b/crates/anvil/src/pubsub.rs @@ -154,10 +154,10 @@ pub fn filter_logs( fn add_log(block_hash: B256, l: &Log, block: &Block, params: &FilteredParams) -> bool { if params.filter.is_some() { let block_number = block.header.number; - if !params.filter_block_range(block_number) || - !params.filter_block_hash(block_hash) || - !params.filter_address(&l.address) || - !params.filter_topics(l.topics()) + if !params.filter_block_range(block_number) + || !params.filter_block_hash(block_hash) + || !params.filter_address(&l.address) + || !params.filter_topics(l.topics()) { return false; } diff --git a/crates/anvil/src/service.rs b/crates/anvil/src/service.rs index 71cfdfecbd8d..0d43e58e1957 100644 --- a/crates/anvil/src/service.rs +++ b/crates/anvil/src/service.rs @@ -82,7 +82,7 @@ impl Future for NodeService { pin.block_producer.queued.push_back(transactions); } else { // no progress made - break + break; } } @@ -155,7 +155,7 @@ impl Stream for BlockProducer { Err(err) => { panic!("miner task failed: {}", err); } - } + }; } else { pin.block_mining = Some(mining) } diff --git a/crates/anvil/src/tasks/block_listener.rs b/crates/anvil/src/tasks/block_listener.rs index 0b9388224ca0..2b3e2cb574c7 100644 --- a/crates/anvil/src/tasks/block_listener.rs +++ b/crates/anvil/src/tasks/block_listener.rs @@ -38,7 +38,7 @@ where let pin = self.get_mut(); if pin.on_shutdown.poll_unpin(cx).is_ready() { - return Poll::Ready(()) + return Poll::Ready(()); } let mut block = None; @@ -46,7 +46,7 @@ where while let Poll::Ready(maybe_block) = pin.stream.poll_next_unpin(cx) { if maybe_block.is_none() { // stream complete - return Poll::Ready(()) + return Poll::Ready(()); } block = maybe_block; } diff --git a/crates/anvil/tests/it/proof/eip1186.rs b/crates/anvil/tests/it/proof/eip1186.rs index c83cdf4f8e06..3bbc6b8b8e5b 100644 --- a/crates/anvil/tests/it/proof/eip1186.rs +++ b/crates/anvil/tests/it/proof/eip1186.rs @@ -75,7 +75,7 @@ where L: TrieLayout, { if proof.is_empty() { - return Err(VerifyError::IncompleteProof) + return Err(VerifyError::IncompleteProof); } let key = NibbleSlice::new(raw_key); process_node::(Some(root), &proof[0], key, expected_value, &proof[1..]) @@ -93,13 +93,13 @@ where { if let Some(value) = expected_value { if encoded_node == value { - return Ok(()) + return Ok(()); } } if let Some(expected) = expected_node_hash { let calculated_node_hash = ::hash(encoded_node); if calculated_node_hash != *expected { - return Err(VerifyError::HashMismatch(calculated_node_hash)) + return Err(VerifyError::HashMismatch(calculated_node_hash)); } } let node = ::decode(encoded_node).map_err(VerifyError::DecodeError)?; @@ -144,9 +144,9 @@ where L: TrieLayout, { if key != nib && expected_value.is_none() { - return Ok(()) + return Ok(()); } else if key != nib { - return Err(VerifyError::NonExistingValue(key)) + return Err(VerifyError::NonExistingValue(key)); } match_value::(Some(data), key, expected_value, proof) } @@ -161,9 +161,9 @@ where L: TrieLayout, { if !key.starts_with(nib) && expected_value.is_none() { - return Ok(()) + return Ok(()); } else if !key.starts_with(nib) { - return Err(VerifyError::NonExistingValue(key)) + return Err(VerifyError::NonExistingValue(key)); } key.advance(nib.len()); @@ -191,9 +191,9 @@ where L: TrieLayout, { if !key.starts_with(&nib) && expected_value.is_none() { - return Ok(()) + return Ok(()); } else if !key.starts_with(&nib) && expected_value.is_some() { - return Err(VerifyError::NonExistingValue(key)) + return Err(VerifyError::NonExistingValue(key)); } key.advance(nib.len()); diff --git a/crates/anvil/tests/it/transaction.rs b/crates/anvil/tests/it/transaction.rs index 18a74e1a9d8a..3a6eb109fc87 100644 --- a/crates/anvil/tests/it/transaction.rs +++ b/crates/anvil/tests/it/transaction.rs @@ -842,7 +842,7 @@ async fn can_stream_pending_transactions() { let sent_txs = sent.iter().map(|tx| tx.transaction_hash).collect::>(); assert_eq!(sent_txs, watch_received.iter().map(|tx| tx.hash).collect()); assert_eq!(sent_txs, sub_received.iter().map(|tx| tx.hash).collect()); - break + break; } } } diff --git a/crates/cast/bin/cmd/logs.rs b/crates/cast/bin/cmd/logs.rs index e7816afa3898..06d682c9ff36 100644 --- a/crates/cast/bin/cmd/logs.rs +++ b/crates/cast/bin/cmd/logs.rs @@ -100,7 +100,7 @@ impl LogsArgs { println!("{}", logs); - return Ok(()) + return Ok(()); } let mut stdout = io::stdout(); diff --git a/crates/cast/bin/cmd/run.rs b/crates/cast/bin/cmd/run.rs index 3fc09565cde6..b78c986abcb2 100644 --- a/crates/cast/bin/cmd/run.rs +++ b/crates/cast/bin/cmd/run.rs @@ -109,8 +109,8 @@ impl RunArgs { .wrap_err_with(|| format!("tx not found: {:?}", tx_hash))?; // check if the tx is a system transaction - if is_known_system_sender(tx.from) || - tx.transaction_type.map(|ty| ty.to::()) == Some(SYSTEM_TRANSACTION_TYPE) + if is_known_system_sender(tx.from) + || tx.transaction_type.map(|ty| ty.to::()) == Some(SYSTEM_TRANSACTION_TYPE) { return Err(eyre::eyre!( "{:?} is a system transaction.\nReplaying system transactions is currently not supported.", @@ -166,16 +166,16 @@ impl RunArgs { pb.set_position(0); let BlockTransactions::Full(txs) = block.transactions else { - return Err(eyre::eyre!("Could not get block txs")) + return Err(eyre::eyre!("Could not get block txs")); }; for (index, tx) in txs.into_iter().enumerate() { // System transactions such as on L2s don't contain any pricing info so // we skip them otherwise this would cause // reverts - if is_known_system_sender(tx.from) || - tx.transaction_type.map(|ty| ty.to::()) == - Some(SYSTEM_TRANSACTION_TYPE) + if is_known_system_sender(tx.from) + || tx.transaction_type.map(|ty| ty.to::()) + == Some(SYSTEM_TRANSACTION_TYPE) { update_progress!(pb, index); continue; diff --git a/crates/cast/bin/cmd/storage.rs b/crates/cast/bin/cmd/storage.rs index 397bd07e2b1b..269f3624338f 100644 --- a/crates/cast/bin/cmd/storage.rs +++ b/crates/cast/bin/cmd/storage.rs @@ -248,7 +248,7 @@ async fn fetch_storage_slots( fn print_storage(layout: StorageLayout, values: Vec, pretty: bool) -> Result<()> { if !pretty { println!("{}", serde_json::to_string_pretty(&serde_json::to_value(layout)?)?); - return Ok(()) + return Ok(()); } let mut table = Table::new(); diff --git a/crates/cast/bin/cmd/wallet/vanity.rs b/crates/cast/bin/cmd/wallet/vanity.rs index c3485ddfa96f..20a1d3f1e9d3 100644 --- a/crates/cast/bin/cmd/wallet/vanity.rs +++ b/crates/cast/bin/cmd/wallet/vanity.rs @@ -347,7 +347,7 @@ impl TypedValueParser for HexAddressValidator { return Err(clap::Error::raw( clap::error::ErrorKind::InvalidValue, "vanity patterns length exceeded. cannot be more than 40 characters", - )) + )); } let value = value.to_str().ok_or_else(|| { clap::Error::raw(clap::error::ErrorKind::InvalidUtf8, "address must be valid utf8") diff --git a/crates/cast/src/lib.rs b/crates/cast/src/lib.rs index 38498786ea18..d29b73dd7952 100644 --- a/crates/cast/src/lib.rs +++ b/crates/cast/src/lib.rs @@ -1069,7 +1069,7 @@ impl SimpleCast { pub fn to_ascii(hex: &str) -> Result { let bytes = hex::decode(hex)?; if !bytes.iter().all(u8::is_ascii) { - return Err(eyre::eyre!("Invalid ASCII bytes")) + return Err(eyre::eyre!("Invalid ASCII bytes")); } Ok(String::from_utf8(bytes).unwrap()) } @@ -1371,7 +1371,7 @@ impl SimpleCast { let base_in = Base::unwrap_or_detect(base_in, value)?; let base_out: Base = base_out.parse()?; if base_in == base_out { - return Ok(value.to_string()) + return Ok(value.to_string()); } let mut n = NumberWithBase::parse_int(value, Some(&base_in.to_string()))?; @@ -1435,7 +1435,7 @@ impl SimpleCast { let s = if let Some(stripped) = s.strip_prefix("000000000000000000000000") { stripped } else { - return Err(eyre::eyre!("Not convertible to address, there are non-zero bytes")) + return Err(eyre::eyre!("Not convertible to address, there are non-zero bytes")); }; let lowercase_address_string = format!("0x{s}"); @@ -1699,20 +1699,20 @@ impl SimpleCast { match v_ty { // For value types, `h` pads the value to 32 bytes in the same way as when storing the // value in memory. - DynSolType::Bool | - DynSolType::Int(_) | - DynSolType::Uint(_) | - DynSolType::FixedBytes(_) | - DynSolType::Address | - DynSolType::Function => hasher.update(v.as_word().unwrap()), + DynSolType::Bool + | DynSolType::Int(_) + | DynSolType::Uint(_) + | DynSolType::FixedBytes(_) + | DynSolType::Address + | DynSolType::Function => hasher.update(v.as_word().unwrap()), // For strings and byte arrays, `h(k)` is just the unpadded data. DynSolType::String | DynSolType::Bytes => hasher.update(v.as_packed_seq().unwrap()), - DynSolType::Array(..) | - DynSolType::FixedArray(..) | - DynSolType::Tuple(..) | - DynSolType::CustomStruct { .. } => { + DynSolType::Array(..) + | DynSolType::FixedArray(..) + | DynSolType::Tuple(..) + | DynSolType::CustomStruct { .. } => { eyre::bail!("Type `{v_ty}` is not supported as a mapping key") } } @@ -1962,7 +1962,7 @@ impl SimpleCast { } if optimize == 0 { let selector = get_func(signature)?.selector(); - return Ok((selector.to_string(), String::from(signature))) + return Ok((selector.to_string(), String::from(signature))); } let Some((name, params)) = signature.split_once('(') else { eyre::bail!("invalid function signature"); @@ -1984,7 +1984,7 @@ impl SimpleCast { if selector.iter().take_while(|&&byte| byte == 0).count() == optimize { found.store(true, Ordering::Relaxed); - return Some((nonce, hex::encode_prefixed(selector), input)) + return Some((nonce, hex::encode_prefixed(selector), input)); } nonce += nonce_step; diff --git a/crates/cast/src/rlp_converter.rs b/crates/cast/src/rlp_converter.rs index d0e94301ee65..cb2b00ea93e6 100644 --- a/crates/cast/src/rlp_converter.rs +++ b/crates/cast/src/rlp_converter.rs @@ -56,7 +56,7 @@ impl Item { Value::Object(_) => { eyre::bail!("RLP input can not contain objects") } - } + }; } } diff --git a/crates/cast/src/tx.rs b/crates/cast/src/tx.rs index 1bfd0c40ff67..a8a9f2a30d70 100644 --- a/crates/cast/src/tx.rs +++ b/crates/cast/src/tx.rs @@ -173,7 +173,7 @@ impl<'a, M: Middleware> TxBuilder<'a, M> { args: Vec, ) -> Result<(Vec, Function)> { if sig.trim().is_empty() { - return Err(FunctionSignatureError::MissingSignature.into()) + return Err(FunctionSignatureError::MissingSignature.into()); } let args = resolve_name_args(&args, self.provider).await; @@ -228,7 +228,7 @@ impl<'a, M: Middleware> TxBuilder<'a, M> { value: Option<(&str, Vec)>, ) -> Result<&mut TxBuilder<'a, M>> { if let Some((sig, args)) = value { - return self.set_args(sig, args).await + return self.set_args(sig, args).await; } Ok(self) } diff --git a/crates/cheatcodes/spec/src/cheatcode.rs b/crates/cheatcodes/spec/src/cheatcode.rs index 95aa9aa47657..4ce8d4ed960a 100644 --- a/crates/cheatcodes/spec/src/cheatcode.rs +++ b/crates/cheatcodes/spec/src/cheatcode.rs @@ -131,13 +131,13 @@ impl Group { pub const fn safety(self) -> Option { match self { Self::Evm | Self::Testing => None, - Self::Scripting | - Self::Filesystem | - Self::Environment | - Self::String | - Self::Json | - Self::Toml | - Self::Utilities => Some(Safety::Safe), + Self::Scripting + | Self::Filesystem + | Self::Environment + | Self::String + | Self::Json + | Self::Toml + | Self::Utilities => Some(Safety::Safe), } } diff --git a/crates/cheatcodes/spec/src/lib.rs b/crates/cheatcodes/spec/src/lib.rs index 10a53e18d874..0093e63d07c6 100644 --- a/crates/cheatcodes/spec/src/lib.rs +++ b/crates/cheatcodes/spec/src/lib.rs @@ -161,7 +161,7 @@ interface Vm {{ if let Ok(old_contents) = fs::read_to_string(file) { if normalize_newlines(&old_contents) == normalize_newlines(contents) { // File is already up to date. - return + return; } } diff --git a/crates/cheatcodes/src/error.rs b/crates/cheatcodes/src/error.rs index 8b5f8102d8e3..2d77b388dcfc 100644 --- a/crates/cheatcodes/src/error.rs +++ b/crates/cheatcodes/src/error.rs @@ -70,7 +70,7 @@ macro_rules! ensure_not_precompile { return Err($crate::error::precompile_error( ::CHEATCODE.func.id, $address, - )) + )); } }; } diff --git a/crates/cheatcodes/src/evm.rs b/crates/cheatcodes/src/evm.rs index 601c97ad0046..2269c467cf91 100644 --- a/crates/cheatcodes/src/evm.rs +++ b/crates/cheatcodes/src/evm.rs @@ -99,13 +99,13 @@ impl Cheatcode for dumpStateCall { // Do not include system account or empty accounts in the dump. let skip = |key: &Address, val: &Account| { - key == &CHEATCODE_ADDRESS || - key == &CALLER || - key == &HARDHAT_CONSOLE_ADDRESS || - key == &TEST_CONTRACT_ADDRESS || - key == &ccx.caller || - key == &ccx.state.config.evm_opts.sender || - val.is_empty() + key == &CHEATCODE_ADDRESS + || key == &CALLER + || key == &HARDHAT_CONSOLE_ADDRESS + || key == &TEST_CONTRACT_ADDRESS + || key == &ccx.caller + || key == &ccx.state.config.evm_opts.sender + || val.is_empty() }; let alloc = ccx diff --git a/crates/cheatcodes/src/evm/mapping.rs b/crates/cheatcodes/src/evm/mapping.rs index f5acc4966595..4ab703a2a91b 100644 --- a/crates/cheatcodes/src/evm/mapping.rs +++ b/crates/cheatcodes/src/evm/mapping.rs @@ -29,7 +29,7 @@ impl MappingSlots { match self.seen_sha3.get(&slot).copied() { Some((key, parent)) => { if self.keys.contains_key(&slot) { - return false + return false; } self.keys.insert(slot, key); self.parent_slots.insert(slot, parent); diff --git a/crates/cheatcodes/src/inspector.rs b/crates/cheatcodes/src/inspector.rs index 699840d9325a..331a7dd41d4d 100644 --- a/crates/cheatcodes/src/inspector.rs +++ b/crates/cheatcodes/src/inspector.rs @@ -514,10 +514,10 @@ impl Inspector for Cheatcodes { ); } // Record account accesses via the EXT family of opcodes - opcode::EXTCODECOPY | - opcode::EXTCODESIZE | - opcode::EXTCODEHASH | - opcode::BALANCE => { + opcode::EXTCODECOPY + | opcode::EXTCODESIZE + | opcode::EXTCODEHASH + | opcode::BALANCE => { let kind = match interpreter.current_opcode() { opcode::EXTCODECOPY => crate::Vm::AccountAccessKind::Extcodecopy, opcode::EXTCODESIZE => crate::Vm::AccountAccessKind::Extcodesize, @@ -739,7 +739,7 @@ impl Inspector for Cheatcodes { let ecx = &mut ecx.inner; if call.contract == HARDHAT_CONSOLE_ADDRESS { - return None + return None; } // Handle expected calls @@ -777,8 +777,8 @@ impl Inspector for Cheatcodes { mocks .iter() .find(|(mock, _)| { - call.input.get(..mock.calldata.len()) == Some(&mock.calldata[..]) && - mock.value.map_or(true, |value| value == call.transfer.value) + call.input.get(..mock.calldata.len()) == Some(&mock.calldata[..]) + && mock.value.map_or(true, |value| value == call.transfer.value) }) .map(|(_, v)| v) }) { @@ -789,14 +789,14 @@ impl Inspector for Cheatcodes { gas, }, memory_offset: call.return_memory_offset.clone(), - }) + }); } } // Apply our prank if let Some(prank) = &self.prank { - if ecx.journaled_state.depth() >= prank.depth && - call.context.caller == prank.prank_caller + if ecx.journaled_state.depth() >= prank.depth + && call.context.caller == prank.prank_caller { let mut prank_applied = false; @@ -828,8 +828,8 @@ impl Inspector for Cheatcodes { // // We do this because any subsequent contract calls *must* exist on chain and // we only want to grab *this* call, not internal ones - if ecx.journaled_state.depth() == broadcast.depth && - call.context.caller == broadcast.original_caller + if ecx.journaled_state.depth() == broadcast.depth + && call.context.caller == broadcast.original_caller { // At the target depth we set `msg.sender` & tx.origin. // We are simulating the caller as being an EOA, so *both* must be set to the @@ -851,7 +851,7 @@ impl Inspector for Cheatcodes { gas, }, memory_offset: call.return_memory_offset.clone(), - }) + }); } let is_fixed_gas_limit = check_if_fixed_gas_limit(ecx, call.gas_limit); @@ -892,7 +892,7 @@ impl Inspector for Cheatcodes { gas, }, memory_offset: call.return_memory_offset.clone(), - }) + }); } } } @@ -1100,7 +1100,7 @@ impl Inspector for Cheatcodes { if self.expected_emits.iter().any(|expected| !expected.found) { outcome.result.result = InstructionResult::Revert; outcome.result.output = "log != expected log".abi_encode().into(); - return outcome + return outcome; } else { // All emits were found, we're good. // Clear the queue, as we expect the user to declare more events for the next call @@ -1118,7 +1118,7 @@ impl Inspector for Cheatcodes { if outcome.result.is_revert() { if let Some(err) = diag { outcome.result.output = Error::encode(err.to_error_msg(&self.labels)); - return outcome + return outcome; } } @@ -1127,9 +1127,9 @@ impl Inspector for Cheatcodes { if let TransactTo::Call(test_contract) = ecx.env.tx.transact_to { // if a call to a different contract than the original test contract returned with // `Stop` we check if the contract actually exists on the active fork - if ecx.db.is_forked_mode() && - outcome.result.result == InstructionResult::Stop && - call.contract != test_contract + if ecx.db.is_forked_mode() + && outcome.result.result == InstructionResult::Stop + && call.contract != test_contract { self.fork_revert_diagnostic = ecx.db.diagnose_revert(call.contract, &ecx.journaled_state); @@ -1241,8 +1241,8 @@ impl Inspector for Cheatcodes { // Apply our broadcast if let Some(broadcast) = &self.broadcast { - if ecx.journaled_state.depth() >= broadcast.depth && - call.caller == broadcast.original_caller + if ecx.journaled_state.depth() >= broadcast.depth + && call.caller == broadcast.original_caller { if let Err(err) = ecx.journaled_state.load_account(broadcast.new_origin, &mut ecx.db) @@ -1254,7 +1254,7 @@ impl Inspector for Cheatcodes { gas, }, address: None, - }) + }); } ecx.env.tx.caller = broadcast.new_origin; @@ -1390,8 +1390,8 @@ impl Inspector for Cheatcodes { // Handle expected reverts if let Some(expected_revert) = &self.expected_revert { - if ecx.journaled_state.depth() <= expected_revert.depth && - matches!(expected_revert.kind, ExpectedRevertKind::Default) + if ecx.journaled_state.depth() <= expected_revert.depth + && matches!(expected_revert.kind, ExpectedRevertKind::Default) { let expected_revert = std::mem::take(&mut self.expected_revert).unwrap(); return match expect::handle_expect_revert( @@ -1638,10 +1638,10 @@ fn apply_dispatch(calls: &Vm::VmCalls, ccx: &mut CheatsCtxt fn access_is_call(kind: crate::Vm::AccountAccessKind) -> bool { matches!( kind, - crate::Vm::AccountAccessKind::Call | - crate::Vm::AccountAccessKind::StaticCall | - crate::Vm::AccountAccessKind::CallCode | - crate::Vm::AccountAccessKind::DelegateCall + crate::Vm::AccountAccessKind::Call + | crate::Vm::AccountAccessKind::StaticCall + | crate::Vm::AccountAccessKind::CallCode + | crate::Vm::AccountAccessKind::DelegateCall ) } diff --git a/crates/cheatcodes/src/string.rs b/crates/cheatcodes/src/string.rs index b7992b9450fd..86f38cfd74c4 100644 --- a/crates/cheatcodes/src/string.rs +++ b/crates/cheatcodes/src/string.rs @@ -183,10 +183,10 @@ fn parse_value_fallback(s: &str, ty: &DynSolType) -> Option { + DynSolType::Int(_) + | DynSolType::Uint(_) + | DynSolType::FixedBytes(_) + | DynSolType::Bytes => { if !s.starts_with("0x") && s.chars().all(|c| c.is_ascii_hexdigit()) { return Some(Err("missing hex prefix (\"0x\") for hex string")); } diff --git a/crates/cheatcodes/src/test/assert.rs b/crates/cheatcodes/src/test/assert.rs index d727626ca48c..e68c08d5daa9 100644 --- a/crates/cheatcodes/src/test/assert.rs +++ b/crates/cheatcodes/src/test/assert.rs @@ -1128,13 +1128,13 @@ fn uint_assert_approx_eq_rel( right, max_delta, real_delta: EqRelDelta::Undefined, - }))) + }))); } let delta = get_delta_uint(left, right) .checked_mul(U256::pow(U256::from(10), EQ_REL_DELTA_RESOLUTION)) - .ok_or(EqRelAssertionError::Overflow)? / - right; + .ok_or(EqRelAssertionError::Overflow)? + / right; if delta <= max_delta { Ok(Default::default()) @@ -1159,14 +1159,14 @@ fn int_assert_approx_eq_rel( right, max_delta, real_delta: EqRelDelta::Undefined, - }))) + }))); } let (_, abs_right) = right.into_sign_and_abs(); let delta = get_delta_int(left, right) .checked_mul(U256::pow(U256::from(10), EQ_REL_DELTA_RESOLUTION)) - .ok_or(EqRelAssertionError::Overflow)? / - abs_right; + .ok_or(EqRelAssertionError::Overflow)? + / abs_right; if delta <= max_delta { Ok(Default::default()) diff --git a/crates/cheatcodes/src/test/expect.rs b/crates/cheatcodes/src/test/expect.rs index 02c747adb2ff..ab52631f3941 100644 --- a/crates/cheatcodes/src/test/expect.rs +++ b/crates/cheatcodes/src/test/expect.rs @@ -410,7 +410,7 @@ pub(crate) fn handle_expect_emit(state: &mut Cheatcodes, log: &alloy_primitives: // This allows a contract to arbitrarily emit more events than expected (additive behavior), // as long as all the previous events were matched in the order they were expected to be. if state.expected_emits.iter().all(|expected| expected.found) { - return + return; } // if there's anything to fill, we need to pop back. @@ -428,7 +428,7 @@ pub(crate) fn handle_expect_emit(state: &mut Cheatcodes, log: &alloy_primitives: // Fill the event. event_to_fill_or_check.log = Some(log.data.clone()); state.expected_emits.push_back(event_to_fill_or_check); - return + return; }; let expected_topic_0 = expected.topics().first(); diff --git a/crates/chisel/bin/main.rs b/crates/chisel/bin/main.rs index 43b6a1b21254..32aebc5a09a1 100644 --- a/crates/chisel/bin/main.rs +++ b/crates/chisel/bin/main.rs @@ -135,7 +135,7 @@ async fn main() -> eyre::Result<()> { DispatchResult::CommandFailed(e) => eprintln!("{e}"), _ => panic!("Unexpected result: Please report this bug."), } - return Ok(()) + return Ok(()); } Some(ChiselSubcommand::Load { id }) | Some(ChiselSubcommand::View { id }) => { // For both of these subcommands, we need to attempt to load the session from cache @@ -143,7 +143,7 @@ async fn main() -> eyre::Result<()> { DispatchResult::CommandSuccess(_) => { /* Continue */ } DispatchResult::CommandFailed(e) => { eprintln!("{e}"); - return Ok(()) + return Ok(()); } _ => panic!("Unexpected result! Please report this bug."), } @@ -156,7 +156,7 @@ async fn main() -> eyre::Result<()> { } _ => panic!("Unexpected result! Please report this bug."), } - return Ok(()) + return Ok(()); } } Some(ChiselSubcommand::ClearCache) => { @@ -165,7 +165,7 @@ async fn main() -> eyre::Result<()> { DispatchResult::CommandFailed(e) => eprintln!("{e}"), _ => panic!("Unexpected result! Please report this bug."), } - return Ok(()) + return Ok(()); } None => { /* No chisel subcommand present; Continue */ } } @@ -207,7 +207,7 @@ async fn main() -> eyre::Result<()> { } Err(ReadlineError::Interrupted) => { if interrupt { - break + break; } else { println!("(To exit, press Ctrl+C again)"); interrupt = true; @@ -216,7 +216,7 @@ async fn main() -> eyre::Result<()> { Err(ReadlineError::Eof) => break, Err(err) => { println!("Error: {err:?}"); - break + break; } } } diff --git a/crates/chisel/src/dispatcher.rs b/crates/chisel/src/dispatcher.rs index cba66f7aa4f7..d9a980de20d2 100644 --- a/crates/chisel/src/dispatcher.rs +++ b/crates/chisel/src/dispatcher.rs @@ -86,11 +86,11 @@ impl DispatchResult { pub fn is_error(&self) -> bool { matches!( self, - DispatchResult::Failure(_) | - DispatchResult::CommandFailed(_) | - DispatchResult::UnrecognizedCommand(_) | - DispatchResult::SolangParserFailed(_) | - DispatchResult::FileIoError(_) + DispatchResult::Failure(_) + | DispatchResult::CommandFailed(_) + | DispatchResult::UnrecognizedCommand(_) + | DispatchResult::SolangParserFailed(_) + | DispatchResult::FileIoError(_) ) } } @@ -248,7 +248,7 @@ impl ChiselDispatcher { } if let Err(e) = self.session.write() { - return DispatchResult::FileIoError(e.into()) + return DispatchResult::FileIoError(e.into()); } DispatchResult::CommandSuccess(Some(format!( "Saved session to cache with ID = {}", @@ -263,7 +263,7 @@ impl ChiselDispatcher { // Must supply a session ID as the argument. return DispatchResult::CommandFailed(Self::make_error( "Must supply a session ID as the argument.", - )) + )); } // Use args as the name @@ -272,7 +272,7 @@ impl ChiselDispatcher { // Don't save an empty session if !self.source().run_code.is_empty() { if let Err(e) = self.session.write() { - return DispatchResult::FileIoError(e.into()) + return DispatchResult::FileIoError(e.into()); } println!("{}", Paint::green("Saved current session!")); } @@ -337,12 +337,12 @@ impl ChiselDispatcher { self.source_mut().config.evm_opts.fork_url = None; return DispatchResult::CommandSuccess(Some( "Now using local environment.".to_string(), - )) + )); } if args.len() != 1 { return DispatchResult::CommandFailed(Self::make_error( "Must supply a session ID as the argument.", - )) + )); } let arg = *args.first().unwrap(); @@ -368,7 +368,7 @@ impl ChiselDispatcher { // Check validity of URL if Url::parse(&fork_url).is_err() { - return DispatchResult::CommandFailed(Self::make_error("Invalid fork URL!")) + return DispatchResult::CommandFailed(Self::make_error("Invalid fork URL!")); } // Create success message before moving the fork_url @@ -401,7 +401,7 @@ impl ChiselDispatcher { if arg.is_empty() { self.source_mut().config.calldata = None; - return DispatchResult::CommandSuccess(Some("Calldata cleared.".to_string())) + return DispatchResult::CommandSuccess(Some("Calldata cleared.".to_string())); } let calldata = hex::decode(arg); @@ -465,7 +465,7 @@ impl ChiselDispatcher { // Create "script" dir if it does not already exist. if !Path::new("script").exists() { if let Err(e) = std::fs::create_dir_all("script") { - return DispatchResult::CommandFailed(Self::make_error(e.to_string())) + return DispatchResult::CommandFailed(Self::make_error(e.to_string())); } } @@ -475,7 +475,7 @@ impl ChiselDispatcher { if let Err(e) = std::fs::write(PathBuf::from("script/REPL.s.sol"), formatted_source) { - return DispatchResult::CommandFailed(Self::make_error(e.to_string())) + return DispatchResult::CommandFailed(Self::make_error(e.to_string())); } DispatchResult::CommandSuccess(Some(String::from( @@ -491,7 +491,7 @@ impl ChiselDispatcher { if args.len() != 2 { return DispatchResult::CommandFailed(Self::make_error( "Incorrect number of arguments supplied. Expected:
", - )) + )); } let request_url = format!( @@ -618,7 +618,7 @@ impl ChiselDispatcher { } ChiselCommand::Exec => { if args.is_empty() { - return DispatchResult::CommandFailed(Self::make_error("No command supplied!")) + return DispatchResult::CommandFailed(Self::make_error("No command supplied!")); } let mut cmd = Command::new(args[0]); @@ -644,7 +644,7 @@ impl ChiselDispatcher { if let Err(e) = result { return DispatchResult::CommandFailed(format!( "Could not write to a temporary file: {e}" - )) + )); } // open the temp file with the editor @@ -658,11 +658,11 @@ impl ChiselDispatcher { if let Some(status_code) = status.code() { return DispatchResult::CommandFailed(format!( "Editor exited with status {status_code}" - )) + )); } else { return DispatchResult::CommandFailed( "Editor exited without a status code".to_string(), - ) + ); } } } @@ -680,7 +680,7 @@ impl ChiselDispatcher { } else { return DispatchResult::CommandFailed( "Could not read the edited file".to_string(), - ) + ); } // if the editor exited successfully, try to compile the new code @@ -692,7 +692,7 @@ impl ChiselDispatcher { Self::decode_traces(&new_session_source.config, &mut res) { if let Err(e) = Self::show_traces(&decoder, &mut res).await { - return DispatchResult::CommandFailed(e.to_string()) + return DispatchResult::CommandFailed(e.to_string()); }; // Show console logs, if there are any @@ -730,7 +730,7 @@ impl ChiselDispatcher { 0 => "No variable supplied!", _ => "!rawstack only takes one argument.", }; - return DispatchResult::CommandFailed(Self::make_error(msg)) + return DispatchResult::CommandFailed(Self::make_error(msg)); } // Store the variable that we want to inspect @@ -768,11 +768,11 @@ impl ChiselDispatcher { return match raw_cmd.parse::() { Ok(cmd) => self.dispatch_command(cmd, &split[1..]).await, Err(e) => DispatchResult::UnrecognizedCommand(e), - } + }; } if input.trim().is_empty() { debug!("empty dispatch input"); - return DispatchResult::Success(None) + return DispatchResult::Success(None); } // Get a mutable reference to the session source @@ -782,7 +782,7 @@ impl ChiselDispatcher { if COMMENT_RE.is_match(input) { debug!(%input, "matched comment"); source.with_run_code(input); - return DispatchResult::Success(None) + return DispatchResult::Success(None); } // If there is an address (or multiple addresses) in the input, ensure that they are @@ -819,7 +819,7 @@ impl ChiselDispatcher { // Return successfully Ok((false, res)) => { debug!(%input, ?res, "inspect success"); - return DispatchResult::Success(res) + return DispatchResult::Success(res); } // Return with the error @@ -836,7 +836,7 @@ impl ChiselDispatcher { if new_source.config.traces || failed { if let Ok(decoder) = Self::decode_traces(&new_source.config, &mut res) { if let Err(e) = Self::show_traces(&decoder, &mut res).await { - return DispatchResult::CommandFailed(e.to_string()) + return DispatchResult::CommandFailed(e.to_string()); }; // Show console logs, if there are any @@ -853,7 +853,7 @@ impl ChiselDispatcher { if failed { return DispatchResult::Failure(Some(Self::make_error( "Failed to execute REPL contract!", - ))) + ))); } } } diff --git a/crates/chisel/src/executor.rs b/crates/chisel/src/executor.rs index 69e35f9477ce..eb8179e3b184 100644 --- a/crates/chisel/src/executor.rs +++ b/crates/chisel/src/executor.rs @@ -136,7 +136,7 @@ impl SessionSource { Ok((source, _)) => source, Err(err) => { debug!(%err, "failed to build new source"); - return Ok((true, None)) + return Ok((true, None)); } }; @@ -154,7 +154,7 @@ impl SessionSource { if self.config.foundry_config.verbosity >= 3 { eprintln!("Could not inspect: {err}"); } - return Ok((true, None)) + return Ok((true, None)); } } } @@ -175,7 +175,7 @@ impl SessionSource { if let Some(event_definition) = intermediate_contract.event_definitions.get(input) { let formatted = format_event_definition(event_definition)?; - return Ok((false, Some(formatted))) + return Ok((false, Some(formatted))); } // we were unable to check the event @@ -184,7 +184,7 @@ impl SessionSource { } debug!(%err, %input, "failed abi encode input"); - return Ok((false, None)) + return Ok((false, None)); } let Some((stack, memory, _)) = &res.state else { @@ -200,7 +200,7 @@ impl SessionSource { } } - return Err(eyre::eyre!("Failed to inspect expression")) + return Err(eyre::eyre!("Failed to inspect expression")); }; let generated_output = source @@ -771,7 +771,7 @@ impl Type { /// See: fn map_special(self) -> Self { if !matches!(self, Self::Function(_, _, _) | Self::Access(_, _) | Self::Custom(_)) { - return self + return self; } let mut types = Vec::with_capacity(5); @@ -780,7 +780,7 @@ impl Type { let len = types.len(); if len == 0 { - return self + return self; } // Type members, like array, bytes etc @@ -818,8 +818,8 @@ impl Type { match name { "block" => match access { "coinbase" => Some(DynSolType::Address), - "timestamp" | "difficulty" | "prevrandao" | "number" | "gaslimit" | - "chainid" | "basefee" | "blobbasefee" => Some(DynSolType::Uint(256)), + "timestamp" | "difficulty" | "prevrandao" | "number" | "gaslimit" + | "chainid" | "basefee" | "blobbasefee" => Some(DynSolType::Uint(256)), _ => None, }, "msg" => match access { @@ -940,7 +940,7 @@ impl Type { custom_type.pop(); } if custom_type.is_empty() { - return Ok(None) + return Ok(None); } // If a contract exists with the given name, check its definitions for a match. @@ -955,7 +955,7 @@ impl Type { if let Some(func) = intermediate_contract.function_definitions.get(cur_type) { // Check if the custom type is a function pointer member access if let res @ Some(_) = func_members(func, custom_type) { - return Ok(res) + return Ok(res); } // Because tuple types cannot be passed to `abi.encode`, we will only be @@ -976,7 +976,7 @@ impl Type { // struct, array, etc. if let pt::Expression::Variable(ident) = return_ty { custom_type.push(ident.name.clone()); - return Self::infer_custom_type(intermediate, custom_type, Some(contract_name)) + return Self::infer_custom_type(intermediate, custom_type, Some(contract_name)); } // Check if our final function call alters the state. If it does, we bail so that it @@ -1015,7 +1015,7 @@ impl Type { // anything. If it is, we can stop here. if let Ok(res) = Self::infer_custom_type(intermediate, custom_type, Some("REPL".into())) { - return Ok(res) + return Ok(res); } // Check if the first element of the custom type is a known contract. If it is, begin @@ -1024,13 +1024,13 @@ impl Type { let contract = intermediate.intermediate_contracts.get(name); if contract.is_some() { let contract_name = custom_type.pop(); - return Self::infer_custom_type(intermediate, custom_type, contract_name) + return Self::infer_custom_type(intermediate, custom_type, contract_name); } // See [`Type::infer_var_expr`] let name = custom_type.last().unwrap(); if let Some(expr) = intermediate.repl_contract_expressions.get(name) { - return Self::infer_var_expr(expr, Some(intermediate), custom_type) + return Self::infer_var_expr(expr, Some(intermediate), custom_type); } // The first element of our custom type was neither a variable or a function within the @@ -1158,7 +1158,7 @@ impl Type { let pt::Expression::Variable(contract_name) = intermediate.repl_contract_expressions.get(&contract_name.name)? else { - return None + return None; }; let contract = intermediate @@ -1196,9 +1196,9 @@ impl Type { Some(DynSolType::Array(inner)) | Some(DynSolType::FixedArray(inner, _)) => { Some(*inner) } - Some(DynSolType::Bytes) | - Some(DynSolType::String) | - Some(DynSolType::FixedBytes(_)) => Some(DynSolType::FixedBytes(1)), + Some(DynSolType::Bytes) + | Some(DynSolType::String) + | Some(DynSolType::FixedBytes(_)) => Some(DynSolType::FixedBytes(1)), ty => ty, } } @@ -1226,10 +1226,10 @@ impl Type { fn is_array(&self) -> bool { matches!( self, - Self::Array(_) | - Self::FixedArray(_, _) | - Self::Builtin(DynSolType::Array(_)) | - Self::Builtin(DynSolType::FixedArray(_, _)) + Self::Array(_) + | Self::FixedArray(_, _) + | Self::Builtin(DynSolType::Array(_)) + | Self::Builtin(DynSolType::FixedArray(_, _)) ) } @@ -1250,7 +1250,7 @@ impl Type { #[inline] fn func_members(func: &pt::FunctionDefinition, custom_type: &[String]) -> Option { if !matches!(func.ty, pt::FunctionTy::Function) { - return None + return None; } let vis = func.attributes.iter().find_map(|attr| match attr { @@ -1694,7 +1694,7 @@ mod tests { Ok((solc, v)) => { // successfully installed eprintln!("found installed Solc v{v} @ {}", solc.solc.display()); - break + break; } Err(e) => { // try reinstalling @@ -1702,7 +1702,7 @@ mod tests { let solc = Solc::blocking_install(&version.parse().unwrap()); if solc.map_err(SolcError::from).and_then(|solc| solc.version()).is_ok() { *is_preinstalled = true; - break + break; } } } diff --git a/crates/chisel/src/runner.rs b/crates/chisel/src/runner.rs index 6ffcb6770be4..28babfb8ba06 100644 --- a/crates/chisel/src/runner.rs +++ b/crates/chisel/src/runner.rs @@ -151,9 +151,9 @@ impl ChiselRunner { self.executor.env.tx.gas_limit = mid_gas_limit; let res = self.executor.call_raw(from, to, calldata.clone(), value)?; match res.exit_reason { - InstructionResult::Revert | - InstructionResult::OutOfGas | - InstructionResult::OutOfFunds => { + InstructionResult::Revert + | InstructionResult::OutOfGas + | InstructionResult::OutOfFunds => { lowest_gas_limit = mid_gas_limit; } _ => { @@ -161,9 +161,9 @@ impl ChiselRunner { // if last two successful estimations only vary by 10%, we consider this to // sufficiently accurate const ACCURACY: u64 = 10; - if (last_highest_gas_limit - highest_gas_limit) * ACCURACY / - last_highest_gas_limit < - 1 + if (last_highest_gas_limit - highest_gas_limit) * ACCURACY + / last_highest_gas_limit + < 1 { // update the gas gas_used = highest_gas_limit; diff --git a/crates/chisel/src/session.rs b/crates/chisel/src/session.rs index 3be34a179cc9..0aed74499133 100644 --- a/crates/chisel/src/session.rs +++ b/crates/chisel/src/session.rs @@ -116,7 +116,7 @@ impl ChiselSession { let mut latest = if let Some(e) = entries.next() { e? } else { - return Ok((String::from("0"), format!("{cache_dir}chisel-0.json"))) + return Ok((String::from("0"), format!("{cache_dir}chisel-0.json"))); }; let mut session_num = 1; diff --git a/crates/chisel/src/session_source.rs b/crates/chisel/src/session_source.rs index 47660ba091ae..19b36b5f3505 100644 --- a/crates/chisel/src/session_source.rs +++ b/crates/chisel/src/session_source.rs @@ -523,9 +523,9 @@ contract {contract_name} {{ .into_iter() .filter_map(|sup| match sup { pt::SourceUnitPart::ImportDirective(i) => match i { - pt::Import::Plain(s, _) | - pt::Import::Rename(s, _, _) | - pt::Import::GlobalSymbol(s, _, _) => { + pt::Import::Plain(s, _) + | pt::Import::Rename(s, _, _) + | pt::Import::GlobalSymbol(s, _, _) => { let s = match s { pt::ImportPath::Filename(s) => s.string.clone(), pt::ImportPath::Path(p) => p.to_string(), diff --git a/crates/chisel/src/solidity_helper.rs b/crates/chisel/src/solidity_helper.rs index 42641a1f0a8d..8c39f5bd2efa 100644 --- a/crates/chisel/src/solidity_helper.rs +++ b/crates/chisel/src/solidity_helper.rs @@ -66,10 +66,10 @@ impl SolidityHelper { // highlight comments too let comments_iter = comments.into_iter().map(|comment| { let loc = match comment { - pt::Comment::Line(loc, _) | - pt::Comment::Block(loc, _) | - pt::Comment::DocLine(loc, _) | - pt::Comment::DocBlock(loc, _) => loc, + pt::Comment::Line(loc, _) + | pt::Comment::Block(loc, _) + | pt::Comment::DocLine(loc, _) + | pt::Comment::DocBlock(loc, _) => loc, }; (loc.start(), Style::default().dimmed(), loc.end()) }); @@ -103,7 +103,7 @@ impl SolidityHelper { /// Highlights a solidity source string pub fn highlight(input: &str) -> Cow { if !Paint::is_enabled() { - return Cow::Borrowed(input) + return Cow::Borrowed(input); } // Highlight commands separately @@ -221,7 +221,7 @@ impl Highlighter for SolidityHelper { _default: bool, ) -> Cow<'b, str> { if !Paint::is_enabled() { - return Cow::Borrowed(prompt) + return Cow::Borrowed(prompt); } let mut out = prompt.to_string(); @@ -280,27 +280,27 @@ impl<'a> TokenStyle for Token<'a> { match self { StringLiteral(_, _) => Color::Green.style(), - AddressLiteral(_) | - HexLiteral(_) | - Number(_, _) | - RationalNumber(_, _, _) | - HexNumber(_) | - True | - False => Color::Yellow.style(), - - Memory | Storage | Calldata | Public | Private | Internal | External | Constant | - Pure | View | Payable | Anonymous | Indexed | Abstract | Virtual | Override | - Modifier | Immutable | Unchecked => Color::Cyan.style(), - - Contract | Library | Interface | Function | Pragma | Import | Struct | Event | - Enum | Type | Constructor | As | Is | Using | New | Delete | Do | Continue | - Break | Throw | Emit | Return | Returns | Revert | For | While | If | Else | Try | - Catch | Assembly | Let | Leave | Switch | Case | Default | YulArrow | Arrow => { + AddressLiteral(_) + | HexLiteral(_) + | Number(_, _) + | RationalNumber(_, _, _) + | HexNumber(_) + | True + | False => Color::Yellow.style(), + + Memory | Storage | Calldata | Public | Private | Internal | External | Constant + | Pure | View | Payable | Anonymous | Indexed | Abstract | Virtual | Override + | Modifier | Immutable | Unchecked => Color::Cyan.style(), + + Contract | Library | Interface | Function | Pragma | Import | Struct | Event | Enum + | Type | Constructor | As | Is | Using | New | Delete | Do | Continue | Break + | Throw | Emit | Return | Returns | Revert | For | While | If | Else | Try | Catch + | Assembly | Let | Leave | Switch | Case | Default | YulArrow | Arrow => { Color::Magenta.style() } - Uint(_) | Int(_) | Bytes(_) | Byte | DynamicBytes | Bool | Address | String | - Mapping => Color::Blue.style(), + Uint(_) | Int(_) | Bytes(_) | Byte | DynamicBytes | Bool | Address | String + | Mapping => Color::Blue.style(), Identifier(_) => Style::default(), diff --git a/crates/cli/src/handler.rs b/crates/cli/src/handler.rs index 6666686c5555..3e4f70e1bf03 100644 --- a/crates/cli/src/handler.rs +++ b/crates/cli/src/handler.rs @@ -13,7 +13,7 @@ impl EyreHandler for Handler { f: &mut core::fmt::Formatter<'_>, ) -> core::fmt::Result { if f.alternate() { - return core::fmt::Debug::fmt(error, f) + return core::fmt::Debug::fmt(error, f); } writeln!(f)?; write!(f, "{}", Paint::red(error))?; diff --git a/crates/cli/src/opts/dependency.rs b/crates/cli/src/opts/dependency.rs index 5fa1d851f3cf..40775b7a6e32 100644 --- a/crates/cli/src/opts/dependency.rs +++ b/crates/cli/src/opts/dependency.rs @@ -60,7 +60,7 @@ impl FromStr for Dependency { for (alias, real_org) in COMMON_ORG_ALIASES.iter() { if dependency.starts_with(alias) { dependency = dependency.replacen(alias, real_org, 1); - break + break; } } diff --git a/crates/cli/src/utils/cmd.rs b/crates/cli/src/utils/cmd.rs index e58fd937d136..64f207365144 100644 --- a/crates/cli/src/utils/cmd.rs +++ b/crates/cli/src/utils/cmd.rs @@ -167,14 +167,14 @@ pub fn has_different_gas_calc(chain_id: u64) -> bool { if let Some(chain) = Chain::from(chain_id).named() { return matches!( chain, - NamedChain::Arbitrum | - NamedChain::ArbitrumTestnet | - NamedChain::ArbitrumGoerli | - NamedChain::ArbitrumSepolia | - NamedChain::Moonbeam | - NamedChain::Moonriver | - NamedChain::Moonbase | - NamedChain::MoonbeamDev + NamedChain::Arbitrum + | NamedChain::ArbitrumTestnet + | NamedChain::ArbitrumGoerli + | NamedChain::ArbitrumSepolia + | NamedChain::Moonbeam + | NamedChain::Moonriver + | NamedChain::Moonbase + | NamedChain::MoonbeamDev ); } false @@ -185,10 +185,10 @@ pub fn has_batch_support(chain_id: u64) -> bool { if let Some(chain) = Chain::from(chain_id).named() { return !matches!( chain, - NamedChain::Arbitrum | - NamedChain::ArbitrumTestnet | - NamedChain::ArbitrumGoerli | - NamedChain::ArbitrumSepolia + NamedChain::Arbitrum + | NamedChain::ArbitrumTestnet + | NamedChain::ArbitrumGoerli + | NamedChain::ArbitrumSepolia ); } true diff --git a/crates/common/src/abi.rs b/crates/common/src/abi.rs index b08620d888d1..2a94fcc17f24 100644 --- a/crates/common/src/abi.rs +++ b/crates/common/src/abi.rs @@ -90,8 +90,8 @@ pub fn get_indexed_event(mut event: Event, raw_log: &LogData) -> Event { if param.name.is_empty() { param.name = format!("param{index}"); } - if num_inputs == indexed_params || - (num_address_params == indexed_params && param.ty == "address") + if num_inputs == indexed_params + || (num_address_params == indexed_params && param.ty == "address") { param.indexed = true; } @@ -119,7 +119,7 @@ pub async fn get_func_etherscan( for func in funcs { let res = encode_function_args(&func, args); if res.is_ok() { - return Ok(func) + return Ok(func); } } diff --git a/crates/common/src/compile.rs b/crates/common/src/compile.rs index 8272dece32ac..a1696e32c54e 100644 --- a/crates/common/src/compile.rs +++ b/crates/common/src/compile.rs @@ -261,9 +261,9 @@ impl ProjectCompiler { let dev_functions = artifact.abi.as_ref().map(|abi| abi.functions()).into_iter().flatten().filter( |func| { - func.name.is_test() || - func.name.eq("IS_TEST") || - func.name.eq("IS_SCRIPT") + func.name.is_test() + || func.name.eq("IS_TEST") + || func.name.eq("IS_SCRIPT") }, ); diff --git a/crates/common/src/errors/fs.rs b/crates/common/src/errors/fs.rs index b929e7838140..e43af77c2f76 100644 --- a/crates/common/src/errors/fs.rs +++ b/crates/common/src/errors/fs.rs @@ -93,17 +93,17 @@ impl FsPathError { impl AsRef for FsPathError { fn as_ref(&self) -> &Path { match self { - Self::Write { path, .. } | - Self::Read { path, .. } | - Self::ReadLink { path, .. } | - Self::Copy { from: path, .. } | - Self::CreateDir { path, .. } | - Self::RemoveDir { path, .. } | - Self::CreateFile { path, .. } | - Self::RemoveFile { path, .. } | - Self::Open { path, .. } | - Self::ReadJson { path, .. } | - Self::WriteJson { path, .. } => path, + Self::Write { path, .. } + | Self::Read { path, .. } + | Self::ReadLink { path, .. } + | Self::Copy { from: path, .. } + | Self::CreateDir { path, .. } + | Self::RemoveDir { path, .. } + | Self::CreateFile { path, .. } + | Self::RemoveFile { path, .. } + | Self::Open { path, .. } + | Self::ReadJson { path, .. } + | Self::WriteJson { path, .. } => path, } } } @@ -111,15 +111,15 @@ impl AsRef for FsPathError { impl From for io::Error { fn from(value: FsPathError) -> Self { match value { - FsPathError::Write { source, .. } | - FsPathError::Read { source, .. } | - FsPathError::ReadLink { source, .. } | - FsPathError::Copy { source, .. } | - FsPathError::CreateDir { source, .. } | - FsPathError::RemoveDir { source, .. } | - FsPathError::CreateFile { source, .. } | - FsPathError::RemoveFile { source, .. } | - FsPathError::Open { source, .. } => source, + FsPathError::Write { source, .. } + | FsPathError::Read { source, .. } + | FsPathError::ReadLink { source, .. } + | FsPathError::Copy { source, .. } + | FsPathError::CreateDir { source, .. } + | FsPathError::RemoveDir { source, .. } + | FsPathError::CreateFile { source, .. } + | FsPathError::RemoveFile { source, .. } + | FsPathError::Open { source, .. } => source, FsPathError::ReadJson { source, .. } | FsPathError::WriteJson { source, .. } => { source.into() diff --git a/crates/common/src/fmt/console.rs b/crates/common/src/fmt/console.rs index e4b33c5cd957..05efe6ad512a 100644 --- a/crates/common/src/fmt/console.rs +++ b/crates/common/src/fmt/console.rs @@ -44,10 +44,10 @@ impl ConsoleFmt for String { match spec { FormatSpec::String => self.clone(), FormatSpec::Object => format!("'{}'", self.clone()), - FormatSpec::Number | - FormatSpec::Integer | - FormatSpec::Exponential | - FormatSpec::Hexadecimal => String::from("NaN"), + FormatSpec::Number + | FormatSpec::Integer + | FormatSpec::Exponential + | FormatSpec::Hexadecimal => String::from("NaN"), } } } @@ -238,7 +238,7 @@ fn format_spec<'a>( // no more values if current_value.is_none() { result.push_str(&s[i..].replace("%%", "%")); - break + break; } if expect_fmt { diff --git a/crates/common/src/fmt/mod.rs b/crates/common/src/fmt/mod.rs index fbe1670fc6cb..b857af59f772 100644 --- a/crates/common/src/fmt/mod.rs +++ b/crates/common/src/fmt/mod.rs @@ -32,7 +32,7 @@ pub use ui::{get_pretty_block_attr, get_pretty_tx_attr, get_pretty_tx_receipt_at /// ``` pub fn format_uint_exp(num: U256) -> String { if num < U256::from(10_000) { - return num.to_string() + return num.to_string(); } let exp = to_exp_notation(num, 4, true, Sign::Positive); diff --git a/crates/common/src/fmt/ui.rs b/crates/common/src/fmt/ui.rs index 5549f36abc5f..e27de04ca1d2 100644 --- a/crates/common/src/fmt/ui.rs +++ b/crates/common/src/fmt/ui.rs @@ -393,7 +393,7 @@ pub fn get_pretty_tx_attr(transaction: &Transaction, attr: &str) -> Option Some(transaction.value.pretty()), other => { if let Some(value) = transaction.other.get(other) { - return Some(value.to_string().trim_matches('"').to_string()) + return Some(value.to_string().trim_matches('"').to_string()); } None } @@ -456,7 +456,7 @@ pub fn get_pretty_block_attr(block: &Block, attr: &str) -> Option { if let Some(value) = block.other.get(other) { let val = EthValue::from(value.clone()); - return Some(val.pretty()) + return Some(val.pretty()); } None } diff --git a/crates/common/src/provider/retry.rs b/crates/common/src/provider/retry.rs index e7277bd4b198..00f5c34983de 100644 --- a/crates/common/src/provider/retry.rs +++ b/crates/common/src/provider/retry.rs @@ -32,7 +32,7 @@ impl RetryPolicy for RateLimitRetryPolicy { TransportError::SerError(_) => false, TransportError::DeserError { text, .. } => { if let Ok(resp) = serde_json::from_str::(text) { - return should_retry_json_rpc_error(&resp) + return should_retry_json_rpc_error(&resp); } // some providers send invalid JSON RPC in the error case (no `id:u64`), but the @@ -43,7 +43,7 @@ impl RetryPolicy for RateLimitRetryPolicy { } if let Ok(resp) = serde_json::from_str::(text) { - return should_retry_json_rpc_error(&resp.error) + return should_retry_json_rpc_error(&resp.error); } false @@ -62,10 +62,10 @@ impl RetryPolicy for RateLimitRetryPolicy { let backoff_seconds = &data["rate"]["backoff_seconds"]; // infura rate limit error if let Some(seconds) = backoff_seconds.as_u64() { - return Some(std::time::Duration::from_secs(seconds)) + return Some(std::time::Duration::from_secs(seconds)); } if let Some(seconds) = backoff_seconds.as_f64() { - return Some(std::time::Duration::from_secs(seconds as u64 + 1)) + return Some(std::time::Duration::from_secs(seconds as u64 + 1)); } } } @@ -97,29 +97,29 @@ fn should_retry_json_rpc_error(error: &ErrorPayload) -> bool { let ErrorPayload { code, message, .. } = error; // alchemy throws it this way if *code == 429 { - return true + return true; } // This is an infura error code for `exceeded project rate limit` if *code == -32005 { - return true + return true; } // alternative alchemy error for specific IPs if *code == -32016 && message.contains("rate limit") { - return true + return true; } // quick node error `"credits limited to 6000/sec"` // if *code == -32012 && message.contains("credits") { - return true + return true; } // quick node rate limit error: `100/second request limit reached - reduce calls per second or // upgrade your account at quicknode.com` if *code == -32007 && message.contains("request limit reached") { - return true + return true; } match message.as_str() { @@ -128,11 +128,11 @@ fn should_retry_json_rpc_error(error: &ErrorPayload) -> bool { // also thrown by infura if out of budget for the day and ratelimited "daily request count exceeded, request rate limited" => true, msg => { - msg.contains("rate limit") || - msg.contains("rate exceeded") || - msg.contains("too many requests") || - msg.contains("credits limited") || - msg.contains("request limit") + msg.contains("rate limit") + || msg.contains("rate exceeded") + || msg.contains("too many requests") + || msg.contains("credits limited") + || msg.contains("request limit") } } } diff --git a/crates/common/src/provider/tower.rs b/crates/common/src/provider/tower.rs index 2f97d2f8fbd1..da628a6c669b 100644 --- a/crates/common/src/provider/tower.rs +++ b/crates/common/src/provider/tower.rs @@ -111,7 +111,7 @@ impl tower::Service for RetryBackoffService { err = TransportError::ErrorResp(e.clone()) } else { this.requests_enqueued.fetch_sub(1, Ordering::SeqCst); - return Ok(res) + return Ok(res); } } Err(e) => err = e, @@ -121,7 +121,7 @@ impl tower::Service for RetryBackoffService { if should_retry { rate_limit_retry_number += 1; if rate_limit_retry_number > this.max_rate_limit_retries { - return Err(TransportErrorKind::custom_str("Max retries exceeded")) + return Err(TransportErrorKind::custom_str("Max retries exceeded")); } trace!("retrying request due to {:?}", err); @@ -150,8 +150,8 @@ impl tower::Service for RetryBackoffService { current_queued_reqs, ahead_in_queue, ); - let total_backoff = next_backoff + - std::time::Duration::from_secs(seconds_to_wait_for_compute_budget); + let total_backoff = next_backoff + + std::time::Duration::from_secs(seconds_to_wait_for_compute_budget); trace!(?total_backoff, budget_backoff = ?seconds_to_wait_for_compute_budget, default_backoff = ?next_backoff, ?backoff_hint, "backing off due to rate limit"); @@ -163,7 +163,7 @@ impl tower::Service for RetryBackoffService { } this.requests_enqueued.fetch_sub(1, Ordering::SeqCst); - return Err(err) + return Err(err); } } }) diff --git a/crates/common/src/term.rs b/crates/common/src/term.rs index afeae0664049..af40a12be397 100644 --- a/crates/common/src/term.rs +++ b/crates/common/src/term.rs @@ -66,7 +66,7 @@ impl Spinner { pub fn tick(&mut self) { if self.no_progress { - return + return; } let indicator = Paint::green(self.indicator[self.idx % self.indicator.len()]); @@ -120,7 +120,7 @@ impl SpinnerReporter { // end with a newline println!(); let _ = ack.send(()); - break + break; } Err(TryRecvError::Disconnected) => break, Err(TryRecvError::Empty) => thread::sleep(Duration::from_millis(100)), diff --git a/crates/common/src/transactions.rs b/crates/common/src/transactions.rs index b337147d6171..bc562884462f 100644 --- a/crates/common/src/transactions.rs +++ b/crates/common/src/transactions.rs @@ -31,7 +31,7 @@ impl TransactionReceiptWithRevertReason { async fn fetch_revert_reason(&self, provider: &M) -> Result> { if let Some(false) | None = self.is_failure() { - return Ok(None) + return Ok(None); } if let Some(ref transaction) = provider diff --git a/crates/config/src/cache.rs b/crates/config/src/cache.rs index ef0ca40a468e..5fcbfdfbf908 100644 --- a/crates/config/src/cache.rs +++ b/crates/config/src/cache.rs @@ -24,7 +24,7 @@ impl StorageCachingConfig { pub fn enable_for_chain_id(&self, chain_id: u64) -> bool { // ignore dev chains if [99, 1337, 31337].contains(&chain_id) { - return false + return false; } self.chains.is_match(chain_id) } diff --git a/crates/config/src/endpoints.rs b/crates/config/src/endpoints.rs index 36cc8c7b6a83..cd7c75685e9d 100644 --- a/crates/config/src/endpoints.rs +++ b/crates/config/src/endpoints.rs @@ -270,9 +270,9 @@ impl Serialize for RpcEndpointConfig { where S: Serializer, { - if self.retries.is_none() && - self.retry_backoff.is_none() && - self.compute_units_per_second.is_none() + if self.retries.is_none() + && self.retry_backoff.is_none() + && self.compute_units_per_second.is_none() { // serialize as endpoint if there's no additional config self.endpoint.serialize(serializer) diff --git a/crates/config/src/fix.rs b/crates/config/src/fix.rs index a0ce9fbc1b0b..d5035a4dfb5e 100644 --- a/crates/config/src/fix.rs +++ b/crates/config/src/fix.rs @@ -78,7 +78,7 @@ impl TomlFile { return Err(InsertProfileError { message: format!("Expected [{profile_str}] to be a Table"), value, - }) + }); } // get or create the profile section let profile_map = if let Some(map) = self.get_mut(Config::PROFILE_SECTION) { @@ -98,7 +98,7 @@ impl TomlFile { return Err(InsertProfileError { message: format!("Expected [{}] to be a Table", Config::PROFILE_SECTION), value, - }) + }); }; // check the profile map for structure and existing keys if let Some(profile) = profile_map.get(profile_str) { @@ -111,7 +111,7 @@ impl TomlFile { profile_str ), value, - }) + }); } } else { return Err(InsertProfileError { @@ -121,7 +121,7 @@ impl TomlFile { profile_str ), value, - }) + }); } } // insert the profile @@ -186,7 +186,7 @@ pub fn fix_tomls() -> Vec { Ok(toml_file) => toml_file, Err(err) => { warnings.push(Warning::CouldNotReadToml { path: toml, err: err.to_string() }); - continue + continue; } }; diff --git a/crates/config/src/fuzz.rs b/crates/config/src/fuzz.rs index 3b0e13bcd509..603e3c370822 100644 --- a/crates/config/src/fuzz.rs +++ b/crates/config/src/fuzz.rs @@ -69,7 +69,7 @@ impl InlineConfigParser for FuzzConfig { let overrides: Vec<(String, String)> = Self::get_config_overrides(configs); if overrides.is_empty() { - return Ok(None) + return Ok(None); } let mut conf_clone = self.clone(); diff --git a/crates/config/src/inline/natspec.rs b/crates/config/src/inline/natspec.rs index 27742eb56e4b..7e593fdce263 100644 --- a/crates/config/src/inline/natspec.rs +++ b/crates/config/src/inline/natspec.rs @@ -99,7 +99,7 @@ impl SolcParser { let contract_data = &n.other; if let Value::String(contract_name) = contract_data.get("name")? { if contract_id.ends_with(contract_name) { - return Some(n) + return Some(n); } } } @@ -130,7 +130,7 @@ impl SolcParser { let fn_data = &node.other; let fn_name: String = self.get_fn_name(fn_data)?; let (fn_docs, docs_src_line): (String, String) = self.get_fn_docs(fn_data)?; - return Some((fn_name, fn_docs, docs_src_line)) + return Some((fn_name, fn_docs, docs_src_line)); } None @@ -159,7 +159,7 @@ impl SolcParser { .unwrap_or_else(|| String::from("")); src_line.retain(|c| c != '"'); - return Some((comment.into(), src_line)) + return Some((comment.into(), src_line)); } } } @@ -193,7 +193,7 @@ impl SolangParser { let pt::SourceUnitPart::ContractDefinition(c) = item else { continue }; let Some(id) = c.name.as_ref() else { continue }; if id.name != contract_name { - continue + continue; }; let mut prev_end = c.loc.start(); for part in &c.parts { diff --git a/crates/config/src/invariant.rs b/crates/config/src/invariant.rs index 13c203d396fa..2bab1920e37b 100644 --- a/crates/config/src/invariant.rs +++ b/crates/config/src/invariant.rs @@ -65,7 +65,7 @@ impl InlineConfigParser for InvariantConfig { let overrides: Vec<(String, String)> = Self::get_config_overrides(configs); if overrides.is_empty() { - return Ok(None) + return Ok(None); } // self is Copy. We clone it with dereference. diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index 0c53a6c14e3f..1242c7f235d4 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -712,7 +712,7 @@ impl Config { if self.offline { return Err(SolcError::msg(format!( "can't install missing solc {version} in offline mode" - ))) + ))); } Solc::blocking_install(version)?; solc = Solc::find_svm_installed_version(&v)?; @@ -724,12 +724,12 @@ impl Config { return Err(SolcError::msg(format!( "`solc` {} does not exist", solc.display() - ))) + ))); } Some(Solc::new(solc)) } }; - return Ok(solc) + return Ok(solc); } Ok(None) @@ -739,7 +739,7 @@ impl Config { #[inline] pub fn evm_spec_id(&self) -> SpecId { if self.cancun { - return SpecId::CANCUN + return SpecId::CANCUN; } evm_spec_id(&self.evm_version) } @@ -750,16 +750,16 @@ impl Config { /// `auto_detect_solc` pub fn is_auto_detect(&self) -> bool { if self.solc.is_some() { - return false + return false; } self.auto_detect_solc } /// Whether caching should be enabled for the given chain id pub fn enable_caching(&self, endpoint: &str, chain_id: impl Into) -> bool { - !self.no_storage_caching && - self.rpc_storage_caching.enable_for_chain_id(chain_id.into()) && - self.rpc_storage_caching.enable_for_endpoint(endpoint) + !self.no_storage_caching + && self.rpc_storage_caching.enable_for_chain_id(chain_id.into()) + && self.rpc_storage_caching.enable_for_endpoint(endpoint) } /// Returns the `ProjectPathsConfig` sub set of the config. @@ -952,7 +952,7 @@ impl Config { ) -> Result, EtherscanConfigError> { if let Some(maybe_alias) = self.etherscan_api_key.as_ref().or(self.eth_rpc_url.as_ref()) { if self.etherscan.contains_key(maybe_alias) { - return self.etherscan.clone().resolved().remove(maybe_alias).transpose() + return self.etherscan.clone().resolved().remove(maybe_alias).transpose(); } } @@ -966,7 +966,7 @@ impl Config { // we update the key, because if an etherscan_api_key is set, it should take // precedence over the entry, since this is usually set via env var or CLI args. config.key.clone_from(key); - return Ok(Some(config)) + return Ok(Some(config)); } (Ok(config), None) => return Ok(Some(config)), (Err(err), None) => return Err(err), @@ -979,7 +979,7 @@ impl Config { // etherscan fallback via API key if let Some(key) = self.etherscan_api_key.as_ref() { let chain = chain.or(self.chain).unwrap_or_default(); - return Ok(ResolvedEtherscanConfig::create(key, chain)) + return Ok(ResolvedEtherscanConfig::create(key, chain)); } Ok(None) @@ -1233,7 +1233,7 @@ impl Config { { let file_path = self.get_config_path(); if !file_path.exists() { - return Ok(()) + return Ok(()); } let contents = fs::read_to_string(&file_path)?; let mut doc = contents.parse::()?; @@ -1395,14 +1395,14 @@ impl Config { return match path.is_file() { true => Some(path.to_path_buf()), false => None, - } + }; } let cwd = std::env::current_dir().ok()?; let mut cwd = cwd.as_path(); loop { let file_path = cwd.join(path); if file_path.is_file() { - return Some(file_path) + return Some(file_path); } cwd = cwd.parent()?; } @@ -1476,7 +1476,7 @@ impl Config { if let Some(cache_dir) = Config::foundry_rpc_cache_dir() { let mut cache = Cache { chains: vec![] }; if !cache_dir.exists() { - return Ok(cache) + return Ok(cache); } if let Ok(entries) = cache_dir.as_path().read_dir() { for entry in entries.flatten().filter(|x| x.path().is_dir()) { @@ -1520,19 +1520,19 @@ impl Config { fn get_cached_blocks(chain_path: &Path) -> eyre::Result> { let mut blocks = vec![]; if !chain_path.exists() { - return Ok(blocks) + return Ok(blocks); } for block in chain_path.read_dir()?.flatten() { let file_type = block.file_type()?; let file_name = block.file_name(); let filepath = if file_type.is_dir() { block.path().join("storage.json") - } else if file_type.is_file() && - file_name.to_string_lossy().chars().all(char::is_numeric) + } else if file_type.is_file() + && file_name.to_string_lossy().chars().all(char::is_numeric) { block.path() } else { - continue + continue; }; blocks.push((file_name.to_string_lossy().into_owned(), fs::metadata(filepath)?.len())); } @@ -1542,7 +1542,7 @@ impl Config { //The path provided to this function should point to the etherscan cache for a chain fn get_cached_block_explorer_data(chain_path: &Path) -> eyre::Result { if !chain_path.exists() { - return Ok(0) + return Ok(0); } fn dir_size_recursive(mut dir: fs::ReadDir) -> eyre::Result { @@ -1759,7 +1759,7 @@ pub(crate) mod from_opt_glob { { let s: Option = Option::deserialize(deserializer)?; if let Some(s) = s { - return Ok(Some(globset::Glob::new(&s).map_err(serde::de::Error::custom)?)) + return Ok(Some(globset::Glob::new(&s).map_err(serde::de::Error::custom)?)); } Ok(None) } @@ -2067,7 +2067,7 @@ impl TomlFileProvider { if let Some(file) = self.env_val() { let path = Path::new(&file); if !path.exists() { - return true + return true; } } false @@ -2087,7 +2087,7 @@ impl TomlFileProvider { "Config file `{}` set in env var `{}` does not exist", file, self.env_var.unwrap() - ))) + ))); } Toml::file(file) } else { @@ -2131,7 +2131,7 @@ impl Provider for ForcedSnakeCaseData

{ if Config::STANDALONE_SECTIONS.contains(&profile.as_ref()) { // don't force snake case for keys in standalone sections map.insert(profile, dict); - continue + continue; } map.insert(profile, dict.into_iter().map(|(k, v)| (k.to_snake_case(), v)).collect()); } @@ -2271,7 +2271,7 @@ impl Provider for DappEnvCompatProvider { if val > 1 { return Err( format!("Invalid $DAPP_BUILD_OPTIMIZE value `{val}`, expected 0 or 1").into() - ) + ); } dict.insert("optimizer".to_string(), (val == 1).into()); } @@ -2337,7 +2337,7 @@ impl Provider for RenameProfileProvider

{ fn data(&self) -> Result, Error> { let mut data = self.provider.data()?; if let Some(data) = data.remove(&self.from) { - return Ok(Map::from([(self.to.clone(), data)])) + return Ok(Map::from([(self.to.clone(), data)])); } Ok(Default::default()) } @@ -2383,7 +2383,7 @@ impl Provider for UnwrapProfileProvider

{ for (profile_str, profile_val) in profiles { let profile = Profile::new(&profile_str); if profile != self.profile { - continue + continue; } match profile_val { Value::Dict(_, dict) => return Ok(profile.collect(dict)), @@ -2394,7 +2394,7 @@ impl Provider for UnwrapProfileProvider

{ )); err.metadata = Some(self.provider.metadata()); err.profile = Some(self.profile.clone()); - return Err(err) + return Err(err); } } } @@ -2506,7 +2506,7 @@ impl Provider for OptionalStrictProfileProvider

{ // provider and can't map the metadata to the error. Therefor we return the root error // if this error originated in the provider's data. if let Err(root_err) = self.provider.data() { - return root_err + return root_err; } err }) diff --git a/crates/config/src/providers/mod.rs b/crates/config/src/providers/mod.rs index 239ee0c74a36..31c4f9acbd26 100644 --- a/crates/config/src/providers/mod.rs +++ b/crates/config/src/providers/mod.rs @@ -51,8 +51,8 @@ impl WarningsProvider

{ .unwrap_or_default() .keys() .filter(|k| { - k != &Config::PROFILE_SECTION && - !Config::STANDALONE_SECTIONS.iter().any(|s| s == k) + k != &Config::PROFILE_SECTION + && !Config::STANDALONE_SECTIONS.iter().any(|s| s == k) }) .map(|unknown_section| { let source = self.provider.metadata().source.map(|s| s.to_string()); diff --git a/crates/config/src/providers/remappings.rs b/crates/config/src/providers/remappings.rs index 67ae449fb814..87010a5390a8 100644 --- a/crates/config/src/providers/remappings.rs +++ b/crates/config/src/providers/remappings.rs @@ -171,7 +171,7 @@ impl<'a> RemappingsProvider<'a> { // this is an additional safety check for weird auto-detected remappings if ["lib/", "src/", "contracts/"].contains(&r.name.as_str()) { trace!(target: "forge", "- skipping the remapping"); - continue + continue; } insert_closest(&mut lib_remappings, r.context, r.name, r.path.into()); } @@ -253,7 +253,7 @@ impl<'a> Provider for RemappingsProvider<'a> { if let figment::error::Kind::MissingField(_) = err.kind { self.get_remappings(vec![]) } else { - return Err(err.clone()) + return Err(err.clone()); } } }?; diff --git a/crates/config/src/utils.rs b/crates/config/src/utils.rs index d0d6f8e06663..52391f632051 100644 --- a/crates/config/src/utils.rs +++ b/crates/config/src/utils.rs @@ -73,12 +73,12 @@ pub fn find_project_root_path(path: Option<&PathBuf>) -> std::io::Result) -> eyre::Result { .find_map(|(i, op)| { if i > 0 { match ( - prev_ops[i - 1].contains("JUMP") && - prev_ops[i - 1] != "JUMPDEST", + prev_ops[i - 1].contains("JUMP") + && prev_ops[i - 1] != "JUMPDEST", &**op, ) { (true, "JUMPDEST") => Some(i - 1), diff --git a/crates/doc/src/builder.rs b/crates/doc/src/builder.rs index ac54e97e21e2..94911ec49cf7 100644 --- a/crates/doc/src/builder.rs +++ b/crates/doc/src/builder.rs @@ -107,7 +107,7 @@ impl DocBuilder { if sources.is_empty() { println!("No sources detected at {}", self.sources.display()); - return Ok(()) + return Ok(()); } let library_sources = self.libraries.iter().flat_map(source_files_iter).collect::>(); @@ -382,7 +382,7 @@ impl DocBuilder { depth: usize, ) -> eyre::Result<()> { if files.is_empty() { - return Ok(()) + return Ok(()); } if let Some(path) = base_path { diff --git a/crates/doc/src/document.rs b/crates/doc/src/document.rs index 3f1f2935c0bd..3ebd57cf6248 100644 --- a/crates/doc/src/document.rs +++ b/crates/doc/src/document.rs @@ -150,10 +150,10 @@ impl<'a> Iterator for ParseItemIter<'a> { fn next(&mut self) -> Option { if let Some(next) = self.next.take() { - return Some(next) + return Some(next); } if let Some(other) = self.other.as_mut() { - return other.next() + return other.next(); } None @@ -171,10 +171,10 @@ impl<'a> Iterator for ParseItemIterMut<'a> { fn next(&mut self) -> Option { if let Some(next) = self.next.take() { - return Some(next) + return Some(next); } if let Some(other) = self.other.as_mut() { - return other.next() + return other.next(); } None diff --git a/crates/doc/src/parser/comment.rs b/crates/doc/src/parser/comment.rs index b6e6d08af276..717c7c2169ae 100644 --- a/crates/doc/src/parser/comment.rs +++ b/crates/doc/src/parser/comment.rs @@ -46,7 +46,7 @@ impl CommentTag { } _ => { warn!(target: "forge::doc", tag=trimmed, "unknown comment tag. custom tags must be preceded by `custom:`"); - return None + return None; } }; Some(tag) @@ -178,8 +178,8 @@ impl<'a> CommentsRef<'a> { self.iter().any(|c| match (&c.tag, &target.tag) { (CommentTag::Inheritdoc, CommentTag::Inheritdoc) => c.value == target.value, (CommentTag::Param, CommentTag::Param) | (CommentTag::Return, CommentTag::Return) => { - c.split_first_word().map(|(name, _)| name) == - target.split_first_word().map(|(name, _)| name) + c.split_first_word().map(|(name, _)| name) + == target.split_first_word().map(|(name, _)| name) } (tag1, tag2) => tag1 == tag2, }) diff --git a/crates/doc/src/preprocessor/contract_inheritance.rs b/crates/doc/src/preprocessor/contract_inheritance.rs index 894f373e775f..f0cf146fad47 100644 --- a/crates/doc/src/preprocessor/contract_inheritance.rs +++ b/crates/doc/src/preprocessor/contract_inheritance.rs @@ -59,7 +59,7 @@ impl ContractInheritance { if let DocumentContent::Single(ref item) = candidate.content { if let ParseSource::Contract(ref contract) = item.source { if base == contract.name.safe_unwrap().name { - return Some(candidate.target_path.clone()) + return Some(candidate.target_path.clone()); } } } diff --git a/crates/doc/src/preprocessor/infer_hyperlinks.rs b/crates/doc/src/preprocessor/infer_hyperlinks.rs index 865c4302fdf4..aac54c54206a 100644 --- a/crates/doc/src/preprocessor/infer_hyperlinks.rs +++ b/crates/doc/src/preprocessor/infer_hyperlinks.rs @@ -88,10 +88,13 @@ impl InferInlineHyperlinks { let name = &contract.name.safe_unwrap().name; if name == link.identifier { if link.part.is_none() { - return Some(InlineLinkTarget::borrowed(name, target_path.to_path_buf())) + return Some(InlineLinkTarget::borrowed( + name, + target_path.to_path_buf(), + )); } // try to find the referenced item in the contract's children - return Self::find_match(link, target_path, item.children.iter()) + return Self::find_match(link, target_path, item.children.iter()); } } ParseSource::Function(fun) => { @@ -104,26 +107,32 @@ impl InferInlineHyperlinks { return Some(InlineLinkTarget::borrowed( &id.name, target_path.to_path_buf(), - )) + )); } } else if link.ref_name() == "constructor" { return Some(InlineLinkTarget::borrowed( "constructor", target_path.to_path_buf(), - )) + )); } } ParseSource::Variable(_) => {} ParseSource::Event(ev) => { let ev_name = &ev.name.safe_unwrap().name; if ev_name == link.ref_name() { - return Some(InlineLinkTarget::borrowed(ev_name, target_path.to_path_buf())) + return Some(InlineLinkTarget::borrowed( + ev_name, + target_path.to_path_buf(), + )); } } ParseSource::Error(err) => { let err_name = &err.name.safe_unwrap().name; if err_name == link.ref_name() { - return Some(InlineLinkTarget::borrowed(err_name, target_path.to_path_buf())) + return Some(InlineLinkTarget::borrowed( + err_name, + target_path.to_path_buf(), + )); } } ParseSource::Struct(structdef) => { @@ -132,7 +141,7 @@ impl InferInlineHyperlinks { return Some(InlineLinkTarget::borrowed( struct_name, target_path.to_path_buf(), - )) + )); } } ParseSource::Enum(_) => {} diff --git a/crates/doc/src/preprocessor/inheritdoc.rs b/crates/doc/src/preprocessor/inheritdoc.rs index 583df72ba863..c5ff5cb872fb 100644 --- a/crates/doc/src/preprocessor/inheritdoc.rs +++ b/crates/doc/src/preprocessor/inheritdoc.rs @@ -80,7 +80,7 @@ impl Inheritdoc { // TODO: improve matching logic if source.ident() == children.source.ident() { let key = format!("{}.{}", base, source.ident()); - return Some((key, children.comments.clone())) + return Some((key, children.comments.clone())); } } } diff --git a/crates/doc/src/writer/buf_writer.rs b/crates/doc/src/writer/buf_writer.rs index 7ab47c953c5f..a9bbaf911141 100644 --- a/crates/doc/src/writer/buf_writer.rs +++ b/crates/doc/src/writer/buf_writer.rs @@ -130,7 +130,7 @@ impl BufWriter { // There is nothing to write. if params.is_empty() || comments.is_empty() { - return Ok(()) + return Ok(()); } self.write_bold(heading)?; diff --git a/crates/evm/core/src/backend/cow.rs b/crates/evm/core/src/backend/cow.rs index c0ff88ea40a1..babe23cecddb 100644 --- a/crates/evm/core/src/backend/cow.rs +++ b/crates/evm/core/src/backend/cow.rs @@ -92,7 +92,7 @@ impl<'a> CowBackend<'a> { let env = EnvWithHandlerCfg::new_with_spec_id(Box::new(env.clone()), self.spec_id); backend.initialize(&env); self.is_initialized = true; - return backend + return backend; } self.backend.to_mut() } @@ -100,7 +100,7 @@ impl<'a> CowBackend<'a> { /// Returns a mutable instance of the Backend if it is initialized. fn initialized_backend_mut(&mut self) -> Option<&mut Backend> { if self.is_initialized { - return Some(self.backend.to_mut()) + return Some(self.backend.to_mut()); } None } @@ -124,7 +124,7 @@ impl<'a> DatabaseExt for CowBackend<'a> { fn delete_snapshot(&mut self, id: U256) -> bool { // delete snapshot requires a previous snapshot to be initialized if let Some(backend) = self.initialized_backend_mut() { - return backend.delete_snapshot(id) + return backend.delete_snapshot(id); } false } diff --git a/crates/evm/core/src/backend/error.rs b/crates/evm/core/src/backend/error.rs index f1f9733d494e..1a2f5f14ba16 100644 --- a/crates/evm/core/src/backend/error.rs +++ b/crates/evm/core/src/backend/error.rs @@ -70,15 +70,15 @@ impl DatabaseError { Self::GetFullBlock(_, err) => Some(err), Self::GetTransaction(_, err) => Some(err), // Enumerate explicitly to make sure errors are updated if a new one is added. - Self::NoCheats(_) | - Self::MissingAccount(_) | - Self::MissingCode(_) | - Self::Recv(_) | - Self::Send(_) | - Self::Message(_) | - Self::BlockNotFound(_) | - Self::TransactionNotFound(_) | - Self::MissingCreate2Deployer => None, + Self::NoCheats(_) + | Self::MissingAccount(_) + | Self::MissingCode(_) + | Self::Recv(_) + | Self::Send(_) + | Self::Message(_) + | Self::BlockNotFound(_) + | Self::TransactionNotFound(_) + | Self::MissingCreate2Deployer => None, DatabaseError::Other(_) => None, } } diff --git a/crates/evm/core/src/backend/mod.rs b/crates/evm/core/src/backend/mod.rs index ca6cbb1ef8bd..c65a1194c57b 100644 --- a/crates/evm/core/src/backend/mod.rs +++ b/crates/evm/core/src/backend/mod.rs @@ -589,8 +589,9 @@ impl Backend { /// Checks if the test contract associated with this backend failed, See /// [Self::is_failed_test_contract] pub fn is_failed(&self) -> bool { - self.has_snapshot_failure() || - self.test_contract_address() + self.has_snapshot_failure() + || self + .test_contract_address() .map(|addr| self.is_failed_test_contract(addr)) .unwrap_or_default() } @@ -838,7 +839,7 @@ impl Backend { // created account takes precedence: for example contract creation in setups if init_account.is_created() { trace!(?loaded_account, "skipping created account"); - continue + continue; } // otherwise we need to replace the account's info with the one from the fork's @@ -903,8 +904,8 @@ impl Backend { for tx in txs.into_iter() { // System transactions such as on L2s don't contain any pricing info so we skip them // otherwise this would cause reverts - if is_known_system_sender(tx.from) || - tx.transaction_type.map(|ty| ty.to::()) == Some(SYSTEM_TRANSACTION_TYPE) + if is_known_system_sender(tx.from) + || tx.transaction_type.map(|ty| ty.to::()) == Some(SYSTEM_TRANSACTION_TYPE) { trace!(tx=?tx.hash, "skipping system transaction"); continue; @@ -912,7 +913,7 @@ impl Backend { if tx.hash == tx_hash { // found the target transaction - return Ok(Some(tx)) + return Ok(Some(tx)); } trace!(tx=?tx.hash, "committing transaction"); diff --git a/crates/evm/core/src/fork/cache.rs b/crates/evm/core/src/fork/cache.rs index 607eced68894..20e7b62eecce 100644 --- a/crates/evm/core/src/fork/cache.rs +++ b/crates/evm/core/src/fork/cache.rs @@ -67,7 +67,7 @@ impl BlockchainDb { .and_then(|p| { JsonBlockCacheDB::load(p).ok().filter(|cache| { if skip_check { - return true + return true; } let mut existing = cache.meta().write(); existing.hosts.extend(meta.hosts.clone()); @@ -400,10 +400,10 @@ impl JsonBlockCacheDB { let mut writer = BufWriter::new(file); if let Err(e) = serde_json::to_writer(&mut writer, &self.data) { - return warn!(target: "cache", %e, "Failed to write to json cache") + return warn!(target: "cache", %e, "Failed to write to json cache"); } if let Err(e) = writer.flush() { - return warn!(target: "cache", %e, "Failed to flush to json cache") + return warn!(target: "cache", %e, "Failed to flush to json cache"); } trace!(target: "cache", "saved json cache"); diff --git a/crates/evm/core/src/fork/multi.rs b/crates/evm/core/src/fork/multi.rs index 4e1cb66e5ff4..26e9c4c00887 100644 --- a/crates/evm/core/src/fork/multi.rs +++ b/crates/evm/core/src/fork/multi.rs @@ -406,8 +406,8 @@ impl Future for MultiForkHandler { .flush_cache_interval .as_mut() .map(|interval| interval.poll_tick(cx).is_ready()) - .unwrap_or_default() && - !pin.forks.is_empty() + .unwrap_or_default() + && !pin.forks.is_empty() { trace!(target: "fork::multi", "tick flushing caches"); let forks = pin.forks.values().map(|f| f.backend.clone()).collect::>(); diff --git a/crates/evm/core/src/opcodes.rs b/crates/evm/core/src/opcodes.rs index 3251036c78f7..4d8ff49b8ef1 100644 --- a/crates/evm/core/src/opcodes.rs +++ b/crates/evm/core/src/opcodes.rs @@ -9,17 +9,17 @@ use revm::interpreter::OpCode; pub const fn modifies_memory(opcode: OpCode) -> bool { matches!( opcode, - OpCode::EXTCODECOPY | - OpCode::MLOAD | - OpCode::MSTORE | - OpCode::MSTORE8 | - OpCode::MCOPY | - OpCode::CODECOPY | - OpCode::CALLDATACOPY | - OpCode::RETURNDATACOPY | - OpCode::CALL | - OpCode::CALLCODE | - OpCode::DELEGATECALL | - OpCode::STATICCALL + OpCode::EXTCODECOPY + | OpCode::MLOAD + | OpCode::MSTORE + | OpCode::MSTORE8 + | OpCode::MCOPY + | OpCode::CODECOPY + | OpCode::CALLDATACOPY + | OpCode::RETURNDATACOPY + | OpCode::CALL + | OpCode::CALLCODE + | OpCode::DELEGATECALL + | OpCode::STATICCALL ) } diff --git a/crates/evm/core/src/utils.rs b/crates/evm/core/src/utils.rs index 7ef8bb47f2d4..c1a95a7b905d 100644 --- a/crates/evm/core/src/utils.rs +++ b/crates/evm/core/src/utils.rs @@ -31,10 +31,10 @@ pub fn apply_chain_and_block_specific_env_changes(env: &mut revm::primitives::En return; } - NamedChain::Arbitrum | - NamedChain::ArbitrumGoerli | - NamedChain::ArbitrumNova | - NamedChain::ArbitrumTestnet => { + NamedChain::Arbitrum + | NamedChain::ArbitrumGoerli + | NamedChain::ArbitrumNova + | NamedChain::ArbitrumTestnet => { // on arbitrum `block.number` is the L1 block which is included in the // `l1BlockNumber` field if let Some(l1_block_number) = block.other.get("l1BlockNumber").cloned() { diff --git a/crates/evm/coverage/src/analysis.rs b/crates/evm/coverage/src/analysis.rs index 1926d2b4ed20..831b299c490e 100644 --- a/crates/evm/coverage/src/analysis.rs +++ b/crates/evm/coverage/src/analysis.rs @@ -74,7 +74,7 @@ impl<'a> ContractVisitor<'a> { let kind: String = node.attribute("kind").ok_or_else(|| eyre::eyre!("Function has no kind"))?; if kind == "constructor" || kind == "receive" { - return Ok(()) + return Ok(()); } match node.body.take() { @@ -112,15 +112,15 @@ impl<'a> ContractVisitor<'a> { .ok_or_else(|| eyre::eyre!("inline assembly block with no AST attribute"))?, ), // Simple statements - NodeType::Break | - NodeType::Continue | - NodeType::EmitStatement | - NodeType::PlaceholderStatement | - NodeType::RevertStatement | - NodeType::YulAssignment | - NodeType::YulBreak | - NodeType::YulContinue | - NodeType::YulLeave => { + NodeType::Break + | NodeType::Continue + | NodeType::EmitStatement + | NodeType::PlaceholderStatement + | NodeType::RevertStatement + | NodeType::YulAssignment + | NodeType::YulBreak + | NodeType::YulContinue + | NodeType::YulLeave => { self.push_item(CoverageItem { kind: CoverageItemKind::Statement, loc: self.source_location_for(&node.src), @@ -350,13 +350,13 @@ impl<'a> ContractVisitor<'a> { Ok(()) } // Does not count towards coverage - NodeType::FunctionCallOptions | - NodeType::Identifier | - NodeType::IndexAccess | - NodeType::IndexRangeAccess | - NodeType::Literal | - NodeType::YulLiteralValue | - NodeType::YulIdentifier => Ok(()), + NodeType::FunctionCallOptions + | NodeType::Identifier + | NodeType::IndexAccess + | NodeType::IndexRangeAccess + | NodeType::Literal + | NodeType::YulLiteralValue + | NodeType::YulIdentifier => Ok(()), _ => { warn!("unexpected node type, expected an expression: {:?}", node.node_type); Ok(()) @@ -367,20 +367,20 @@ impl<'a> ContractVisitor<'a> { fn visit_block_or_statement(&mut self, node: Node) -> eyre::Result<()> { match node.node_type { NodeType::Block => self.visit_block(node), - NodeType::Break | - NodeType::Continue | - NodeType::DoWhileStatement | - NodeType::EmitStatement | - NodeType::ExpressionStatement | - NodeType::ForStatement | - NodeType::IfStatement | - NodeType::InlineAssembly | - NodeType::PlaceholderStatement | - NodeType::Return | - NodeType::RevertStatement | - NodeType::TryStatement | - NodeType::VariableDeclarationStatement | - NodeType::WhileStatement => self.visit_statement(node), + NodeType::Break + | NodeType::Continue + | NodeType::DoWhileStatement + | NodeType::EmitStatement + | NodeType::ExpressionStatement + | NodeType::ForStatement + | NodeType::IfStatement + | NodeType::InlineAssembly + | NodeType::PlaceholderStatement + | NodeType::Return + | NodeType::RevertStatement + | NodeType::TryStatement + | NodeType::VariableDeclarationStatement + | NodeType::WhileStatement => self.visit_statement(node), _ => { warn!("unexpected node type, expected block or statement: {:?}", node.node_type); Ok(()) @@ -393,8 +393,8 @@ impl<'a> ContractVisitor<'a> { let source_location = &item.loc; // Push a line item if we haven't already - if matches!(item.kind, CoverageItemKind::Statement | CoverageItemKind::Branch { .. }) && - self.last_line < source_location.line + if matches!(item.kind, CoverageItemKind::Statement | CoverageItemKind::Branch { .. }) + && self.last_line < source_location.line { self.items.push(CoverageItem { kind: CoverageItemKind::Line, @@ -473,7 +473,7 @@ impl SourceAnalyzer { for (source_id, ast) in asts.into_iter() { for child in ast.nodes { if !matches!(child.node_type, NodeType::ContractDefinition) { - continue + continue; } let node_id = diff --git a/crates/evm/coverage/src/anchors.rs b/crates/evm/coverage/src/anchors.rs index 237d941d1a3d..84006e2b2591 100644 --- a/crates/evm/coverage/src/anchors.rs +++ b/crates/evm/coverage/src/anchors.rs @@ -121,7 +121,7 @@ pub fn find_anchor_branch( } else { // NOTE(onbjerg): For some reason the last few bytes of the bytecode do not have // a source map associated, so at that point we just stop searching - break + break; }; // Do push byte accounting diff --git a/crates/evm/evm/src/executors/fuzz/mod.rs b/crates/evm/evm/src/executors/fuzz/mod.rs index 41beb7e43317..8bccd3bc853f 100644 --- a/crates/evm/evm/src/executors/fuzz/mod.rs +++ b/crates/evm/evm/src/executors/fuzz/mod.rs @@ -211,7 +211,7 @@ impl FuzzedExecutor { // When the `assume` cheatcode is called it returns a special string if call.result.as_ref() == MAGIC_ASSUME { - return Err(TestCaseError::reject(FuzzError::AssumeReject)) + return Err(TestCaseError::reject(FuzzError::AssumeReject)); } let breakpoints = call diff --git a/crates/evm/evm/src/executors/invariant/error.rs b/crates/evm/evm/src/executors/invariant/error.rs index d46d6da2c289..52bbdda97ef6 100644 --- a/crates/evm/evm/src/executors/invariant/error.rs +++ b/crates/evm/evm/src/executors/invariant/error.rs @@ -191,7 +191,7 @@ impl FailedInvariantCaseData { logs.extend(error_call_result.logs); if error_call_result.reverted { - break + break; } } } @@ -217,7 +217,7 @@ impl FailedInvariantCaseData { let mut new_sequence = Vec::with_capacity(calls.len()); for index in 0..calls.len() { if !use_calls.contains(&index) { - continue + continue; } new_sequence.push(index); @@ -313,41 +313,40 @@ impl FailedInvariantCaseData { let upper_bound = calls.len().saturating_sub(1); // We construct either a full powerset (this guarantees we maximally shrunk for the given // calls) or a random subset - let (set_of_indices, is_powerset): (Vec<_>, bool) = if calls.len() <= 64 && - (1 << calls.len() as u32) <= shrink_limit - { - // We add the last tx always because thats ultimately what broke the invariant - let powerset = (0..upper_bound) - .powerset() - .map(|mut subset| { - subset.push(upper_bound); - subset - }) - .collect(); - (powerset, true) - } else { - // construct a random set of subsequences - let mut rng = thread_rng(); - ( - (0..shrink_limit / 3) - .map(|_| { - // Select between 1 and calls.len() - 2 number of indices - let amt: usize = rng.gen_range(1..upper_bound); - // Construct a random sequence of indices, up to calls.len() - 1 (sample is - // exclusive range and we dont include the last tx - // because its always included), and amt number of indices - let mut seq = seq::index::sample(&mut rng, upper_bound, amt).into_vec(); - // Sort the indices because seq::index::sample is unordered - seq.sort(); - // We add the last tx always because thats what ultimately broke the - // invariant - seq.push(upper_bound); - seq + let (set_of_indices, is_powerset): (Vec<_>, bool) = + if calls.len() <= 64 && (1 << calls.len() as u32) <= shrink_limit { + // We add the last tx always because thats ultimately what broke the invariant + let powerset = (0..upper_bound) + .powerset() + .map(|mut subset| { + subset.push(upper_bound); + subset }) - .collect(), - false, - ) - }; + .collect(); + (powerset, true) + } else { + // construct a random set of subsequences + let mut rng = thread_rng(); + ( + (0..shrink_limit / 3) + .map(|_| { + // Select between 1 and calls.len() - 2 number of indices + let amt: usize = rng.gen_range(1..upper_bound); + // Construct a random sequence of indices, up to calls.len() - 1 (sample is + // exclusive range and we dont include the last tx + // because its always included), and amt number of indices + let mut seq = seq::index::sample(&mut rng, upper_bound, amt).into_vec(); + // Sort the indices because seq::index::sample is unordered + seq.sort(); + // We add the last tx always because thats what ultimately broke the + // invariant + seq.push(upper_bound); + seq + }) + .collect(), + false, + ) + }; let new_runs = set_of_indices.len(); diff --git a/crates/evm/evm/src/executors/invariant/mod.rs b/crates/evm/evm/src/executors/invariant/mod.rs index 5ed7998ac3e1..84a9cdcada07 100644 --- a/crates/evm/evm/src/executors/invariant/mod.rs +++ b/crates/evm/evm/src/executors/invariant/mod.rs @@ -155,7 +155,7 @@ impl<'a> InvariantExecutor<'a> { ) -> Result { // Throw an error to abort test run if the invariant function accepts input params if !invariant_contract.invariant_function.inputs.is_empty() { - return Err(eyre!("Invariant test function should have no inputs")) + return Err(eyre!("Invariant test function should have no inputs")); } let (fuzz_state, targeted_contracts, strat, calldata_fuzz_dictionary) = @@ -200,7 +200,7 @@ impl<'a> InvariantExecutor<'a> { // We stop the run immediately if we have reverted, and `fail_on_revert` is set. if self.config.fail_on_revert && failures.borrow().reverts > 0 { - return Err(TestCaseError::fail("Revert occurred.")) + return Err(TestCaseError::fail("Revert occurred.")); } // Before each run, we must reset the backend state. @@ -239,7 +239,9 @@ impl<'a> InvariantExecutor<'a> { failures.borrow_mut().error = Some(InvariantFuzzError::MaxAssumeRejects( self.config.max_assume_rejects, )); - return Err(TestCaseError::fail("Max number of vm.assume rejects reached.")) + return Err(TestCaseError::fail( + "Max number of vm.assume rejects reached.", + )); } } else { // Collect data for fuzzing from the state changeset. @@ -295,7 +297,7 @@ impl<'a> InvariantExecutor<'a> { } if !can_continue { - break + break; } *last_call_results.borrow_mut() = call_results; @@ -449,13 +451,13 @@ impl<'a> InvariantExecutor<'a> { .filter(|func| { !matches!( func.state_mutability, - alloy_json_abi::StateMutability::Pure | - alloy_json_abi::StateMutability::View + alloy_json_abi::StateMutability::Pure + | alloy_json_abi::StateMutability::View ) }) - .count() == - 0 && - !self.artifact_filters.excluded.contains(&artifact.identifier()) + .count() + == 0 + && !self.artifact_filters.excluded.contains(&artifact.identifier()) { self.artifact_filters.excluded.push(artifact.identifier()); } @@ -466,8 +468,8 @@ impl<'a> InvariantExecutor<'a> { for contract in selected.targetedArtifacts { let identifier = self.validate_selected_contract(contract, &[])?; - if !self.artifact_filters.targeted.contains_key(&identifier) && - !self.artifact_filters.excluded.contains(&identifier) + if !self.artifact_filters.targeted.contains_key(&identifier) + && !self.artifact_filters.excluded.contains(&identifier) { self.artifact_filters.targeted.insert(identifier, vec![]); } @@ -492,7 +494,7 @@ impl<'a> InvariantExecutor<'a> { .wrap_err(format!("{contract} does not have the selector {selector:?}"))?; } - return Ok(artifact.identifier()) + return Ok(artifact.identifier()); } eyre::bail!("{contract} not found in the project. Allowed format: `contract_name` or `contract_path:contract_name`."); } @@ -517,15 +519,15 @@ impl<'a> InvariantExecutor<'a> { .clone() .into_iter() .filter(|(addr, (identifier, _))| { - *addr != to && - *addr != CHEATCODE_ADDRESS && - *addr != HARDHAT_CONSOLE_ADDRESS && - (selected.is_empty() || selected.contains(addr)) && - (self.artifact_filters.targeted.is_empty() || - self.artifact_filters.targeted.contains_key(identifier)) && - (excluded.is_empty() || !excluded.contains(addr)) && - (self.artifact_filters.excluded.is_empty() || - !self.artifact_filters.excluded.contains(identifier)) + *addr != to + && *addr != CHEATCODE_ADDRESS + && *addr != HARDHAT_CONSOLE_ADDRESS + && (selected.is_empty() || selected.contains(addr)) + && (self.artifact_filters.targeted.is_empty() + || self.artifact_filters.targeted.contains_key(identifier)) + && (excluded.is_empty() || !excluded.contains(addr)) + && (self.artifact_filters.excluded.is_empty() + || !self.artifact_filters.excluded.contains(identifier)) }) .map(|(addr, (identifier, abi))| (addr, (identifier, abi, vec![]))) .collect(); diff --git a/crates/evm/evm/src/executors/mod.rs b/crates/evm/evm/src/executors/mod.rs index 76f67abd9aa5..d7711274c8ab 100644 --- a/crates/evm/evm/src/executors/mod.rs +++ b/crates/evm/evm/src/executors/mod.rs @@ -461,7 +461,7 @@ impl Executor { ) -> bool { if call_result.has_snapshot_failure { // a failure occurred in a reverted snapshot, which is considered a failed test - return should_fail + return should_fail; } self.is_success(address, call_result.reverted, state_changeset, should_fail) } @@ -475,7 +475,7 @@ impl Executor { ) -> Result { if self.backend.has_snapshot_failure() { // a failure occurred in a reverted snapshot, which is considered a failed test - return Ok(should_fail) + return Ok(should_fail); } let mut success = !reverted; diff --git a/crates/evm/evm/src/inspectors/logs.rs b/crates/evm/evm/src/inspectors/logs.rs index a8e4a063c352..104507892021 100644 --- a/crates/evm/evm/src/inspectors/logs.rs +++ b/crates/evm/evm/src/inspectors/logs.rs @@ -58,7 +58,7 @@ impl Inspector for LogCollector { gas: Gas::new(inputs.gas_limit), }, memory_offset: inputs.return_memory_offset.clone(), - }) + }); } } diff --git a/crates/evm/evm/src/inspectors/stack.rs b/crates/evm/evm/src/inspectors/stack.rs index 6f83bf43f867..eb0d3c6ef82d 100644 --- a/crates/evm/evm/src/inspectors/stack.rs +++ b/crates/evm/evm/src/inspectors/stack.rs @@ -405,9 +405,9 @@ impl InspectorStack { // If the inspector returns a different status or a revert with a non-empty message, // we assume it wants to tell us something - let different = new_outcome.result.result != result || - (new_outcome.result.result == InstructionResult::Revert && - new_outcome.output() != outcome.output()); + let different = new_outcome.result.result != result + || (new_outcome.result.result == InstructionResult::Revert + && new_outcome.output() != outcome.output()); different.then_some(new_outcome) }, self, @@ -486,7 +486,7 @@ impl InspectorStack { // Should we match, encode and propagate error as a revert reason? let result = InterpreterResult { result: InstructionResult::Revert, output: Bytes::new(), gas }; - return (result, None) + return (result, None); }; // Commit changes after transaction @@ -499,7 +499,7 @@ impl InspectorStack { output: Bytes::from(e.to_string()), gas, }; - return (res, None) + return (res, None); } if let Err(e) = update_state(&mut res.state, &mut ecx.db) { let res = InterpreterResult { @@ -507,7 +507,7 @@ impl InspectorStack { output: Bytes::from(e.to_string()), gas, }; - return (res, None) + return (res, None); } // Merge transaction journal into the active journal. @@ -651,10 +651,10 @@ impl Inspector<&mut DB> for InspectorStack { ecx ); - if self.enable_isolation && - call.context.scheme == CallScheme::Call && - !self.in_inner_context && - ecx.journaled_state.depth == 1 + if self.enable_isolation + && call.context.scheme == CallScheme::Call + && !self.in_inner_context + && ecx.journaled_state.depth == 1 { let (result, _) = self.transact_inner( ecx, @@ -664,7 +664,7 @@ impl Inspector<&mut DB> for InspectorStack { call.gas_limit, call.transfer.value, ); - return Some(CallOutcome { result, memory_offset: call.return_memory_offset.clone() }) + return Some(CallOutcome { result, memory_offset: call.return_memory_offset.clone() }); } None @@ -679,7 +679,7 @@ impl Inspector<&mut DB> for InspectorStack { // Inner context calls with depth 0 are being dispatched as top-level calls with depth 1. // Avoid processing twice. if self.in_inner_context && ecx.journaled_state.depth == 0 { - return outcome + return outcome; } let outcome = self.do_call_end(ecx, inputs, outcome); @@ -721,7 +721,7 @@ impl Inspector<&mut DB> for InspectorStack { create.gas_limit, create.value, ); - return Some(CreateOutcome { result, address }) + return Some(CreateOutcome { result, address }); } None @@ -736,7 +736,7 @@ impl Inspector<&mut DB> for InspectorStack { // Inner context calls with depth 0 are being dispatched as top-level calls with depth 1. // Avoid processing twice. if self.in_inner_context && ecx.journaled_state.depth == 0 { - return outcome + return outcome; } let result = outcome.result.result; @@ -748,9 +748,9 @@ impl Inspector<&mut DB> for InspectorStack { // If the inspector returns a different status or a revert with a non-empty message, // we assume it wants to tell us something - let different = new_outcome.result.result != result || - (new_outcome.result.result == InstructionResult::Revert && - new_outcome.output() != outcome.output()); + let different = new_outcome.result.result != result + || (new_outcome.result.result == InstructionResult::Revert + && new_outcome.output() != outcome.output()); different.then_some(new_outcome) }, self, diff --git a/crates/evm/fuzz/Cargo.toml b/crates/evm/fuzz/Cargo.toml index 3c20b029a628..8a21d9652687 100644 --- a/crates/evm/fuzz/Cargo.toml +++ b/crates/evm/fuzz/Cargo.toml @@ -39,5 +39,4 @@ rand.workspace = true serde = "1" thiserror = "1" tracing = "0.1" -rustc-hash.workspace = true indexmap.workspace = true diff --git a/crates/evm/fuzz/src/inspector.rs b/crates/evm/fuzz/src/inspector.rs index e58afb214fee..a0299d59ee81 100644 --- a/crates/evm/fuzz/src/inspector.rs +++ b/crates/evm/fuzz/src/inspector.rs @@ -80,9 +80,9 @@ impl Fuzzer { fn override_call(&mut self, call: &mut CallInputs) { if let Some(ref mut call_generator) = self.call_generator { // We only override external calls which are not coming from the test contract. - if call.context.caller != call_generator.test_address && - call.context.scheme == CallScheme::Call && - !call_generator.used + if call.context.caller != call_generator.test_address + && call.context.scheme == CallScheme::Call + && !call_generator.used { // There's only a 30% chance that an override happens. if let Some((sender, (contract, input))) = diff --git a/crates/evm/fuzz/src/invariant/filters.rs b/crates/evm/fuzz/src/invariant/filters.rs index c56450c27065..8e64b6f59da1 100644 --- a/crates/evm/fuzz/src/invariant/filters.rs +++ b/crates/evm/fuzz/src/invariant/filters.rs @@ -32,14 +32,14 @@ impl ArtifactFilters { .collect::>>()?; // targetArtifactSelectors > excludeArtifacts > targetArtifacts if functions.is_empty() && self.excluded.contains(&artifact.identifier()) { - return Ok(None) + return Ok(None); } - return Ok(Some(functions)) + return Ok(Some(functions)); } // If no contract is specifically targeted, and this contract is not excluded, then accept // all functions. if self.targeted.is_empty() && !self.excluded.contains(&artifact.identifier()) { - return Ok(Some(vec![])) + return Ok(Some(vec![])); } Ok(None) } diff --git a/crates/evm/fuzz/src/strategies/int.rs b/crates/evm/fuzz/src/strategies/int.rs index f772d97c0c1e..fbf9928fb228 100644 --- a/crates/evm/fuzz/src/strategies/int.rs +++ b/crates/evm/fuzz/src/strategies/int.rs @@ -41,7 +41,7 @@ impl IntValueTree { fn magnitude_greater(lhs: I256, rhs: I256) -> bool { if lhs.is_zero() { - return false + return false; } (lhs > rhs) ^ (lhs.is_negative()) } @@ -56,7 +56,7 @@ impl ValueTree for IntValueTree { fn simplify(&mut self) -> bool { if self.fixed || !IntValueTree::magnitude_greater(self.hi, self.lo) { - return false + return false; } self.hi = self.curr; self.reposition() @@ -64,7 +64,7 @@ impl ValueTree for IntValueTree { fn complicate(&mut self) -> bool { if self.fixed || !IntValueTree::magnitude_greater(self.hi, self.lo) { - return false + return false; } self.lo = if self.curr != I256::MIN && self.curr != I256::MAX { @@ -134,7 +134,7 @@ impl IntStrategy { fn generate_fixtures_tree(&self, runner: &mut TestRunner) -> NewTree { // generate edge cases if there's no fixtures if self.fixtures.is_empty() { - return self.generate_edge_tree(runner) + return self.generate_edge_tree(runner); } let idx = runner.rng().gen_range(0..self.fixtures.len()); Ok(IntValueTree::new(self.fixtures[idx], false)) @@ -147,7 +147,7 @@ impl IntStrategy { let bits = rng.gen_range(0..=self.bits); if bits == 0 { - return Ok(IntValueTree::new(I256::ZERO, false)) + return Ok(IntValueTree::new(I256::ZERO, false)); } // init 2 128-bit randoms diff --git a/crates/evm/fuzz/src/strategies/state.rs b/crates/evm/fuzz/src/strategies/state.rs index 1cf1d37882f1..a01c5566810b 100644 --- a/crates/evm/fuzz/src/strategies/state.rs +++ b/crates/evm/fuzz/src/strategies/state.rs @@ -17,8 +17,7 @@ use std::{fmt, sync::Arc}; // We're using `IndexSet` to have a stable element order when restoring persisted state, as well as // for performance when iterating over the sets. -type FxIndexSet = - indexmap::set::IndexSet>; +type FxIndexSet = indexmap::set::IndexSet; /// A set of arbitrary 32 byte data from the VM used to generate values for the strategy. /// diff --git a/crates/evm/fuzz/src/strategies/uint.rs b/crates/evm/fuzz/src/strategies/uint.rs index 7b9aac1d49ed..2978f53c92b0 100644 --- a/crates/evm/fuzz/src/strategies/uint.rs +++ b/crates/evm/fuzz/src/strategies/uint.rs @@ -49,7 +49,7 @@ impl ValueTree for UintValueTree { fn simplify(&mut self) -> bool { if self.fixed || (self.hi <= self.lo) { - return false + return false; } self.hi = self.curr; self.reposition() @@ -57,7 +57,7 @@ impl ValueTree for UintValueTree { fn complicate(&mut self) -> bool { if self.fixed || (self.hi <= self.lo) { - return false + return false; } self.lo = self.curr + U256::from(1); @@ -114,7 +114,7 @@ impl UintStrategy { fn generate_fixtures_tree(&self, runner: &mut TestRunner) -> NewTree { // generate edge cases if there's no fixtures if self.fixtures.is_empty() { - return self.generate_edge_tree(runner) + return self.generate_edge_tree(runner); } let idx = runner.rng().gen_range(0..self.fixtures.len()); Ok(UintValueTree::new(self.fixtures[idx], false)) diff --git a/crates/evm/traces/src/decoder/precompiles.rs b/crates/evm/traces/src/decoder/precompiles.rs index 1475208f40c8..a6480bd8ea37 100644 --- a/crates/evm/traces/src/decoder/precompiles.rs +++ b/crates/evm/traces/src/decoder/precompiles.rs @@ -46,7 +46,7 @@ pub(super) fn decode(trace: &CallTrace, _chain_id: u64) -> Option<(String, Decod let [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x @ 0x01..=0x0a] = trace.address.0 .0 else { - return None + return None; }; let data = &trace.data; diff --git a/crates/evm/traces/src/identifier/etherscan.rs b/crates/evm/traces/src/identifier/etherscan.rs index 50c273d07b0f..ffda7e73b2d2 100644 --- a/crates/evm/traces/src/identifier/etherscan.rs +++ b/crates/evm/traces/src/identifier/etherscan.rs @@ -101,7 +101,7 @@ impl TraceIdentifier for EtherscanIdentifier { if self.invalid_api_key.load(Ordering::Relaxed) { // api key was marked as invalid - return Vec::new() + return Vec::new(); } let mut fetcher = EtherscanFetcher::new( @@ -205,7 +205,7 @@ impl Stream for EtherscanFetcher { if let Some(mut backoff) = pin.backoff.take() { if backoff.poll_tick(cx).is_pending() { pin.backoff = Some(backoff); - return Poll::Pending + return Poll::Pending; } } @@ -220,7 +220,7 @@ impl Stream for EtherscanFetcher { match res { Ok(mut metadata) => { if let Some(item) = metadata.items.pop() { - return Poll::Ready(Some((addr, item))) + return Poll::Ready(Some((addr, item))); } } Err(EtherscanError::RateLimitExceeded) => { @@ -232,13 +232,13 @@ impl Stream for EtherscanFetcher { warn!(target: "traces::etherscan", "invalid api key"); // mark key as invalid pin.invalid_api_key.store(true, Ordering::Relaxed); - return Poll::Ready(None) + return Poll::Ready(None); } Err(EtherscanError::BlockedByCloudflare) => { warn!(target: "traces::etherscan", "blocked by cloudflare"); // mark key as invalid pin.invalid_api_key.store(true, Ordering::Relaxed); - return Poll::Ready(None) + return Poll::Ready(None); } Err(err) => { warn!(target: "traces::etherscan", "could not get etherscan info: {:?}", err); @@ -248,7 +248,7 @@ impl Stream for EtherscanFetcher { } if !made_progress_this_iter { - return Poll::Pending + return Poll::Pending; } } } diff --git a/crates/fmt/src/buffer.rs b/crates/fmt/src/buffer.rs index 11c0838ecd37..35a82d15928a 100644 --- a/crates/fmt/src/buffer.rs +++ b/crates/fmt/src/buffer.rs @@ -189,7 +189,7 @@ impl FormatBuffer { } if lines.peek().is_some() || s.as_ref().ends_with('\n') { if self.restrict_to_single_line { - return Err(std::fmt::Error) + return Err(std::fmt::Error); } self.w.write_char('\n')?; self.handle_newline(comment_state); @@ -202,7 +202,7 @@ impl FormatBuffer { impl Write for FormatBuffer { fn write_str(&mut self, mut s: &str) -> std::fmt::Result { if s.is_empty() { - return Ok(()) + return Ok(()); } let mut indent = " ".repeat(self.current_indent_len()); @@ -217,7 +217,7 @@ impl Write for FormatBuffer { self.w.write_str(s)?; self.handle_newline(comment_state); } - break + break; } // We can see the next non-empty line. Write up to the @@ -246,7 +246,7 @@ impl Write for FormatBuffer { } WriteState::WriteTokens(comment_state) => { if s.is_empty() { - break + break; } // find the next newline or non-comment string separator (e.g. ' or ") @@ -257,13 +257,13 @@ impl Write for FormatBuffer { len = idx; if ch == '\n' { if self.restrict_to_single_line { - return Err(std::fmt::Error) + return Err(std::fmt::Error); } new_state = WriteState::LineStart(state); - break + break; } else if state == CommentState::None && (ch == '\'' || ch == '"') { new_state = WriteState::WriteString(ch); - break + break; } else { new_state = WriteState::WriteTokens(state); } @@ -275,7 +275,7 @@ impl Write for FormatBuffer { self.current_line_len += s.len(); self.last_char = s.chars().next_back(); self.state = new_state; - break + break; } else { // A newline or string has been found. Write up to that character and // continue on the tail @@ -301,7 +301,7 @@ impl Write for FormatBuffer { self.w.write_str(s)?; self.current_line_len += s.len(); self.last_char = s.chars().next_back(); - break + break; } // String end found, write the string and continue to add tokens after Some((_, _, len)) => { diff --git a/crates/fmt/src/comments.rs b/crates/fmt/src/comments.rs index 03f4e41813c1..ec467864f799 100644 --- a/crates/fmt/src/comments.rs +++ b/crates/fmt/src/comments.rs @@ -79,7 +79,7 @@ impl CommentWithMetadata { ) -> Self { let src_before = &src[..comment.loc().start()]; if src_before.is_empty() { - return Self::new(comment, CommentPosition::Prefix, false, 0) + return Self::new(comment, CommentPosition::Prefix, false, 0); } let mut lines_before = src_before.lines().rev(); @@ -94,7 +94,7 @@ impl CommentWithMetadata { CommentPosition::Prefix, last_line.map_or(true, str::is_empty), indent_len, - ) + ); } // TODO: this loop takes almost the entirety of the time spent in parsing, which is up to @@ -245,7 +245,7 @@ impl Comments { .map(|(idx, _)| idx) .unwrap_or_else(|| comments.len()); if pos == 0 { - return Vec::new() + return Vec::new(); } comments.rotate_left(pos); comments.split_off(comments.len() - pos).into() @@ -420,7 +420,7 @@ impl<'a> Iterator for NonCommentChars<'a> { fn next(&mut self) -> Option { for (state, _, ch) in self.0.by_ref() { if state == CommentState::None { - return Some(ch) + return Some(ch); } } None diff --git a/crates/fmt/src/formatter.rs b/crates/fmt/src/formatter.rs index bf69651003f6..78df2c07dd2b 100644 --- a/crates/fmt/src/formatter.rs +++ b/crates/fmt/src/formatter.rs @@ -170,12 +170,12 @@ impl<'a, W: Write> Formatter<'a, W> { /// Does the next written character require whitespace before fn next_char_needs_space(&self, next_char: char) -> bool { if self.is_beginning_of_line() { - return false + return false; } let last_char = if let Some(last_char) = self.last_char() { last_char } else { return false }; if last_char.is_whitespace() || next_char.is_whitespace() { - return false + return false; } match last_char { '{' => match next_char { @@ -197,14 +197,15 @@ impl<'a, W: Write> Formatter<'a, W> { fn will_it_fit(&self, text: impl AsRef) -> bool { let text = text.as_ref(); if text.is_empty() { - return true + return true; } if text.contains('\n') { - return false + return false; } let space: usize = self.next_char_needs_space(text.chars().next().unwrap()).into(); - self.config.line_length >= - self.total_indent_len() + self.config.line_length + >= self + .total_indent_len() .saturating_add(self.current_line_len()) .saturating_add(text.chars().count() + space) } @@ -244,7 +245,7 @@ impl<'a, W: Write> Formatter<'a, W> { fn blank_lines(&self, start: usize, end: usize) -> usize { // because of sorting import statements, start can be greater than end if start > end { - return 0 + return 0; } self.source[start..end].trim_comments().matches('\n').count() } @@ -282,10 +283,10 @@ impl<'a, W: Write> Formatter<'a, W> { subset .comment_state_char_indices() .position(|(state, idx, ch)| { - first_char == ch && - state == CommentState::None && - idx + needle.len() <= subset.len() && - subset[idx..idx + needle.len()] == *needle + first_char == ch + && state == CommentState::None + && idx + needle.len() <= subset.len() + && subset[idx..idx + needle.len()] == *needle }) .map(|p| byte_offset + p) }) @@ -416,7 +417,7 @@ impl<'a, W: Write> Formatter<'a, W> { /// or if the comment are wrapped fn write_comment(&mut self, comment: &CommentWithMetadata, is_first: bool) -> Result<()> { if self.inline_config.is_disabled(comment.loc) { - return self.write_raw_comment(comment) + return self.write_raw_comment(comment); } match comment.position { @@ -444,7 +445,7 @@ impl<'a, W: Write> Formatter<'a, W> { lines.try_for_each(|l| self.write_doc_block_line(comment, l))?; write!(self.buf(), " {}", comment.end_token().unwrap())?; self.write_preserved_line()?; - return Ok(()) + return Ok(()); } write!(self.buf(), "{}", comment.start_token())?; @@ -519,7 +520,7 @@ impl<'a, W: Write> Formatter<'a, W> { write!(self.buf(), " *{}", if needs_space { " " } else { "" })?; self.write_comment_line(comment, line)?; self.write_whitespace_separator(true)?; - return Ok(()) + return Ok(()); } let indent_whitespace_count = line @@ -545,7 +546,7 @@ impl<'a, W: Write> Formatter<'a, W> { line.chars().next().map(|ch| ch.is_whitespace()).unwrap_or_default(); if !self.is_beginning_of_line() || !start_with_ws { write!(self.buf(), "{line}")?; - return Ok(false) + return Ok(false); } // if this is the beginning of the line, @@ -557,7 +558,7 @@ impl<'a, W: Write> Formatter<'a, W> { .map(|(_, ch)| ch); let padded = format!("{}{}", " ".repeat(indent), chars.join("")); self.write_raw(padded)?; - return Ok(false) + return Ok(false); } let mut words = line.split(' ').peekable(); @@ -576,7 +577,7 @@ impl<'a, W: Write> Formatter<'a, W> { // write newline wrap token write!(self.buf(), "{}", comment.wrap_token())?; self.write_comment_line(comment, &words.join(" "))?; - return Ok(true) + return Ok(true); } self.write_whitespace_separator(false)?; @@ -1021,9 +1022,9 @@ impl<'a, W: Write> Formatter<'a, W> { Some(CommentWithMetadata { ty: CommentType::DocBlock, .. }) ); - if needs_space || - (!is_last_doc_comment && - self.blank_lines(last_loc.end(), loc.start()) > 1) + if needs_space + || (!is_last_doc_comment + && self.blank_lines(last_loc.end(), loc.start()) > 1) { writeln!(self.buf())?; } @@ -1083,14 +1084,14 @@ impl<'a, W: Write> Formatter<'a, W> { /// expression decide how to split itself on multiple lines fn visit_assignment(&mut self, expr: &mut Expression) -> Result<()> { if self.try_on_single_line(|fmt| expr.visit(fmt))? { - return Ok(()) + return Ok(()); } self.write_postfix_comments_before(expr.loc().start())?; self.write_prefix_comments_before(expr.loc().start())?; if self.try_on_single_line(|fmt| fmt.indented(1, |fmt| expr.visit(fmt)))? { - return Ok(()) + return Ok(()); } let mut fit_on_next_line = false; @@ -1182,7 +1183,7 @@ impl<'a, W: Write> Formatter<'a, W> { })?; if fits_on_single { - return Ok(true) + return Ok(true); } } @@ -1346,7 +1347,7 @@ impl<'a, W: Write> Formatter<'a, W> { let add_underscores = |string: &str, reversed: bool| -> String { if !config.is_thousands() || string.len() < 5 { - return string.to_string() + return string.to_string(); } if reversed { Box::new(string.as_bytes().chunks(3)) as Box> @@ -1484,14 +1485,14 @@ impl<'a, W: Write> Formatter<'a, W> { } else { ";" }; - let should_multiline = header_multiline && - matches!( + let should_multiline = header_multiline + && matches!( fmt.config.multiline_func_header, MultilineFuncHeaderStyle::ParamsFirst | MultilineFuncHeaderStyle::All ); - params_multiline = should_multiline || - multiline || - fmt.are_chunks_separated_multiline( + params_multiline = should_multiline + || multiline + || fmt.are_chunks_separated_multiline( &format!("{{}}){after_params}"), ¶ms, ",", @@ -1571,8 +1572,8 @@ impl<'a, W: Write> Formatter<'a, W> { Ok(()) }; - let should_multiline = header_multiline && - if params_multiline { + let should_multiline = header_multiline + && if params_multiline { matches!(self.config.multiline_func_header, MultilineFuncHeaderStyle::All) } else { matches!( @@ -1580,8 +1581,8 @@ impl<'a, W: Write> Formatter<'a, W> { MultilineFuncHeaderStyle::AttributesFirst ) }; - let attrs_multiline = should_multiline || - !self.try_on_single_line(|fmt| { + let attrs_multiline = should_multiline + || !self.try_on_single_line(|fmt| { write_attributes(fmt, false)?; if !fmt.will_it_fit(if func.body.is_some() { " {" } else { ";" }) { bail!(FormatterError::fmt()) @@ -1617,8 +1618,8 @@ impl<'a, W: Write> Formatter<'a, W> { let cond_close_paren_loc = self.find_next_in_src(cond.loc().end(), ')').unwrap_or_else(|| cond.loc().end()); - let attempt_single_line = single_line_stmt_wide && - self.should_attempt_block_single_line(if_branch.as_mut(), cond_close_paren_loc); + let attempt_single_line = single_line_stmt_wide + && self.should_attempt_block_single_line(if_branch.as_mut(), cond_close_paren_loc); let if_branch_is_single_line = self.visit_stmt_as_block(if_branch, attempt_single_line)?; if single_line_stmt_wide && !if_branch_is_single_line { bail!(FormatterError::fmt()) @@ -1673,7 +1674,7 @@ impl<'a, W: Write> Formatter<'a, W> { if import_groups.is_empty() { // nothing to sort - return + return; } // order all groups alphabetically @@ -1842,7 +1843,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { fmt.write_postfix_comments_before(first.loc().start())?; fmt.write_whitespace_separator(true)?; } else { - return Ok(()) + return Ok(()); } if fmt.config.contract_new_lines { @@ -1990,7 +1991,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { fmt.write_semicolon()?; Ok(()) })?; - return Ok(()) + return Ok(()); } let imports_start = imports.first().unwrap().0.loc.start(); @@ -2158,9 +2159,9 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { } if let Some(first) = chunks.first_mut() { - if first.prefixes.is_empty() && - first.postfixes_before.is_empty() && - !self.config.bracket_spacing + if first.prefixes.is_empty() + && first.postfixes_before.is_empty() + && !self.config.bracket_spacing { first.needs_space = Some(false); } @@ -2314,9 +2315,9 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { fmt.chunked(end.loc().start(), Some(loc.end()), |fmt| { end.visit(fmt) })?; - if chunk.prefixes.is_empty() && - chunk.postfixes_before.is_empty() && - (start.is_none() || fmt.will_it_fit(&chunk.content)) + if chunk.prefixes.is_empty() + && chunk.postfixes_before.is_empty() + && (start.is_none() || fmt.will_it_fit(&chunk.content)) { chunk.needs_space = Some(false); } @@ -2354,33 +2355,33 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { })?; write_chunk!(self, loc.end(), "]")?; } - Expression::PreIncrement(..) | - Expression::PostIncrement(..) | - Expression::PreDecrement(..) | - Expression::PostDecrement(..) | - Expression::Not(..) | - Expression::UnaryPlus(..) | - Expression::Add(..) | - Expression::Negate(..) | - Expression::Subtract(..) | - Expression::Power(..) | - Expression::Multiply(..) | - Expression::Divide(..) | - Expression::Modulo(..) | - Expression::ShiftLeft(..) | - Expression::ShiftRight(..) | - Expression::BitwiseNot(..) | - Expression::BitwiseAnd(..) | - Expression::BitwiseXor(..) | - Expression::BitwiseOr(..) | - Expression::Less(..) | - Expression::More(..) | - Expression::LessEqual(..) | - Expression::MoreEqual(..) | - Expression::And(..) | - Expression::Or(..) | - Expression::Equal(..) | - Expression::NotEqual(..) => { + Expression::PreIncrement(..) + | Expression::PostIncrement(..) + | Expression::PreDecrement(..) + | Expression::PostDecrement(..) + | Expression::Not(..) + | Expression::UnaryPlus(..) + | Expression::Add(..) + | Expression::Negate(..) + | Expression::Subtract(..) + | Expression::Power(..) + | Expression::Multiply(..) + | Expression::Divide(..) + | Expression::Modulo(..) + | Expression::ShiftLeft(..) + | Expression::ShiftRight(..) + | Expression::BitwiseNot(..) + | Expression::BitwiseAnd(..) + | Expression::BitwiseXor(..) + | Expression::BitwiseOr(..) + | Expression::Less(..) + | Expression::More(..) + | Expression::LessEqual(..) + | Expression::MoreEqual(..) + | Expression::And(..) + | Expression::Or(..) + | Expression::Equal(..) + | Expression::NotEqual(..) => { let spaced = expr.has_space_around(); let op = expr.operator().unwrap(); @@ -2411,17 +2412,17 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { (None, None) => {} } } - Expression::Assign(..) | - Expression::AssignOr(..) | - Expression::AssignAnd(..) | - Expression::AssignXor(..) | - Expression::AssignShiftLeft(..) | - Expression::AssignShiftRight(..) | - Expression::AssignAdd(..) | - Expression::AssignSubtract(..) | - Expression::AssignMultiply(..) | - Expression::AssignDivide(..) | - Expression::AssignModulo(..) => { + Expression::Assign(..) + | Expression::AssignOr(..) + | Expression::AssignAnd(..) + | Expression::AssignXor(..) + | Expression::AssignShiftLeft(..) + | Expression::AssignShiftRight(..) + | Expression::AssignAdd(..) + | Expression::AssignSubtract(..) + | Expression::AssignMultiply(..) + | Expression::AssignDivide(..) + | Expression::AssignModulo(..) => { let op = expr.operator().unwrap(); let (left, right) = expr.components_mut(); let (left, right) = (left.unwrap(), right.unwrap()); @@ -2523,7 +2524,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { #[instrument(name = "ident_path", skip_all)] fn visit_ident_path(&mut self, idents: &mut IdentifierPath) -> Result<(), Self::Error> { if idents.identifiers.is_empty() { - return Ok(()) + return Ok(()); } return_source_if_disabled!(self, idents.loc); @@ -2631,7 +2632,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { if expr.is_none() { write_chunk!(self, loc.end(), "return;")?; - return Ok(()) + return Ok(()); } let expr = expr.as_mut().unwrap(); @@ -2648,7 +2649,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { expr.visit(fmt) })?; if fits_on_single { - return Ok(()) + return Ok(()); } let mut fit_on_next_line = false; @@ -2665,7 +2666,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { })?; if fit_on_next_line { tx.commit()?; - return Ok(()) + return Ok(()); } write_return(fmt)?; @@ -2716,7 +2717,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { if args.is_empty() { write!(self.buf(), "({{}});")?; - return Ok(()) + return Ok(()); } write!(self.buf(), "(")?; @@ -2822,7 +2823,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { let multiline = self.are_chunks_separated_multiline("{}", &chunks, "")?; if !multiline { self.write_chunks_separated(&chunks, "", false)?; - return Ok(()) + return Ok(()); } let mut chunks = chunks.iter_mut().peekable(); @@ -2870,7 +2871,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { if !is_first_stmt { self.write_if_stmt(loc, cond, if_branch, else_branch)?; - return Ok(()) + return Ok(()); } self.context.if_stmt_single_line = Some(true); @@ -3152,7 +3153,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { name.content.push_str("()"); } self.write_chunk(&name)?; - return Ok(()) + return Ok(()); } let args = base.args.as_mut().unwrap(); @@ -3171,9 +3172,9 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { Some(base.loc.end()), args.iter_mut().map(|arg| (arg.loc(), arg)), )?; - let multiline = multiline || - multiline_hint || - fmt.are_chunks_separated_multiline("{}", &args, ",")?; + let multiline = multiline + || multiline_hint + || fmt.are_chunks_separated_multiline("{}", &args, ",")?; fmt.write_chunks_separated(&args, ",", multiline)?; Ok(()) }, @@ -3206,7 +3207,7 @@ impl<'a, W: Write> Visitor for Formatter<'a, W> { write_chunk!(fmt, struct_name.loc.start(), "struct")?; struct_name.visit(fmt)?; if structure.fields.is_empty() { - return fmt.write_empty_brackets() + return fmt.write_empty_brackets(); } write!(fmt.buf(), " {{")?; diff --git a/crates/fmt/src/helpers.rs b/crates/fmt/src/helpers.rs index 8d472e3bb33b..084e28ea6ef1 100644 --- a/crates/fmt/src/helpers.rs +++ b/crates/fmt/src/helpers.rs @@ -68,7 +68,7 @@ pub fn offset_to_line_column(content: &str, start: usize) -> (usize, usize) { line_counter += 1; } if offset > start { - return (line_counter, offset - start) + return (line_counter, offset - start); } } diff --git a/crates/fmt/src/macros.rs b/crates/fmt/src/macros.rs index c5c9d31a7d0e..68305d9f2f11 100644 --- a/crates/fmt/src/macros.rs +++ b/crates/fmt/src/macros.rs @@ -91,7 +91,7 @@ macro_rules! return_source_if_disabled { let loc = $loc; if $self.inline_config.is_disabled(loc) { trace!("Returning because disabled: {loc:?}"); - return $self.visit_source(loc) + return $self.visit_source(loc); } }}; ($self:expr, $loc:expr, $suffix:literal) => {{ @@ -103,7 +103,7 @@ macro_rules! return_source_if_disabled { if !has_suffix { write!($self.buf(), "{}", $suffix)?; } - return Ok(()) + return Ok(()); } }}; } diff --git a/crates/fmt/src/solang_ext/ast_eq.rs b/crates/fmt/src/solang_ext/ast_eq.rs index e31fc2b41013..8a779dbf6f0c 100644 --- a/crates/fmt/src/solang_ext/ast_eq.rs +++ b/crates/fmt/src/solang_ext/ast_eq.rs @@ -5,7 +5,7 @@ use std::str::FromStr; /// Helper to convert a string number into a comparable one fn to_num(string: &str) -> I256 { if string.is_empty() { - return I256::ZERO + return I256::ZERO; } string.replace('_', "").trim().parse().unwrap() } @@ -14,7 +14,7 @@ fn to_num(string: &str) -> I256 { /// This will reverse the number so that 0's can be ignored fn to_num_reversed(string: &str) -> U256 { if string.is_empty() { - return U256::from(0) + return U256::from(0); } string.replace('_', "").trim().chars().rev().collect::().parse().unwrap() } @@ -56,10 +56,10 @@ impl AstEq for VariableDefinition { attrs.sort(); attrs }; - self.ty.ast_eq(&other.ty) && - self.name.ast_eq(&other.name) && - self.initializer.ast_eq(&other.initializer) && - sorted_attrs(self).ast_eq(&sorted_attrs(other)) + self.ty.ast_eq(&other.ty) + && self.name.ast_eq(&other.name) + && self.initializer.ast_eq(&other.initializer) + && sorted_attrs(self).ast_eq(&sorted_attrs(other)) } } @@ -78,20 +78,20 @@ impl AstEq for FunctionDefinition { let left_returns = filter_params(&self.returns); let right_returns = filter_params(&other.returns); - self.ty.ast_eq(&other.ty) && - self.name.ast_eq(&other.name) && - left_params.ast_eq(&right_params) && - self.return_not_returns.ast_eq(&other.return_not_returns) && - left_returns.ast_eq(&right_returns) && - self.body.ast_eq(&other.body) && - sorted_attrs(self).ast_eq(&sorted_attrs(other)) + self.ty.ast_eq(&other.ty) + && self.name.ast_eq(&other.name) + && left_params.ast_eq(&right_params) + && self.return_not_returns.ast_eq(&other.return_not_returns) + && left_returns.ast_eq(&right_returns) + && self.body.ast_eq(&other.body) + && sorted_attrs(self).ast_eq(&sorted_attrs(other)) } } impl AstEq for Base { fn ast_eq(&self, other: &Self) -> bool { - self.name.ast_eq(&other.name) && - self.args.clone().unwrap_or_default().ast_eq(&other.args.clone().unwrap_or_default()) + self.name.ast_eq(&other.name) + && self.args.clone().unwrap_or_default().ast_eq(&other.args.clone().unwrap_or_default()) } } diff --git a/crates/fmt/src/string.rs b/crates/fmt/src/string.rs index 607c890e7c7c..69f94656144d 100644 --- a/crates/fmt/src/string.rs +++ b/crates/fmt/src/string.rs @@ -81,17 +81,17 @@ impl<'a> Iterator for QuotedRanges<'a> { let (quote, start) = loop { let (state, idx, _) = self.0.next()?; match state { - QuoteState::Opening(quote) | - QuoteState::Escaping(quote) | - QuoteState::Escaped(quote) | - QuoteState::String(quote) => break (quote, idx), + QuoteState::Opening(quote) + | QuoteState::Escaping(quote) + | QuoteState::Escaped(quote) + | QuoteState::String(quote) => break (quote, idx), QuoteState::Closing(quote) => return Some((quote, idx, idx)), QuoteState::None => {} } }; for (state, idx, _) in self.0.by_ref() { if matches!(state, QuoteState::Closing(_)) { - return Some((quote, start, idx)) + return Some((quote, start, idx)); } } None @@ -111,11 +111,11 @@ pub trait QuotedStringExt { fn is_quoted(&self) -> bool { let mut iter = self.quote_state_char_indices(); if !matches!(iter.next(), Some((QuoteState::Opening(_), _, _))) { - return false + return false; } while let Some((state, _, _)) = iter.next() { if matches!(state, QuoteState::Closing(_)) { - return iter.next().is_none() + return iter.next().is_none(); } } false diff --git a/crates/fmt/tests/formatter.rs b/crates/fmt/tests/formatter.rs index 18b72a54512b..37c72ef6c62d 100644 --- a/crates/fmt/tests/formatter.rs +++ b/crates/fmt/tests/formatter.rs @@ -60,7 +60,7 @@ fn test_directory(base_name: &str, test_config: TestConfig) { .try_into() .unwrap_or_else(|err| panic!("Invalid config for {filename}: {err}")); - return Some((filename.to_string(), config, lines.join("\n"))) + return Some((filename.to_string(), config, lines.join("\n"))); } } diff --git a/crates/forge/Cargo.toml b/crates/forge/Cargo.toml index 84abd46373e2..2faae4ef1ff6 100644 --- a/crates/forge/Cargo.toml +++ b/crates/forge/Cargo.toml @@ -77,6 +77,8 @@ solang-parser.workspace = true strum = { workspace = true, features = ["derive"] } thiserror = "1" tokio = { version = "1", features = ["time"] } +toml = { version = "0.8", features = ["preserve_order"] } +toml_edit = "0.21" watchexec = "2.3.2" evm-disassembler.workspace = true rustc-hash.workspace = true diff --git a/crates/forge/bin/cmd/bind.rs b/crates/forge/bin/cmd/bind.rs index 5be0f262a1a2..1b8867181ff5 100644 --- a/crates/forge/bin/cmd/bind.rs +++ b/crates/forge/bin/cmd/bind.rs @@ -97,7 +97,7 @@ impl BindArgs { if !self.overwrite && self.bindings_exist(&artifacts) { println!("Bindings found. Checking for consistency."); - return self.check_existing_bindings(&artifacts) + return self.check_existing_bindings(&artifacts); } if self.overwrite && self.bindings_exist(&artifacts) { @@ -127,13 +127,13 @@ impl BindArgs { /// Returns the filter to use for `MultiAbigen` fn get_filter(&self) -> ContractFilter { if self.select_all { - return ContractFilter::All + return ContractFilter::All; } if !self.select.is_empty() { - return SelectContracts::default().extend_regex(self.select.clone()).into() + return SelectContracts::default().extend_regex(self.select.clone()).into(); } if !self.skip.is_empty() { - return ExcludeContracts::default().extend_regex(self.skip.clone()).into() + return ExcludeContracts::default().extend_regex(self.skip.clone()).into(); } // This excludes all Test/Script and forge-std contracts ExcludeContracts::default() @@ -157,7 +157,7 @@ impl BindArgs { .filter_map(|path| { if path.to_string_lossy().contains("/build-info/") { // ignore the build info json - return None + return None; } // we don't want `.metadata.json files let stem = path.file_stem()?; diff --git a/crates/forge/bin/cmd/build.rs b/crates/forge/bin/cmd/build.rs index 66dae630e1b0..887236bb89d2 100644 --- a/crates/forge/bin/cmd/build.rs +++ b/crates/forge/bin/cmd/build.rs @@ -79,8 +79,8 @@ impl BuildArgs { let mut config = self.try_load_config_emit_warnings()?; let mut project = config.project()?; - if install::install_missing_dependencies(&mut config, self.args.silent) && - config.auto_detect_remappings + if install::install_missing_dependencies(&mut config, self.args.silent) + && config.auto_detect_remappings { // need to re-configure here to also catch additional remappings config = self.load_config(); diff --git a/crates/forge/bin/cmd/cache.rs b/crates/forge/bin/cmd/cache.rs index ff3117d345f1..001f60c0bf20 100644 --- a/crates/forge/bin/cmd/cache.rs +++ b/crates/forge/bin/cmd/cache.rs @@ -131,7 +131,7 @@ fn clean_chain_cache(chain: impl Into, blocks: Vec, etherscan: bool) if blocks.is_empty() { Config::clean_foundry_etherscan_chain_cache(chain)?; if etherscan { - return Ok(()) + return Ok(()); } Config::clean_foundry_chain_cache(chain)?; } else { diff --git a/crates/forge/bin/cmd/clone.rs b/crates/forge/bin/cmd/clone.rs new file mode 100644 index 000000000000..035092430493 --- /dev/null +++ b/crates/forge/bin/cmd/clone.rs @@ -0,0 +1,401 @@ +use std::{fs::read_dir, path::PathBuf}; + +use alloy_primitives::Address; +use clap::{Parser, ValueHint}; +use eyre::Result; +use foundry_block_explorers::{contract::Metadata, Client}; +use foundry_cli::opts::EtherscanOpts; +use foundry_common::fs; +use foundry_compilers::artifacts::Settings; +use foundry_compilers::remappings::{RelativeRemapping, Remapping}; +use foundry_compilers::ProjectPathsConfig; +use foundry_config::Config; +use toml_edit; + +use super::init::InitArgs; + +/// CLI arguments for `forge clone`. +#[derive(Clone, Debug, Parser)] +pub struct CloneArgs { + /// The contract address to clone. + address: String, + + /// The root directory of the cloned project. + #[arg(value_hint = ValueHint::DirPath, default_value = ".", value_name = "PATH")] + root: PathBuf, + + #[command(flatten)] + etherscan: EtherscanOpts, +} + +impl CloneArgs { + pub async fn run(self) -> Result<()> { + let CloneArgs { address, root, etherscan } = self; + + // parse the contract address + let contract_address: Address = address.parse()?; + + // get the chain and api key from the config + let config = Config::from(ðerscan); + let chain = config.chain.unwrap_or_default(); + let etherscan_api_key = config.get_etherscan_api_key(Some(chain)).unwrap_or_default(); + + // get the contract code + let client = Client::new(chain, etherscan_api_key)?; + let mut meta = client.contract_source_code(contract_address).await?; + if meta.items.len() != 1 { + return Err(eyre::eyre!("contract not found or ill-formed")); + } + let meta = meta.items.remove(0); + if meta.is_vyper() { + return Err(eyre::eyre!("Vyper contracts are not supported")); + } + + // let's try to init the project with default init args + let init_args = InitArgs { root: root.clone(), ..Default::default() }; + init_args.run().map_err(|e| eyre::eyre!("Project init error: {:?}", e))?; + + // canonicalize the root path + // note that at this point, the root directory must have been created + let root = dunce::canonicalize(root)?; + + // remove the unnecessary example contracts + // XXX (ZZ): this is a temporary solution until we have a proper way to remove contracts, + // e.g., add a field in the InitArgs to control the example contract generation + fs::remove_file(root.join("src/Counter.sol"))?; + fs::remove_file(root.join("test/Counter.t.sol"))?; + fs::remove_file(root.join("script/Counter.s.sol"))?; + + // dump sources and update the remapping in configuration + let remappings = dump_sources(&meta, root.clone())?; + Config::update_at(root.clone(), |config, doc| { + let profile = config.profile.as_str().as_str(); + let mut remapping_array = toml_edit::Array::new(); + for r in remappings { + remapping_array.push(r.to_string()); + } + doc[Config::PROFILE_SECTION][profile]["remappings"] = toml_edit::value(remapping_array); + + true + })?; + + // update configuration + Config::update_at(root, |config, doc| { + update_config_by_metadata(config, doc, &meta).is_ok() + })?; + + Ok(()) + } +} + +/// Update the configuration file with the metadata. +/// This function will update the configuration file with the metadata from the contract. +/// It will update the following fields: +/// - `auto_detect_solc` to `false` +/// - `solc_version` to the value from the metadata +/// - `evm_version` to the value from the metadata +/// - `via_ir` to the value from the metadata +/// - `libraries` to the value from the metadata +/// - `metadata` to the value from the metadata +/// - `cbor_metadata`, `use_literal_content`, and `bytecode_hash` +/// - `optimizer` to the value from the metadata +/// - `optimizer_runs` to the value from the metadata +/// - `optimizer_details` to the value from the metadata +/// - `yul_details`, `yul`, etc. +/// - `simpleCounterForLoopUncheckedIncrement` is ignored for now +/// - `remappings` and `stop_after` are pre-validated to be empty and None, respectively +/// - `model_checker`, `debug`, and `output_selection` are ignored for now +/// +/// Detailed information can be found from the following link: +/// - https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options +/// - https://docs.soliditylang.org/en/latest/using-the-compiler.html#compiler-input-and-output-json-description +fn update_config_by_metadata( + config: &Config, + doc: &mut toml_edit::Document, + meta: &Metadata, +) -> Result<()> { + let profile = config.profile.as_str().as_str(); + + // macro to update the config if the value exists + macro_rules! update_if_needed { + ([$($key:expr),+], $value:expr) => { + { + if let Some(value) = $value { + let mut current = &mut doc[Config::PROFILE_SECTION][profile]; + $( + if let Some(nested_doc) = current.get_mut(&$key) { + current = nested_doc; + } else { + return Err(eyre::eyre!("cannot find the key: {}", $key)); + } + )+ + *current = toml_edit::value(value); + } + } + }; + } + + // disable auto detect solc and set the solc version + doc[Config::PROFILE_SECTION][profile]["auto_detect_solc"] = toml_edit::value(false); + let version = meta.compiler_version()?; + doc[Config::PROFILE_SECTION][profile]["solc_version"] = + toml_edit::value(format!("{}.{}.{}", version.major, version.minor, version.patch)); + + // get optimizer settings + // XXX (ZZ): we ignore `model_checker`, `debug`, and `output_selection` for now, + // it seems they do not have impacts on the actual compilation + let Settings { + optimizer, + libraries, + evm_version, + via_ir, + stop_after, + remappings, + metadata, + .. + } = meta.settings()?; + eyre::ensure!(stop_after.is_none(), "stop_after should be None"); + eyre::ensure!(remappings.is_empty(), "remappings should be empty"); + + update_if_needed!(["evm_version"], evm_version.map(|v| v.to_string())); + update_if_needed!(["via_ir"], via_ir); + + // update metadata if needed + if let Some(metadata) = metadata { + update_if_needed!(["cbor_metadata"], metadata.cbor_metadata); + update_if_needed!(["use_literal_content"], metadata.use_literal_content); + update_if_needed!(["bytecode_hash"], metadata.bytecode_hash.map(|v| v.to_string())); + } + + // update optimizer settings if needed + update_if_needed!(["optimizer"], optimizer.enabled); + update_if_needed!(["optimizer_runs"], optimizer.runs.map(|v| v as i64)); + // update optimizer details if needed + if let Some(detail) = optimizer.details { + doc[Config::PROFILE_SECTION][profile]["optimizer_details"] = toml_edit::table(); + + update_if_needed!(["optimizer_details", "peephole"], detail.peephole); + update_if_needed!(["optimizer_details", "inliner"], detail.inliner); + update_if_needed!(["optimizer_details", "jumpdestRemover"], detail.jumpdest_remover); + update_if_needed!(["optimizer_details", "orderLiterals"], detail.order_literals); + update_if_needed!(["optimizer_details", "deduplicate"], detail.deduplicate); + update_if_needed!(["optimizer_details", "cse"], detail.cse); + update_if_needed!(["optimizer_details", "constantOptimizer"], detail.constant_optimizer); + // XXX (ZZ): simpleCounterForLoopUncheckedIncrement seems not supported by fourndry + update_if_needed!(["optimizer_details", "yul"], detail.yul); + + if let Some(yul_detail) = detail.yul_details { + doc[Config::PROFILE_SECTION][profile]["optimizer_details"]["yulDetails"] = + toml_edit::table(); + update_if_needed!( + ["optimizer_details", "yulDetails", "stackAllocation"], + yul_detail.stack_allocation + ); + update_if_needed!( + ["optimizer_details", "yulDetails", "optimizerSteps"], + yul_detail.optimizer_steps + ); + } + } + + // apply remapping on libraries + let path_config = config.project_paths(); + let libraries = + libraries.with_stripped_file_prefixes("contracts").with_applied_remappings(&path_config); + + // update libraries + let mut lib_array = toml_edit::Array::new(); + for (path_to_lib, info) in libraries.libs { + for (lib_name, address) in info { + lib_array.push(format!( + "{}:{}:{}", + path_to_lib.to_str().unwrap(), + lib_name, + address.to_string() + )); + } + } + doc[Config::PROFILE_SECTION][profile]["libraries"] = toml_edit::value(lib_array); + + Ok(()) +} + +/// Dump the contract sources to the root directory. +/// The sources are dumped to the `src` directory. +/// The library sources are dumped to the `lib` directory. +/// IO errors may be returned. +fn dump_sources(meta: &Metadata, root: PathBuf) -> Result> { + // get config + let path_config = ProjectPathsConfig::builder().build_with_root(&root); + let src_dir = root.join(path_config.sources.clone()).canonicalize()?; + let contract_name = meta.contract_name.clone(); + let source_tree = meta.source_tree(); + + // first we dump the sources to a temporary directory + let tmp_dump_dir = root.join("raw_sources"); + source_tree + .write_to(&tmp_dump_dir) + .map_err(|e| eyre::eyre!("failed to dump sources: {}", e))?; + + // then we move the sources to the correct directories + // 1. we will first load existing remappings if necessary + // make sure this happens before dumping sources + let mut remappings: Vec = Remapping::find_many(root.clone()); + // we also load the original remappings from the metadata + remappings.extend(meta.settings()?.remappings); + + // 1. move contract sources to the `src` directory + for entry in std::fs::read_dir(tmp_dump_dir.join(contract_name))? { + if std::fs::metadata(&src_dir).is_err() { + std::fs::create_dir(&src_dir)?; + } + let entry = entry?; + if entry.file_name().to_string_lossy().to_string().as_str() == "contracts" { + // move all sub folders in contracts to src + for e in read_dir(entry.path())? { + let e = e?; + let dest = src_dir.join(e.file_name()); + std::fs::rename(e.path(), dest.clone())?; + remappings.push(Remapping { + context: None, + name: e.file_name().to_string_lossy().to_string(), + path: dest.to_string_lossy().to_string(), + }); + } + } else { + // move the other folders to src + let dest = src_dir.join(entry.file_name()); + std::fs::rename(entry.path(), dest.clone())?; + remappings.push(Remapping { + context: None, + name: entry.file_name().to_string_lossy().to_string(), + path: dest.to_string_lossy().to_string(), + }); + } + } + + // remove the temporary directory + std::fs::remove_dir_all(tmp_dump_dir)?; + + Ok(remappings.into_iter().map(|r| r.into_relative(&root)).collect()) +} + +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use super::CloneArgs; + use foundry_common::compile::ProjectCompiler; + use foundry_compilers::{Artifact, ProjectCompileOutput}; + use foundry_config::Config; + use hex::ToHex; + use tempfile; + + fn assert_successful_compilation(root: &PathBuf) -> ProjectCompileOutput { + println!("project_root: {:#?}", root); + // change directory to the root + std::env::set_current_dir(root).unwrap(); + let config = Config::load(); + let project = config.project().unwrap(); + let compiler = ProjectCompiler::new(); + compiler.compile(&project).expect("compilation failure") + } + + fn assert_compilation_result( + compiled: ProjectCompileOutput, + contract_name: &str, + stripped_creation_code: &str, + ) { + compiled.compiled_contracts_by_compiler_version().iter().for_each(|(_, contracts)| { + contracts.iter().for_each(|(name, contract)| { + if name == contract_name { + let compiled_creation_code = + contract.get_bytecode_object().expect("creation code not found"); + let compiled_creation_code: String = compiled_creation_code.encode_hex(); + assert!( + compiled_creation_code.starts_with(&stripped_creation_code), + "inconsistent creation code" + ); + } + }); + }); + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] + async fn test_clone_single_file_contract() { + let project_root = tempfile::tempdir().unwrap().path().to_path_buf(); + let args = CloneArgs { + address: "0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193".to_string(), + root: project_root.clone(), + etherscan: Default::default(), + }; + let (contract_name, stripped_creation_code) = + pick_creation_info(&args.address).expect("creation code not found"); + args.run().await.unwrap(); + let rv = assert_successful_compilation(&project_root); + assert_compilation_result(rv, contract_name, stripped_creation_code) + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] + async fn test_clone_contract_with_optimization_details() { + let project_root = tempfile::tempdir().unwrap().path().to_path_buf(); + let args = CloneArgs { + address: "0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545".to_string(), + root: project_root.clone(), + etherscan: Default::default(), + }; + let (contract_name, stripped_creation_code) = + pick_creation_info(&args.address).expect("creation code not found"); + args.run().await.unwrap(); + let rv = assert_successful_compilation(&project_root); + assert_compilation_result(rv, contract_name, stripped_creation_code) + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] + async fn test_clone_contract_with_libraries() { + let project_root = tempfile::tempdir().unwrap().path().to_path_buf(); + let args = CloneArgs { + address: "0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec".to_string(), + root: project_root.clone(), + etherscan: Default::default(), + }; + let (contract_name, stripped_creation_code) = + pick_creation_info(&args.address).expect("creation code not found"); + args.run().await.unwrap(); + let rv = assert_successful_compilation(&project_root); + assert_compilation_result(rv, contract_name, stripped_creation_code) + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] + async fn test_clone_contract_with_metadata() { + let project_root = tempfile::tempdir().unwrap().path().to_path_buf(); + let args = CloneArgs { + address: "0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05".to_string(), + root: project_root.clone(), + etherscan: Default::default(), + }; + let (contract_name, stripped_creation_code) = + pick_creation_info(&args.address).expect("creation code not found"); + args.run().await.unwrap(); + let rv = assert_successful_compilation(&project_root); + assert_compilation_result(rv, contract_name, stripped_creation_code) + } + + fn pick_creation_info(address: &str) -> Option<(&'static str, &'static str)> { + for (addr, contract_name, creation_code) in CREATION_ARRAY.iter() { + if address == *addr { + return Some((contract_name, creation_code)); + } + } + + None + } + + // XXX (ZZ): remember to remove CBOR metadata from the creation code + const CREATION_ARRAY: [(&'static str, &'static str, &'static str); 4] = [ + ("0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193", "BearXNFTStaking", "608060405234801561001057600080fd5b50613000806100206000396000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c80638129fc1c11610130578063bca35a71116100b8578063dada55011161007c578063dada550114610458578063f2fde38b1461046b578063f83d08ba1461047e578063fbb0022714610486578063fccd7f721461048e57600080fd5b8063bca35a71146103fa578063bf9befb11461040d578063c89d5b8b14610416578063d5d423001461041e578063d976e09f1461042657600080fd5b8063b1c92f95116100ff578063b1c92f95146103c5578063b549445c146103ce578063b81f8e89146103d6578063b9ade5b7146103de578063ba0848db146103e757600080fd5b80638129fc1c146103905780638da5cb5b14610398578063aaed083b146103a9578063b10dcc93146103b257600080fd5b8063367c164e116101b35780635923489b116101825780635923489b146103245780636e2751211461034f578063706ce3e114610362578063715018a614610375578063760a2e8a1461037d57600080fd5b8063367c164e146102bd57806338ff8a85146102d05780633a17f4f0146102f1578063426233601461030457600080fd5b8063206635e7116101fa578063206635e71461026d5780632afe761a146102805780632bd30f1114610289578063305f839a146102ab57806333ddacd1146102b457600080fd5b8062944f621461022b5780630d00368b146102405780630e8feed41461025c578063120957fd14610264575b600080fd5b61023e610239366004612aa4565b6104bc565b005b61024960735481565b6040519081526020015b60405180910390f35b61023e61053a565b610249606d5481565b61023e61027b366004612b2c565b61057e565b610249606f5481565b60785461029b90610100900460ff1681565b6040519015158152602001610253565b61024960715481565b61024960765481565b61023e6102cb366004612bc2565b6105d1565b6102e36102de366004612aa4565b610829565b604051610253929190612c16565b61023e6102ff366004612aa4565b6109e1565b610317610312366004612aa4565b610a56565b6040516102539190612c2f565b606a54610337906001600160a01b031681565b6040516001600160a01b039091168152602001610253565b6102e361035d366004612aa4565b610b4c565b606b54610337906001600160a01b031681565b61023e610cf8565b61029b61038b366004612aa4565b610d2e565b61023e610dc2565b6033546001600160a01b0316610337565b61024960705481565b61023e6103c0366004612b2c565b610fc0565b610249606e5481565b61023e611236565b61023e6112bb565b61024960725481565b6102e36103f5366004612aa4565b6112ef565b61023e610408366004612aa4565b61149b565b610249606c5481565b610249611510565b606f54610249565b610439610434366004612aa4565b611594565b6040805192151583526001600160a01b03909116602083015201610253565b606954610337906001600160a01b031681565b61023e610479366004612aa4565b6115cf565b61023e611667565b61023e6116a0565b6104a161049c366004612aa4565b6116e1565b60408051938452602084019290925290820152606001610253565b6033546001600160a01b031633146104ef5760405162461bcd60e51b81526004016104e690612c42565b60405180910390fd5b606b546001600160a01b03163b6105185760405162461bcd60e51b81526004016104e690612c77565b606b80546001600160a01b0319166001600160a01b0392909216919091179055565b600061054533611594565b509050806105655760405162461bcd60e51b81526004016104e690612cae565b61056e33610d2e565b61057b5761057b33611c73565b50565b610587336116e1565b505060765560005b81518110156105cd576105bb8282815181106105ad576105ad612cda565b602002602001015133611d7b565b806105c581612d06565b91505061058f565b5050565b606a54604051636eb1769f60e11b815233600482015273871770e3e03bfaefa3597056e540a1a9c9ac7f6b602482015282916001600160a01b03169063dd62ed3e90604401602060405180830381865afa158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612d21565b10156106bb5760405162461bcd60e51b815260206004820152602d60248201527f596f75206861766520746f20617070726f766520726f6f747820746f2073746160448201526c1ada5b99c818dbdb9d1c9858dd609a1b60648201526084016104e6565b606a546040516323b872dd60e01b815233600482015273871770e3e03bfaefa3597056e540a1a9c9ac7f6b6024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015610726573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074a9190612d3a565b50606a546040516326c7e79d60e21b8152600481018390526001600160a01b0390911690639b1f9e7490602401600060405180830381600087803b15801561079157600080fd5b505af11580156107a5573d6000803e3d6000fd5b5050606b546001600160a01b031691506379c650689050336107c88460056120a1565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561080e57600080fd5b505af1158015610822573d6000803e3d6000fd5b5050505050565b600060606000805b6001600160a01b0385166000908152607460205260409020548110156108bc576001600160a01b0385166000908152607460205260409020805461089791908390811061088057610880612cda565b906000526020600020906005020160000154612129565b156108aa576108a7600183612d5c565b91505b806108b481612d06565b915050610831565b5060008167ffffffffffffffff8111156108d8576108d8612ac1565b604051908082528060200260200182016040528015610901578160200160208202803683370190505b5090506000805b6001600160a01b0387166000908152607460205260409020548110156109d5576001600160a01b0387166000908152607460205260409020805461095791908390811061088057610880612cda565b156109c3576001600160a01b038716600090815260746020526040902080548290811061098657610986612cda565b9060005260206000209060050201600001548383815181106109aa576109aa612cda565b60209081029190910101526109c0826001612154565b91505b806109cd81612d06565b915050610908565b50919590945092505050565b6033546001600160a01b03163314610a0b5760405162461bcd60e51b81526004016104e690612c42565b6069546001600160a01b03163b610a345760405162461bcd60e51b81526004016104e690612c77565b606980546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0381166000908152607460205260408120546060919067ffffffffffffffff811115610a8b57610a8b612ac1565b604051908082528060200260200182016040528015610ab4578160200160208202803683370190505b50905060005b6001600160a01b038416600090815260746020526040902054811015610b45576001600160a01b0384166000908152607460205260409020805482908110610b0457610b04612cda565b906000526020600020906005020160000154828281518110610b2857610b28612cda565b602090810291909101015280610b3d81612d06565b915050610aba565b5092915050565b600060606000805b6001600160a01b038516600090815260746020526040902054811015610bdf576001600160a01b03851660009081526074602052604090208054610bba919083908110610ba357610ba3612cda565b9060005260206000209060050201600001546121b3565b15610bcd57610bca826001612154565b91505b80610bd781612d06565b915050610b54565b5060008167ffffffffffffffff811115610bfb57610bfb612ac1565b604051908082528060200260200182016040528015610c24578160200160208202803683370190505b5090506000805b6001600160a01b0387166000908152607460205260409020548110156109d5576001600160a01b03871660009081526074602052604090208054610c7a919083908110610ba357610ba3612cda565b15610ce6576001600160a01b0387166000908152607460205260409020805482908110610ca957610ca9612cda565b906000526020600020906005020160000154838381518110610ccd57610ccd612cda565b6020908102919091010152610ce3826001612154565b91505b80610cf081612d06565b915050610c2b565b6033546001600160a01b03163314610d225760405162461bcd60e51b81526004016104e690612c42565b610d2c60006121d0565b565b60006001815b6001600160a01b038416600090815260746020526040902054811015610b45576001600160a01b03841660009081526074602052604081208054610d9a919084908110610d8357610d83612cda565b906000526020600020906005020160010154612222565b9050603c8111610daa5750610db0565b60009250505b80610dba81612d06565b915050610d34565b600054610100900460ff16610ddd5760005460ff1615610de1565b303b155b610e445760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104e6565b600054610100900460ff16158015610e66576000805461ffff19166101011790555b610e6e61223c565b606580546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d1790915560668054821673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2179055620151806067556312cc030060685560698054821673e22e1e620dffb03065cd77db0162249c0c91bf01179055606a8054821673d718ad25285d65ef4d79262a6cd3aea6a8e01023179055606b80549091167399cfdf48d0ba4885a73786148a2f89d86c7021701790556000606c5568056bc75e2d63100000606d556802b5e3af16b1880000606e55690257058e269742680000606f819055681b1ae4d6e2ef5000006070819055610bb8607181905591610f709190612d74565b610f7a9190612d8b565b607255607154606e54606d54610f909190612d74565b610f9a9190612d8b565b60735560006076556078805460ff19169055801561057b576000805461ff001916905550565b6000610fcb33611594565b50905080610feb5760405162461bcd60e51b81526004016104e690612cae565b607854610100900460ff161561102c5760405162461bcd60e51b8152602060048201526006602482015265131bd8dad95960d21b60448201526064016104e6565b600061103733610a56565b90508051835111156110775760405162461bcd60e51b81526020600482015260096024820152684964206572726f727360b81b60448201526064016104e6565b6000805b84518110156110fd5760005b83518110156110ea578381815181106110a2576110a2612cda565b60200260200101518683815181106110bc576110bc612cda565b602002602001015114156110d8576110d5836001612154565b92505b806110e281612d06565b915050611087565b50806110f581612d06565b91505061107b565b50835181141561123057835161112761111e82678ac7230489e800006120a1565b606f5490612154565b606f55611132612273565b600060768190555b855181101561122d5760695486516001600160a01b03909116906323b872dd90309033908a908690811061117057611170612cda565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b1580156111ca57600080fd5b505af11580156111de573d6000803e3d6000fd5b5050606c80549250905060006111f383612dad565b919050555061121b3387838151811061120e5761120e612cda565b602002602001015161229b565b8061122581612d06565b91505061113a565b50505b50505050565b60785460ff166112ac5760005b60755481101561057b576001607760006075848154811061126657611266612cda565b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff1916911515919091179055806112a481612d06565b915050611243565b6078805460ff19166001179055565b60006112c633611594565b509050806112e65760405162461bcd60e51b81526004016104e690612cae565b61057b33612470565b600060606000805b6001600160a01b038516600090815260746020526040902054811015611382576001600160a01b0385166000908152607460205260409020805461135d91908390811061134657611346612cda565b906000526020600020906005020160000154612574565b156113705761136d600183612d5c565b91505b8061137a81612d06565b9150506112f7565b5060008167ffffffffffffffff81111561139e5761139e612ac1565b6040519080825280602002602001820160405280156113c7578160200160208202803683370190505b5090506000805b6001600160a01b0387166000908152607460205260409020548110156109d5576001600160a01b0387166000908152607460205260409020805461141d91908390811061134657611346612cda565b15611489576001600160a01b038716600090815260746020526040902080548290811061144c5761144c612cda565b90600052602060002090600502016000015483838151811061147057611470612cda565b6020908102919091010152611486826001612154565b91505b8061149381612d06565b9150506113ce565b6033546001600160a01b031633146114c55760405162461bcd60e51b81526004016104e690612c42565b606a546001600160a01b03163b6114ee5760405162461bcd60e51b81526004016104e690612c77565b606a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000806064606f5460016115249190612dc4565b61152e9190612d8b565b611539906001612d5c565b606d546115469190612dc4565b90506000606d54826115589190612d74565b905060006001606d548361156c9190612d8b565b6115769190612d8b565b611581906001612dc4565b61158c906064612dc4565b949350505050565b6001600160a01b038116600090815260776020526040812054819060ff161515600114156115c457506001929050565b506000928392509050565b6033546001600160a01b031633146115f95760405162461bcd60e51b81526004016104e690612c42565b6001600160a01b03811661165e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104e6565b61057b816121d0565b73d0d725208fd36be1561050fc1dd6a651d7ea7c89331415610d2c576078805461ff001981166101009182900460ff1615909102179055565b60006116ab33611594565b509050806116cb5760405162461bcd60e51b81526004016104e690612cae565b6116d433610d2e565b61057b5761057b336125aa565b600080808080808087816116f482610829565b509050600061170283610b4c565b50905060058110611a3b57600160005b6001600160a01b038516600090815260746020526040902054811015611a0e576001600160a01b0385166000908152607460205260408120805461177891908490811061176157611761612cda565b906000526020600020906005020160040154612222565b6001600160a01b038716600090815260746020526040902080549192506117a99184908110610ba357610ba3612cda565b806117de57506001600160a01b038616600090815260746020526040902080546117de91908490811061088057610880612cda565b80156117ea5750600181105b156117f457600092505b82801561181857506001600160a01b03861660009081526074602052604090205415155b156118715761186a8561182c83600a612dc4565b6118369190612dc4565b6118648661184585600a612dc4565b61184f9190612dc4565b60765461186490670de0b6b3a7640000612798565b90612154565b995061188e565b8261188e5760765461188b90670de0b6b3a7640000612798565b99505b6001600160a01b038616600090815260746020526040902080546118bd91908490811061088057610880612cda565b15611950576001600160a01b038616600090815260746020526040812080546119089190859081106118f1576118f1612cda565b906000526020600020906005020160020154612222565b90508061192861192182680ad78ebc5ac6200000612dc4565b8c90612154565b9a5061194761194082680ad78ebc5ac6200000612dc4565b8b90612154565b995050506119fb565b6001600160a01b0386166000908152607460205260409020805461197f919084908110610ba357610ba3612cda565b156119fb576001600160a01b038616600090815260746020526040812080546119b39190859081106118f1576118f1612cda565b905060008190506119d76002606d54846119cd9190612dc4565b6119219190612d8b565b9a506119f66002606d54836119ec9190612dc4565b6119409190612d8b565b995050505b5080611a0681612d06565b915050611712565b508515611a3557606b54606654611a32916001600160a01b039081169116886127da565b94505b50611c4f565b60005b6001600160a01b038416600090815260746020526040902054811015611c28576001600160a01b03841660009081526074602052604090208054611a8d91908390811061088057610880612cda565b15611b9f576001600160a01b03841660009081526074602052604081208054611ac191908490811061176157611761612cda565b9050611ad8611ad182600a612dc4565b8a90612154565b98506000611b1560746000886001600160a01b03166001600160a01b0316815260200190815260200160002084815481106118f1576118f1612cda565b9050611b2d611ad182680ad78ebc5ac6200000612dc4565b98506000611b8160746000896001600160a01b03166001600160a01b031681526020019081526020016000208581548110611b6a57611b6a612cda565b906000526020600020906005020160030154612222565b9050611b99611ad182680ad78ebc5ac6200000612dc4565b98505050505b6001600160a01b03841660009081526074602052604090208054611bce919083908110610ba357610ba3612cda565b15611c16576001600160a01b03841660009081526074602052604081208054611c0291908490811061176157611761612cda565b9050611c12611ad182600a612dc4565b9850505b80611c2081612d06565b915050611a3e565b508415611c4f57606b54606654611c4c916001600160a01b039081169116876127da565b93505b611c6187670de0b6b3a7640000612dc4565b9b959a50929850939650505050505050565b6000611c7e826116e1565b5091505080156105cd57606b5460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016020604051808303816000875af1158015611cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cff9190612d3a565b5060005b6001600160a01b038316600090815260746020526040902054811015611d76576001600160a01b0383166000908152607460205260409020805442919083908110611d5057611d50612cda565b600091825260209091206002600590920201015580611d6e81612d06565b915050611d03565b505050565b607054606f5410611db857607354606d6000828254611d9a9190612d74565b9091555050606f54611db490678ac7230489e80000612905565b606f555b6069546040516331a9108f60e11b8152600481018490526001600160a01b03838116921690636352211e90602401602060405180830381865afa158015611e03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e279190612de3565b6001600160a01b031614611e7d5760405162461bcd60e51b815260206004820152601e60248201527f596f7520617265206e6f742061206f776e6572206f6620746865206e6674000060448201526064016104e6565b60695460405163e985e9c560e01b81523360048201523060248201526001600160a01b039091169063e985e9c590604401602060405180830381865afa158015611ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eef9190612d3a565b1515600114611f575760405162461bcd60e51b815260206004820152602e60248201527f596f752073686f756c6420617070726f7665206e667420746f2074686520737460448201526d185ada5b99c818dbdb9d1c9858dd60921b60648201526084016104e6565b6069546040516323b872dd60e01b81526001600160a01b03838116600483015230602483015260448201859052909116906323b872dd90606401600060405180830381600087803b158015611fab57600080fd5b505af1158015611fbf573d6000803e3d6000fd5b505050506000611fce82611594565b50905060006040518060a001604052808581526020014281526020014281526020014281526020014281525090506120126001606c5461215490919063ffffffff16565b606c556001600160a01b03831660009081526074602090815260408083208054600181810183559185529383902085516005909502019384559184015191830191909155820151600282015560608201516003820155608082015160049091015581611230576001600160a01b0383166000908152607760205260409020805460ff1916600117905550505050565b6000826120b057506000612123565b60006120bc8385612dc4565b9050826120c98583612d8b565b146121205760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b60648201526084016104e6565b90505b92915050565b60008064e8d4a510008310158015612146575064e8d4a510058311155b156121235750600192915050565b6000806121618385612d5c565b9050838110156121205760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f77000000000060448201526064016104e6565b600080610e7483116121c757506001612123565b50600092915050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6067546000906122328342612d74565b6121239190612d8b565b600054610100900460ff166122635760405162461bcd60e51b81526004016104e690612e00565b61226b612947565b610d2c61296e565b61227c33612470565b61228533610d2e565b610d2c5761229233611c73565b610d2c336125aa565b60005b6001600160a01b038316600090815260746020526040902054811015612428576001600160a01b03831660009081526074602052604090208054839190839081106122eb576122eb612cda565b9060005260206000209060050201600001541415612416576001600160a01b0383166000908152607460205260409020805461232990600190612d74565b8154811061233957612339612cda565b906000526020600020906005020160746000856001600160a01b03166001600160a01b03168152602001908152602001600020828154811061237d5761237d612cda565b60009182526020808320845460059093020191825560018085015490830155600280850154908301556003808501549083015560049384015493909101929092556001600160a01b03851681526074909152604090208054806123e2576123e2612e4b565b6000828152602081206005600019909301928302018181556001810182905560028101829055600381018290556004015590555b8061242081612d06565b91505061229e565b506001600160a01b0382166000908152607460205260409020546105cd576001600160a01b038216600090815260746020526040812061246791612a3f565b6105cd8261299e565b600061247b826116e1565b509091505080156105cd57606a5460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016020604051808303816000875af11580156124d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124fd9190612d3a565b5060005b6001600160a01b038316600090815260746020526040902054811015611d76576001600160a01b038316600090815260746020526040902080544291908390811061254e5761254e612cda565b60009182526020909120600460059092020101558061256c81612d06565b915050612501565b60006509184e72a00682101561258c57506000919050565b6509184e72b4b38211156125a257506000919050565b506001919050565b60006125b5826116e1565b5091505080156105cd57606b5460655460405163095ea7b360e01b81526001600160a01b0391821660048201526024810184905291169063095ea7b3906044016020604051808303816000875af1158015612614573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126389190612d3a565b5060408051600280825260608083018452926020830190803683375050606b5482519293506001600160a01b03169183915060009061267957612679612cda565b6001600160a01b0392831660209182029290920101526066548251911690829060019081106126aa576126aa612cda565b6001600160a01b03928316602091820292909201015260655460405163791ac94760e01b815291169063791ac947906126f0908590600090869089904290600401612e9a565b600060405180830381600087803b15801561270a57600080fd5b505af115801561271e573d6000803e3d6000fd5b5050505060005b6001600160a01b038416600090815260746020526040902054811015611230576001600160a01b038416600090815260746020526040902080544291908390811061277257612772612cda565b60009182526020909120600360059092020101558061279081612d06565b915050612725565b600061212083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506129d7565b6040805160028082526060808301845260009390929190602083019080368337019050509050848160008151811061281457612814612cda565b60200260200101906001600160a01b031690816001600160a01b031681525050838160018151811061284857612848612cda565b6001600160a01b03928316602091820292909201015260655460405163d06ca61f60e01b8152600092919091169063d06ca61f9061288c9087908690600401612ed6565b600060405180830381865afa1580156128a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128d19190810190612eef565b905080600183516128e29190612d74565b815181106128f2576128f2612cda565b6020026020010151925050509392505050565b600061212083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612a0e565b600054610100900460ff16610d2c5760405162461bcd60e51b81526004016104e690612e00565b600054610100900460ff166129955760405162461bcd60e51b81526004016104e690612e00565b610d2c336121d0565b6000806129aa83611594565b915091508115611d76576001600160a01b03166000908152607760205260409020805460ff191690555050565b600081836129f85760405162461bcd60e51b81526004016104e69190612f75565b506000612a058486612d8b565b95945050505050565b60008184841115612a325760405162461bcd60e51b81526004016104e69190612f75565b506000612a058486612d74565b508054600082556005029060005260206000209081019061057b91905b80821115612a8b5760008082556001820181905560028201819055600382018190556004820155600501612a5c565b5090565b6001600160a01b038116811461057b57600080fd5b600060208284031215612ab657600080fd5b813561212081612a8f565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612b0057612b00612ac1565b604052919050565b600067ffffffffffffffff821115612b2257612b22612ac1565b5060051b60200190565b60006020808385031215612b3f57600080fd5b823567ffffffffffffffff811115612b5657600080fd5b8301601f81018513612b6757600080fd5b8035612b7a612b7582612b08565b612ad7565b81815260059190911b82018301908381019087831115612b9957600080fd5b928401925b82841015612bb757833582529284019290840190612b9e565b979650505050505050565b600060208284031215612bd457600080fd5b5035919050565b600081518084526020808501945080840160005b83811015612c0b57815187529582019590820190600101612bef565b509495945050505050565b82815260406020820152600061158c6040830184612bdb565b6020815260006121206020830184612bdb565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526017908201527f41646472657373206973206e6f7420636f6e7472616374000000000000000000604082015260600190565b6020808252601290820152712cb7ba9030b932903737ba1039ba30b5b2b960711b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415612d1a57612d1a612cf0565b5060010190565b600060208284031215612d3357600080fd5b5051919050565b600060208284031215612d4c57600080fd5b8151801515811461212057600080fd5b60008219821115612d6f57612d6f612cf0565b500190565b600082821015612d8657612d86612cf0565b500390565b600082612da857634e487b7160e01b600052601260045260246000fd5b500490565b600081612dbc57612dbc612cf0565b506000190190565b6000816000190483118215151615612dde57612dde612cf0565b500290565b600060208284031215612df557600080fd5b815161212081612a8f565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052603160045260246000fd5b600081518084526020808501945080840160005b83811015612c0b5781516001600160a01b031687529582019590820190600101612e75565b85815284602082015260a060408201526000612eb960a0830186612e61565b6001600160a01b0394909416606083015250608001529392505050565b82815260406020820152600061158c6040830184612e61565b60006020808385031215612f0257600080fd5b825167ffffffffffffffff811115612f1957600080fd5b8301601f81018513612f2a57600080fd5b8051612f38612b7582612b08565b81815260059190911b82018301908381019087831115612f5757600080fd5b928401925b82841015612bb757835182529284019290840190612f5c565b600060208083528351808285015260005b81811015612fa257858101830151858201604001528201612f86565b81811115612fb4576000604083870101525b50601f01601f191692909201604001939250505056fe"), + ("0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545", "GovernorCharlieDelegate", "608060405234801561001057600080fd5b50613e45806100206000396000f3fe60806040526004361061031a5760003560e01c80637b3c71d3116101ab578063d50572ee116100f7578063f0843ba811610095578063fc176c041161006f578063fc176c0414610b82578063fc4eee4214610ba2578063fc66ff1414610bb8578063fe0d94c114610bd857600080fd5b8063f0843ba814610b12578063f2b0653714610b32578063f682e04c14610b6257600080fd5b8063de7bc127116100d1578063de7bc127146109ec578063deaaa7cc14610a02578063e23a9a5214610a36578063e837159c14610afc57600080fd5b8063d50572ee146109a0578063da35c664146109b6578063ddf0b009146109cc57600080fd5b8063a6d8784a11610164578063c1a287e21161013e578063c1a287e214610933578063c4d66de81461094a578063c5a8425d1461096a578063c9fb9e871461098a57600080fd5b8063a6d8784a146108e7578063abaac6a8146108fd578063b58131b01461091d57600080fd5b80637b3c71d31461083c5780637bdbe4d01461085c5780637cae57bb14610871578063806bd5811461088757806386d37e8b146108a757806399533365146108c757600080fd5b80632fedff591161026a5780633e4f49e61161022357806350442098116101fd578063504420981461074657806356781388146107665780635c60da1b1461078657806366176743146107be57600080fd5b80633e4f49e6146106d957806340e58ee5146107065780634d6733d21461072657600080fd5b80632fedff59146105ee578063328dd9821461060e57806338bd0dda1461063e5780633932abb11461066b5780633af32abf146106815780633bccf4fd146106b957600080fd5b8063158ef93e116102d757806318b62629116102b157806318b626291461056e5780631dfb1b5a1461058457806320606b70146105a457806324bc1a64146105d857600080fd5b8063158ef93e146104f757806317977c611461052157806317ba1b8b1461054e57600080fd5b8063013cf08b1461031f57806302a251a31461042857806306fdde031461044c5780630825f38f146104a25780630ea2d98c146104b7578063140499ea146104d7575b600080fd5b34801561032b57600080fd5b506103b361033a3660046132ee565b60096020819052600091825260409091208054600182015460028301546007840154600885015495850154600a860154600b870154600c880154600d890154600e9099015497996001600160a01b0390971698959794969593949293919260ff808316936101008404821693620100009004909116918d565b604080519d8e526001600160a01b03909c1660208e01529a8c019990995260608b019790975260808a019590955260a089019390935260c088019190915260e08701521515610100860152151561012085015215156101408401526101608301526101808201526101a0015b60405180910390f35b34801561043457600080fd5b5061043e60045481565b60405190815260200161041f565b34801561045857600080fd5b506104956040518060400160405280601a81526020017f496e7465726573742050726f746f636f6c20476f7665726e6f7200000000000081525081565b60405161041f9190613363565b6104b56104b0366004613450565b610beb565b005b3480156104c357600080fd5b506104b56104d23660046132ee565b610e61565b3480156104e357600080fd5b506104b56104f23660046134d6565b610ec6565b34801561050357600080fd5b506012546105119060ff1681565b604051901515815260200161041f565b34801561052d57600080fd5b5061043e61053c3660046134d6565b600a6020526000908152604090205481565b34801561055a57600080fd5b506104b56105693660046132ee565b610f07565b34801561057a57600080fd5b5061043e600f5481565b34801561059057600080fd5b506104b561059f3660046132ee565b610f64565b3480156105b057600080fd5b5061043e7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b3480156105e457600080fd5b5061043e60015481565b3480156105fa57600080fd5b506104b56106093660046132ee565b610fc1565b34801561061a57600080fd5b5061062e6106293660046132ee565b61101e565b60405161041f94939291906135ba565b34801561064a57600080fd5b5061043e6106593660046134d6565b600d6020526000908152604090205481565b34801561067757600080fd5b5061043e60035481565b34801561068d57600080fd5b5061051161069c3660046134d6565b6001600160a01b03166000908152600d6020526040902054421090565b3480156106c557600080fd5b506104b56106d4366004613623565b6112af565b3480156106e557600080fd5b506106f96106f43660046132ee565b611516565b60405161041f9190613687565b34801561071257600080fd5b506104b56107213660046132ee565b61169e565b34801561073257600080fd5b506104b56107413660046136af565b611b80565b34801561075257600080fd5b506104b56107613660046132ee565b611c45565b34801561077257600080fd5b506104b56107813660046136d9565b611ca2565b34801561079257600080fd5b506000546107a6906001600160a01b031681565b6040516001600160a01b03909116815260200161041f565b3480156107ca57600080fd5b506108146107d9366004613705565b601160209081526000928352604080842090915290825290205460ff808216916101008104909116906201000090046001600160601b031683565b60408051931515845260ff90921660208401526001600160601b03169082015260600161041f565b34801561084857600080fd5b506104b5610857366004613728565b611d09565b34801561086857600080fd5b5061043e600a81565b34801561087d57600080fd5b5061043e600c5481565b34801561089357600080fd5b506104b56108a23660046132ee565b611d58565b3480156108b357600080fd5b506104b56108c23660046132ee565b611db5565b3480156108d357600080fd5b506104b56108e23660046134d6565b611e12565b3480156108f357600080fd5b5061043e60155481565b34801561090957600080fd5b506104b56109183660046132ee565b611e8b565b34801561092957600080fd5b5061043e60055481565b34801561093f57600080fd5b5061043e6212750081565b34801561095657600080fd5b506104b56109653660046134d6565b611ee8565b34801561097657600080fd5b50600e546107a6906001600160a01b031681565b34801561099657600080fd5b5061043e60135481565b3480156109ac57600080fd5b5061043e60025481565b3480156109c257600080fd5b5061043e60075481565b3480156109d857600080fd5b506104b56109e73660046132ee565b611fd9565b3480156109f857600080fd5b5061043e60105481565b348015610a0e57600080fd5b5061043e7f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b348015610a4257600080fd5b50610acc610a51366004613705565b60408051606081018252600080825260208201819052918101919091525060009182526011602090815260408084206001600160a01b03939093168452918152918190208151606081018352905460ff8082161515835261010082041693820193909352620100009092046001600160601b03169082015290565b6040805182511515815260208084015160ff1690820152918101516001600160601b03169082015260600161041f565b348015610b0857600080fd5b5061043e60145481565b348015610b1e57600080fd5b506104b5610b2d3660046132ee565b61238f565b348015610b3e57600080fd5b50610511610b4d3660046132ee565b600b6020526000908152604090205460ff1681565b348015610b6e57600080fd5b5061043e610b7d3660046139b0565b6123ec565b348015610b8e57600080fd5b506104b5610b9d3660046132ee565b612a48565b348015610bae57600080fd5b5061043e60065481565b348015610bc457600080fd5b506008546107a6906001600160a01b031681565b6104b5610be63660046132ee565b612aa5565b60008585858585604051602001610c06959493929190613a91565b60408051601f1981840301815291815281516020928301206000818152600b90935291205490915060ff16610c7b5760405162461bcd60e51b81526020600482015260166024820152753a3c103430b9b713ba103132b2b71038bab2bab2b21760511b60448201526064015b60405180910390fd5b81421015610ccb5760405162461bcd60e51b815260206004820152601d60248201527f7478206861736e2774207375727061737365642074696d656c6f636b2e0000006044820152606401610c72565b610cd86212750083613af3565b421115610d165760405162461bcd60e51b815260206004820152600c60248201526b3a3c1034b99039ba30b6329760a11b6044820152606401610c72565b6000818152600b60205260409020805460ff191690558351606090610d3c575082610d68565b848051906020012084604051602001610d56929190613b0b565b60405160208183030381529060405290505b6000876001600160a01b03168783604051610d839190613b3c565b60006040518083038185875af1925050503d8060008114610dc0576040519150601f19603f3d011682016040523d82523d6000602084013e610dc5565b606091505b5050905080610e0f5760405162461bcd60e51b81526020600482015260166024820152753a3c1032bc32b1baba34b7b7103932bb32b93a32b21760511b6044820152606401610c72565b876001600160a01b0316837fa560e3198060a2f10670c1ec5b403077ea6ae93ca8de1c32b451dc1a943cd6e789898989604051610e4f9493929190613b58565b60405180910390a35050505050505050565b333014610e805760405162461bcd60e51b8152600401610c7290613b95565b600480549082905560408051828152602081018490527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e882891015b60405180910390a15050565b333014610ee55760405162461bcd60e51b8152600401610c7290613b95565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b333014610f265760405162461bcd60e51b8152600401610c7290613b95565b600580549082905560408051828152602081018490527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc054619101610eba565b333014610f835760405162461bcd60e51b8152600401610c7290613b95565b600380549082905560408051828152602081018490527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a939101610eba565b333014610fe05760405162461bcd60e51b8152600401610c7290613b95565b601480549082905560408051828152602081018490527f519a192fe8db9e38785eb494c69f530ddb21b9e34322f8d08fe29bd3849749889101610eba565b606080606080600060096000878152602001908152602001600020905080600301816004018260050183600601838054806020026020016040519081016040528092919081815260200182805480156110a057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611082575b50505050509350828054806020026020016040519081016040528092919081815260200182805480156110f257602002820191906000526020600020905b8154815260200190600101908083116110de575b5050505050925081805480602002602001604051908101604052809291908181526020016000905b828210156111c657838290600052602060002001805461113990613bcc565b80601f016020809104026020016040519081016040528092919081815260200182805461116590613bcc565b80156111b25780601f10611187576101008083540402835291602001916111b2565b820191906000526020600020905b81548152906001019060200180831161119557829003601f168201915b50505050508152602001906001019061111a565b50505050915080805480602002602001604051908101604052809291908181526020016000905b8282101561129957838290600052602060002001805461120c90613bcc565b80601f016020809104026020016040519081016040528092919081815260200182805461123890613bcc565b80156112855780601f1061125a57610100808354040283529160200191611285565b820191906000526020600020905b81548152906001019060200180831161126857829003601f168201915b5050505050815260200190600101906111ed565b5050505090509450945094509450509193509193565b604080518082018252601a81527f496e7465726573742050726f746f636f6c20476f7665726e6f7200000000000060209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f75a838dcd8ee5903cc7f4a5799344d0080864f57a6e9911f8bdfb4c8ddce9b5481840152466060820152306080808301919091528351808303909101815260a0820184528051908301207f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f60c083015260e0820189905260ff8816610100808401919091528451808403909101815261012083019094528351939092019290922061190160f01b6101408401526101428301829052610162830181905290916000906101820160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa15801561143c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661149f5760405162461bcd60e51b815260206004820181905260248201527f63617374566f746542795369673a20696e76616c6964207369676e61747572656044820152606401610c72565b88816001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48a6114d7858e8e612c90565b6040805160ff90931683526001600160601b039091166020830152606090820181905260009082015260800160405180910390a3505050505050505050565b6000816007541015801561152b575060065482115b6115775760405162461bcd60e51b815260206004820152601a60248201527f73746174653a20696e76616c69642070726f706f73616c2069640000000000006044820152606401610c72565b600082815260096020908152604080832060018101546001600160a01b03168452600d90925290912054600c82015442919091109060ff16156115be575060029392505050565b816007015443116115d3575060009392505050565b816008015443116115e8575060019392505050565b8080156115fc575081600d015482600a0154115b80611618575080158015611618575081600a0154826009015411155b80611633575080158015611633575081600d01548260090154105b15611642575060039392505050565b6002820154611655575060049392505050565b600c820154610100900460ff1615611671575060079392505050565b6212750082600201546116849190613af3565b4210611694575060069392505050565b5060059392505050565b60076116a982611516565b60078111156116ba576116ba613671565b14156117085760405162461bcd60e51b815260206004820152601d60248201527f63616e742063616e63656c2065786563757465642070726f706f73616c0000006044820152606401610c72565b600081815260096020526040902060018101546001600160a01b0316336001600160a01b0316146119755760018101546001600160a01b03166000908152600d6020526040902054421015611878576005546008546001838101546001600160a01b039283169263782d6fe1929116906117829043613c07565b6040516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b1580156117c657600080fd5b505afa1580156117da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117fe9190613c1e565b6001600160601b03161080156118275750600e546001600160a01b0316336001600160a01b0316145b6118735760405162461bcd60e51b815260206004820152601c60248201527f63616e63656c3a2077686974656c69737465642070726f706f736572000000006044820152606401610c72565b611975565b6005546008546001838101546001600160a01b039283169263782d6fe1929116906118a39043613c07565b6040516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b1580156118e757600080fd5b505afa1580156118fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191f9190613c1e565b6001600160601b0316106119755760405162461bcd60e51b815260206004820181905260248201527f63616e63656c3a2070726f706f7365722061626f7665207468726573686f6c646044820152606401610c72565b600c8101805460ff1916600117905560005b6003820154811015611b5057611b3e8260030182815481106119ab576119ab613c47565b6000918252602090912001546004840180546001600160a01b0390921691849081106119d9576119d9613c47565b90600052602060002001548460050184815481106119f9576119f9613c47565b906000526020600020018054611a0e90613bcc565b80601f0160208091040260200160405190810160405280929190818152602001828054611a3a90613bcc565b8015611a875780601f10611a5c57610100808354040283529160200191611a87565b820191906000526020600020905b815481529060010190602001808311611a6a57829003601f168201915b5050505050856006018581548110611aa157611aa1613c47565b906000526020600020018054611ab690613bcc565b80601f0160208091040260200160405190810160405280929190818152602001828054611ae290613bcc565b8015611b2f5780601f10611b0457610100808354040283529160200191611b2f565b820191906000526020600020905b815481529060010190602001808311611b1257829003601f168201915b50505050508660020154612f12565b80611b4881613c5d565b915050611987565b5060405182907f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90600090a25050565b333014611b9f5760405162461bcd60e51b8152600401610c7290613b95565b42601554611bad9190613af3565b8110611bf45760405162461bcd60e51b81526020600482015260166024820152750caf0e0d2e4c2e8d2dedc40caf0c6cacac8e640dac2f60531b6044820152606401610c72565b6001600160a01b0382166000818152600d6020908152604091829020849055815192835282018390527f4e7b7545bc5744d0e30425959f4687475774b6c7edad77d24cb51c7d967d45159101610eba565b333014611c645760405162461bcd60e51b8152600401610c7290613b95565b601080549082905560408051828152602081018490527f2a61b867418a359864adca8bb250ea65ee8bd41dbfd0279198d8e7552d4a27c29101610eba565b81337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda483611cd1838583612c90565b6040805160ff90931683526001600160601b039091166020830152606090820181905260009082015260800160405180910390a35050565b83337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda485611d38838583612c90565b8686604051611d4a9493929190613c78565b60405180910390a350505050565b333014611d775760405162461bcd60e51b8152600401610c7290613b95565b601380549082905560408051828152602081018490527f8cb5451eee8feb516cec9cd600201bbc31a30886d70c841a085a3fa69a4294d19101610eba565b333014611dd45760405162461bcd60e51b8152600401610c7290613b95565b600180549082905560408051828152602081018490527fa74554b0f53da47d07ec571d712428b3720460f54f81375fbcf78f6b5f72e7ed9101610eba565b333014611e315760405162461bcd60e51b8152600401610c7290613b95565b600e80546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f80a07e73e552148844a9c216d9724212d609cfa54e9c1a2e97203bdd2c4ad3419101610eba565b333014611eaa5760405162461bcd60e51b8152600401610c7290613b95565b600f80549082905560408051828152602081018490527f80a384652af83fc00bfd40ef94edda7ede83e7db39931b2c889821573f314e239101610eba565b60125460ff1615611f3b5760405162461bcd60e51b815260206004820152601860248201527f616c7265616479206265656e20696e697469616c697a656400000000000000006044820152606401610c72565b600880546001600160a01b0319166001600160a01b0392909216919091179055619d8060045561335460035569d3c21bcecceda10000006005556202a300600c5560006007556a084595161401484a00000060019081556a21165458500521280000006002556119aa600f5561a8c06010556a01a784379d99db420000006013556146506014556301e133806015556012805460ff19169091179055565b6004611fe482611516565b6007811115611ff557611ff5613671565b146120425760405162461bcd60e51b815260206004820152601f60248201527f63616e206f6e6c792062652071756575656420696620737563636565646564006044820152606401610c72565b6000818152600960205260408120600e8101549091906120629042613af3565b905060005b600383015481101561234d57600b600084600301838154811061208c5761208c613c47565b6000918252602090912001546004860180546001600160a01b0390921691859081106120ba576120ba613c47565b90600052602060002001548660050185815481106120da576120da613c47565b906000526020600020018760060186815481106120f9576120f9613c47565b9060005260206000200187604051602001612118959493929190613d62565b60408051601f198184030181529181528151602092830120835290820192909252016000205460ff161561218e5760405162461bcd60e51b815260206004820152601760248201527f70726f706f73616c20616c7265616479207175657565640000000000000000006044820152606401610c72565b61233a8360030182815481106121a6576121a6613c47565b6000918252602090912001546004850180546001600160a01b0390921691849081106121d4576121d4613c47565b90600052602060002001548560050184815481106121f4576121f4613c47565b90600052602060002001805461220990613bcc565b80601f016020809104026020016040519081016040528092919081815260200182805461223590613bcc565b80156122825780601f1061225757610100808354040283529160200191612282565b820191906000526020600020905b81548152906001019060200180831161226557829003601f168201915b505050505086600601858154811061229c5761229c613c47565b9060005260206000200180546122b190613bcc565b80601f01602080910402602001604051908101604052809291908181526020018280546122dd90613bcc565b801561232a5780601f106122ff5761010080835404028352916020019161232a565b820191906000526020600020905b81548152906001019060200180831161230d57829003601f168201915b50505050508688600e0154612fac565b508061234581613c5d565b915050612067565b506002820181905560405181815283907f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda28929060200160405180910390a2505050565b3330146123ae5760405162461bcd60e51b8152600401610c7290613b95565b600280549082905560408051828152602081018490527fc2adf06da6765dba7faaccde4c0ce3f91c35dd3390e7f0b6bc2844202c9fa9529101610eba565b6000600154600014156124365760405162461bcd60e51b8152602060048201526012602482015271436861726c6965206e6f742061637469766560701b6044820152606401610c72565b6005546008546001600160a01b031663782d6fe133612456600143613c07565b6040516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b15801561249a57600080fd5b505afa1580156124ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d29190613c1e565b6001600160601b03161015806124ec57506124ec3361069c565b6125385760405162461bcd60e51b815260206004820152601e60248201527f766f7465732062656c6f772070726f706f73616c207468726573686f6c6400006044820152606401610c72565b8551875114801561254a575084518751145b8015612557575083518751145b6125a35760405162461bcd60e51b815260206004820152601a60248201527f696e666f726d6174696f6e206172697479206d69736d617463680000000000006044820152606401610c72565b86516125e85760405162461bcd60e51b81526020600482015260146024820152736d7573742070726f7669646520616374696f6e7360601b6044820152606401610c72565b600a8751111561262d5760405162461bcd60e51b815260206004820152601060248201526f746f6f206d616e7920616374696f6e7360801b6044820152606401610c72565b336000908152600a6020526040902054801561271657600061264e82611516565b9050600181600781111561266457612664613671565b14156126b25760405162461bcd60e51b815260206004820152601e60248201527f6f6e65206c6976652070726f706f73616c207065722070726f706f73657200006044820152606401610c72565b60008160078111156126c6576126c6613671565b14156127145760405162461bcd60e51b815260206004820152601e60248201527f6f6e65206c6976652070726f706f73616c207065722070726f706f73657200006044820152606401610c72565b505b6007805490600061272683613c5d565b9190505550600060405180610220016040528060075481526020016127483390565b6001600160a01b03168152602001600081526020018a8152602001898152602001888152602001878152602001600354436127839190613af3565b8152602001600454600354436127999190613af3565b6127a39190613af3565b815260200160008152602001600081526020016000815260200160001515815260200160001515815260200185151581526020016001548152602001600c5481525090508380156127fa57506127f83361069c565b155b1561282c574360e08201819052600f5461281391613af3565b6101008201526002546101e08201526010546102008201525b6128353361069c565b15612876576013546101e08201526014546128509043613af3565b60e08201526004546014546128659043613af3565b61286f9190613af3565b6101008201525b805160009081526009602090815260409182902083518155818401516001820180546001600160a01b0319166001600160a01b03909216919091179055918301516002830155606083015180518493926128d792600385019291019061309d565b50608082015180516128f3916004840191602090910190613102565b5060a0820151805161290f91600584019160209091019061313d565b5060c0820151805161292b916006840191602090910190613196565b5060e08281015160078301556101008084015160088401556101208401516009840155610140840151600a80850191909155610160850151600b850155610180850151600c850180546101a08801516101c089015161ffff1990921693151561ff0019169390931792151585029290921762ff0000191662010000921515929092029190911790556101e0850151600d85015561020090940151600e9093019290925583516020808601516001600160a01b0316600090815294905260409384902055830151835191840151925190923392917f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e091612a33918f918f918f918f918f90613d9b565b60405180910390a45198975050505050505050565b333014612a675760405162461bcd60e51b8152600401610c7290613b95565b600c80549082905560408051828152602081018490527fed0229422af39d4d7d33f7a27d31d6f5cb20ec628293da58dd6e8a528ed466be9101610eba565b6005612ab082611516565b6007811115612ac157612ac1613671565b14612b0e5760405162461bcd60e51b815260206004820152601c60248201527f63616e206f6e6c792062652065786563276420696620717565756564000000006044820152606401610c72565b6000818152600960205260408120600c8101805461ff001916610100179055905b6003820154811015612c6057306001600160a01b0316630825f38f836004018381548110612b5f57612b5f613c47565b9060005260206000200154846003018481548110612b7f57612b7f613c47565b6000918252602090912001546004860180546001600160a01b039092169186908110612bad57612bad613c47565b9060005260206000200154866005018681548110612bcd57612bcd613c47565b90600052602060002001876006018781548110612bec57612bec613c47565b9060005260206000200188600201546040518763ffffffff1660e01b8152600401612c1b959493929190613d62565b6000604051808303818588803b158015612c3457600080fd5b505af1158015612c48573d6000803e3d6000fd5b50505050508080612c5890613c5d565b915050612b2f565b5060405182907f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90600090a25050565b60006001612c9d84611516565b6007811115612cae57612cae613671565b14612cee5760405162461bcd60e51b815260206004820152601060248201526f1d9bdd1a5b99c81a5cc818db1bdcd95960821b6044820152606401610c72565b60028260ff161115612d365760405162461bcd60e51b8152602060048201526011602482015270696e76616c696420766f7465207479706560781b6044820152606401610c72565b6000838152600960209081526040808320601183528184206001600160a01b0389168552909252909120805460ff1615612da85760405162461bcd60e51b81526020600482015260136024820152721d9bdd195c88185b1c9958591e481d9bdd1959606a1b6044820152606401610c72565b600854600783015460405163782d6fe160e01b81526000926001600160a01b03169163782d6fe191612df2918b916004016001600160a01b03929092168252602082015260400190565b60206040518083038186803b158015612e0a57600080fd5b505afa158015612e1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e429190613c1e565b905060ff8516612e6f57806001600160601b031683600a0154612e659190613af3565b600a840155612ec9565b8460ff1660011415612e9e57806001600160601b03168360090154612e949190613af3565b6009840155612ec9565b8460ff1660021415612ec957806001600160601b031683600b0154612ec39190613af3565b600b8401555b81546001600160601b03821662010000026dffffffffffffffffffffffff00001960ff88166101000261ffff199093169290921760011791909116179091559150509392505050565b60008585858585604051602001612f2d959493929190613a91565b60408051601f1981840301815282825280516020918201206000818152600b909252919020805460ff1916905591506001600160a01b0387169082907f2fffc091a501fd91bfbff27141450d3acb40fb8e6d8382b243ec7a812a3aaf8790612f9c908990899089908990613b58565b60405180910390a3505050505050565b6000612fb88242613af3565b831015612ffd5760405162461bcd60e51b815260206004820152601360248201527236bab9ba1039b0ba34b9b33c903232b630bc9760691b6044820152606401610c72565b60008787878787604051602001613018959493929190613a91565b60408051601f1981840301815282825280516020918201206000818152600b909252919020805460ff1916600117905591506001600160a01b0389169082907f76e2796dc3a81d57b0e8504b647febcbeeb5f4af818e164f11eef8131a6a763f9061308a908b908b908b908b90613b58565b60405180910390a3979650505050505050565b8280548282559060005260206000209081019282156130f2579160200282015b828111156130f257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906130bd565b506130fe9291506131ef565b5090565b8280548282559060005260206000209081019282156130f2579160200282015b828111156130f2578251825591602001919060010190613122565b82805482825590600052602060002090810192821561318a579160200282015b8281111561318a578251805161317a918491602090910190613204565b509160200191906001019061315d565b506130fe929150613277565b8280548282559060005260206000209081019282156131e3579160200282015b828111156131e357825180516131d3918491602090910190613204565b50916020019190600101906131b6565b506130fe929150613294565b5b808211156130fe57600081556001016131f0565b82805461321090613bcc565b90600052602060002090601f01602090048101928261323257600085556130f2565b82601f1061324b57805160ff19168380011785556130f2565b828001600101855582156130f257918201828111156130f2578251825591602001919060010190613122565b808211156130fe57600061328b82826132b1565b50600101613277565b808211156130fe5760006132a882826132b1565b50600101613294565b5080546132bd90613bcc565b6000825580601f106132cd575050565b601f0160209004906000526020600020908101906132eb91906131ef565b50565b60006020828403121561330057600080fd5b5035919050565b60005b8381101561332257818101518382015260200161330a565b83811115613331576000848401525b50505050565b6000815180845261334f816020860160208601613307565b601f01601f19169290920160200192915050565b6020815260006133766020830184613337565b9392505050565b80356001600160a01b038116811461339457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156133d8576133d8613399565b604052919050565b600082601f8301126133f157600080fd5b813567ffffffffffffffff81111561340b5761340b613399565b61341e601f8201601f19166020016133af565b81815284602083860101111561343357600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561346857600080fd5b6134718661337d565b945060208601359350604086013567ffffffffffffffff8082111561349557600080fd5b6134a189838a016133e0565b945060608801359150808211156134b757600080fd5b506134c4888289016133e0565b95989497509295608001359392505050565b6000602082840312156134e857600080fd5b6133768261337d565b600081518084526020808501945080840160005b8381101561352a5781516001600160a01b031687529582019590820190600101613505565b509495945050505050565b600081518084526020808501945080840160005b8381101561352a57815187529582019590820190600101613549565b600081518084526020808501808196508360051b8101915082860160005b858110156135ad57828403895261359b848351613337565b98850198935090840190600101613583565b5091979650505050505050565b6080815260006135cd60808301876134f1565b82810360208401526135df8187613535565b905082810360408401526135f38186613565565b905082810360608401526136078185613565565b979650505050505050565b803560ff8116811461339457600080fd5b600080600080600060a0868803121561363b57600080fd5b8535945061364b60208701613612565b935061365960408701613612565b94979396509394606081013594506080013592915050565b634e487b7160e01b600052602160045260246000fd5b60208101600883106136a957634e487b7160e01b600052602160045260246000fd5b91905290565b600080604083850312156136c257600080fd5b6136cb8361337d565b946020939093013593505050565b600080604083850312156136ec57600080fd5b823591506136fc60208401613612565b90509250929050565b6000806040838503121561371857600080fd5b823591506136fc6020840161337d565b6000806000806060858703121561373e57600080fd5b8435935061374e60208601613612565b9250604085013567ffffffffffffffff8082111561376b57600080fd5b818701915087601f83011261377f57600080fd5b81358181111561378e57600080fd5b8860208285010111156137a057600080fd5b95989497505060200194505050565b600067ffffffffffffffff8211156137c9576137c9613399565b5060051b60200190565b600082601f8301126137e457600080fd5b813560206137f96137f4836137af565b6133af565b82815260059290921b8401810191818101908684111561381857600080fd5b8286015b8481101561383a5761382d8161337d565b835291830191830161381c565b509695505050505050565b600082601f83011261385657600080fd5b813560206138666137f4836137af565b82815260059290921b8401810191818101908684111561388557600080fd5b8286015b8481101561383a5780358352918301918301613889565b600082601f8301126138b157600080fd5b813560206138c16137f4836137af565b82815260059290921b840181019181810190868411156138e057600080fd5b8286015b8481101561383a57803567ffffffffffffffff8111156139045760008081fd5b6139128986838b01016133e0565b8452509183019183016138e4565b600082601f83011261393157600080fd5b813560206139416137f4836137af565b82815260059290921b8401810191818101908684111561396057600080fd5b8286015b8481101561383a57803567ffffffffffffffff8111156139845760008081fd5b6139928986838b01016133e0565b845250918301918301613964565b8035801515811461339457600080fd5b60008060008060008060c087890312156139c957600080fd5b863567ffffffffffffffff808211156139e157600080fd5b6139ed8a838b016137d3565b97506020890135915080821115613a0357600080fd5b613a0f8a838b01613845565b96506040890135915080821115613a2557600080fd5b613a318a838b016138a0565b95506060890135915080821115613a4757600080fd5b613a538a838b01613920565b94506080890135915080821115613a6957600080fd5b50613a7689828a016133e0565b925050613a8560a088016139a0565b90509295509295509295565b60018060a01b038616815284602082015260a060408201526000613ab860a0830186613337565b8281036060840152613aca8186613337565b9150508260808301529695505050505050565b634e487b7160e01b600052601160045260246000fd5b60008219821115613b0657613b06613add565b500190565b6001600160e01b0319831681528151600090613b2e816004850160208701613307565b919091016004019392505050565b60008251613b4e818460208701613307565b9190910192915050565b848152608060208201526000613b716080830186613337565b8281036040840152613b838186613337565b91505082606083015295945050505050565b60208082526017908201527f6d75737420636f6d652066726f6d2074686520676f762e000000000000000000604082015260600190565b600181811c90821680613be057607f821691505b60208210811415613c0157634e487b7160e01b600052602260045260246000fd5b50919050565b600082821015613c1957613c19613add565b500390565b600060208284031215613c3057600080fd5b81516001600160601b038116811461337657600080fd5b634e487b7160e01b600052603260045260246000fd5b6000600019821415613c7157613c71613add565b5060010190565b60ff851681526001600160601b038416602082015260606040820152816060820152818360808301376000818301608090810191909152601f909201601f191601019392505050565b8054600090600181811c9080831680613cdb57607f831692505b6020808410821415613cfd57634e487b7160e01b600052602260045260246000fd5b838852818015613d145760018114613d2857613d56565b60ff19861689830152604089019650613d56565b876000528160002060005b86811015613d4e5781548b8201850152908501908301613d33565b8a0183019750505b50505050505092915050565b60018060a01b038616815284602082015260a060408201526000613d8960a0830186613cc1565b8281036060840152613aca8186613cc1565b60c081526000613dae60c08301896134f1565b8281036020840152613dc08189613535565b90508281036040840152613dd48188613565565b90508281036060840152613de88187613565565b905084608084015282810360a0840152613e028185613337565b999850505050505050505056fe"), + ("0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec", "PoolExercise", "6101c06040523480156200001257600080fd5b50604051620030713803806200307183398101604081905262000035916200016a565b6001600160a01b038681166101005285811660805284811660a05283811660c052821660e052600f81900b61012052858585858585620000846000808062000101602090811b6200011917901c565b6101408181525050620000a660016000806200010160201b620001191760201c565b6101608181525050620000c860026000806200010160201b620001191760201c565b6101808181525050620000ea60036000806200010160201b620001191760201c565b6101a05250620002319a5050505050505050505050565b600081600f0b6080846001600160401b0316901b60f88660078111156200012c576200012c620001f4565b6200013992911b6200020a565b6200014591906200020a565b949350505050565b80516001600160a01b03811681146200016557600080fd5b919050565b60008060008060008060c087890312156200018457600080fd5b6200018f876200014d565b95506200019f602088016200014d565b9450620001af604088016200014d565b9350620001bf606088016200014d565b9250620001cf608088016200014d565b915060a087015180600f0b8114620001e657600080fd5b809150509295509295509295565b634e487b7160e01b600052602160045260246000fd5b600082198211156200022c57634e487b7160e01b600052601160045260246000fd5b500190565b60805160a05160c05160e05161010051610120516101405161016051610180516101a051612d6f6200030260003960008181610e1c015261137b015260008181610e420152818161135101526113f4015260008181611327015281816114b801526122c90152600081816112fe015281816113cb0152818161148f015281816114e101526122ef0152600081816103a8015281816107ed0152610cda0152600050506000818161176601526117b201526000610485015260008181611964015261212c015260005050612d6f6000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063477130981461003b578063b50e7ee314610050575b600080fd5b61004e610049366004612986565b610063565b005b61004e61005e3660046129c7565b610109565b336001600160a01b038416146100f9576001600160a01b03831660009081527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c6020908152604080832033845290915290205460ff166100f95760405162461bcd60e51b815260206004820152600c60248201526b1b9bdd08185c1c1c9bdd995960a21b60448201526064015b60405180910390fd5b61010483838361015f565b505050565b6101156000838361015f565b5050565b600081600f0b60808467ffffffffffffffff16901b60f8866007811115610142576101426129e9565b61014d92911b612a15565b6101579190612a15565b949350505050565b608082901c8260006001600160a01b0386161560f883901c600481600781111561018b5761018b6129e9565b14806101a8575060068160078111156101a6576101a66129e9565b145b6101e35760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964207479706560a01b60448201526064016100f0565b8115806101f95750428567ffffffffffffffff16105b6102335760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08195e1c1a5c995960aa1b60448201526064016100f0565b6004816007811115610247576102476129e9565b149250506000610262600080516020612d1a83398151915290565b9050600061026f826104c0565b9050428667ffffffffffffffff16101561029a576102978267ffffffffffffffff8816610526565b90505b82806102be5750836102b45784600f0b81600f0b126102be565b84600f0b81600f0b135b6102f45760405162461bcd60e51b81526020600482015260076024820152666e6f742049544d60c81b60448201526064016100f0565b6000841561033a5785600f0b82600f0b1315610335576103328861032984610320600f82900b8b61061e565b600f0b90610659565b600f0b906106b1565b90505b610367565b85600f0b82600f0b12156103675761036461035d89610329600f8a900b8661061e565b8490610719565b90505b6000841561038c5761037b89838c89610754565b6103859082612a15565b9050610454565b6103978b8b8b6108cb565b600082156103ff576103d58c6103d07f0000000000000000000000000000000000000000000000000000000000000000600f0b866106b1565b610a5d565b90506103e18183612a15565b91506103ff8c6103f089610a8c565b6103fa8487612a2d565b610ae1565b604080518c8152602081018c9052908101849052606081018290526001600160a01b038d16907f31939b125e073bbdbf69ac6eb0cb59489894a9bea509d658589af5917b53cca19060800160405180910390a2505b610474898361046e6104678a6000610bb1565b8c8c610119565b89610be4565b61047e9082612a15565b90506104b37f00000000000000000000000000000000000000000000000000000000000000006104ad88610e13565b83610e67565b5050505050505050505050565b60004282600c015414156104de576104d88242610e82565b92915050565b6104e782610eb0565b90506104f38242610e82565b600f0b61050557610505824283610fd3565b42600c830155610516826001611051565b610521826000611051565b919050565b600080610535610e1084612a5a565b600881901c6000818152601287016020526040812054929350909160ff84169190821b821c90610568620e100042612a5a565b90505b811580156105795750808411155b156105a65760128801600061058d86612a7c565b955085815260200190815260200160002054915061056b565b600060805b80156105d25783811c156105ca576105c38183612a15565b93811c9391505b60011c6105ab565b5060118901600060018360086105e88a84612a15565b6105f392911b612a2d565b6105fd9190612a2d565b8152602081019190915260400160002054600f0b9998505050505050505050565b6000600f82810b9084900b0360016001607f1b03198112801590610649575060016001607f1b038113155b61065257600080fd5b9392505050565b600081600f0b6000141561066c57600080fd5b600082600f0b604085600f0b901b8161068757610687612a44565b05905060016001607f1b03198112801590610649575060016001607f1b0381131561065257600080fd5b6000816106c0575060006104d8565b600083600f0b12156106d157600080fd5b600f83900b6001600160801b038316810260401c90608084901c026001600160c01b0381111561070057600080fd5b60401b811981111561071157600080fd5b019392505050565b600080610737838560030160149054906101000a900460ff166110e1565b9050610157818560030160159054906101000a900460ff166110f7565b60008281527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eb602052604081205b85156108c25760006107a9600161079884611112565b6107a29190612a2d565b839061111c565b905060006107b78287611128565b9050878111156107c45750865b600080881561084657896107d8848b612a97565b6107e29190612a5a565b9150610815846103d07f0000000000000000000000000000000000000000000000000000000000000000600f0b856106b1565b90506108218187612a15565b955061082d828a612a2d565b98506108468461083c89610a8c565b6103fa8486612a2d565b610850838b612a2d565b99506001600160a01b0384167f31939b125e073bbdbf69ac6eb0cb59489894a9bea509d658589af5917b53cca189856108898587612a2d565b604080519384526020840192909252908201526060810184905260800160405180910390a26108b98489856108cb565b50505050610782565b50949350505050565b6001600160a01b03831661092d5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b60648201526084016100f0565b61095b3384600061093d866111db565b610946866111db565b60405180602001604052806000815250611226565b60008281527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b602090815260408083206001600160a01b038716845291829052909120548211156109fc5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015264616e63657360d81b60648201526084016100f0565b6001600160a01b03841660008181526020838152604080832080548790039055805187815291820186905291929133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a450505050565b600080610a6984611762565b9050612710610a788285612a97565b610a829190612a5a565b6101579084612a2d565b600081610ab157600080516020612d1a833981519152546001600160a01b03166104d8565b50507fbbd6af8edd89d04327b00c29df7f272b9b1ae01bf6d9c54a784f935706df52ec546001600160a01b031690565b80610aeb57505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb90604401602060405180830381600087803b158015610b3557600080fd5b505af1158015610b49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6d9190612ab6565b6101045760405162461bcd60e51b8152602060048201526015602482015274115490cc8c081d1c985b9cd9995c8819985a5b1959605a1b60448201526064016100f0565b60008215610bcf5781610bc5576005610bc8565b60045b90506104d8565b81610bdb576007610652565b60069392505050565b60008281527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eb60205260408120835b8615610e09576000610c3a6001610c2985611112565b610c339190612a2d565b849061111c565b90506000610c488288611128565b905088811115610c555750875b600089610c62838b612a97565b610c6c9190612a5a565b9050610c78818a612a2d565b9850610c84828b612a2d565b9950600087610cc35781610cb4610c9f600f88900b866106b1565b600080516020612d1a83398151915290610719565b610cbe9190612a2d565b610ccd565b610ccd8284612a2d565b90506000610d02856103d07f0000000000000000000000000000000000000000000000000000000000000000600f0b856106b1565b9050610d0e8189612a15565b975082610d2a600080516020612d1a833981519152878c61182c565b15610d5457610d4386610d3d8486612a2d565b8c611869565b610d4d8282612a15565b9050610d7d565b610d7086610d618c610e13565b610d6b8587612a2d565b610e67565b610d7a8382612a15565b90505b610d97600080516020612d1a833981519152878c8461192c565b610da2868c876108cb565b6001600160a01b0386167f69a2ef6bf9e7ff92cbf1b71963ba1751b1abe8f99e3b3aae2ab99e416df614938c610dd88587612a2d565b60408051928352602083019190915281018890526060810185905260800160405180910390a2505050505050610c13565b5050949350505050565b600081610e40577f00000000000000000000000000000000000000000000000000000000000000006104d8565b7f000000000000000000000000000000000000000000000000000000000000000092915050565b61010483838360405180602001604052806000815250611a6c565b60006011830181610e95610e1085612a5a565b8152602081019190915260400160002054600f0b9392505050565b6000808260030160009054906101000a90046001600160a01b03166001600160a01b03166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f0357600080fd5b505afa158015610f17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3b9190612ad8565b905060008360020160009054906101000a90046001600160a01b03166001600160a01b03166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8f57600080fd5b505afa158015610fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc79190612ad8565b90506101578282611b93565b6000610fe1610e1084612a5a565b6000818152601186016020526040902080546001600160801b0319166001600160801b038516179055905061101a60ff80831690612a2d565b6001901b846012016000600884901c815260200190815260200160002060008282546110469190612a15565b909155505050505050565b80151560009081526013830160205260409020805415806110725750805442105b1561107c57505050565b60006110888484611c2e565b90506110c384826110bd6110b286600101546110ad898b611c9890919063ffffffff16565b6110e1565b600f86900b90611cc6565b86611cf9565b50501515600090815260139091016020526040812081815560010155565b6000610652836110f284600a612bd5565b611d76565b600061065261110783600a612bd5565b600f85900b906106b1565b60006104d8825490565b60006106528383611dad565b60006001600160a01b0383166111945760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b60648201526084016100f0565b7f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b6000928352602090815260408084206001600160a01b0395909516845293905250205490565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061121557611215612be4565b602090810291909101015292915050565b611234868686868686611e33565b600080516020612d1a83398151915260005b845181101561175857600085828151811061126357611263612be4565b60200260200101519050600085838151811061128157611281612be4565b60200260200101519050806000141561129b575050611746565b6001600160a01b0389166112b8576112b66015850183612011565b505b6001600160a01b0388161580156112e857506000828152600080516020612cfa8339815191526020526040902054155b156112fc576112fa601585018361201d565b505b7f000000000000000000000000000000000000000000000000000000000000000082148061134957507f000000000000000000000000000000000000000000000000000000000000000082145b8061137357507f000000000000000000000000000000000000000000000000000000000000000082145b8061139d57507f000000000000000000000000000000000000000000000000000000000000000082145b1561148d576001600160a01b038916158015906113c257506001600160a01b03881615155b1561148d5760007f000000000000000000000000000000000000000000000000000000000000000083148061141657507f000000000000000000000000000000000000000000000000000000000000000083145b6001600160a01b038b166000908152600d870160209081526040808320841515845290915290205490915042906114509062015180612a15565b1061148b5760405162461bcd60e51b815260206004820152600b60248201526a1b1a5c481b1bd8dac80c5960aa1b60448201526064016100f0565b505b7f00000000000000000000000000000000000000000000000000000000000000008214806114da57507f000000000000000000000000000000000000000000000000000000000000000082145b15611682577f00000000000000000000000000000000000000000000000000000000000000008214600061150e8683612029565b90506001600160a01b038b161561163857600061152b8c86611128565b9050818111801561154557506115418285612a15565b8111155b156115dd576001600160a01b038c166000908152601488016020908152604080832086151580855260138c01845282852054855290835281842090845290915290205484906115949083612a2d565b10156115d25760405162461bcd60e51b815260206004820152600d60248201526c496e7375662062616c616e636560981b60448201526064016100f0565b6115dd878d85612043565b6001600160a01b038b161561163657611611878d858c8a8151811061160457611604612be4565b602002602001015161192c565b611636878c858c8a8151811061162957611629612be4565b60200260200101516120f4565b505b6001600160a01b038a161561167f5760006116538b86611128565b905081811115801561166d57508161166b8583612a15565b115b1561167d5761167d878c85612218565b505b50505b60f882901c826001600160a01b038b16158015906116a857506001600160a01b038a1615155b80156116e0575060058260078111156116c3576116c36129e9565b14806116e0575060078260078111156116de576116de6129e9565b145b1561174157600060058360078111156116fb576116fb6129e9565b1490506000816117225761171d611716600f85900b876106b1565b8990610719565b611724565b845b9050611732888e848461192c565b61173e888d84846120f4565b50505b505050505b8061175081612a7c565b915050611246565b5050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615610521576040516303793c8d60e11b81526001600160a01b0383811660048301527f000000000000000000000000000000000000000000000000000000000000000016906306f2791a9060240160206040518083038186803b1580156117f457600080fd5b505afa158015611808573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d89190612ad8565b6001600160a01b0382166000908152600e840160209081526040808320841515845290915281205480158061186057504281115b95945050505050565b600080516020612d1a83398151915261188b84611885846122c0565b85610e67565b60006101048061189b8142612a5a565b6118a59190612a97565b6118af9190612a15565b6001600160a01b03861660009081526014840160209081526040808320848452825280832087151584529091528120805492935086929091906118f3908490612a15565b90915550508215156000908152601383016020526040812060018101805491928792611920908490612a15565b90915550505550505050565b6001600160a01b03808416600090815260178601602090815260408083208615158452825280832054601889019092529091205490917f00000000000000000000000000000000000000000000000000000000000000001663edaf7d5b863087866119978982612a2d565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015290151560448401526064830152608482015260a4810184905260c401600060405180830381600087803b1580156119fa57600080fd5b505af1158015611a0e573d6000803e3d6000fd5b505050508282611a1e9190612a2d565b6001600160a01b038616600090815260178801602090815260408083208815158452909152902055611a508382612a2d565b9315156000908152601890960160205250506040909320555050565b6001600160a01b038416611acc5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b60648201526084016100f0565b611aeb33600086611adc876111db565b611ae5876111db565b86611226565b60008381527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b602090815260408083206001600160a01b0388168452918290528220805491928592611b3e908490612a15565b909155505060408051858152602081018590526001600160a01b0387169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a45050505050565b600081611b9f57600080fd5b600080841215611bb457836000039350600190505b6000831215611bc65760009290920391155b6000611bd28585612314565b90508115611c00576001607f1b816001600160801b03161115611bf457600080fd5b60000391506104d89050565b60016001607f1b03816001600160801b03161115611c1d57600080fd5b91506104d89050565b505092915050565b600080611c4b83611c40576001611c43565b60005b600080610119565b831515600090815260138601602052604090206001015490915061015790600080516020612cfa83398151915260008481526020919091526040902054611c929190612a2d565b6110ad86865b600081611cb3576003830154600160a81b900460ff16610652565b505060030154600160a01b900460ff1690565b6000600f83810b9083900b0160016001607f1b03198112801590610649575060016001607f1b0381131561065257600080fd5b6000611d058583612476565b90506000611d16868387878761248f565b9050611d23868285612595565b60408051600f83810b825287810b602083015286900b818301529051841515917f4e23621c6f591f14bf9505cb8326b45af9dc6c5569fd608de2a7a2ddd6146b2e919081900360600190a2505050505050565b600081611d8257600080fd5b6000611d8e8484612314565b905060016001607f1b036001600160801b038216111561065257600080fd5b81546000908210611e0b5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b60648201526084016100f0565b826000018281548110611e2057611e20612be4565b9060005260206000200154905092915050565b836001600160a01b0316856001600160a01b031614612009576001600160a01b0385811660009081527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424ec602052604080822092871682528120600080516020612cfa833981519152927fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eb929091905b87518110156104b3576000878281518110611edf57611edf612be4565b602002602001015190506000811115611ff6576000898381518110611f0657611f06612be4565b6020026020010151905060006001600160a01b03168c6001600160a01b03161415611f545760008181526020889052604081208054849290611f49908490612a15565b90915550611f8a9050565b81611f5f8d83611128565b1415611f8a576000818152602087905260409020611f7d908d6125ec565b50611f88858261201d565b505b6001600160a01b038b16611fc15760008181526020889052604081208054849290611fb6908490612a2d565b90915550611ff49050565b611fcb8b82611128565b611ff4576000818152602087905260409020611fe7908c612601565b50611ff28482612011565b505b505b508061200181612a7c565b915050611ec2565b505050505050565b60006106528383612612565b60006106528383612661565b60008161203a578260040154610652565b50506005015490565b6001600160a01b03821661205657600080fd5b8015156000908152600f8401602090815260408083206010870190925290912061208184838361274c565b61208c575050505050565b6001600160a01b0393841660008181526020838152604080832080549683528184208054978a16808652838620805499909b166001600160a01b0319998a168117909b5599855295909252822080548616909717909655528054821690558254169091555050565b6001600160a01b03808416600090815260178601602090815260408083208615158452825280832054601889019092529091205490917f00000000000000000000000000000000000000000000000000000000000000001663edaf7d5b8630878661215f8982612a15565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015290151560448401526064830152608482015260a4810184905260c401600060405180830381600087803b1580156121c257600080fd5b505af11580156121d6573d6000803e3d6000fd5b5050505082826121e69190612a15565b6001600160a01b038616600090815260178801602090815260408083208815158452909152902055611a508382612a15565b6001600160a01b03821661222b57600080fd5b8015156000908152600f8401602090815260408083206010870190925290912061225684838361274c565b15612262575050505050565b60008080526020828152604080832080546001600160a01b0390811680865296845282852080546001600160a01b03199081169a909216998a1790558885529490925282208054841690941790935580528154169092179091555050565b6000816122ed577f00000000000000000000000000000000000000000000000000000000000000006104d8565b7f000000000000000000000000000000000000000000000000000000000000000092915050565b60008161232057600080fd5b60006001600160c01b03841161234b5782604085901b8161234357612343612a44565b049050612462565b60c084811c6401000000008110612364576020918201911c5b620100008110612376576010918201911c5b6101008110612387576008918201911c5b60108110612397576004918201911c5b600481106123a7576002918201911c5b600281106123b6576001820191505b60bf820360018603901c6001018260ff0387901b816123d7576123d7612a44565b0492506001600160801b038311156123ee57600080fd5b608085901c83026001600160801b038616840260c088901c604089901b8281101561241a576001820391505b608084901b92900382811015612431576001820391505b829003608084901c821461244757612447612bfa565b88818161245657612456612a44565b04870196505050505050505b6001600160801b0381111561065257600080fd5b60006124828383612798565b90506106528382846127bf565b600080826124a4576019870154600f0b6124b4565b6019870154600160801b9004600f0b5b905080600f0b600014156124cc57506008860154600f0b5b60405163e101a89b60e01b8152600f87810b600483015286810b602483015285810b604483015282900b6064820152730f6e8ef18fb5bb61d545fee60f779d8aed60408f9063e101a89b9060840160206040518083038186803b15801561253257600080fd5b505af4158015612546573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256a9190612c10565b915067b33333333333333382600f0b121561258b5767b33333333333333391505b5095945050505050565b80156125c5576009830180546001600160801b0384166001600160801b031990911617905542600b840155505050565b6008830180546001600160801b03808516600160801b02911617905542600a840155505050565b6000610652836001600160a01b038416612661565b6000610652836001600160a01b0384165b6000818152600183016020526040812054612659575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104d8565b5060006104d8565b60008181526001830160205260408120548015612742576000612685600183612a2d565b8554909150600090869061269b90600190612a2d565b815481106126ab576126ab612be4565b90600052602060002001549050808660000183815481106126ce576126ce612be4565b6000918252602090912001556126e5826001612a15565b6000828152600188016020526040902055855486908061270757612707612c33565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104d8565b60009150506104d8565b6001600160a01b0383811660009081526020849052604081205490911615158061015757506000808052602083905260409020546001600160a01b039081169085161490509392505050565b6000816127b3576008830154600160801b9004600f0b610652565b505060090154600f0b90565b600080826127d15784600a01546127d7565b84600b01545b6127e19042612a2d565b905061a8c0811115612800576127f961a8c082612a2d565b9050612809565b83915050610652565b600061281782613840611d76565b9050600061282a85611c40576001611c43565b851515600090815260188901602090815260408083205460138c01835281842060010154858552600080516020612cfa83398151915290935290832054939450926128889161287891612a2d565b6128829084612a2d565b83611d76565b6040805161012081018252600f87810b82528b810b602083015283900b8183015267b333333333333333606082015267e666666666666666608082018190526801000000000000000060a0830181905260c083015260e082015268056fc2a2c515da32ea6101008201529051634916d70d60e01b8152919250730f6e8ef18fb5bb61d545fee60f779d8aed60408f91634916d70d9161292991600401612c49565b60206040518083038186803b15801561294157600080fd5b505af4158015612955573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129799190612c10565b9998505050505050505050565b60008060006060848603121561299b57600080fd5b83356001600160a01b03811681146129b257600080fd5b95602085013595506040909401359392505050565b600080604083850312156129da57600080fd5b50508035926020909101359150565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115612a2857612a286129ff565b500190565b600082821015612a3f57612a3f6129ff565b500390565b634e487b7160e01b600052601260045260246000fd5b600082612a7757634e487b7160e01b600052601260045260246000fd5b500490565b6000600019821415612a9057612a906129ff565b5060010190565b6000816000190483118215151615612ab157612ab16129ff565b500290565b600060208284031215612ac857600080fd5b8151801515811461065257600080fd5b600060208284031215612aea57600080fd5b5051919050565b600181815b80851115612b2c578160001904821115612b1257612b126129ff565b80851615612b1f57918102915b93841c9390800290612af6565b509250929050565b600082612b43575060016104d8565b81612b50575060006104d8565b8160018114612b665760028114612b7057612b8c565b60019150506104d8565b60ff841115612b8157612b816129ff565b50506001821b6104d8565b5060208310610133831016604e8410600b8410161715612baf575081810a6104d8565b612bb98383612af1565b8060001904821115612bcd57612bcd6129ff565b029392505050565b600061065260ff841683612b34565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052600160045260246000fd5b600060208284031215612c2257600080fd5b815180600f0b811461065257600080fd5b634e487b7160e01b600052603160045260246000fd5b6000610120820190508251600f0b82526020830151600f0b60208301526040830151612c7a6040840182600f0b9052565b506060830151612c8f6060840182600f0b9052565b506080830151612ca46080840182600f0b9052565b5060a0830151612cb960a0840182600f0b9052565b5060c0830151612cce60c0840182600f0b9052565b5060e0830151612ce360e0840182600f0b9052565b5061010080840151611c2682850182600f0b905256feb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eabbd6af8edd89d04327b00c29df7f272b9b1ae01bf6d9c54a784f935706df52eb"), + ("0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05", "MainchainGatewayV2", "608060405234801561001057600080fd5b506000805460ff1916905561582e806200002b6000396000f3fe60806040526004361061032d5760003560e01c80639157921c116101a5578063b2975794116100ec578063d547741f11610095578063dafae4081161006f578063dafae4081461096e578063dff525e11461098e578063e400327c146109ae578063e75235b8146109ce5761033c565b8063d547741f14610901578063d55ed10314610921578063d64af2a61461094e5761033c565b8063cdb67444116100c6578063cdb674441461089c578063cdf64a76146108b4578063d19773d2146108d45761033c565b8063b29757941461082f578063b9c362091461085c578063ca15c8731461087c5761033c565b8063a3912ec81161014e578063affed0e011610128578063affed0e0146107cc578063b1a2567e146107e2578063b1d08a03146108025761033c565b8063a3912ec81461033a578063ab7965661461077f578063ac78dfe8146107ac5761033c565b8063994390891161017f57806399439089146107155780639dcc4da314610735578063a217fddf1461076a5761033c565b80639157921c1461068f57806391d14854146106af57806393c5678f146106f55761033c565b806336568abe116102745780635c975abb1161021d5780637de5dedd116101f75780637de5dedd146106115780638456cb59146106265780638f34e3471461063b5780639010d07c1461066f5761033c565b80635c975abb146105ac5780636932be98146105c45780636c1ce670146105f15761033c565b80634d0d66731161024e5780634d0d66731461052f5780634d493f4e1461054f57806359122f6b1461057f5761033c565b806336568abe146104e75780633f4ba83a146105075780634b14557e1461051c5761033c565b80631d4a7210116102d65780632f2ff15d116102b05780632f2ff15d1461049b578063302d12db146104bb5780633644e515146104d25761033c565b80631d4a721014610428578063248a9ca3146104555780632dfdf0b5146104855761033c565b8063180ff1e911610307578063180ff1e9146103d55780631a8e55b0146103e85780631b6e7594146104085761033c565b806301ffc9a71461034457806317ce2dd41461037957806317fcb39b1461039d5761033c565b3661033c5761033a6109e6565b005b61033a6109e6565b34801561035057600080fd5b5061036461035f366004614843565b610a69565b60405190151581526020015b60405180910390f35b34801561038557600080fd5b5061038f60755481565b604051908152602001610370565b3480156103a957600080fd5b506074546103bd906001600160a01b031681565b6040516001600160a01b039091168152602001610370565b61033a6103e33660046148f4565b610aad565b3480156103f457600080fd5b5061033a6104033660046149e6565b610dbd565b34801561041457600080fd5b5061033a610423366004614a52565b610e8f565b34801561043457600080fd5b5061038f610443366004614aec565b603e6020526000908152604090205481565b34801561046157600080fd5b5061038f610470366004614b09565b60009081526072602052604090206001015490565b34801561049157600080fd5b5061038f60765481565b3480156104a757600080fd5b5061033a6104b6366004614b22565b610f64565b3480156104c757600080fd5b5061038f620f424081565b3480156104de57600080fd5b5060775461038f565b3480156104f357600080fd5b5061033a610502366004614b22565b610f8f565b34801561051357600080fd5b5061033a61101b565b61033a61052a366004614b52565b611083565b34801561053b57600080fd5b5061036461054a366004614b7d565b6110e1565b34801561055b57600080fd5b5061036461056a366004614b09565b607a6020526000908152604090205460ff1681565b34801561058b57600080fd5b5061038f61059a366004614aec565b603a6020526000908152604090205481565b3480156105b857600080fd5b5060005460ff16610364565b3480156105d057600080fd5b5061038f6105df366004614b09565b60796020526000908152604090205481565b3480156105fd57600080fd5b5061036461060c366004614c06565b61118c565b34801561061d57600080fd5b5061038f61119f565b34801561063257600080fd5b5061033a611234565b34801561064757600080fd5b5061038f7f5e5712e902fff5e704bc4d506ad976718319e019e9d2a872528a01a85db433e481565b34801561067b57600080fd5b506103bd61068a366004614c32565b61129c565b34801561069b57600080fd5b5061033a6106aa366004614c54565b6112b4565b3480156106bb57600080fd5b506103646106ca366004614b22565b60009182526072602090815260408084206001600160a01b0393909316845291905290205460ff1690565b34801561070157600080fd5b5061033a6107103660046149e6565b6115ca565b34801561072157600080fd5b506003546103bd906001600160a01b031681565b34801561074157600080fd5b50610755610750366004614c32565b611696565b60408051928352602083019190915201610370565b34801561077657600080fd5b5061038f600081565b34801561078b57600080fd5b5061038f61079a366004614aec565b603c6020526000908152604090205481565b3480156107b857600080fd5b506103646107c7366004614b09565b61172f565b3480156107d857600080fd5b5061038f60045481565b3480156107ee57600080fd5b5061033a6107fd3660046149e6565b6117ce565b34801561080e57600080fd5b5061038f61081d366004614aec565b60396020526000908152604090205481565b34801561083b57600080fd5b5061084f61084a366004614aec565b61189a565b6040516103709190614ca5565b34801561086857600080fd5b50610755610877366004614c32565b611992565b34801561088857600080fd5b5061038f610897366004614b09565b611a17565b3480156108a857600080fd5b50603754603854610755565b3480156108c057600080fd5b5061033a6108cf366004614aec565b611a2e565b3480156108e057600080fd5b5061038f6108ef366004614aec565b603b6020526000908152604090205481565b34801561090d57600080fd5b5061033a61091c366004614b22565b611a97565b34801561092d57600080fd5b5061038f61093c366004614aec565b603d6020526000908152604090205481565b34801561095a57600080fd5b5061033a610969366004614aec565b611abd565b34801561097a57600080fd5b50610364610989366004614b09565b611b26565b34801561099a57600080fd5b5061033a6109a9366004614cd2565b611bbd565b3480156109ba57600080fd5b5061033a6109c93660046149e6565b611cc7565b3480156109da57600080fd5b50600154600254610755565b60005460ff1615610a315760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064015b60405180910390fd5b6074546001600160a01b03163314610a6757610a4b614802565b338152604080820151349101528051610a65908290611d93565b505b565b60006001600160e01b031982167f5a05180f000000000000000000000000000000000000000000000000000000001480610aa75750610aa78261210a565b92915050565b607154610100900460ff16610ac85760715460ff1615610acc565b303b155b610b3e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a28565b607154610100900460ff16158015610b60576071805461ffff19166101011790555b610b6b60008d612171565b6075899055610b798b61217b565b610b828a6121dd565b610c29604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f159f52c1e3a2b6a6aad3950adf713516211484e0516dad685ea662a094b7c43b918101919091527fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a560608201524660808201523060a082015260c00160408051601f198184030181529190528051602090910120607755565b610c338887612238565b5050610c3f87876122f8565b5050610c496123d3565b6000610c558680614da6565b90501115610d1657610c7e610c6a8680614da6565b610c776020890189614da6565b8787612467565b610ca4610c8b8680614da6565b8660005b602002810190610c9f9190614da6565b612666565b610cca610cb18680614da6565b8660015b602002810190610cc59190614da6565b612779565b610cf0610cd78680614da6565b8660025b602002810190610ceb9190614da6565b61288c565b610d16610cfd8680614da6565b8660035b602002810190610d119190614da6565b612a30565b60005b610d266040870187614da6565b9050811015610d9c57610d8a7f5e5712e902fff5e704bc4d506ad976718319e019e9d2a872528a01a85db433e4610d606040890189614da6565b84818110610d7057610d70614d90565b9050602002016020810190610d859190614aec565b612b43565b80610d9481614e06565b915050610d19565b508015610daf576071805461ff00191690555b505050505050505050505050565b6000805160206157b9833981519152546001600160a01b03163314610e1d5760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b82610e7d5760405162461bcd60e51b815260206004820152602a60248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c69642061726044820152690e4c2f240d8cadccee8d60b31b6064820152608401610a28565b610e8984848484612779565b50505050565b6000805160206157b9833981519152546001600160a01b03163314610eef5760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b84610f4e5760405162461bcd60e51b815260206004820152602960248201527f4d61696e636861696e4761746577617956323a20717565727920666f7220656d60448201526870747920617272617960b81b6064820152608401610a28565b610f5c868686868686612467565b505050505050565b600082815260726020526040902060010154610f808133612b65565b610f8a8383612b43565b505050565b6001600160a01b038116331461100d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a28565b6110178282612be5565b5050565b6000805160206157b9833981519152546001600160a01b0316331461107b5760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b610a67612c07565b60005460ff16156110c95760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a28565b610a656110db36839003830183614ec0565b33611d93565b6000805460ff16156111285760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a28565b611184848484808060200260200160405190810160405280939291908181526020016000905b8282101561117a5761116b60608302860136819003810190614f13565b8152602001906001019061114e565b5050505050612ca3565b949350505050565b600061119883836133bc565b9392505050565b600061122f600360009054906101000a90046001600160a01b03166001600160a01b031663926323d56040518163ffffffff1660e01b815260040160206040518083038186803b1580156111f257600080fd5b505afa158015611206573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122a9190614f89565b613480565b905090565b6000805160206157b9833981519152546001600160a01b031633146112945760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b610a676134b6565b60008281526073602052604081206111989083613531565b7f5e5712e902fff5e704bc4d506ad976718319e019e9d2a872528a01a85db433e46112df8133612b65565b60006112f86112f336859003850185614ff0565b61353d565b905061130c6112f336859003850185614ff0565b8335600090815260796020526040902054146113765760405162461bcd60e51b815260206004820152602360248201527f4d61696e636861696e4761746577617956323a20696e76616c696420726563656044820152621a5c1d60ea1b6064820152608401610a28565b82356000908152607a602052604090205460ff166113fc5760405162461bcd60e51b815260206004820152603160248201527f4d61696e636861696e4761746577617956323a20717565727920666f7220617060448201527f70726f766564207769746864726177616c0000000000000000000000000000006064820152608401610a28565b82356000908152607a602052604090819020805460ff19169055517fd639511b37b3b002cca6cfe6bca0d833945a5af5a045578a0627fc43b79b26309061144690839086906150c4565b60405180910390a160006114606080850160608601614aec565b9050600061147661012086016101008701615151565b600181111561148757611487614c71565b141561154f5760006114a2368690038601610100870161516e565b6001600160a01b0383166000908152603b60205260409020549091506114ce90610140870135906135c6565b604082015260006114e8368790038701610100880161516e565b60408301519091506114ff9061014088013561518a565b604082015260745461151f908390339086906001600160a01b03166135e0565b6115486115326060880160408901614aec565b60745483919086906001600160a01b03166135e0565b505061158b565b61158b6115626060860160408701614aec565b60745483906001600160a01b03166115833689900389016101008a0161516e565b9291906135e0565b7f21e88e956aa3e086f6388e899965cef814688f99ad8bb29b08d396571016372d82856040516115bc9291906150c4565b60405180910390a150505050565b6000805160206157b9833981519152546001600160a01b0316331461162a5760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b8261168a5760405162461bcd60e51b815260206004820152602a60248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c69642061726044820152690e4c2f240d8cadccee8d60b31b6064820152608401610a28565b610e8984848484612666565b6000806116b86000805160206157b9833981519152546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146117115760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b61171b84846122f8565b90925090506117286123d3565b9250929050565b6003546040805163926323d560e01b815290516000926001600160a01b03169163926323d5916004808301926020929190829003018186803b15801561177457600080fd5b505afa158015611788573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ac9190614f89565b6037546117b991906151a1565b6038546117c690846151a1565b101592915050565b6000805160206157b9833981519152546001600160a01b0316331461182e5760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b8261188e5760405162461bcd60e51b815260206004820152602a60248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c69642061726044820152690e4c2f240d8cadccee8d60b31b6064820152608401610a28565b610e898484848461288c565b60408051808201909152600080825260208201526001600160a01b0382166000908152607860205260409081902081518083019092528054829060ff1660018111156118e8576118e8614c71565b60018111156118f9576118f9614c71565b815290546001600160a01b036101009091048116602092830152908201519192501661198d5760405162461bcd60e51b815260206004820152602560248201527f4d61696e636861696e4761746577617956323a20756e737570706f727465642060448201527f746f6b656e0000000000000000000000000000000000000000000000000000006064820152608401610a28565b919050565b6000806119b46000805160206157b9833981519152546001600160a01b031690565b6001600160a01b0316336001600160a01b031614611a0d5760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b61171b8484612238565b6000818152607360205260408120610aa790613a13565b6000805160206157b9833981519152546001600160a01b03163314611a8e5760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b610a65816121dd565b600082815260726020526040902060010154611ab38133612b65565b610f8a8383612be5565b6000805160206157b9833981519152546001600160a01b03163314611b1d5760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b610a658161217b565b6003546040805163926323d560e01b815290516000926001600160a01b03169163926323d5916004808301926020929190829003018186803b158015611b6b57600080fd5b505afa158015611b7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba39190614f89565b600154611bb091906151a1565b6002546117c690846151a1565b6000805160206157b9833981519152546001600160a01b03163314611c1d5760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b85611c7c5760405162461bcd60e51b815260206004820152602960248201527f4d61696e636861696e4761746577617956323a20717565727920666f7220656d60448201526870747920617272617960b81b6064820152608401610a28565b611c8a878787878787612467565b611c978787836000610c8f565b611ca48787836001610cb5565b611cb18787836002610cdb565b611cbe8787836003610d01565b50505050505050565b6000805160206157b9833981519152546001600160a01b03163314611d275760405162461bcd60e51b815260206004820152602260248201526000805160206157d983398151915260448201526132b960f11b6064820152608401610a28565b82611d875760405162461bcd60e51b815260206004820152602a60248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c69642061726044820152690e4c2f240d8cadccee8d60b31b6064820152608401610a28565b610e8984848484612a30565b604080518082018252600080825260208201526074549184015190916001600160a01b031690611dc290613a1d565b60208401516001600160a01b0316611ee1573484604001516040015114611e375760405162461bcd60e51b815260206004820152602360248201527f4d61696e636861696e4761746577617956323a20696e76616c69642072657175604482015262195cdd60ea1b6064820152608401610a28565b611e408161189a565b6040850151519092506001811115611e5a57611e5a614c71565b82516001811115611e6d57611e6d614c71565b14611ecd5760405162461bcd60e51b815260206004820152602a60248201527f4d61696e636861696e4761746577617956323a20696e76616c696420746f6b656044820152691b881cdd185b99185c9960b21b6064820152608401610a28565b6001600160a01b0381166020850152612087565b3415611f3b5760405162461bcd60e51b815260206004820152602360248201527f4d61696e636861696e4761746577617956323a20696e76616c69642072657175604482015262195cdd60ea1b6064820152608401610a28565b611f48846020015161189a565b6040850151519092506001811115611f6257611f62614c71565b82516001811115611f7557611f75614c71565b14611fd55760405162461bcd60e51b815260206004820152602a60248201527f4d61696e636861696e4761746577617956323a20696e76616c696420746f6b656044820152691b881cdd185b99185c9960b21b6064820152608401610a28565b60208401516040850151611fec9185903090613ac7565b83602001516001600160a01b0316816001600160a01b031614156120875760408481015181015190517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815260048101919091526001600160a01b03821690632e1a7d4d90602401600060405180830381600087803b15801561206e57600080fd5b505af1158015612082573d6000803e3d6000fd5b505050505b607680546000918261209883614e06565b91905055905060006120bf858386602001516075548a613ce190949392919063ffffffff16565b90507fd7b25068d9dc8d00765254cfb7f5070f98d263c8d68931d937c7362fa738048b6120eb8261353d565b826040516120fa9291906151c0565b60405180910390a1505050505050565b60006001600160e01b031982167f7965db0b000000000000000000000000000000000000000000000000000000001480610aa757507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b0319831614610aa7565b6110178282612b43565b6074805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527f9d2334c23be647e994f27a72c5eee42a43d5bdcfe15bb88e939103c2b114cbaf906020015b60405180910390a150565b6003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fef40dc07567635f84f5edbd2f8dbc16b40d9d282dd8e7e6f4ff58236b6836169906020016121d2565b6000808284111561228b5760405162461bcd60e51b815260206004820152601c60248201527f4761746577617956323a20696e76616c6964207468726573686f6c64000000006044820152606401610a28565b505060018054600280549285905583905560048054919291849186919060006122b383614e06565b9091555060408051868152602081018690527f976f8a9c5bdf8248dec172376d6e2b80a8e3df2f0328e381c6db8e1cf138c0f891015b60405180910390a49250929050565b600080828411156123715760405162461bcd60e51b815260206004820152602760248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c696420746860448201527f726573686f6c64000000000000000000000000000000000000000000000000006064820152608401610a28565b5050603780546038805492859055839055600480549192918491869190600061239983614e06565b9091555060408051868152602081018690527f31312c97b89cc751b832d98fd459b967a2c3eef3b49757d1cf5ebaa12bb6eee191016122e9565b6002546037546123e391906151a1565b6038546001546123f391906151a1565b1115610a675760405162461bcd60e51b815260206004820152602860248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c696420746860448201527f726573686f6c64730000000000000000000000000000000000000000000000006064820152608401610a28565b848314801561247557508481145b6124e75760405162461bcd60e51b815260206004820152602860248201527f4d61696e636861696e4761746577617956323a20696e76616c6964206172726160448201527f79206c656e6774680000000000000000000000000000000000000000000000006064820152608401610a28565b60005b8581101561262c5784848281811061250457612504614d90565b90506020020160208101906125199190614aec565b6078600089898581811061252f5761252f614d90565b90506020020160208101906125449190614aec565b6001600160a01b039081168252602082019290925260400160002080547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010093909216929092021790558282828181106125a3576125a3614d90565b90506020020160208101906125b89190615151565b607860008989858181106125ce576125ce614d90565b90506020020160208101906125e39190614aec565b6001600160a01b031681526020810191909152604001600020805460ff19166001838181111561261557612615614c71565b02179055508061262481614e06565b9150506124ea565b507fa4f03cc9c0e0aeb5b71b4ec800702753f65748c2cf3064695ba8e8b46be704448686868686866040516120fa969594939291906152c1565b8281146126c85760405162461bcd60e51b815260206004820152602a60248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c69642061726044820152690e4c2f240d8cadccee8d60b31b6064820152608401610a28565b60005b83811015612743578282828181106126e5576126e5614d90565b905060200201356039600087878581811061270257612702614d90565b90506020020160208101906127179190614aec565b6001600160a01b031681526020810191909152604001600020558061273b81614e06565b9150506126cb565b507f80bc635c452ae67f12f9b6f12ad4daa6dbbc04eeb9ebb87d354ce10c0e210dc0848484846040516115bc9493929190615339565b8281146127db5760405162461bcd60e51b815260206004820152602a60248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c69642061726044820152690e4c2f240d8cadccee8d60b31b6064820152608401610a28565b60005b83811015612856578282828181106127f8576127f8614d90565b90506020020135603a600087878581811061281557612815614d90565b905060200201602081019061282a9190614aec565b6001600160a01b031681526020810191909152604001600020558061284e81614e06565b9150506127de565b507f64557254143204d91ba2d95acb9fda1e5fea55f77efd028685765bc1e94dd4b5848484846040516115bc9493929190615339565b8281146128ee5760405162461bcd60e51b815260206004820152602a60248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c69642061726044820152690e4c2f240d8cadccee8d60b31b6064820152608401610a28565b60005b838110156129fa57620f424083838381811061290f5761290f614d90565b90506020020135111561298a5760405162461bcd60e51b815260206004820152602860248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c696420706560448201527f7263656e746167650000000000000000000000000000000000000000000000006064820152608401610a28565b82828281811061299c5761299c614d90565b90506020020135603b60008787858181106129b9576129b9614d90565b90506020020160208101906129ce9190614aec565b6001600160a01b03168152602081019190915260400160002055806129f281614e06565b9150506128f1565b507fb05f5de88ae0294ebb6f67c5af2fcbbd593cc6bdfe543e2869794a4c8ce3ea50848484846040516115bc9493929190615339565b828114612a925760405162461bcd60e51b815260206004820152602a60248201527f5769746864726177616c4c696d69746174696f6e3a20696e76616c69642061726044820152690e4c2f240d8cadccee8d60b31b6064820152608401610a28565b60005b83811015612b0d57828282818110612aaf57612aaf614d90565b90506020020135603c6000878785818110612acc57612acc614d90565b9050602002016020810190612ae19190614aec565b6001600160a01b0316815260208101919091526040016000205580612b0581614e06565b915050612a95565b507fb5d2963614d72181b4df1f993d45b83edf42fa19710f0204217ba1b3e183bb73848484846040516115bc9493929190615339565b612b4d8282613db6565b6000828152607360205260409020610f8a9082613e58565b60008281526072602090815260408083206001600160a01b038516845290915290205460ff1661101757612ba3816001600160a01b03166014613e6d565b612bae836020613e6d565b604051602001612bbf9291906153d0565b60408051601f198184030181529082905262461bcd60e51b8252610a2891600401615451565b612bef828261404e565b6000828152607360205260409020610f8a90826140d1565b60005460ff16612c595760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610a28565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000823561014084013582612cbe6080870160608801614aec565b9050612cdb612cd6368890038801610100890161516e565b613a1d565b6001612ced6040880160208901615151565b6001811115612cfe57612cfe614c71565b14612d715760405162461bcd60e51b815260206004820152602860248201527f4d61696e636861696e4761746577617956323a20696e76616c6964207265636560448201527f697074206b696e640000000000000000000000000000000000000000000000006064820152608401610a28565b60808601354614612de95760405162461bcd60e51b8152602060048201526024808201527f4d61696e636861696e4761746577617956323a20696e76616c6964206368616960448201527f6e206964000000000000000000000000000000000000000000000000000000006064820152608401610a28565b6000612dfe61084a6080890160608a01614aec565b9050612e1261012088016101008901615151565b6001811115612e2357612e23614c71565b81516001811115612e3657612e36614c71565b148015612e675750612e4e60e0880160c08901614aec565b6001600160a01b031681602001516001600160a01b0316145b612ebf5760405162461bcd60e51b815260206004820152602360248201527f4d61696e636861696e4761746577617956323a20696e76616c696420726563656044820152621a5c1d60ea1b6064820152608401610a28565b60008481526079602052604090205415612f415760405162461bcd60e51b815260206004820152603260248201527f4d61696e636861696e4761746577617956323a20717565727920666f7220707260448201527f6f636573736564207769746864726177616c00000000000000000000000000006064820152608401610a28565b6001612f5561012089016101008a01615151565b6001811115612f6657612f66614c71565b1480612f795750612f7782846133bc565b155b612feb5760405162461bcd60e51b815260206004820152603260248201527f4d61696e636861696e4761746577617956323a2072656163686564206461696c60448201527f79207769746864726177616c206c696d697400000000000000000000000000006064820152608401610a28565b6000612fff6112f3368a90038a018a614ff0565b9050600061300f607754836140e6565b6003549091506001600160a01b0316600061303d6130356101208d016101008e01615151565b878985614142565b60408051606081018252600080825260208201819052918101829052919b50919250819081906000805b8f5181101561323c578f818151811061308257613082614d90565b6020908102919091018101518051818301516040808401518151600081529586018083528f905260ff9093169085015260608401526080830152935060019060a0016020604051602081039080840390855afa1580156130e6573d6000803e3d6000fd5b505050602060405103519450846001600160a01b0316846001600160a01b0316106131795760405162461bcd60e51b815260206004820152602160248201527f4d61696e636861696e4761746577617956323a20696e76616c6964206f72646560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610a28565b6040517f953865650000000000000000000000000000000000000000000000000000000081526001600160a01b03808716600483015286955089169063953865659060240160206040518083038186803b1580156131d657600080fd5b505afa1580156131ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320e9190614f89565b6132189083615484565b915086821061322a576001955061323c565b8061323481614e06565b915050613067565b50846132b05760405162461bcd60e51b815260206004820152603660248201527f4d61696e636861696e4761746577617956323a20717565727920666f7220696e60448201527f73756666696369656e7420766f746520776569676874000000000000000000006064820152608401610a28565b50505060008a81526079602052604090208690555050881561332c576000888152607a602052604090819020805460ff19166001179055517f89e52969465b1f1866fc5d46fd62de953962e9cb33552443cd999eba05bd20dc906133179086908e906150c4565b60405180910390a15050505050505050610aa7565b6133368688614233565b61337561334960608d0160408e01614aec565b87607460009054906101000a90046001600160a01b03168e61010001803603810190611583919061516e565b7f21e88e956aa3e086f6388e899965cef814688f99ad8bb29b08d396571016372d848c6040516133a69291906150c4565b60405180910390a1505050505050505092915050565b6001600160a01b0382166000908152603a602052604081205482106133e357506000610aa7565b60006133f2620151804261549c565b6001600160a01b0385166000908152603e60205260409020549091508111156134385750506001600160a01b0382166000908152603c6020526040902054811015610aa7565b6001600160a01b0384166000908152603d602052604090205461345c908490615484565b6001600160a01b0385166000908152603c602052604090205411159150610aa79050565b600060025460016002548460015461349891906151a1565b6134a29190615484565b6134ac919061518a565b610aa7919061549c565b60005460ff16156134fc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a28565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612c863390565b600061119883836142c3565b60007fb9d1fe7c9deeec5dc90a2f47ff1684239519f2545b2228d3d91fb27df3189eea60001b8260000151836020015161357a85604001516142ed565b61358786606001516142ed565b6135948760800151614350565b6040516020016135a9969594939291906154be565b604051602081830303815290604052805190602001209050919050565b6000620f42406135d683856151a1565b611198919061549c565b6000816001600160a01b0316836001600160a01b031614156136905760408086015190516001600160a01b0386169180156108fc02916000818181858888f1935050505061368b57816001600160a01b031663d0e30db086604001516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561366757600080fd5b505af115801561367b573d6000803e3d6000fd5b505050505061368b858585614393565b613a0c565b6000855160018111156136a5576136a5614c71565b1415613866576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038516906370a082319060240160206040518083038186803b15801561370657600080fd5b505afa15801561371a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061373e9190614f89565b9050856040015181101561385557836001600160a01b03166340c10f193083896040015161376c919061518a565b6040516001600160a01b03909216602483015260448201526064016040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516137c091906154f8565b6000604051808303816000865af19150503d80600081146137fd576040519150601f19603f3d011682016040523d82523d6000602084013e613802565b606091505b505080925050816138555760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e3a204552433230206d696e74696e67206661696c656400000000006044820152606401610a28565b613860868686614393565b50613a0c565b60018551600181111561387b5761387b614c71565b141561399e5761389083858760200151614437565b61368b57602085810151604080516001600160a01b038881166024830152604480830194909452825180830390940184526064909101825292820180516001600160e01b03167f40c10f1900000000000000000000000000000000000000000000000000000000179052519185169161390991906154f8565b6000604051808303816000865af19150503d8060008114613946576040519150601f19603f3d011682016040523d82523d6000602084013e61394b565b606091505b5050809150508061368b5760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e3a20455243373231206d696e74696e67206661696c6564000000006044820152606401610a28565b60405162461bcd60e51b815260206004820152602160248201527f546f6b656e3a20756e737570706f7274656420746f6b656e207374616e64617260448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610a28565b5050505050565b6000610aa7825490565b600081516001811115613a3257613a32614c71565b148015613a43575060008160400151115b8015613a5157506020810151155b80613a7b5750600181516001811115613a6c57613a6c614c71565b148015613a7b57506040810151155b610a655760405162461bcd60e51b815260206004820152601360248201527f546f6b656e3a20696e76616c696420696e666f000000000000000000000000006044820152606401610a28565b600060608186516001811115613adf57613adf614c71565b1415613bbd5760408681015181516001600160a01b038881166024830152878116604483015260648083019390935283518083039093018352608490910183526020820180516001600160e01b03166323b872dd60e01b179052915191851691613b4991906154f8565b6000604051808303816000865af19150503d8060008114613b86576040519150601f19603f3d011682016040523d82523d6000602084013e613b8b565b606091505b509092509050818015613bb6575080511580613bb6575080806020019051810190613bb69190615514565b9150613c84565b600186516001811115613bd257613bd2614c71565b141561399e57602086810151604080516001600160a01b0389811660248301528881166044830152606480830194909452825180830390940184526084909101825292820180516001600160e01b03166323b872dd60e01b1790525191851691613c3c91906154f8565b6000604051808303816000865af19150503d8060008114613c79576040519150601f19603f3d011682016040523d82523d6000602084013e613c7e565b606091505b50909250505b81610f5c57613c92866144e2565b613ca6866001600160a01b03166014613e6d565b613cba866001600160a01b03166014613e6d565b613cce866001600160a01b03166014613e6d565b604051602001612bbf9493929190615536565b613d516040805160a08101825260008082526020808301829052835160608082018652838252818301849052818601849052848601919091528451808201865283815280830184905280860184905281850152845190810185528281529081018290529283015290608082015290565b83815260006020820181905250604080820180516001600160a01b039788169052602080890151825190891690820152905146908301528751606084018051918916909152805195909716940193909352935182015292909201516080820152919050565b60008281526072602090815260408083206001600160a01b038516845290915290205460ff166110175760008281526072602090815260408083206001600160a01b03851684529091529020805460ff19166001179055613e143390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000611198836001600160a01b03841661454f565b60606000613e7c8360026151a1565b613e87906002615484565b67ffffffffffffffff811115613e9f57613e9f614e21565b6040519080825280601f01601f191660200182016040528015613ec9576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110613f0057613f00614d90565b60200101906001600160f81b031916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110613f4b57613f4b614d90565b60200101906001600160f81b031916908160001a9053506000613f6f8460026151a1565b613f7a906001615484565b90505b6001811115613fff577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110613fbb57613fbb614d90565b1a60f81b828281518110613fd157613fd1614d90565b60200101906001600160f81b031916908160001a90535060049490941c93613ff881615606565b9050613f7d565b5083156111985760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a28565b60008281526072602090815260408083206001600160a01b038516845290915290205460ff16156110175760008281526072602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000611198836001600160a01b03841661459e565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091526022820185905260428083018590528351808403909101815260629092019092528051910120600090611198565b6000806000836001600160a01b031663926323d56040518163ffffffff1660e01b815260040160206040518083038186803b15801561418057600080fd5b505afa158015614194573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141b89190614f89565b90506141c381613480565b925060008760018111156141d9576141d9614c71565b1415614229576001600160a01b038616600090815260396020526040902054851061420a5761420781614691565b92505b6001600160a01b0386166000908152603a602052604090205485101591505b5094509492505050565b6000614242620151804261549c565b6001600160a01b0384166000908152603e6020526040902054909150811115614291576001600160a01b03929092166000908152603e6020908152604080832094909455603d90529190912055565b6001600160a01b0383166000908152603d6020526040812080548492906142b9908490615484565b9091555050505050565b60008260000182815481106142da576142da614d90565b9060005260206000200154905092915050565b805160208083015160408085015190516000946135a9947f353bdd8d69b9e3185b3972e08b03845c0c14a21a390215302776a7a34b0e87649491939192019384526001600160a01b03928316602085015291166040830152606082015260800190565b805160208083015160408085015190516000946135a9947f1e2b74b2a792d5c0f0b6e59b037fa9d43d84fbb759337f0112fcc15ca414fc8d94919391920161561d565b600080845160018111156143a9576143a9614c71565b14156143c5576143be828486604001516146a9565b90506143ef565b6001845160018111156143da576143da614c71565b141561399e576143be82848660200151614437565b80610e89576143fd846144e2565b614411846001600160a01b03166014613e6d565b614425846001600160a01b03166014613e6d565b604051602001612bbf93929190615648565b604080513060248201526001600160a01b038481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092861691614495916154f8565b6000604051808303816000865af19150503d80600081146144d2576040519150601f19603f3d011682016040523d82523d6000602084013e6144d7565b606091505b509095945050505050565b606061450d826000015160018111156144fd576144fd614c71565b6001600160a01b03166001613e6d565b61451a8360200151614795565b6145278460400151614795565b604051602001614539939291906156d9565b6040516020818303038152906040529050919050565b600081815260018301602052604081205461459657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610aa7565b506000610aa7565b600081815260018301602052604081205480156146875760006145c260018361518a565b85549091506000906145d69060019061518a565b905081811461463b5760008660000182815481106145f6576145f6614d90565b906000526020600020015490508087600001848154811061461957614619614d90565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061464c5761464c6157a2565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610aa7565b6000915050610aa7565b600060385460016038548460375461349891906151a1565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000926060929087169161471f91906154f8565b6000604051808303816000865af19150503d806000811461475c576040519150601f19603f3d011682016040523d82523d6000602084013e614761565b606091505b50909250905081801561478c57508051158061478c57508080602001905181019061478c9190615514565b95945050505050565b6060816147d557505060408051808201909152600481527f3078303000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156147f857806147e981614e06565b915050600882901c91506147d9565b6111848482613e6d565b604080516060810182526000808252602082015290810161483e6040805160608101909152806000815260200160008152602001600081525090565b905290565b60006020828403121561485557600080fd5b81356001600160e01b03198116811461119857600080fd5b6001600160a01b0381168114610a6557600080fd5b803561198d8161486d565b8060608101831015610aa757600080fd5b8060808101831015610aa757600080fd5b60008083601f8401126148c157600080fd5b50813567ffffffffffffffff8111156148d957600080fd5b6020830191508360208260051b850101111561172857600080fd5b60008060008060008060008060008060006101408c8e03121561491657600080fd5b61491f8c614882565b9a5061492d60208d01614882565b995061493b60408d01614882565b985060608c0135975060808c0135965060a08c0135955060c08c0135945067ffffffffffffffff8060e08e0135111561497357600080fd5b6149838e60e08f01358f0161488d565b9450806101008e0135111561499757600080fd5b6149a88e6101008f01358f0161489e565b9350806101208e013511156149bc57600080fd5b506149ce8d6101208e01358e016148af565b81935080925050509295989b509295989b9093969950565b600080600080604085870312156149fc57600080fd5b843567ffffffffffffffff80821115614a1457600080fd5b614a20888389016148af565b90965094506020870135915080821115614a3957600080fd5b50614a46878288016148af565b95989497509550505050565b60008060008060008060608789031215614a6b57600080fd5b863567ffffffffffffffff80821115614a8357600080fd5b614a8f8a838b016148af565b90985096506020890135915080821115614aa857600080fd5b614ab48a838b016148af565b90965094506040890135915080821115614acd57600080fd5b50614ada89828a016148af565b979a9699509497509295939492505050565b600060208284031215614afe57600080fd5b81356111988161486d565b600060208284031215614b1b57600080fd5b5035919050565b60008060408385031215614b3557600080fd5b823591506020830135614b478161486d565b809150509250929050565b600060a08284031215614b6457600080fd5b50919050565b60006101608284031215614b6457600080fd5b60008060006101808486031215614b9357600080fd5b614b9d8585614b6a565b925061016084013567ffffffffffffffff80821115614bbb57600080fd5b818601915086601f830112614bcf57600080fd5b813581811115614bde57600080fd5b876020606083028501011115614bf357600080fd5b6020830194508093505050509250925092565b60008060408385031215614c1957600080fd5b8235614c248161486d565b946020939093013593505050565b60008060408385031215614c4557600080fd5b50508035926020909101359150565b60006101608284031215614c6757600080fd5b6111988383614b6a565b634e487b7160e01b600052602160045260246000fd5b60028110610a6557634e487b7160e01b600052602160045260246000fd5b81516040820190614cb581614c87565b808352506001600160a01b03602084015116602083015292915050565b60008060008060008060006080888a031215614ced57600080fd5b873567ffffffffffffffff80821115614d0557600080fd5b614d118b838c016148af565b909950975060208a0135915080821115614d2a57600080fd5b614d368b838c016148af565b909750955060408a0135915080821115614d4f57600080fd5b614d5b8b838c016148af565b909550935060608a0135915080821115614d7457600080fd5b50614d818a828b0161489e565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112614dbd57600080fd5b83018035915067ffffffffffffffff821115614dd857600080fd5b6020019150600581901b360382131561172857600080fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415614e1a57614e1a614df0565b5060010190565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715614e6857634e487b7160e01b600052604160045260246000fd5b60405290565b60028110610a6557600080fd5b600060608284031215614e8d57600080fd5b614e95614e37565b90508135614ea281614e6e565b80825250602082013560208201526040820135604082015292915050565b600060a08284031215614ed257600080fd5b614eda614e37565b8235614ee58161486d565b81526020830135614ef58161486d565b6020820152614f078460408501614e7b565b60408201529392505050565b600060608284031215614f2557600080fd5b6040516060810181811067ffffffffffffffff82111715614f5657634e487b7160e01b600052604160045260246000fd5b604052823560ff81168114614f6a57600080fd5b8152602083810135908201526040928301359281019290925250919050565b600060208284031215614f9b57600080fd5b5051919050565b600060608284031215614fb457600080fd5b614fbc614e37565b90508135614fc98161486d565b81526020820135614fd98161486d565b806020830152506040820135604082015292915050565b6000610160828403121561500357600080fd5b60405160a0810181811067ffffffffffffffff8211171561503457634e487b7160e01b600052604160045260246000fd5b60405282358152602083013561504981614e6e565b602082015261505b8460408501614fa2565b604082015261506d8460a08501614fa2565b6060820152615080846101008501614e7b565b60808201529392505050565b80356150978161486d565b6001600160a01b0390811683526020820135906150b38261486d565b166020830152604090810135910152565b6000610180820190508382528235602083015260208301356150e581614e6e565b6150ee81614c87565b80604084015250615105606083016040850161508c565b61511560c0830160a0850161508c565b61012061010084013561512781614e6e565b61513081614c87565b81840152830135610140808401919091529092013561016090910152919050565b60006020828403121561516357600080fd5b813561119881614e6e565b60006060828403121561518057600080fd5b6111988383614e7b565b60008282101561519c5761519c614df0565b500390565b60008160001904831182151516156151bb576151bb614df0565b500290565b6000610180820190508382528251602083015260208301516151e181614c87565b6040838101919091528381015180516001600160a01b03908116606086015260208201511660808501529081015160a084015250606083015180516001600160a01b0390811660c085015260208201511660e08401526040810151610100840152506080830151805161525381614c87565b6101208401526020810151610140840152604001516101609092019190915292915050565b8183526000602080850194508260005b858110156152b657813561529b8161486d565b6001600160a01b031687529582019590820190600101615288565b509495945050505050565b6060815260006152d560608301888a615278565b6020838203818501526152e982888a615278565b8481036040860152858152869250810160005b8681101561532a57833561530f81614e6e565b61531881614c87565b825292820192908201906001016152fc565b509a9950505050505050505050565b60408152600061534d604083018688615278565b82810360208401528381527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84111561538557600080fd5b8360051b80866020840137600091016020019081529695505050505050565b60005b838110156153bf5781810151838201526020016153a7565b83811115610e895750506000910152565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516154088160178501602088016153a4565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516154458160288401602088016153a4565b01602801949350505050565b60208152600082518060208401526154708160408501602087016153a4565b601f01601f19169190910160400192915050565b6000821982111561549757615497614df0565b500190565b6000826154b957634e487b7160e01b600052601260045260246000fd5b500490565b8681526020810186905260c081016154d586614c87565b8560408301528460608301528360808301528260a0830152979650505050505050565b6000825161550a8184602087016153a4565b9190910192915050565b60006020828403121561552657600080fd5b8151801515811461119857600080fd5b7f546f6b656e3a20636f756c64206e6f74207472616e7366657220000000000000815260008551602061556f82601a8601838b016153a4565b7f2066726f6d200000000000000000000000000000000000000000000000000000601a9285019283015286516155aa81838501848b016153a4565b630103a37960e51b92018181019290925285516155cd81602485018985016153a4565b660103a37b5b2b7160cd1b6024939091019283015284516155f481602b85018489016153a4565b91909101602b01979650505050505050565b60008161561557615615614df0565b506000190190565b8481526080810161562d85614c87565b84602083015283604083015282606083015295945050505050565b7f546f6b656e3a20636f756c64206e6f74207472616e736665722000000000000081526000845161568081601a8501602089016153a4565b630103a37960e51b601a9184019182015284516156a481601e8401602089016153a4565b660103a37b5b2b7160cd1b601e929091019182015283516156cc8160258401602088016153a4565b0160250195945050505050565b7f546f6b656e496e666f280000000000000000000000000000000000000000000081526000845161571181600a8501602089016153a4565b80830190507f2c0000000000000000000000000000000000000000000000000000000000000080600a830152855161575081600b850160208a016153a4565b600b920191820152835161576b81600c8401602088016153a4565b7f2900000000000000000000000000000000000000000000000000000000000000600c9290910191820152600d0195945050505050565b634e487b7160e01b600052603160045260246000fdfeb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610348617350726f787941646d696e3a20756e617574686f72697a65642073656e64") + ]; +} diff --git a/crates/forge/bin/cmd/config.rs b/crates/forge/bin/cmd/config.rs index fc325e39d99c..27d16c5fc467 100644 --- a/crates/forge/bin/cmd/config.rs +++ b/crates/forge/bin/cmd/config.rs @@ -36,7 +36,7 @@ impl ConfigArgs { for warning in fix_tomls() { cli_warn!("{warning}"); } - return Ok(()) + return Ok(()); } let config = self diff --git a/crates/forge/bin/cmd/coverage.rs b/crates/forge/bin/cmd/coverage.rs index e140b8436aaf..d1a74260271e 100644 --- a/crates/forge/bin/cmd/coverage.rs +++ b/crates/forge/bin/cmd/coverage.rs @@ -79,8 +79,8 @@ impl CoverageArgs { let (mut config, evm_opts) = self.load_config_and_evm_opts_emit_warnings()?; // install missing dependencies - if install::install_missing_dependencies(&mut config, self.build_args().silent) && - config.auto_detect_remappings + if install::install_missing_dependencies(&mut config, self.build_args().silent) + && config.auto_detect_remappings { // need to re-configure here to also catch additional remappings config = self.load_config(); @@ -163,7 +163,7 @@ impl CoverageArgs { // Filter out dependencies if project_paths.has_library_ancestor(std::path::Path::new(&path)) { - continue + continue; } if let Some(ast) = source_file.ast.take() { @@ -360,10 +360,10 @@ impl CoverageArgs { CoverageReportKind::Lcov => { if let Some(report_file) = self.report_file { return LcovReporter::new(&mut fs::create_file(root.join(report_file))?) - .report(&report) + .report(&report); } else { return LcovReporter::new(&mut fs::create_file(root.join("lcov.info"))?) - .report(&report) + .report(&report); } } CoverageReportKind::Bytecode => { diff --git a/crates/forge/bin/cmd/create.rs b/crates/forge/bin/cmd/create.rs index 9dee30675d5f..7f52e835d131 100644 --- a/crates/forge/bin/cmd/create.rs +++ b/crates/forge/bin/cmd/create.rs @@ -231,8 +231,8 @@ impl CreateArgs { e } })?; - let is_legacy = self.tx.legacy || - Chain::try_from(chain).map(|x| Chain::is_legacy(&x)).unwrap_or_default(); + let is_legacy = self.tx.legacy + || Chain::try_from(chain).map(|x| Chain::is_legacy(&x)).unwrap_or_default(); let mut deployer = if is_legacy { deployer.legacy() } else { deployer }; // set tx value if specified diff --git a/crates/forge/bin/cmd/fmt.rs b/crates/forge/bin/cmd/fmt.rs index 36c0800008f1..24a2ba5425ce 100644 --- a/crates/forge/bin/cmd/fmt.rs +++ b/crates/forge/bin/cmd/fmt.rs @@ -73,11 +73,11 @@ impl FmtArgs { paths => { let mut inputs = Vec::with_capacity(paths.len()); for path in paths { - if !ignored.is_empty() && - ((path.is_absolute() && ignored.contains(path)) || - ignored.contains(&cwd.join(path))) + if !ignored.is_empty() + && ((path.is_absolute() && ignored.contains(path)) + || ignored.contains(&cwd.join(path))) { - continue + continue; } if path.is_dir() { @@ -131,7 +131,7 @@ impl FmtArgs { let diff = TextDiff::from_lines(&source, &output); if diff.ratio() < 1.0 { - return Ok(Some(format_diff_summary(&name, &diff))) + return Ok(Some(format_diff_summary(&name, &diff))); } } else if let Some(path) = path { fs::write(path, output)?; @@ -148,7 +148,7 @@ impl FmtArgs { HINT: If you are working outside of the project, \ try providing paths to your source files: `forge fmt `" ); - return Ok(()) + return Ok(()); } paths .par_iter() diff --git a/crates/forge/bin/cmd/geiger/find.rs b/crates/forge/bin/cmd/geiger/find.rs index ed1d5e691ae8..3eed2f8f2ed5 100644 --- a/crates/forge/bin/cmd/geiger/find.rs +++ b/crates/forge/bin/cmd/geiger/find.rs @@ -118,15 +118,15 @@ impl UnsafeCheatcodes { /// The total number of unsafe calls. pub fn len(&self) -> usize { - self.ffi.len() + - self.read_file.len() + - self.read_line.len() + - self.write_file.len() + - self.write_line.len() + - self.close_file.len() + - self.set_env.len() + - self.derive_key.len() + - self.remove_file.len() + self.ffi.len() + + self.read_file.len() + + self.read_line.len() + + self.write_file.len() + + self.write_line.len() + + self.close_file.len() + + self.set_env.len() + + self.derive_key.len() + + self.remove_file.len() } } diff --git a/crates/forge/bin/cmd/init.rs b/crates/forge/bin/cmd/init.rs index 96144dc63d7e..d05c8a7bd472 100644 --- a/crates/forge/bin/cmd/init.rs +++ b/crates/forge/bin/cmd/init.rs @@ -9,36 +9,36 @@ use std::path::{Path, PathBuf}; use yansi::Paint; /// CLI arguments for `forge init`. -#[derive(Clone, Debug, Parser)] +#[derive(Clone, Debug, Default, Parser)] pub struct InitArgs { /// The root directory of the new project. #[arg(value_hint = ValueHint::DirPath, default_value = ".", value_name = "PATH")] - root: PathBuf, + pub root: PathBuf, /// The template to start from. #[arg(long, short)] - template: Option, + pub template: Option, /// Branch argument that can only be used with template option. /// If not specified, the default branch is used. #[arg(long, short, requires = "template")] - branch: Option, + pub branch: Option, /// Do not install dependencies from the network. #[arg(long, conflicts_with = "template", visible_alias = "no-deps")] - offline: bool, + pub offline: bool, /// Create the project even if the specified root directory is not empty. #[arg(long, conflicts_with = "template")] - force: bool, + pub force: bool, /// Create a .vscode/settings.json file with Solidity settings, and generate a remappings.txt /// file. #[arg(long, conflicts_with = "template")] - vscode: bool, + pub vscode: bool, #[command(flatten)] - opts: DependencyInstallOpts, + pub opts: DependencyInstallOpts, } impl InitArgs { diff --git a/crates/forge/bin/cmd/inspect.rs b/crates/forge/bin/cmd/inspect.rs index b76ca2878da6..7712c2c4a531 100644 --- a/crates/forge/bin/cmd/inspect.rs +++ b/crates/forge/bin/cmd/inspect.rs @@ -170,7 +170,7 @@ pub fn print_storage_layout(storage_layout: Option<&StorageLayout>, pretty: bool }; if !pretty { - return print_json(&storage_layout) + return print_json(&storage_layout); } let mut table = Table::new(); @@ -332,20 +332,20 @@ impl PartialEq for ContractArtifactField { type Eos = EvmOutputSelection; matches!( (self, other), - (Self::Abi | Self::Events, Cos::Abi) | - (Self::Errors, Cos::Abi) | - (Self::Bytecode, Cos::Evm(Eos::ByteCode(_))) | - (Self::DeployedBytecode, Cos::Evm(Eos::DeployedByteCode(_))) | - (Self::Assembly | Self::AssemblyOptimized, Cos::Evm(Eos::Assembly)) | - (Self::MethodIdentifiers, Cos::Evm(Eos::MethodIdentifiers)) | - (Self::GasEstimates, Cos::Evm(Eos::GasEstimates)) | - (Self::StorageLayout, Cos::StorageLayout) | - (Self::DevDoc, Cos::DevDoc) | - (Self::Ir, Cos::Ir) | - (Self::IrOptimized, Cos::IrOptimized) | - (Self::Metadata, Cos::Metadata) | - (Self::UserDoc, Cos::UserDoc) | - (Self::Ewasm, Cos::Ewasm(_)) + (Self::Abi | Self::Events, Cos::Abi) + | (Self::Errors, Cos::Abi) + | (Self::Bytecode, Cos::Evm(Eos::ByteCode(_))) + | (Self::DeployedBytecode, Cos::Evm(Eos::DeployedByteCode(_))) + | (Self::Assembly | Self::AssemblyOptimized, Cos::Evm(Eos::Assembly)) + | (Self::MethodIdentifiers, Cos::Evm(Eos::MethodIdentifiers)) + | (Self::GasEstimates, Cos::Evm(Eos::GasEstimates)) + | (Self::StorageLayout, Cos::StorageLayout) + | (Self::DevDoc, Cos::DevDoc) + | (Self::Ir, Cos::Ir) + | (Self::IrOptimized, Cos::IrOptimized) + | (Self::Metadata, Cos::Metadata) + | (Self::UserDoc, Cos::UserDoc) + | (Self::Ewasm, Cos::Ewasm(_)) ) } } diff --git a/crates/forge/bin/cmd/install.rs b/crates/forge/bin/cmd/install.rs index 75fdbe3aa2ea..bdda01151868 100644 --- a/crates/forge/bin/cmd/install.rs +++ b/crates/forge/bin/cmd/install.rs @@ -304,7 +304,7 @@ impl Installer<'_> { for &prefix in common_prefixes { if let Some(rem) = tag.strip_prefix(prefix) { maybe_semver = rem; - break + break; } } match Version::parse(maybe_semver) { @@ -360,7 +360,7 @@ impl Installer<'_> { if e.to_string().contains("did not match any file(s) known to git") { e = eyre::eyre!("Tag: \"{tag}\" not found for repo \"{url}\"!") } - return Err(e) + return Err(e); } if is_branch { @@ -374,7 +374,7 @@ impl Installer<'_> { fn match_tag(self, tag: &str, path: &Path) -> Result { // only try to match if it looks like a version tag if !DEPENDENCY_VERSION_TAG_REGEX.is_match(tag) { - return Ok(tag.into()) + return Ok(tag.into()); } // generate candidate list by filtering `git tag` output, valid ones are those "starting @@ -392,13 +392,13 @@ impl Installer<'_> { // no match found, fall back to the user-provided tag if candidates.is_empty() { - return Ok(tag.into()) + return Ok(tag.into()); } // have exact match for candidate in candidates.iter() { if candidate == tag { - return Ok(tag.into()) + return Ok(tag.into()); } } @@ -408,7 +408,7 @@ impl Installer<'_> { let input = prompt!( "Found a similar version tag: {matched_tag}, do you want to use this instead? [Y/n] " )?; - return if match_yn(input) { Ok(matched_tag.clone()) } else { Ok(tag.into()) } + return if match_yn(input) { Ok(matched_tag.clone()) } else { Ok(tag.into()) }; } // multiple candidates, ask the user to choose one or skip @@ -431,7 +431,7 @@ impl Installer<'_> { Ok(i) if (1..=n_candidates).contains(&i) => { let c = &candidates[i]; println!("[{i}] {c} selected"); - return Ok(c.clone()) + return Ok(c.clone()); } _ => continue, } @@ -454,13 +454,13 @@ impl Installer<'_> { // no match found, fall back to the user-provided tag if candidates.is_empty() { - return Ok(None) + return Ok(None); } // have exact match for candidate in candidates.iter() { if candidate == tag { - return Ok(Some(tag.to_string())) + return Ok(Some(tag.to_string())); } } @@ -470,7 +470,7 @@ impl Installer<'_> { let input = prompt!( "Found a similar branch: {matched_tag}, do you want to use this instead? [Y/n] " )?; - return if match_yn(input) { Ok(Some(matched_tag.clone())) } else { Ok(None) } + return if match_yn(input) { Ok(Some(matched_tag.clone())) } else { Ok(None) }; } // multiple candidates, ask the user to choose one or skip @@ -490,7 +490,7 @@ impl Installer<'_> { // default selection, return None if input.is_empty() { println!("Canceled branch matching"); - return Ok(None) + return Ok(None); } // match user input, 0 indicates skipping and use original tag diff --git a/crates/forge/bin/cmd/mod.rs b/crates/forge/bin/cmd/mod.rs index b01366aa7ce8..c8d1dbb0e006 100644 --- a/crates/forge/bin/cmd/mod.rs +++ b/crates/forge/bin/cmd/mod.rs @@ -42,6 +42,7 @@ pub mod bind; pub mod build; pub mod cache; +pub mod clone; pub mod config; pub mod coverage; pub mod create; diff --git a/crates/forge/bin/cmd/selectors.rs b/crates/forge/bin/cmd/selectors.rs index 1ee251082b37..b18d4d811ea6 100644 --- a/crates/forge/bin/cmd/selectors.rs +++ b/crates/forge/bin/cmd/selectors.rs @@ -101,7 +101,7 @@ impl SelectorsSubcommands { while let Some((contract, artifact)) = artifacts.next() { let abi = artifact.abi.ok_or_else(|| eyre::eyre!("Unable to fetch abi"))?; if abi.functions.is_empty() && abi.events.is_empty() && abi.errors.is_empty() { - continue + continue; } println!("Uploading selectors for {contract}..."); @@ -222,7 +222,7 @@ impl SelectorsSubcommands { while let Some((contract, artifact)) = artifacts.next() { let abi = artifact.abi.ok_or_else(|| eyre::eyre!("Unable to fetch abi"))?; if abi.functions.is_empty() && abi.events.is_empty() && abi.errors.is_empty() { - continue + continue; } println!("{contract}"); diff --git a/crates/forge/bin/cmd/snapshot.rs b/crates/forge/bin/cmd/snapshot.rs index d7147f49b6c1..2a6c90cbe6d7 100644 --- a/crates/forge/bin/cmd/snapshot.rs +++ b/crates/forge/bin/cmd/snapshot.rs @@ -161,12 +161,12 @@ impl SnapshotConfig { fn is_in_gas_range(&self, gas_used: u64) -> bool { if let Some(min) = self.min { if gas_used < min { - return false + return false; } } if let Some(max) = self.max { if gas_used > max { - return false + return false; } } true diff --git a/crates/forge/bin/cmd/test/filter.rs b/crates/forge/bin/cmd/test/filter.rs index 65d3d0ed508d..d5af10f6e862 100644 --- a/crates/forge/bin/cmd/test/filter.rs +++ b/crates/forge/bin/cmd/test/filter.rs @@ -45,12 +45,12 @@ pub struct FilterArgs { impl FilterArgs { /// Returns true if the filter is empty. pub fn is_empty(&self) -> bool { - self.test_pattern.is_none() && - self.test_pattern_inverse.is_none() && - self.contract_pattern.is_none() && - self.contract_pattern_inverse.is_none() && - self.path_pattern.is_none() && - self.path_pattern_inverse.is_none() + self.test_pattern.is_none() + && self.test_pattern_inverse.is_none() + && self.contract_pattern.is_none() + && self.contract_pattern_inverse.is_none() + && self.path_pattern.is_none() + && self.path_pattern_inverse.is_none() } /// Merges the set filter globs with the config's values @@ -97,10 +97,10 @@ impl FileFilter for FilterArgs { /// [`FoundryPathExt::is_sol_test()`]. fn is_match(&self, file: &Path) -> bool { if let Some(glob) = &self.path_pattern { - return glob.is_match(file) + return glob.is_match(file); } if let Some(glob) = &self.path_pattern_inverse { - return !glob.is_match(file) + return !glob.is_match(file); } file.is_sol_test() } diff --git a/crates/forge/bin/cmd/test/mod.rs b/crates/forge/bin/cmd/test/mod.rs index 13130d4642f7..d59aab02ced2 100644 --- a/crates/forge/bin/cmd/test/mod.rs +++ b/crates/forge/bin/cmd/test/mod.rs @@ -157,8 +157,8 @@ impl TestArgs { let mut project = config.project()?; // Install missing dependencies. - if install::install_missing_dependencies(&mut config, self.build_args().silent) && - config.auto_detect_remappings + if install::install_missing_dependencies(&mut config, self.build_args().silent) + && config.auto_detect_remappings { // need to re-configure here to also catch additional remappings config = self.load_config(); diff --git a/crates/forge/bin/cmd/watch.rs b/crates/forge/bin/cmd/watch.rs index 1412cb15e4f6..df1263e2684e 100644 --- a/crates/forge/bin/cmd/watch.rs +++ b/crates/forge/bin/cmd/watch.rs @@ -131,10 +131,10 @@ pub async fn watch_test(args: TestArgs) -> Result<()> { let filter = args.filter(&config); // marker to check whether to override the command - let no_reconfigure = filter.args().test_pattern.is_some() || - filter.args().path_pattern.is_some() || - filter.args().contract_pattern.is_some() || - args.watch.run_all; + let no_reconfigure = filter.args().test_pattern.is_some() + || filter.args().path_pattern.is_some() + || filter.args().contract_pattern.is_some() + || args.watch.run_all; let state = WatchTestState { project_root: config.__root.0, @@ -169,7 +169,7 @@ fn on_test(action: OnActionState) { if no_reconfigure { // nothing to reconfigure - return + return; } let mut cmd = cmd.clone(); @@ -189,8 +189,8 @@ fn on_test(action: OnActionState) { cmd.drain(pos..=(pos + 1)); } - if changed_sol_test_files.len() > 1 || - (changed_sol_test_files.is_empty() && last_test_files.is_empty()) + if changed_sol_test_files.len() > 1 + || (changed_sol_test_files.is_empty() && last_test_files.is_empty()) { // this could happen if multiple files were changed at once, for example `forge fmt` was // run, or if no test files were changed and no previous test files were modified in which @@ -210,7 +210,7 @@ fn on_test(action: OnActionState) { }, on_test, ); - return + return; } if changed_sol_test_files.is_empty() { @@ -278,11 +278,11 @@ fn clean_cmd_args(num: usize, mut cmd_args: Vec) -> Vec { fn contains_w_in_short(arg: &str) -> Option { let mut iter = arg.chars().peekable(); if *iter.peek()? != '-' { - return None + return None; } iter.next(); if *iter.peek()? == '-' { - return None + return None; } Some(iter.any(|c| c == 'w')) } @@ -347,7 +347,7 @@ fn on_action( if signals.contains(&MainSignal::Terminate) || signals.contains(&MainSignal::Interrupt) { action.outcome(Outcome::both(Outcome::Stop, Outcome::Exit)); - return fut + return fut; } if !has_paths { @@ -358,7 +358,7 @@ fn on_action( } action.outcome(out); - return fut + return fut; } let completion = action.events.iter().flat_map(|e| e.completions()).next(); @@ -382,7 +382,7 @@ fn on_action( }; action.outcome(Outcome::DoNothing); - return fut + return fut; } } diff --git a/crates/forge/bin/main.rs b/crates/forge/bin/main.rs index 0743d69e61aa..ee046c32ba4c 100644 --- a/crates/forge/bin/main.rs +++ b/crates/forge/bin/main.rs @@ -48,6 +48,7 @@ fn main() -> Result<()> { ForgeSubcommand::Debug(cmd) => utils::block_on(cmd.run()), ForgeSubcommand::VerifyContract(args) => utils::block_on(args.run()), ForgeSubcommand::VerifyCheck(args) => utils::block_on(args.run()), + ForgeSubcommand::Clone(cmd) => utils::block_on(cmd.run()), ForgeSubcommand::Cache(cmd) => match cmd.sub { CacheSubcommands::Clean(cmd) => cmd.run(), CacheSubcommands::Ls(cmd) => cmd.run(), diff --git a/crates/forge/bin/opts.rs b/crates/forge/bin/opts.rs index 03ed4d551f4b..f96aec87b70d 100644 --- a/crates/forge/bin/opts.rs +++ b/crates/forge/bin/opts.rs @@ -1,7 +1,7 @@ use crate::cmd::{ - bind::BindArgs, build::BuildArgs, cache::CacheArgs, config, coverage, create::CreateArgs, - debug::DebugArgs, doc::DocArgs, flatten, fmt::FmtArgs, geiger, generate, init::InitArgs, - inspect, install::InstallArgs, remappings::RemappingArgs, remove::RemoveArgs, + bind::BindArgs, build::BuildArgs, cache::CacheArgs, clone::CloneArgs, config, coverage, + create::CreateArgs, debug::DebugArgs, doc::DocArgs, flatten, fmt::FmtArgs, geiger, generate, + init::InitArgs, inspect, install::InstallArgs, remappings::RemappingArgs, remove::RemoveArgs, selectors::SelectorsSubcommands, snapshot, test, tree, update, }; use clap::{Parser, Subcommand, ValueHint}; @@ -52,6 +52,9 @@ pub enum ForgeSubcommand { #[command(visible_aliases = ["b", "compile"])] Build(BuildArgs), + /// Clone a contract from Etherscan. + Clone(CloneArgs), + /// Debugs a single smart contract as a script. #[command(visible_alias = "d")] Debug(DebugArgs), diff --git a/crates/forge/src/gas_report.rs b/crates/forge/src/gas_report.rs index 2bdd6d4daec6..ce9e4a234b45 100644 --- a/crates/forge/src/gas_report.rs +++ b/crates/forge/src/gas_report.rs @@ -80,10 +80,10 @@ impl GasReport { // Only include top-level calls which accout for calldata and base (21.000) cost. // Only include Calls and Creates as only these calls are isolated in inspector. - if trace.depth > 1 && - (trace.kind == CallKind::Call || - trace.kind == CallKind::Create || - trace.kind == CallKind::Create2) + if trace.depth > 1 + && (trace.kind == CallKind::Call + || trace.kind == CallKind::Create + || trace.kind == CallKind::Create2) { return; } @@ -143,7 +143,7 @@ impl Display for GasReport { for (name, contract) in &self.contracts { if contract.functions.is_empty() { trace!(name, "gas report contract without functions"); - continue + continue; } let mut table = Table::new(); diff --git a/crates/forge/src/multi_runner.rs b/crates/forge/src/multi_runner.rs index 7712a7ee6a36..b89fac410ccd 100644 --- a/crates/forge/src/multi_runner.rs +++ b/crates/forge/src/multi_runner.rs @@ -338,8 +338,8 @@ impl MultiContractRunnerBuilder { }; // if it's a test, add it to deployable contracts - if abi.constructor.as_ref().map(|c| c.inputs.is_empty()).unwrap_or(true) && - abi.functions().any(|func| func.name.is_test() || func.name.is_invariant_test()) + if abi.constructor.as_ref().map(|c| c.inputs.is_empty()).unwrap_or(true) + && abi.functions().any(|func| func.name.is_test() || func.name.is_invariant_test()) { deployable_contracts.insert(id.clone(), (abi.clone(), bytecode, libs_to_deploy)); } @@ -371,8 +371,8 @@ impl MultiContractRunnerBuilder { } fn matches_contract(id: &ArtifactId, abi: &JsonAbi, filter: &dyn TestFilter) -> bool { - (filter.matches_path(&id.source) && filter.matches_contract(&id.name)) && - abi.functions().any(|func| is_matching_test(func, filter)) + (filter.matches_path(&id.source) && filter.matches_contract(&id.name)) + && abi.functions().any(|func| is_matching_test(func, filter)) } /// Returns `true` if the function is a test function that matches the given filter. diff --git a/crates/forge/src/runner.rs b/crates/forge/src/runner.rs index 3c9eee1ddaf5..54dd163fee97 100644 --- a/crates/forge/src/runner.rs +++ b/crates/forge/src/runner.rs @@ -215,7 +215,7 @@ impl<'a> ContractRunner<'a> { [("setUp()".to_string(), TestResult::fail("multiple setUp functions".to_string()))] .into(), warnings, - ) + ); } let has_invariants = self.contract.functions().any(|func| func.is_invariant_test()); @@ -251,7 +251,7 @@ impl<'a> ContractRunner<'a> { )] .into(), warnings, - ) + ); } // Filter out functions sequentially since it's very fast and there is no need to do it @@ -482,7 +482,7 @@ impl<'a> ContractRunner<'a> { coverage, duration: start.elapsed(), ..Default::default() - } + }; }; let mut evm = InvariantExecutor::new( @@ -524,8 +524,8 @@ impl<'a> ContractRunner<'a> { match error { // If invariants were broken, replay the error to collect logs and traces Some(error) => match error { - InvariantFuzzError::BrokenInvariant(case_data) | - InvariantFuzzError::Revert(case_data) => { + InvariantFuzzError::BrokenInvariant(case_data) + | InvariantFuzzError::Revert(case_data) => { match case_data.replay( self.executor.clone(), known_contracts, @@ -637,7 +637,7 @@ impl<'a> ContractRunner<'a> { coverage, duration: start.elapsed(), ..Default::default() - } + }; } // if should debug diff --git a/crates/forge/tests/cli/coverage.rs b/crates/forge/tests/cli/coverage.rs index df44a1cf6a50..f4ae1c4c38bf 100644 --- a/crates/forge/tests/cli/coverage.rs +++ b/crates/forge/tests/cli/coverage.rs @@ -75,6 +75,6 @@ contract AContractTest is DSTest { .unwrap() .as_str() .parse::() - .unwrap() > - 0))); + .unwrap() + > 0))); }); diff --git a/crates/forge/tests/cli/utils.rs b/crates/forge/tests/cli/utils.rs index 12b0fe13470f..0c3ef0c014c6 100644 --- a/crates/forge/tests/cli/utils.rs +++ b/crates/forge/tests/cli/utils.rs @@ -126,7 +126,7 @@ impl EnvExternalities { pub fn parse_deployed_address(out: &str) -> Option { for line in out.lines() { if line.starts_with("Deployed to") { - return Some(line.trim_start_matches("Deployed to: ").to_string()) + return Some(line.trim_start_matches("Deployed to: ").to_string()); } } None @@ -135,7 +135,7 @@ pub fn parse_deployed_address(out: &str) -> Option { pub fn parse_verification_guid(out: &str) -> Option { for line in out.lines() { if line.contains("GUID") { - return Some(line.replace("GUID:", "").replace('`', "").trim().to_string()) + return Some(line.replace("GUID:", "").replace('`', "").trim().to_string()); } } None diff --git a/crates/forge/tests/cli/verify.rs b/crates/forge/tests/cli/verify.rs index deedcc9abf83..4a2e372653ee 100644 --- a/crates/forge/tests/cli/verify.rs +++ b/crates/forge/tests/cli/verify.rs @@ -81,7 +81,7 @@ fn parse_verification_result(cmd: &mut TestCommand, retries: u32) -> eyre::Resul let out = String::from_utf8_lossy(&output.stdout); println!("{}", out); if out.contains("Contract successfully verified") { - return Ok(()) + return Ok(()); } eyre::bail!( "Failed to get verification, stdout: {}, stderr: {}", diff --git a/crates/forge/tests/it/config.rs b/crates/forge/tests/it/config.rs index 1b2a1398d1f6..3124571c6890 100644 --- a/crates/forge/tests/it/config.rs +++ b/crates/forge/tests/it/config.rs @@ -66,8 +66,8 @@ impl TestConfig { } for (_, SuiteResult { test_results, .. }) in suite_result { for (test_name, result) in test_results { - if self.should_fail && (result.status == TestStatus::Success) || - !self.should_fail && (result.status == TestStatus::Failure) + if self.should_fail && (result.status == TestStatus::Success) + || !self.should_fail && (result.status == TestStatus::Failure) { let logs = decode_console_logs(&result.logs); let outcome = if self.should_fail { "fail" } else { "pass" }; diff --git a/crates/forge/tests/it/fuzz.rs b/crates/forge/tests/it/fuzz.rs index c6369e896615..b002ba9f8571 100644 --- a/crates/forge/tests/it/fuzz.rs +++ b/crates/forge/tests/it/fuzz.rs @@ -22,10 +22,10 @@ async fn test_fuzz() { for (_, SuiteResult { test_results, .. }) in suite_result { for (test_name, result) in test_results { match test_name.as_str() { - "testPositive(uint256)" | - "testPositive(int256)" | - "testSuccessfulFuzz(uint128,uint128)" | - "testToStringFuzz(bytes32)" => assert_eq!( + "testPositive(uint256)" + | "testPositive(int256)" + | "testSuccessfulFuzz(uint128,uint128)" + | "testToStringFuzz(bytes32)" => assert_eq!( result.status, TestStatus::Success, "Test {} did not pass as expected.\nReason: {:?}\nLogs:\n{}", @@ -59,9 +59,9 @@ async fn test_successful_fuzz_cases() { for (_, SuiteResult { test_results, .. }) in suite_result { for (test_name, result) in test_results { match test_name.as_str() { - "testSuccessChecker(uint256)" | - "testSuccessChecker2(int256)" | - "testSuccessChecker3(uint32)" => assert_eq!( + "testSuccessChecker(uint256)" + | "testSuccessChecker2(int256)" + | "testSuccessChecker3(uint32)" => assert_eq!( result.status, TestStatus::Success, "Test {} did not pass as expected.\nReason: {:?}\nLogs:\n{}", diff --git a/crates/macros/src/cheatcodes.rs b/crates/macros/src/cheatcodes.rs index b38186e57732..a2db16cb6acb 100644 --- a/crates/macros/src/cheatcodes.rs +++ b/crates/macros/src/cheatcodes.rs @@ -94,7 +94,7 @@ fn derive_call(name: &Ident, data: &DataStruct, attrs: &[Attribute]) -> Result Result { if input.variants.iter().any(|v| v.fields.len() != 1) { - return Err(syn::Error::new(name.span(), "expected all variants to have a single field")) + return Err(syn::Error::new(name.span(), "expected all variants to have a single field")); } // keep original order for matching @@ -127,7 +127,7 @@ fn derive_errors_events_enum( events: bool, ) -> Result { if input.variants.iter().any(|v| v.fields.len() != 1) { - return Err(syn::Error::new(name.span(), "expected all variants to have a single field")) + return Err(syn::Error::new(name.span(), "expected all variants to have a single field")); } let (ident, ty_assoc_name, ty, doc) = if events { @@ -317,14 +317,14 @@ fn get_docstring(attrs: &[Attribute]) -> String { let mut doc = String::new(); for attr in attrs { if !attr.path().is_ident("doc") { - continue + continue; } let syn::Meta::NameValue(syn::MetaNameValue { value: syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(s), .. }), .. }) = &attr.meta else { - continue + continue; }; let value = s.value(); @@ -398,7 +398,7 @@ fn func_docstring(doc: &str) -> (&str, &str, &str, &str) { /// Returns `(visibility, mutability)` from a given Solidity function declaration. fn parse_function_attrs(f: &str, span: Span) -> Result<(&str, &str)> { let Some(ext_start) = f.find("external") else { - return Err(Error::new(span, "functions must have `external` visibility")) + return Err(Error::new(span, "functions must have `external` visibility")); }; let visibility = "External"; diff --git a/crates/macros/src/console_fmt.rs b/crates/macros/src/console_fmt.rs index 3ee0077d9739..9342e4d86308 100644 --- a/crates/macros/src/console_fmt.rs +++ b/crates/macros/src/console_fmt.rs @@ -33,7 +33,7 @@ fn impl_struct(s: &DataStruct) -> Option { }; if fields.is_empty() { - return None + return None; } let first_ty = match &fields.first().unwrap().ty { diff --git a/crates/script/src/broadcast.rs b/crates/script/src/broadcast.rs index 224bcc44cf45..3e0b9562011f 100644 --- a/crates/script/src/broadcast.rs +++ b/crates/script/src/broadcast.rs @@ -47,9 +47,9 @@ where provider .estimate_gas(tx, None) .await - .wrap_err_with(|| format!("Failed to estimate gas for tx: {:?}", tx.sighash()))? * - estimate_multiplier / - 100, + .wrap_err_with(|| format!("Failed to estimate gas for tx: {:?}", tx.sighash()))? + * estimate_multiplier + / 100, ); Ok(()) } @@ -312,10 +312,10 @@ impl BundledState { // their order otherwise. // Or if the chain does not support batched transactions (eg. Arbitrum). // Or if we need to invoke eth_estimateGas before sending transactions. - let sequential_broadcast = estimate_via_rpc || - self.args.slow || - send_kind.signers_count() != 1 || - !has_batch_support(sequence.chain); + let sequential_broadcast = estimate_via_rpc + || self.args.slow + || send_kind.signers_count() != 1 + || !has_batch_support(sequence.chain); let pb = init_progress!(transactions, "txes"); @@ -409,8 +409,9 @@ impl BundledState { pub fn verify_preflight_check(&self) -> Result<()> { for sequence in self.sequence.sequences() { - if self.args.verifier.verifier == VerificationProviderType::Etherscan && - self.script_config + if self.args.verifier.verifier == VerificationProviderType::Etherscan + && self + .script_config .config .get_etherscan_api_key(Some(sequence.chain.into())) .is_none() diff --git a/crates/script/src/build.rs b/crates/script/src/build.rs index 41e898d96a72..5657fcc3facd 100644 --- a/crates/script/src/build.rs +++ b/crates/script/src/build.rs @@ -196,8 +196,8 @@ impl PreprocessedState { if id.name != *name { continue; } - } else if contract.abi.as_ref().map_or(true, |abi| abi.is_empty()) || - contract.bytecode.as_ref().map_or(true, |b| match &b.object { + } else if contract.abi.as_ref().map_or(true, |abi| abi.is_empty()) + || contract.bytecode.as_ref().map_or(true, |b| match &b.object { BytecodeObject::Bytecode(b) => b.is_empty(), BytecodeObject::Unlinked(_) => false, }) diff --git a/crates/script/src/execute.rs b/crates/script/src/execute.rs index 4a3a3485208b..0350dd4125a7 100644 --- a/crates/script/src/execute.rs +++ b/crates/script/src/execute.rs @@ -198,8 +198,8 @@ impl PreExecutionState { if let Some(txs) = transactions { // If the user passed a `--sender` don't check anything. - if !self.build_data.predeploy_libraries.is_empty() && - self.args.evm_opts.sender.is_none() + if !self.build_data.predeploy_libraries.is_empty() + && self.args.evm_opts.sender.is_none() { for tx in txs.iter() { if tx.transaction.to.is_none() { diff --git a/crates/script/src/lib.rs b/crates/script/src/lib.rs index 010b5bbe970d..4d9aa66b34ac 100644 --- a/crates/script/src/lib.rs +++ b/crates/script/src/lib.rs @@ -428,9 +428,9 @@ impl ScriptArgs { } // Only prompt if we're broadcasting and we've not disabled interactivity. - if prompt_user && - !self.non_interactive && - !Confirm::new().with_prompt("Do you wish to continue?".to_string()).interact()? + if prompt_user + && !self.non_interactive + && !Confirm::new().with_prompt("Do you wish to continue?".to_string()).interact()? { eyre::bail!("User canceled the script."); } diff --git a/crates/script/src/runner.rs b/crates/script/src/runner.rs index 23c25d133dc0..f7b5e831de7e 100644 --- a/crates/script/src/runner.rs +++ b/crates/script/src/runner.rs @@ -301,9 +301,9 @@ impl ScriptRunner { self.executor.env.tx.gas_limit = mid_gas_limit; let res = self.executor.call_raw(from, to, calldata.0.clone().into(), value)?; match res.exit_reason { - InstructionResult::Revert | - InstructionResult::OutOfGas | - InstructionResult::OutOfFunds => { + InstructionResult::Revert + | InstructionResult::OutOfGas + | InstructionResult::OutOfFunds => { lowest_gas_limit = mid_gas_limit; } _ => { @@ -311,9 +311,9 @@ impl ScriptRunner { // if last two successful estimations only vary by 10%, we consider this to // sufficiently accurate const ACCURACY: u64 = 10; - if (last_highest_gas_limit - highest_gas_limit) * ACCURACY / - last_highest_gas_limit < - 1 + if (last_highest_gas_limit - highest_gas_limit) * ACCURACY + / last_highest_gas_limit + < 1 { // update the gas gas_used = highest_gas_limit; diff --git a/crates/script/src/sequence.rs b/crates/script/src/sequence.rs index 9fdee7b021bf..0d7d5237fc06 100644 --- a/crates/script/src/sequence.rs +++ b/crates/script/src/sequence.rs @@ -163,7 +163,7 @@ impl ScriptSequence { self.sort_receipts(); if self.transactions.is_empty() { - return Ok(()) + return Ok(()); } let Some((path, sensitive_path)) = self.paths.clone() else { return Ok(()) }; @@ -268,8 +268,8 @@ impl ScriptSequence { verify.set_chain(config, self.chain.into()); - if verify.etherscan.has_key() || - verify.verifier.verifier != VerificationProviderType::Etherscan + if verify.etherscan.has_key() + || verify.verifier.verifier != VerificationProviderType::Etherscan { trace!(target: "script", "prepare future verifications"); @@ -376,12 +376,12 @@ impl ScriptSequence { pub fn sig_to_file_name(sig: &str) -> String { if let Some((name, _)) = sig.split_once('(') { // strip until call argument parenthesis - return name.to_string() + return name.to_string(); } // assume calldata if `sig` is hex if let Ok(calldata) = hex::decode(sig) { // in which case we return the function signature - return hex::encode(&calldata[..SELECTOR_LEN]) + return hex::encode(&calldata[..SELECTOR_LEN]); } // return sig as is diff --git a/crates/script/src/simulate.rs b/crates/script/src/simulate.rs index e63c5efcefee..96b1eaefe2f0 100644 --- a/crates/script/src/simulate.rs +++ b/crates/script/src/simulate.rs @@ -21,7 +21,7 @@ use foundry_common::{ get_contract_name, provider::ethers::RpcUrl, shell, types::ToAlloy, ContractsByArtifact, }; use foundry_evm::traces::render_trace_arena; -use futures::future::join_all; +use futures::future::{join_all, try_join_all}; use parking_lot::RwLock; use std::{ collections::{BTreeMap, HashMap, VecDeque}, @@ -207,7 +207,7 @@ impl PreSimulationState { } /// Build [ScriptRunner] forking given RPC for each RPC used in the script. - async fn build_runners(&self) -> Result> { + async fn build_runners(&self) -> Result> { let rpcs = self.execution_artifacts.rpc_data.total_rpcs.clone(); if !shell::verbosity().is_silent() { let n = rpcs.len(); @@ -215,17 +215,13 @@ impl PreSimulationState { println!("\n## Setting up {n} EVM{s}."); } - let futs = rpcs - .into_iter() - .map(|rpc| async move { - let mut script_config = self.script_config.clone(); - script_config.evm_opts.fork_url = Some(rpc.clone()); - let runner = script_config.get_runner().await?; - Ok((rpc.clone(), runner)) - }) - .collect::>(); - - join_all(futs).await.into_iter().collect() + let futs = rpcs.into_iter().map(|rpc| async move { + let mut script_config = self.script_config.clone(); + script_config.evm_opts.fork_url = Some(rpc.clone()); + let runner = script_config.get_runner().await?; + Ok((rpc.clone(), runner)) + }); + try_join_all(futs).await } /// If simulation is disabled, converts transactions into [TransactionWithMetadata] type diff --git a/crates/script/src/transaction.rs b/crates/script/src/transaction.rs index 80a2814207aa..a7252dab4587 100644 --- a/crates/script/src/transaction.rs +++ b/crates/script/src/transaction.rs @@ -156,7 +156,7 @@ impl TransactionWithMetadata { // `create2` transactions are prefixed by a 32 byte salt. let creation_code = if is_create2 { if data.len() < 32 { - return Ok(()) + return Ok(()); } &data[32..] } else { diff --git a/crates/script/src/verify.rs b/crates/script/src/verify.rs index 217d880b07b7..1ecd69655b43 100644 --- a/crates/script/src/verify.rs +++ b/crates/script/src/verify.rs @@ -150,7 +150,7 @@ impl VerifyBundle { guess_constructor_args: false, }; - return Some(verify) + return Some(verify); } } None diff --git a/crates/test-utils/src/script.rs b/crates/test-utils/src/script.rs index 80b06ae769b2..1a5f46283ae7 100644 --- a/crates/test-utils/src/script.rs +++ b/crates/test-utils/src/script.rs @@ -284,16 +284,16 @@ impl ScriptOutcome { pub fn is_err(&self) -> bool { match self { - ScriptOutcome::OkNoEndpoint | - ScriptOutcome::OkSimulation | - ScriptOutcome::OkBroadcast | - ScriptOutcome::WarnSpecifyDeployer => false, - ScriptOutcome::MissingSender | - ScriptOutcome::MissingWallet | - ScriptOutcome::StaticCallNotAllowed | - ScriptOutcome::UnsupportedLibraries | - ScriptOutcome::ErrorSelectForkOnBroadcast | - ScriptOutcome::ScriptFailed => true, + ScriptOutcome::OkNoEndpoint + | ScriptOutcome::OkSimulation + | ScriptOutcome::OkBroadcast + | ScriptOutcome::WarnSpecifyDeployer => false, + ScriptOutcome::MissingSender + | ScriptOutcome::MissingWallet + | ScriptOutcome::StaticCallNotAllowed + | ScriptOutcome::UnsupportedLibraries + | ScriptOutcome::ErrorSelectForkOnBroadcast + | ScriptOutcome::ScriptFailed => true, } } } diff --git a/crates/test-utils/src/util.rs b/crates/test-utils/src/util.rs index dbb872d8ace1..567986597196 100644 --- a/crates/test-utils/src/util.rs +++ b/crates/test-utils/src/util.rs @@ -1115,7 +1115,7 @@ pub fn tty_fixture_path(path: impl AsRef) -> PathBuf { path.with_extension(format!("tty.{ext}")) } else { path.with_extension("tty") - } + }; } path.to_path_buf() } diff --git a/crates/verify/src/etherscan/mod.rs b/crates/verify/src/etherscan/mod.rs index 7e79321efa4c..361c6353f7f8 100644 --- a/crates/verify/src/etherscan/mod.rs +++ b/crates/verify/src/etherscan/mod.rs @@ -65,8 +65,8 @@ impl VerificationProvider for EtherscanVerificationProvider { async fn verify(&mut self, args: VerifyArgs) -> Result<()> { let (etherscan, verify_args) = self.prepare_request(&args).await?; - if !args.skip_is_verified_check && - self.is_contract_verified(ðerscan, &verify_args).await? + if !args.skip_is_verified_check + && self.is_contract_verified(ðerscan, &verify_args).await? { println!( "\nContract [{}] {:?} is already verified. Skipping verification.", @@ -74,7 +74,7 @@ impl VerificationProvider for EtherscanVerificationProvider { verify_args.address.to_checksum(None) ); - return Ok(()) + return Ok(()); } trace!(target: "forge::verify", ?verify_args, "submitting verification request"); @@ -139,7 +139,7 @@ impl VerificationProvider for EtherscanVerificationProvider { verifier: args.verifier, }; // return check_args.run().await - return self.check(check_args).await + return self.check(check_args).await; } } else { println!("Contract source code already verified"); @@ -174,16 +174,16 @@ impl VerificationProvider for EtherscanVerificationProvider { ); if resp.result == "Pending in queue" { - return Err(eyre!("Verification is still pending...",)) + return Err(eyre!("Verification is still pending...",)); } if resp.result == "Unable to verify" { - return Err(eyre!("Unable to verify.",)) + return Err(eyre!("Unable to verify.",)); } if resp.result == "Already Verified" { println!("Contract source code already verified"); - return Ok(()) + return Ok(()); } if resp.status == "0" { @@ -222,7 +222,7 @@ impl EtherscanVerificationProvider { contract: &ContractInfo, ) -> Result<&(PathBuf, CacheEntry, CompactContract)> { if let Some(ref entry) = self.cached_entry { - return Ok(entry) + return Ok(entry); } let cache = project.read_cache_file()?; @@ -396,7 +396,7 @@ impl EtherscanVerificationProvider { project: &Project, ) -> Result { if let Some(ref version) = args.compiler_version { - return Ok(version.trim_start_matches('v').parse()?) + return Ok(version.trim_start_matches('v').parse()?); } if let Some(ref solc) = config.solc { @@ -404,7 +404,7 @@ impl EtherscanVerificationProvider { SolcReq::Version(version) => return Ok(version.to_owned()), SolcReq::Local(solc) => { if solc.is_file() { - return Ok(Solc::new(solc).version()?) + return Ok(Solc::new(solc).version()?); } } } @@ -467,10 +467,10 @@ impl EtherscanVerificationProvider { read_constructor_args_file(constructor_args_path.to_path_buf())?, )?; let encoded_args = hex::encode(encoded_args); - return Ok(Some(encoded_args[8..].into())) + return Ok(Some(encoded_args[8..].into())); } if args.guess_constructor_args { - return Ok(Some(self.guess_constructor_args(args, project, config).await?)) + return Ok(Some(self.guess_constructor_args(args, project, config).await?)); } Ok(args.constructor_args.clone()) diff --git a/crates/verify/src/lib.rs b/crates/verify/src/lib.rs index be451d83fbb2..ef0f13b3083a 100644 --- a/crates/verify/src/lib.rs +++ b/crates/verify/src/lib.rs @@ -198,7 +198,7 @@ impl VerifyArgs { let args = EtherscanVerificationProvider::default().create_verify_request(&self, None).await?; println!("{}", args.source); - return Ok(()) + return Ok(()); } let verifier_url = self.verifier.verifier_url.clone(); diff --git a/crates/wallets/src/raw_wallet.rs b/crates/wallets/src/raw_wallet.rs index f8a9d447cf9d..3a5169cad977 100644 --- a/crates/wallets/src/raw_wallet.rs +++ b/crates/wallets/src/raw_wallet.rs @@ -47,7 +47,7 @@ impl RawWalletOpts { return Ok(Some(PendingSigner::Interactive.unlock()?)); } if let Some(private_key) = &self.private_key { - return Ok(Some(utils::create_private_key_signer(private_key)?)) + return Ok(Some(utils::create_private_key_signer(private_key)?)); } if let Some(mnemonic) = &self.mnemonic { return Ok(Some(utils::create_mnemonic_signer( @@ -55,7 +55,7 @@ impl RawWalletOpts { self.mnemonic_passphrase.as_deref(), self.hd_path.as_deref(), self.mnemonic_index, - )?)) + )?)); } Ok(None) } diff --git a/crates/wallets/src/utils.rs b/crates/wallets/src/utils.rs index a10903313034..9245f8ed849b 100644 --- a/crates/wallets/src/utils.rs +++ b/crates/wallets/src/utils.rs @@ -22,7 +22,7 @@ pub fn create_private_key_signer(private_key: &str) -> Result { // SAFETY: at this point we know the user actually wanted to use an env var // and most likely forgot the `$` anchor, so the // `private_key` here is an unresolved env var - return Err(PrivateKeyError::ExistsAsEnvVar(pk.to_string())) + return Err(PrivateKeyError::ExistsAsEnvVar(pk.to_string())); } Ok(()) };