Skip to content

Commit b44b045

Browse files
authored
feat(anvil): add TipAboveFeeCap error (#4395)
1 parent c7db4af commit b44b045

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

anvil/src/eth/backend/mem/mod.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2015,9 +2015,20 @@ impl TransactionValidator for Backend {
20152015
return Err(InvalidTransactionError::NonceTooLow)
20162016
}
20172017

2018-
if (env.cfg.spec_id as u8) >= (SpecId::LONDON as u8) && tx.gas_price() < env.block.basefee {
2019-
warn!(target: "backend", "max fee per gas={}, too low, block basefee={}",tx.gas_price(), env.block.basefee);
2020-
return Err(InvalidTransactionError::FeeTooLow)
2018+
if (env.cfg.spec_id as u8) >= (SpecId::LONDON as u8) {
2019+
if tx.gas_price() < env.block.basefee {
2020+
warn!(target: "backend", "max fee per gas={}, too low, block basefee={}",tx.gas_price(), env.block.basefee);
2021+
return Err(InvalidTransactionError::FeeTooLow)
2022+
}
2023+
2024+
if let (Some(max_priority_fee_per_gas), Some(max_fee_per_gas)) =
2025+
(tx.essentials().max_priority_fee_per_gas, tx.essentials().max_fee_per_gas)
2026+
{
2027+
if max_priority_fee_per_gas > max_fee_per_gas {
2028+
warn!(target: "backend", "max priority fee per gas={}, too high, max fee per gas={}", max_priority_fee_per_gas, max_fee_per_gas);
2029+
return Err(InvalidTransactionError::TipAboveFeeCap)
2030+
}
2031+
}
20212032
}
20222033

20232034
let max_cost = tx.max_cost();

anvil/src/eth/error.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ pub enum InvalidTransactionError {
144144
#[error("max fee per gas less than block base fee")]
145145
FeeTooLow,
146146

147+
/// Thrown to ensure no one is able to specify a transaction with a tip higher than the total
148+
/// fee cap.
149+
#[error("max priority fee per gas higher than max fee per gas")]
150+
TipAboveFeeCap,
151+
147152
/// Thrown when a tx was signed with a different chain_id
148153
#[error("invalid chain id for signer")]
149154
InvalidChainId,

anvil/tests/it/gas.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
use anvil::{eth::fees::INITIAL_BASE_FEE, spawn, NodeConfig};
44
use ethers::{
55
prelude::Middleware,
6-
types::{transaction::eip2718::TypedTransaction, Address, BlockNumber, TransactionRequest},
6+
types::{
7+
transaction::eip2718::TypedTransaction, Address, BlockNumber, Eip1559TransactionRequest,
8+
TransactionRequest,
9+
},
710
};
811

912
const GAS_TRANSFER: u64 = 21_000u64;
@@ -87,3 +90,23 @@ async fn test_respect_base_fee() {
8790
let tx = provider.send_transaction(tx, None).await.unwrap().await.unwrap().unwrap();
8891
assert_eq!(tx.status, Some(1u64.into()));
8992
}
93+
94+
#[tokio::test(flavor = "multi_thread")]
95+
async fn test_tip_above_fee_cap() {
96+
let base_fee = 50u64;
97+
let (_api, handle) = spawn(NodeConfig::test().with_base_fee(Some(base_fee))).await;
98+
let provider = handle.http_provider();
99+
let tx = TypedTransaction::Eip1559(
100+
Eip1559TransactionRequest::new()
101+
.max_fee_per_gas(base_fee)
102+
.max_priority_fee_per_gas(base_fee + 1)
103+
.to(Address::random())
104+
.value(100u64),
105+
);
106+
let res = provider.send_transaction(tx, None).await;
107+
assert!(res.is_err());
108+
assert!(res
109+
.unwrap_err()
110+
.to_string()
111+
.contains("max priority fee per gas higher than max fee per gas"));
112+
}

0 commit comments

Comments
 (0)