Skip to content

Commit

Permalink
refunds working
Browse files Browse the repository at this point in the history
  • Loading branch information
ZanCorDX committed Feb 7, 2025
1 parent 62d0e40 commit 1217bdd
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 11 deletions.
51 changes: 46 additions & 5 deletions crates/rbuilder/src/building/testing/bundle_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use crate::{
TransactionErr,
},
primitives::{
Bundle, BundleReplacementData, BundleReplacementKey, Order, OrderId, Refund, RefundConfig,
TxRevertBehavior,
Bundle, BundleRefund, BundleReplacementData, BundleReplacementKey, Order, OrderId, Refund,
RefundConfig, TxRevertBehavior,
},
utils::{constants::BASE_TX_GAS, int_percentage},
};
Expand Down Expand Up @@ -324,6 +324,38 @@ fn test_share_bundle_revert() -> eyre::Result<()> {
Ok(())
}

#[test]
fn test_bundle_ok_refunds() -> eyre::Result<()> {
let target_block = 11;
let mut test_setup = TestSetup::gen_test_setup(BlockArgs::default().number(target_block))?;
let profit: u64 = 100_000;
let percent: u8 = 90;
let refundable_value = int_percentage(profit, percent as usize);
let recipient_named_address = NamedAddr::User(2);
let recipient = test_setup.named_address(recipient_named_address)?;
let recipient_balance_before = test_setup.balance(recipient_named_address)?;
test_setup.begin_bundle_order(target_block);
test_setup.add_dummy_tx_0_1_no_rev()?;
let profit_tx_hash = test_setup.add_send_to_coinbase_tx(NamedAddr::User(1), profit)?;
test_setup.set_bundle_refund(BundleRefund {
percent,
recipient,
tx_hashes: vec![profit_tx_hash],
});
let result = test_setup.commit_order_ok();
let recipient_balance_after = test_setup.balance(recipient_named_address)?;
let expected_refund = refundable_value - BASE_TX_GAS;
assert_eq!(
recipient_balance_after - recipient_balance_before,
expected_refund as i128
);
assert_eq!(
result.paid_kickbacks,
vec![(recipient, U256::from(expected_refund))]
);
Ok(())
}

#[test]
fn test_mev_share_ok_refunds() -> eyre::Result<()> {
let target_block = 11;
Expand Down Expand Up @@ -473,7 +505,16 @@ fn test_mev_share_failed_refunds() -> eyre::Result<()> {
body_idx: 0,
percent: 90,
}]);
test_setup.commit_order_err_check_text("Not enough refund for gas");
test_setup.commit_order_err_check(|err| {
assert!(matches!(
err,
OrderErr::Bundle(BundleErr::NotEnoughRefundForGas {
to: _,
refundable_value: _,
needed_value: _,
})
))
});

// this bundle tries to go into the builder balance by having really high refund config percent
test_setup.begin_share_bundle_order(11, 11);
Expand All @@ -489,7 +530,7 @@ fn test_mev_share_failed_refunds() -> eyre::Result<()> {
body_idx: 0,
percent: 50,
}]);
test_setup.commit_order_err_check_text("Negative profit");
test_setup.commit_order_err_check(|err| assert!(matches!(err, OrderErr::NegativeProfit(_))));

// this bundle tries to go into the builder balance by having high refund percentage
test_setup.begin_share_bundle_order(11, 11);
Expand All @@ -499,7 +540,7 @@ fn test_mev_share_failed_refunds() -> eyre::Result<()> {
body_idx: 0,
percent: 101,
}]);
test_setup.commit_order_err_check_text("Negative profit");
test_setup.commit_order_err_check(|err| assert!(matches!(err, OrderErr::NegativeProfit(_))));

Ok(())
}
Expand Down
18 changes: 16 additions & 2 deletions crates/rbuilder/src/building/testing/bundle_tests/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::{
BlockState, ExecutionError, ExecutionResult, OrderErr, PartialBlock,
},
primitives::{
order_builder::OrderBuilder, BundleReplacementData, OrderId, Refund, RefundConfig,
SimulatedOrder, TransactionSignedEcRecoveredWithBlobs, TxRevertBehavior,
order_builder::OrderBuilder, BundleRefund, BundleReplacementData, OrderId, Refund,
RefundConfig, SimulatedOrder, TransactionSignedEcRecoveredWithBlobs, TxRevertBehavior,
},
};
use alloy_primitives::{Address, TxHash};
Expand Down Expand Up @@ -87,6 +87,10 @@ impl TestSetup {
self.order_builder.set_inner_bundle_refund(refund)
}

