Skip to content

Commit 000f607

Browse files
authored
Fix/liquidations (#720)
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * try * wip * wip * wip * wip * try * wip * fixo * wip * wip * wip * fixo * fix * wip * wip * wip * wip * iwp * wip * wip * wip * iwp * fixo * fixo * fix: ignore delegate eth transfers * remove log * wip * wip * wip * wip * wip * fix * confirm * testing * wip * wip * fixo * fixo * wip * wip * wip * undo * wtf * fixo * wip * clippy * wip * wip * wip * wip * wip * wip * wip * finally
1 parent ba4c82b commit 000f607

File tree

15 files changed

+149
-117
lines changed

15 files changed

+149
-117
lines changed

crates/brontes-classifier/src/classifiers/aave/v2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ action_impl!(
2525
return Ok(NormalizedLiquidation {
2626
protocol: Protocol::AaveV2,
2727
trace_index: info.trace_idx,
28-
pool: info.target_address,
28+
pool: info.from_address,
2929
liquidator: info.msg_sender,
3030
debtor: call_data.user,
3131
collateral_asset: collateral_info,

crates/brontes-classifier/src/classifiers/aave/v3.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ action_impl!(
2626
return Ok(NormalizedLiquidation {
2727
protocol: Protocol::AaveV3,
2828
trace_index: info.trace_idx,
29-
pool: info.target_address,
29+
pool: info.from_address,
3030
liquidator: info.msg_sender,
3131
debtor: call_data.user,
3232
collateral_asset: collateral_info,
@@ -140,7 +140,7 @@ mod tests {
140140
collateral_asset: classifier_utils
141141
.get_token_info(Address::from(hex!("2260fac5e5542a773aa44fbcfedf7c193bc2c599"))),
142142
liquidator: Address::from(hex!("80d4230c0a68fc59cb264329d3a717fcaa472a13")),
143-
pool: Address::from(hex!("5faab9e1adbddad0a08734be8a52185fd6558e14")),
143+
pool: Address::from(hex!("87870bca3f3fd6335c3f4ce8392d69350b4fa4e2")),
144144
trace_index: 6,
145145
msg_value: U256::ZERO,
146146
});

crates/brontes-classifier/src/classifiers/erc20.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub async fn try_decode_transfer<T: TracingProvider, DB: LibmdbxReader + DBWrite
5858
to: to_addr,
5959
from: from_addr,
6060
trace_index: idx,
61+
msg_value: value,
6162
fee: Rational::ZERO,
6263
})
6364
}

crates/brontes-classifier/src/classifiers/maker/dss_flash.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ mod tests {
7676
// Ignore child actions as we only need to focus on pruning necessary nodes.
7777
child_actions: vec![],
7878
repayments: vec![NormalizedTransfer {
79+
msg_value: U256::ZERO,
7980
trace_index: 238,
8081
from: Address::new(hex!("1aecea38b8626eeb3748234343cff427268dd487")),
8182
to: Address::new(hex!("60744434d6339a6b27d73d9eda62b6f66a0a04fa")),

crates/brontes-classifier/src/classifiers/oneinch/one_inch_aggregation_router_v5.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ mod tests {
235235
child_actions: vec![
236236
Action::Transfer(NormalizedTransfer {
237237
trace_index: 1,
238+
msg_value: U256::ZERO,
238239
from: Address::new(hex!("f4f8845cede63e79de1b2c3bba395e8547fe4283")),
239240
to: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
240241
token: TokenInfoWithAddress::usdc(),
@@ -245,6 +246,7 @@ mod tests {
245246
}),
246247
Action::Transfer(NormalizedTransfer {
247248
trace_index: 5,
249+
msg_value: U256::ZERO,
248250
from: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
249251
to: Address::new(hex!("beec796a4a2a27b687e1d48efad3805d78800522")),
250252
token: TokenInfoWithAddress::usdc(),
@@ -269,6 +271,7 @@ mod tests {
269271
}),
270272
Action::Transfer(NormalizedTransfer {
271273
trace_index: 12,
274+
msg_value: U256::ZERO,
272275
from: Address::new(hex!("3416cf6c708da44db2624d63ea0aaef7113527c6")),
273276
to: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
274277
token: TokenInfoWithAddress::usdt(),
@@ -279,6 +282,7 @@ mod tests {
279282
}),
280283
Action::Transfer(NormalizedTransfer {
281284
trace_index: 16,
285+
msg_value: U256::ZERO,
282286
from: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
283287
to: Address::new(hex!("3416cf6c708da44db2624d63ea0aaef7113527c6")),
284288
token: TokenInfoWithAddress::usdc(),
@@ -289,6 +293,7 @@ mod tests {
289293
}),
290294
Action::Transfer(NormalizedTransfer {
291295
trace_index: 21,
296+
msg_value: U256::ZERO,
292297
from: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
293298
to: Address::new(hex!("1111111254eeb25477b68fb85ed929f73a960582")),
294299
token: TokenInfoWithAddress::usdt(),
@@ -299,6 +304,7 @@ mod tests {
299304
}),
300305
Action::Transfer(NormalizedTransfer {
301306
trace_index: 23,
307+
msg_value: U256::ZERO,
302308
from: Address::new(hex!("1111111254eeb25477b68fb85ed929f73a960582")),
303309
to: Address::new(hex!("f4f8845cede63e79de1b2c3bba395e8547fe4283")),
304310
token: TokenInfoWithAddress::usdt(),

crates/brontes-classifier/src/classifiers/oneinch/one_inch_fusion.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ mod tests {
5151
child_actions: vec![
5252
Action::Transfer(NormalizedTransfer {
5353
trace_index: 5,
54+
msg_value: U256::ZERO,
5455
from: Address::new(hex!("d10f17699137dd6215c01f539726227fc042c9b2")),
5556
to: Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
5657
token: TokenInfoWithAddress::usdc(),
@@ -59,6 +60,7 @@ mod tests {
5960
}),
6061
Action::Transfer(NormalizedTransfer {
6162
trace_index: 9,
63+
msg_value: U256::ZERO,
6264
from: Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
6365
to: Address::new(hex!("655edce464cc797526600a462a8154650eee4b77")),
6466
token: TokenInfoWithAddress::usdc(),
@@ -84,6 +86,7 @@ mod tests {
8486
token: TokenInfoWithAddress::usdt(),
8587
amount: U256::from_str("269716012").unwrap().to_scaled_rational(6),
8688
fee: U256::from_str("0").unwrap().to_scaled_rational(1),
89+
msg_value: U256::ZERO,
8790
}),
8891
Action::Transfer(NormalizedTransfer {
8992
trace_index: 16,
@@ -92,6 +95,7 @@ mod tests {
9295
token: TokenInfoWithAddress::usdt(),
9396
amount: U256::from_str("216122672").unwrap().to_scaled_rational(6),
9497
fee: U256::from_str("0").unwrap().to_scaled_rational(1),
98+
msg_value: U256::ZERO,
9599
}),
96100
Action::Transfer(NormalizedTransfer {
97101
trace_index: 18,
@@ -100,6 +104,7 @@ mod tests {
100104
token: TokenInfoWithAddress::usdt(),
101105
amount: U256::from_str("216122672").unwrap().to_scaled_rational(6),
102106
fee: U256::from_str("0").unwrap().to_scaled_rational(1),
107+
msg_value: U256::ZERO,
103108
}),
104109
],
105110

crates/brontes-classifier/src/multi_frame_classification/liquidations/aave.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,13 @@ fn parse_v2_v3(this: &mut Action, child_nodes: Vec<(NodeDataIndex, Action)>) ->
4242
let this = this.try_liquidation_mut().unwrap();
4343
child_nodes
4444
.into_iter()
45-
.find_map(|(index, action)| {
45+
.find_map(|(_, action)| {
4646
if let Action::Transfer(transfer) = action {
4747
// because aave has the option to return the Atoken or regular,
4848
// we can't filter by collateral filter. This might be an issue...
4949
// tbd tho
5050
if transfer.to == this.liquidator {
5151
this.liquidated_collateral = transfer.amount;
52-
return Some(index)
5352
}
5453
}
5554

crates/brontes-classifier/src/tree_builder/mod.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,12 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
350350
.await
351351
}
352352
TraceAction::Selfdestruct(sd) => {
353-
(vec![], Action::SelfDestruct(SelfdestructWithIndex::new(trace_index, *sd)))
353+
(vec![], vec![Action::SelfDestruct(SelfdestructWithIndex::new(trace_index, *sd))])
354354
}
355-
TraceAction::Reward(_) => (vec![], Action::Unclassified(trace.clone())),
355+
TraceAction::Reward(_) => (vec![], vec![Action::Unclassified(trace.clone())]),
356356
};
357357

358-
(pricing, vec![base_action])
358+
(pricing, base_action)
359359
}
360360

361361
async fn classify_call(
@@ -365,9 +365,9 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
365365
trace: TransactionTraceWithLogs,
366366
full_trace: &[TransactionTraceWithLogs],
367367
trace_index: u64,
368-
) -> (Vec<DexPriceMsg>, Action) {
368+
) -> (Vec<DexPriceMsg>, Vec<Action>) {
369369
if trace.is_static_call() {
370-
return (vec![], Action::Unclassified(trace))
370+
return (vec![], vec![Action::Unclassified(trace)])
371371
}
372372
let mut call_info = trace.get_callframe_info();
373373

@@ -407,7 +407,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
407407
}
408408
}
409409

410-
(vec![results.0], results.1)
410+
(vec![results.0], vec![results.1])
411411
} else if let Some(transfer) = self
412412
.classify_transfer(tx_idx, trace_index, &trace, block)
413413
.await
@@ -416,8 +416,9 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
416416
} else {
417417
return (
418418
vec![],
419-
self.classify_eth_transfer(&trace, trace_index)
420-
.unwrap_or(Action::Unclassified(trace)),
419+
vec![self
420+
.classify_eth_transfer(&trace, trace_index)
421+
.unwrap_or(Action::Unclassified(trace))],
421422
)
422423
}
423424
}
@@ -428,7 +429,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
428429
trace_idx: u64,
429430
trace: &TransactionTraceWithLogs,
430431
block: u64,
431-
) -> Option<(Vec<DexPriceMsg>, Action)> {
432+
) -> Option<(Vec<DexPriceMsg>, Vec<Action>)> {
432433
if trace.is_delegate_call() {
433434
return None
434435
};
@@ -470,6 +471,17 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
470471
}
471472
}
472473

474+
let mut result = vec![Action::Transfer(transfer.clone())];
475+
if trace.get_msg_value() != U256::ZERO {
476+
result.push(Action::EthTransfer(NormalizedEthTransfer {
477+
coinbase_transfer: false,
478+
trace_index: trace_idx,
479+
to: trace.get_to_address(),
480+
from: trace.get_from_addr(),
481+
value: trace.get_msg_value(),
482+
}));
483+
}
484+
473485
// Return the adjusted transfer as an action
474486
Some((
475487
vec![DexPriceMsg::Update(brontes_pricing::types::PoolUpdate {
@@ -478,7 +490,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
478490
logs: vec![],
479491
action: Action::Transfer(transfer.clone()),
480492
})],
481-
Action::Transfer(transfer),
493+
result,
482494
))
483495
}
484496
Err(_) => {
@@ -497,6 +509,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
497509
from,
498510
fee: Rational::ZERO,
499511
trace_index: trace_idx,
512+
msg_value: trace.get_msg_value(),
500513
};
501514

502515
return Some((
@@ -506,7 +519,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
506519
logs: vec![],
507520
action: Action::Transfer(transfer.clone()),
508521
})],
509-
Action::Transfer(transfer),
522+
vec![Action::Transfer(transfer)],
510523
))
511524
}
512525
}
@@ -539,27 +552,27 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
539552
tx_idx: u64,
540553
trace: TransactionTraceWithLogs,
541554
trace_index: u64,
542-
) -> (Vec<DexPriceMsg>, Action) {
555+
) -> (Vec<DexPriceMsg>, Vec<Action>) {
543556
let from_address = trace.get_from_addr();
544557
let created_addr = trace.get_create_output();
545558

546559
// get the immediate parent node of this create action so that we can decode the
547560
// deployment function params
548561
let node_data = match root_head {
549562
Some(head) => head.get_immediate_parent_node(trace_index - 1),
550-
None => return (vec![], Action::Unclassified(trace)),
563+
None => return (vec![], vec![Action::Unclassified(trace)]),
551564
};
552565
let Some(node_data) = node_data else {
553566
debug!(block, tx_idx, "failed to find create parent node");
554-
return (vec![], Action::Unclassified(trace));
567+
return (vec![], vec![Action::Unclassified(trace)]);
555568
};
556569

557570
let Some(calldata) = node_data_store
558571
.get_ref(node_data.data)
559572
.and_then(|node| node.first())
560573
.and_then(|res| res.get_calldata())
561574
else {
562-
return (vec![], Action::Unclassified(trace));
575+
return (vec![], vec![Action::Unclassified(trace)]);
563576
};
564577

565578
(
@@ -586,7 +599,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
586599
.flatten()
587600
.map(DexPriceMsg::DiscoveredPool)
588601
.collect_vec(),
589-
Action::Unclassified(trace),
602+
vec![Action::Unclassified(trace)],
590603
)
591604
}
592605

crates/brontes-database/brontes-db/src/clickhouse/tables/searcher_tx.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ CREATE TABLE mev.searcher_tx ON CLUSTER eth_cluster0
88
`pool` String,
99
`token` Tuple(String, String),
1010
`amount` Tuple(UInt256, UInt256),
11-
`fee` Tuple(UInt256, UInt256)
11+
`fee` Tuple(UInt256, UInt256),
12+
`msg_value` UInt256
1213
),
1314
`gas_details` Tuple(Nullable(UInt128), UInt128, UInt128, UInt128),
1415
`last_updated` UInt64 DEFAULT now()

crates/brontes-inspect/src/mev_inspectors/liquidations.rs

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,40 +38,35 @@ impl<DB: LibmdbxReader> Inspector for LiquidationInspector<'_, DB> {
3838
}
3939

4040
fn inspect_block(&self, tree: Arc<BlockTree<Action>>, metadata: Arc<Metadata>) -> Self::Result {
41+
let ex = || {
42+
let (tx, liq): (Vec<_>, Vec<_>) = tree
43+
.clone()
44+
.collect_all(TreeSearchBuilder::default().with_actions([
45+
Action::is_swap,
46+
Action::is_liquidation,
47+
Action::is_transfer,
48+
Action::is_eth_transfer,
49+
Action::is_aggregator,
50+
]))
51+
.unzip();
52+
let tx_info = tree.get_tx_info_batch(&tx, self.utils.db);
53+
54+
multizip((liq, tx_info))
55+
.filter_map(|(liq, info)| {
56+
let info = info?;
57+
let actions = self
58+
.utils
59+
.flatten_nested_actions_default(liq.into_iter())
60+
.collect::<Vec<_>>();
61+
62+
self.calculate_liquidation(info, metadata.clone(), actions)
63+
})
64+
.collect::<Vec<_>>()
65+
};
4166
self.utils
4267
.get_metrics()
43-
.map(|m| {
44-
m.run_inspector(MevType::Liquidation, || {
45-
let (tx, liq): (Vec<_>, Vec<_>) = tree
46-
.clone()
47-
.collect_all(
48-
TreeSearchBuilder::default()
49-
.with_actions([Action::is_swap, Action::is_liquidation]),
50-
)
51-
.unzip();
52-
let tx_info = tree.get_tx_info_batch(&tx, self.utils.db);
53-
54-
multizip((liq, tx_info))
55-
.filter_map(|(liq, info)| {
56-
let info = info?;
57-
self.calculate_liquidation(info, metadata.clone(), liq)
58-
})
59-
.collect::<Vec<_>>()
60-
})
61-
})
62-
.unwrap_or_else(|| {
63-
tree.clone()
64-
.collect_all(
65-
TreeSearchBuilder::default()
66-
.with_actions([Action::is_swap, Action::is_liquidation]),
67-
)
68-
.filter_map(|(tx_hash, liq)| {
69-
let info = tree.get_tx_info(tx_hash, self.utils.db)?;
70-
71-
self.calculate_liquidation(info, metadata.clone(), liq)
72-
})
73-
.collect::<Vec<_>>()
74-
})
68+
.map(|m| m.run_inspector(MevType::Liquidation, ex))
69+
.unwrap_or_else(ex)
7570
}
7671
}
7772

@@ -82,6 +77,9 @@ impl<DB: LibmdbxReader> LiquidationInspector<'_, DB> {
8277
metadata: Arc<Metadata>,
8378
actions: Vec<Action>,
8479
) -> Option<Bundle> {
80+
tracing::debug!("trying liquidation\n{actions:#?}");
81+
let total_val = info.get_total_eth_value();
82+
tracing::debug!(other_eth_transfers=?total_val);
8583
let (swaps, liqs): (Vec<_>, Vec<_>) = actions
8684
.clone()
8785
.into_iter()
@@ -97,6 +95,7 @@ impl<DB: LibmdbxReader> LiquidationInspector<'_, DB> {
9795
let deltas = actions
9896
.into_iter()
9997
.chain(info.get_total_eth_value().iter().cloned().map(Action::from))
98+
.filter(|a| a.is_eth_transfer() || a.is_transfer())
10099
.account_for_actions();
101100

102101
let (rev, mut has_dex_price) = if let Some(rev) = self.utils.get_deltas_usd(
@@ -152,6 +151,7 @@ impl<DB: LibmdbxReader> LiquidationInspector<'_, DB> {
152151
liquidations: liqs,
153152
gas_details: info.gas_details,
154153
};
154+
tracing::debug!("{:#?}\n {:#?}", new_liquidation, header);
155155

156156
Some(Bundle { header, data: BundleData::Liquidation(new_liquidation) })
157157
}

0 commit comments

Comments
 (0)