Skip to content

Commit

Permalink
Fix/liquidations (#720)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Will-Smith11 authored Jun 28, 2024
1 parent ba4c82b commit 000f607
Show file tree
Hide file tree
Showing 15 changed files with 149 additions and 117 deletions.
2 changes: 1 addition & 1 deletion crates/brontes-classifier/src/classifiers/aave/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ action_impl!(
return Ok(NormalizedLiquidation {
protocol: Protocol::AaveV2,
trace_index: info.trace_idx,
pool: info.target_address,
pool: info.from_address,
liquidator: info.msg_sender,
debtor: call_data.user,
collateral_asset: collateral_info,
Expand Down
4 changes: 2 additions & 2 deletions crates/brontes-classifier/src/classifiers/aave/v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ action_impl!(
return Ok(NormalizedLiquidation {
protocol: Protocol::AaveV3,
trace_index: info.trace_idx,
pool: info.target_address,
pool: info.from_address,
liquidator: info.msg_sender,
debtor: call_data.user,
collateral_asset: collateral_info,
Expand Down Expand Up @@ -140,7 +140,7 @@ mod tests {
collateral_asset: classifier_utils
.get_token_info(Address::from(hex!("2260fac5e5542a773aa44fbcfedf7c193bc2c599"))),
liquidator: Address::from(hex!("80d4230c0a68fc59cb264329d3a717fcaa472a13")),
pool: Address::from(hex!("5faab9e1adbddad0a08734be8a52185fd6558e14")),
pool: Address::from(hex!("87870bca3f3fd6335c3f4ce8392d69350b4fa4e2")),
trace_index: 6,
msg_value: U256::ZERO,
});
Expand Down
1 change: 1 addition & 0 deletions crates/brontes-classifier/src/classifiers/erc20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub async fn try_decode_transfer<T: TracingProvider, DB: LibmdbxReader + DBWrite
to: to_addr,
from: from_addr,
trace_index: idx,
msg_value: value,
fee: Rational::ZERO,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ mod tests {
// Ignore child actions as we only need to focus on pruning necessary nodes.
child_actions: vec![],
repayments: vec![NormalizedTransfer {
msg_value: U256::ZERO,
trace_index: 238,
from: Address::new(hex!("1aecea38b8626eeb3748234343cff427268dd487")),
to: Address::new(hex!("60744434d6339a6b27d73d9eda62b6f66a0a04fa")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ mod tests {
child_actions: vec![
Action::Transfer(NormalizedTransfer {
trace_index: 1,
msg_value: U256::ZERO,
from: Address::new(hex!("f4f8845cede63e79de1b2c3bba395e8547fe4283")),
to: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
token: TokenInfoWithAddress::usdc(),
Expand All @@ -245,6 +246,7 @@ mod tests {
}),
Action::Transfer(NormalizedTransfer {
trace_index: 5,
msg_value: U256::ZERO,
from: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
to: Address::new(hex!("beec796a4a2a27b687e1d48efad3805d78800522")),
token: TokenInfoWithAddress::usdc(),
Expand All @@ -269,6 +271,7 @@ mod tests {
}),
Action::Transfer(NormalizedTransfer {
trace_index: 12,
msg_value: U256::ZERO,
from: Address::new(hex!("3416cf6c708da44db2624d63ea0aaef7113527c6")),
to: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
token: TokenInfoWithAddress::usdt(),
Expand All @@ -279,6 +282,7 @@ mod tests {
}),
Action::Transfer(NormalizedTransfer {
trace_index: 16,
msg_value: U256::ZERO,
from: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
to: Address::new(hex!("3416cf6c708da44db2624d63ea0aaef7113527c6")),
token: TokenInfoWithAddress::usdc(),
Expand All @@ -289,6 +293,7 @@ mod tests {
}),
Action::Transfer(NormalizedTransfer {
trace_index: 21,
msg_value: U256::ZERO,
from: Address::new(hex!("e37e799d5077682fa0a244d46e5649f71457bd09")),
to: Address::new(hex!("1111111254eeb25477b68fb85ed929f73a960582")),
token: TokenInfoWithAddress::usdt(),
Expand All @@ -299,6 +304,7 @@ mod tests {
}),
Action::Transfer(NormalizedTransfer {
trace_index: 23,
msg_value: U256::ZERO,
from: Address::new(hex!("1111111254eeb25477b68fb85ed929f73a960582")),
to: Address::new(hex!("f4f8845cede63e79de1b2c3bba395e8547fe4283")),
token: TokenInfoWithAddress::usdt(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ mod tests {
child_actions: vec![
Action::Transfer(NormalizedTransfer {
trace_index: 5,
msg_value: U256::ZERO,
from: Address::new(hex!("d10f17699137dd6215c01f539726227fc042c9b2")),
to: Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
token: TokenInfoWithAddress::usdc(),
Expand All @@ -59,6 +60,7 @@ mod tests {
}),
Action::Transfer(NormalizedTransfer {
trace_index: 9,
msg_value: U256::ZERO,
from: Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
to: Address::new(hex!("655edce464cc797526600a462a8154650eee4b77")),
token: TokenInfoWithAddress::usdc(),
Expand All @@ -84,6 +86,7 @@ mod tests {
token: TokenInfoWithAddress::usdt(),
amount: U256::from_str("269716012").unwrap().to_scaled_rational(6),
fee: U256::from_str("0").unwrap().to_scaled_rational(1),
msg_value: U256::ZERO,
}),
Action::Transfer(NormalizedTransfer {
trace_index: 16,
Expand All @@ -92,6 +95,7 @@ mod tests {
token: TokenInfoWithAddress::usdt(),
amount: U256::from_str("216122672").unwrap().to_scaled_rational(6),
fee: U256::from_str("0").unwrap().to_scaled_rational(1),
msg_value: U256::ZERO,
}),
Action::Transfer(NormalizedTransfer {
trace_index: 18,
Expand All @@ -100,6 +104,7 @@ mod tests {
token: TokenInfoWithAddress::usdt(),
amount: U256::from_str("216122672").unwrap().to_scaled_rational(6),
fee: U256::from_str("0").unwrap().to_scaled_rational(1),
msg_value: U256::ZERO,
}),
],

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,13 @@ fn parse_v2_v3(this: &mut Action, child_nodes: Vec<(NodeDataIndex, Action)>) ->
let this = this.try_liquidation_mut().unwrap();
child_nodes
.into_iter()
.find_map(|(index, action)| {
.find_map(|(_, action)| {
if let Action::Transfer(transfer) = action {
// because aave has the option to return the Atoken or regular,
// we can't filter by collateral filter. This might be an issue...
// tbd tho
if transfer.to == this.liquidator {
this.liquidated_collateral = transfer.amount;
return Some(index)
}
}

Expand Down
45 changes: 29 additions & 16 deletions crates/brontes-classifier/src/tree_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,12 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
.await
}
TraceAction::Selfdestruct(sd) => {
(vec![], Action::SelfDestruct(SelfdestructWithIndex::new(trace_index, *sd)))
(vec![], vec![Action::SelfDestruct(SelfdestructWithIndex::new(trace_index, *sd))])
}
TraceAction::Reward(_) => (vec![], Action::Unclassified(trace.clone())),
TraceAction::Reward(_) => (vec![], vec![Action::Unclassified(trace.clone())]),
};

(pricing, vec![base_action])
(pricing, base_action)
}

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

Expand Down Expand Up @@ -407,7 +407,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
}
}

(vec![results.0], results.1)
(vec![results.0], vec![results.1])
} else if let Some(transfer) = self
.classify_transfer(tx_idx, trace_index, &trace, block)
.await
Expand All @@ -416,8 +416,9 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
} else {
return (
vec![],
self.classify_eth_transfer(&trace, trace_index)
.unwrap_or(Action::Unclassified(trace)),
vec![self
.classify_eth_transfer(&trace, trace_index)
.unwrap_or(Action::Unclassified(trace))],
)
}
}
Expand All @@ -428,7 +429,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
trace_idx: u64,
trace: &TransactionTraceWithLogs,
block: u64,
) -> Option<(Vec<DexPriceMsg>, Action)> {
) -> Option<(Vec<DexPriceMsg>, Vec<Action>)> {
if trace.is_delegate_call() {
return None
};
Expand Down Expand Up @@ -470,6 +471,17 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
}
}

let mut result = vec![Action::Transfer(transfer.clone())];
if trace.get_msg_value() != U256::ZERO {
result.push(Action::EthTransfer(NormalizedEthTransfer {
coinbase_transfer: false,
trace_index: trace_idx,
to: trace.get_to_address(),
from: trace.get_from_addr(),
value: trace.get_msg_value(),
}));
}

// Return the adjusted transfer as an action
Some((
vec![DexPriceMsg::Update(brontes_pricing::types::PoolUpdate {
Expand All @@ -478,7 +490,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
logs: vec![],
action: Action::Transfer(transfer.clone()),
})],
Action::Transfer(transfer),
result,
))
}
Err(_) => {
Expand All @@ -497,6 +509,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
from,
fee: Rational::ZERO,
trace_index: trace_idx,
msg_value: trace.get_msg_value(),
};

return Some((
Expand All @@ -506,7 +519,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
logs: vec![],
action: Action::Transfer(transfer.clone()),
})],
Action::Transfer(transfer),
vec![Action::Transfer(transfer)],
))
}
}
Expand Down Expand Up @@ -539,27 +552,27 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
tx_idx: u64,
trace: TransactionTraceWithLogs,
trace_index: u64,
) -> (Vec<DexPriceMsg>, Action) {
) -> (Vec<DexPriceMsg>, Vec<Action>) {
let from_address = trace.get_from_addr();
let created_addr = trace.get_create_output();

// get the immediate parent node of this create action so that we can decode the
// deployment function params
let node_data = match root_head {
Some(head) => head.get_immediate_parent_node(trace_index - 1),
None => return (vec![], Action::Unclassified(trace)),
None => return (vec![], vec![Action::Unclassified(trace)]),
};
let Some(node_data) = node_data else {
debug!(block, tx_idx, "failed to find create parent node");
return (vec![], Action::Unclassified(trace));
return (vec![], vec![Action::Unclassified(trace)]);
};

let Some(calldata) = node_data_store
.get_ref(node_data.data)
.and_then(|node| node.first())
.and_then(|res| res.get_calldata())
else {
return (vec![], Action::Unclassified(trace));
return (vec![], vec![Action::Unclassified(trace)]);
};

(
Expand All @@ -586,7 +599,7 @@ impl<'db, T: TracingProvider, DB: LibmdbxReader + DBWriter> Classifier<'db, T, D
.flatten()
.map(DexPriceMsg::DiscoveredPool)
.collect_vec(),
Action::Unclassified(trace),
vec![Action::Unclassified(trace)],
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ CREATE TABLE mev.searcher_tx ON CLUSTER eth_cluster0
`pool` String,
`token` Tuple(String, String),
`amount` Tuple(UInt256, UInt256),
`fee` Tuple(UInt256, UInt256)
`fee` Tuple(UInt256, UInt256),
`msg_value` UInt256
),
`gas_details` Tuple(Nullable(UInt128), UInt128, UInt128, UInt128),
`last_updated` UInt64 DEFAULT now()
Expand Down
64 changes: 32 additions & 32 deletions crates/brontes-inspect/src/mev_inspectors/liquidations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,40 +38,35 @@ impl<DB: LibmdbxReader> Inspector for LiquidationInspector<'_, DB> {
}

fn inspect_block(&self, tree: Arc<BlockTree<Action>>, metadata: Arc<Metadata>) -> Self::Result {
let ex = || {
let (tx, liq): (Vec<_>, Vec<_>) = tree
.clone()
.collect_all(TreeSearchBuilder::default().with_actions([
Action::is_swap,
Action::is_liquidation,
Action::is_transfer,
Action::is_eth_transfer,
Action::is_aggregator,
]))
.unzip();
let tx_info = tree.get_tx_info_batch(&tx, self.utils.db);

multizip((liq, tx_info))
.filter_map(|(liq, info)| {
let info = info?;
let actions = self
.utils
.flatten_nested_actions_default(liq.into_iter())
.collect::<Vec<_>>();

self.calculate_liquidation(info, metadata.clone(), actions)
})
.collect::<Vec<_>>()
};
self.utils
.get_metrics()
.map(|m| {
m.run_inspector(MevType::Liquidation, || {
let (tx, liq): (Vec<_>, Vec<_>) = tree
.clone()
.collect_all(
TreeSearchBuilder::default()
.with_actions([Action::is_swap, Action::is_liquidation]),
)
.unzip();
let tx_info = tree.get_tx_info_batch(&tx, self.utils.db);

multizip((liq, tx_info))
.filter_map(|(liq, info)| {
let info = info?;
self.calculate_liquidation(info, metadata.clone(), liq)
})
.collect::<Vec<_>>()
})
})
.unwrap_or_else(|| {
tree.clone()
.collect_all(
TreeSearchBuilder::default()
.with_actions([Action::is_swap, Action::is_liquidation]),
)
.filter_map(|(tx_hash, liq)| {
let info = tree.get_tx_info(tx_hash, self.utils.db)?;

self.calculate_liquidation(info, metadata.clone(), liq)
})
.collect::<Vec<_>>()
})
.map(|m| m.run_inspector(MevType::Liquidation, ex))
.unwrap_or_else(ex)
}
}

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

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

Some(Bundle { header, data: BundleData::Liquidation(new_liquidation) })
}
Expand Down
Loading

0 comments on commit 000f607

Please sign in to comment.