pub fn set_bundle_refund(&mut self, refund: BundleRefund) {
self.order_builder.set_bundle_refund(refund)
}

pub fn set_inner_bundle_refund_config(&mut self, refund_config: Vec<RefundConfig>) {
self.order_builder
.set_inner_bundle_refund_config(refund_config)
Expand Down Expand Up @@ -275,6 +279,16 @@ impl TestSetup {
Ok(block_state.nonce(self.test_chain.named_address(named_addr)?)?)
}

pub fn balance(&self, named_addr: NamedAddr) -> eyre::Result<i128> {
let state_provider = self.test_chain.provider_factory().latest()?;
let mut block_state = BlockState::new(state_provider)
.with_bundle_state(self.bundle_state.clone().unwrap_or_default())
.with_cached_reads(self.cached_reads.clone().unwrap_or_default());
Ok(block_state
.balance(self.test_chain.named_address(named_addr)?)?
.to())
}

pub fn nonce(&self, named_addr: NamedAddr, nonce_value: NonceValue) -> eyre::Result<u64> {
match nonce_value {
NonceValue::Fixed(v) => Ok(v),
Expand Down
2 changes: 2 additions & 0 deletions crates/rbuilder/src/primitives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ pub struct BundleRefund {
/// Address where to refund to.
pub recipient: Address,
/// A list of transaction hashes to refund.
/// This means that part (percent%) of the profit from the execution these txs goes to refund.recipient
pub tx_hashes: Vec<TxHash>,
}

Expand Down Expand Up @@ -165,6 +166,7 @@ impl Bundle {
}

/// Returns `true` if the provided transaction hash is refundable.
/// This means that part the profit from this execution goes to the self.refund.recipient
pub fn is_tx_refundable(&self, hash: &B256) -> bool {
self.refund
.as_ref()
Expand Down
23 changes: 19 additions & 4 deletions crates/rbuilder/src/primitives/order_builder.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::mem;

use super::{
Bundle, BundleReplacementData, MempoolTx, Order, OrderId, Refund, RefundConfig, ShareBundle,
ShareBundleBody, ShareBundleInner, ShareBundleTx, TransactionSignedEcRecoveredWithBlobs,
TxRevertBehavior,
Bundle, BundleRefund, BundleReplacementData, MempoolTx, Order, OrderId, Refund, RefundConfig,
ShareBundle, ShareBundleBody, ShareBundleInner, ShareBundleTx,
TransactionSignedEcRecoveredWithBlobs, TxRevertBehavior,
};

/// Helper object to build Orders for testing.
Expand Down Expand Up @@ -124,6 +124,15 @@ impl OrderBuilder {
}
}

pub fn set_bundle_refund(&mut self, refund: BundleRefund) {
match self {
OrderBuilder::Bundle(builder) => {
builder.set_bundle_refund(refund);
}
_ => panic!("Only Bundle can have BundleRefund"),
}
}

pub fn set_inner_bundle_refund_config(&mut self, refund_config: Vec<RefundConfig>) {
match self {
OrderBuilder::ShareBundle(builder) => {
Expand All @@ -150,6 +159,7 @@ pub struct BundleBuilder {
min_timestamp: Option<u64>,
max_timestamp: Option<u64>,
replacement_data: Option<BundleReplacementData>,
refund: Option<BundleRefund>,
}

impl BundleBuilder {
Expand All @@ -160,6 +170,7 @@ impl BundleBuilder {
min_timestamp: None,
max_timestamp: None,
replacement_data: None,
refund: None,
}
}

Expand All @@ -172,6 +183,10 @@ impl BundleBuilder {
self.replacement_data = Some(data);
}

fn set_bundle_refund(&mut self, refund: BundleRefund) {
self.refund = Some(refund);
}

fn build(self) -> Bundle {
let mut reverting_tx_hashes = Vec::new();
let mut dropping_tx_hashes = Vec::new();
Expand Down Expand Up @@ -200,7 +215,7 @@ impl BundleBuilder {
signer: None,
metadata: Default::default(),
dropping_tx_hashes,
refund: None,
refund: self.refund,
};
bundle.hash_slow();
bundle
Expand Down

0 comments on commit 1217bdd

Please sign in to comment.