feat: using Transfer and other various fixes

This commit is contained in:
0xMochan
2024-05-23 17:43:46 -04:00
parent 379baebfb7
commit 8c37a74ea6
11 changed files with 9288 additions and 246 deletions

View File

@@ -1,7 +1,4 @@
use substreams::{
scalar::BigInt,
store::{StoreGet, StoreGetInt64, StoreGetString},
};
use substreams::store::{StoreGet, StoreGetString};
use substreams_ethereum::{block_view::LogView, Event};
use tycho_substreams::prelude::*;
@@ -16,219 +13,42 @@ fn tx_from_log(log: &LogView) -> Transaction {
}
}
/// This function emits balance deltas for mints, burns, and exchanges in Curve pools. Since some
/// pools contain differing ABIs, we load in several examples of abis in order to best match the
/// topic ID to the correct event. The repetition in this function is dervived from the fact that
/// most of these events have similar structures, but the specific topic id differs.
pub fn emit_deltas(log: LogView, tokens_store: &StoreGetString) -> Option<Vec<BalanceDelta>> {
let pool_key = format!("pool:{}", hex::encode(&log.address()));
let tokens = tokens_store
.get_last(pool_key)?
.split(":")
.map(|token| token.to_owned())
.collect::<Vec<_>>();
fn get_pool_tokens(pool_address: &Vec<u8>, tokens_store: &StoreGetString) -> Option<Vec<String>> {
let pool_key = format!("pool:{}", hex::encode(&pool_address));
Some(
tokens_store
.get_last(pool_key)?
.split(":")
.map(|token| token.to_owned())
.collect::<Vec<_>>(),
)
}
if let Some(event) = abi::pool::events::TokenExchange::match_and_decode(log) {
token_change_deltas(tokens, event, log)
} else if let Some(event) = abi::pool_3pool::events::TokenExchange::match_and_decode(log) {
token_change_deltas(
tokens,
abi::pool::events::TokenExchange {
sold_id: event.sold_id,
bought_id: event.bought_id,
tokens_sold: event.tokens_sold,
tokens_bought: event.tokens_bought,
buyer: event.buyer,
},
log,
)
} else if let Some(event) = abi::pool_steth::events::TokenExchange::match_and_decode(log) {
token_change_deltas(
tokens,
abi::pool::events::TokenExchange {
sold_id: event.sold_id,
bought_id: event.bought_id,
tokens_sold: event.tokens_sold,
tokens_bought: event.tokens_bought,
buyer: event.buyer,
},
log,
)
} else if let Some(event) = abi::pool_tricrypto::events::TokenExchange::match_and_decode(log) {
token_change_deltas(
tokens,
abi::pool::events::TokenExchange {
sold_id: event.sold_id,
bought_id: event.bought_id,
tokens_sold: event.tokens_sold,
tokens_bought: event.tokens_bought,
buyer: event.buyer,
},
log,
)
} else if let Some(event) = abi::pool_tricrypto2::events::TokenExchange::match_and_decode(log) {
token_change_deltas(
tokens,
abi::pool::events::TokenExchange {
sold_id: event.sold_id,
bought_id: event.bought_id,
tokens_sold: event.tokens_sold,
tokens_bought: event.tokens_bought,
buyer: event.buyer,
},
log,
)
} else if let Some(event) =
abi::pool_crypto_swap_ng::events::TokenExchange::match_and_decode(log)
{
token_change_deltas(
tokens,
abi::pool::events::TokenExchange {
sold_id: event.sold_id,
bought_id: event.bought_id,
tokens_sold: event.tokens_sold,
tokens_bought: event.tokens_bought,
buyer: event.buyer,
},
log,
)
} else if let Some(event) =
abi::pool_crypto_swap_ng::events::TokenExchangeUnderlying::match_and_decode(log)
{
token_change_deltas(
tokens,
abi::pool::events::TokenExchange {
sold_id: event.sold_id,
bought_id: event.bought_id,
tokens_sold: event.tokens_sold,
tokens_bought: event.tokens_bought,
buyer: event.buyer,
},
log,
)
} else if let Some(event) = abi::pool::events::AddLiquidity::match_and_decode(log) {
add_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) = abi::pool_3pool::events::AddLiquidity::match_and_decode(log) {
add_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) = abi::pool_steth::events::AddLiquidity::match_and_decode(log) {
add_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) = abi::pool_tricrypto::events::AddLiquidity::match_and_decode(log) {
add_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) = abi::pool_tricrypto2::events::AddLiquidity::match_and_decode(log) {
add_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) =
abi::pool_crypto_swap_ng::events::AddLiquidity::match_and_decode(log)
{
add_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) = abi::pool::events::RemoveLiquidity::match_and_decode(log) {
remove_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) = abi::pool_3pool::events::RemoveLiquidity::match_and_decode(log) {
remove_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) = abi::pool_steth::events::RemoveLiquidity::match_and_decode(log) {
remove_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) = abi::pool_tricrypto::events::RemoveLiquidity::match_and_decode(log)
{
remove_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) = abi::pool_tricrypto2::events::RemoveLiquidity::match_and_decode(log)
{
remove_liquidity_deltas(event.token_amounts.into(), &tokens, log)
} else if let Some(event) =
abi::pool_crypto_swap_ng::events::RemoveLiquidity::match_and_decode(log)
{
remove_liquidity_deltas(event.token_amounts.into(), &tokens, log)
// } else if let Some(event) =
// abi::pool_crypto_swap_ng::events::RemoveLiquidityImbalance::match_and_decode(log)
// {
// remove_liquidity_deltas(event.token_amounts.into(), &tokens, log)
// } else if let Some(event) =
// abi::pool_crypto_swap_ng::events::RemoveLiquidityOne::match_and_decode(log)
// {
// Some(vec![
// BalanceDelta {
// ord: log.log.ordinal,
// tx: Some(tx_from_log(&log)),
// token: hex::decode(sold_token_id.clone()).unwrap(),
// delta: event.tokens_sold.to_signed_bytes_be(),
// component_id: hex::encode(log.address()).into(),
// },
// BalanceDelta {
// ord: log.log.ordinal,
// tx: Some(tx_from_log(&log)),
// token: hex::decode(sold_token_id.clone()).unwrap(),
// delta: event.tokens_sold.to_signed_bytes_be(),
// component_id: hex::encode(log.address()).into(),
// },
// ])
/// TODO rewrite
pub fn emit_deltas(log: LogView, tokens_store: &StoreGetString) -> Option<BalanceDelta> {
let transfer = abi::ERC20::events::Transfer::match_and_decode(log)?;
let (component_id, pool_tokens, is_incoming) =
if let Some(pool_tokens) = get_pool_tokens(&transfer.to, tokens_store) {
(hex::encode(&transfer.to), pool_tokens, true)
} else if let Some(pool_tokens) = get_pool_tokens(&transfer.from, tokens_store) {
(hex::encode(&transfer.from), pool_tokens, false)
} else {
return None;
};
let token_id = hex::encode(log.address());
if pool_tokens.contains(&token_id) {
let delta = if is_incoming { transfer.value } else { transfer.value * -1 };
Some(BalanceDelta {
ord: log.log.ordinal,
tx: Some(tx_from_log(&log)),
token: hex::decode(token_id).unwrap(),
delta: delta.to_signed_bytes_be(),
component_id: component_id.into(),
})
} else {
substreams::log::info!("Token {:?} not in pool: {:?}", token_id, &component_id);
None
}
}
fn token_change_deltas(
tokens: Vec<String>,
event: abi::pool::events::TokenExchange,
log: LogView<'_>,
) -> Option<Vec<BalanceDelta>> {
let tokens_bought_delta: BigInt = event.tokens_bought * -1;
let sold_token_id = &tokens[event.sold_id.to_u64() as usize];
let bought_token_id = &tokens[event.bought_id.to_u64() as usize];
Some(vec![
BalanceDelta {
ord: log.log.ordinal,
tx: Some(tx_from_log(&log)),
token: hex::decode(sold_token_id.clone()).unwrap(),
delta: event.tokens_sold.to_signed_bytes_be(),
component_id: hex::encode(log.address()).into(),
},
BalanceDelta {
ord: log.log.ordinal,
tx: Some(tx_from_log(&log)),
token: hex::decode(bought_token_id.clone()).unwrap(),
delta: tokens_bought_delta.to_signed_bytes_be(),
component_id: hex::encode(log.address()).into(),
},
])
}
fn add_liquidity_deltas(
amounts: Vec<BigInt>,
tokens: &Vec<String>,
log: LogView<'_>,
) -> Option<Vec<BalanceDelta>> {
Some(
amounts
.iter()
.zip(tokens)
.map(move |(token_amount, token_id)| BalanceDelta {
ord: log.log.ordinal,
tx: Some(tx_from_log(&log)),
token: hex::decode(token_id).unwrap(),
delta: token_amount.to_signed_bytes_be(),
component_id: hex::encode(log.address()).into(),
})
.collect::<Vec<_>>(),
)
}
fn remove_liquidity_deltas(
amounts: Vec<BigInt>,
tokens: &Vec<String>,
log: LogView<'_>,
) -> Option<Vec<BalanceDelta>> {
Some(
amounts
.iter()
.zip(tokens)
.map(move |(token_amount, token_id)| {
let token_amount_neg: BigInt = token_amount.clone() * -1;
BalanceDelta {
ord: log.log.ordinal,
tx: Some(tx_from_log(&log)),
token: hex::decode(token_id).unwrap(),
delta: token_amount_neg.to_signed_bytes_be(),
component_id: hex::encode(log.address()).into(),
}
})
.collect::<Vec<_>>(),
)
}