sdk: update to latest sdk
This commit is contained in:
19
substreams/Cargo.lock
generated
19
substreams/Cargo.lock
generated
@@ -227,6 +227,25 @@ dependencies = [
|
|||||||
"tycho-substreams",
|
"tycho-substreams",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ethereum-curve"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bytes",
|
||||||
|
"ethabi 18.0.0",
|
||||||
|
"getrandom",
|
||||||
|
"hex",
|
||||||
|
"hex-literal 0.4.1",
|
||||||
|
"itertools 0.12.1",
|
||||||
|
"num-bigint",
|
||||||
|
"prost 0.11.9",
|
||||||
|
"prost-types 0.12.3",
|
||||||
|
"substreams",
|
||||||
|
"substreams-ethereum",
|
||||||
|
"tycho-substreams",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethereum-types"
|
name = "ethereum-types"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = ["ethereum-balancer", "ethereum-curve", "crates/tycho-substreams"]
|
||||||
"ethereum-balancer",
|
|
||||||
"crates/tycho-substreams",
|
|
||||||
]
|
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
|
||||||
@@ -14,9 +11,9 @@ prost-types = "0.12.3"
|
|||||||
hex-literal = "0.4.1"
|
hex-literal = "0.4.1"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
ethabi = "18.0.0"
|
ethabi = "18.0.0"
|
||||||
tycho-substreams = {path ="crates/tycho-substreams"}
|
tycho-substreams = { path = "crates/tycho-substreams" }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
opt-level = 's'
|
opt-level = 's'
|
||||||
strip = "debuginfo"
|
strip = "debuginfo"
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "substreams-curve"
|
name = "ethereum-curve"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "substreams_curve"
|
name = "ethereum_curve"
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
substreams = "0.5"
|
substreams.workspace = true
|
||||||
substreams-ethereum = "0.9.9"
|
substreams-ethereum.workspace = true
|
||||||
prost = "0.11"
|
prost.workspace = true
|
||||||
hex-literal = "0.4.1"
|
prost-types.workspace = true
|
||||||
ethabi = "18.0.0"
|
hex-literal.workspace = true
|
||||||
hex = "0.4.2"
|
ethabi.workspace = true
|
||||||
|
hex.workspace = true
|
||||||
bytes = "1.5.0"
|
bytes = "1.5.0"
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
prost-types = "0.12.3"
|
|
||||||
num-bigint = "0.4.4"
|
num-bigint = "0.4.4"
|
||||||
itertools = "0.12.0"
|
itertools = "0.12.0"
|
||||||
|
tycho-substreams.workspace = true
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package tycho.evm.v1;
|
|
||||||
|
|
||||||
// This file contains the proto definitions for Substreams common to all integrations.
|
|
||||||
|
|
||||||
// A struct describing a block.
|
|
||||||
message Block {
|
|
||||||
// The blocks hash.
|
|
||||||
bytes hash = 1;
|
|
||||||
// The parent blocks hash.
|
|
||||||
bytes parent_hash = 2;
|
|
||||||
// The block number.
|
|
||||||
uint64 number = 3;
|
|
||||||
// The block timestamp.
|
|
||||||
uint64 ts = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A struct describing a transaction.
|
|
||||||
message Transaction {
|
|
||||||
// The transaction hash.
|
|
||||||
bytes hash = 1;
|
|
||||||
// The sender of the transaction.
|
|
||||||
bytes from = 2;
|
|
||||||
// The receiver of the transaction.
|
|
||||||
bytes to = 3;
|
|
||||||
// The transactions index within the block.
|
|
||||||
// TODO: should this be uint32? to match the type from the native substream type?
|
|
||||||
uint64 index = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enum to specify the type of a change.
|
|
||||||
enum ChangeType {
|
|
||||||
CHANGE_TYPE_UNSPECIFIED = 0;
|
|
||||||
CHANGE_TYPE_UPDATE = 1;
|
|
||||||
CHANGE_TYPE_CREATION = 2;
|
|
||||||
CHANGE_TYPE_DELETION = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A custom struct representing an arbitrary attribute of a protocol component.
|
|
||||||
// This is mainly used by the native integration to track the necessary information about the protocol.
|
|
||||||
message Attribute {
|
|
||||||
// The name of the attribute.
|
|
||||||
string name = 1;
|
|
||||||
// The value of the attribute.
|
|
||||||
bytes value = 2;
|
|
||||||
// The type of change the attribute underwent.
|
|
||||||
ChangeType change = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A struct describing a part of the protocol.
|
|
||||||
// Note: For example this can be a UniswapV2 pair, that tracks the two ERC20 tokens used by the pair,
|
|
||||||
// the component would represent a single contract. In case of VM integration, such component would
|
|
||||||
// not need any attributes, because all the relevant info would be tracked via storage slots and balance changes.
|
|
||||||
// It can also be a wrapping contract, like WETH, that has a constant price, but it allows swapping tokens.
|
|
||||||
// This is why the name ProtocolComponent is used instead of "Pool" or "Pair".
|
|
||||||
message ProtocolComponent {
|
|
||||||
// A unique identifier for the component within the protocol.
|
|
||||||
// Can be e.g. a stringified address or a string describing the trading pair.
|
|
||||||
string id = 1;
|
|
||||||
// Addresses of the ERC20 tokens used by the component.
|
|
||||||
repeated bytes tokens = 2;
|
|
||||||
// Addresses of the contracts used by the component.
|
|
||||||
// Usually it is a single contract, but some protocols use multiple contracts.
|
|
||||||
repeated bytes contracts = 3;
|
|
||||||
// Attributes of the component. Used mainly be the native integration.
|
|
||||||
// The inner ChangeType of the attribute has to match the ChangeType of the ProtocolComponent.
|
|
||||||
repeated Attribute static_att = 4;
|
|
||||||
// Type of change the component underwent.
|
|
||||||
ChangeType change = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TransactionProtocolComponents {
|
|
||||||
Transaction tx = 1;
|
|
||||||
repeated ProtocolComponent components = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GroupedTransactionProtocolComponents {
|
|
||||||
repeated TransactionProtocolComponents tx_components = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A struct for following the changes of Total Value Locked (TVL) of a protocol component.
|
|
||||||
// Note that if a ProtocolComponent contains multiple contracts, the TVL is tracked for the component as a whole.
|
|
||||||
// E.g. for UniswapV2 pair WETH/USDC, this tracks the USDC and WETH balance of the pair contract.
|
|
||||||
message BalanceChange {
|
|
||||||
// The address of the ERC20 token whose balance changed.
|
|
||||||
bytes token = 1;
|
|
||||||
// The new balance of the token.
|
|
||||||
bytes balance = 2;
|
|
||||||
// The id of the component whose TVL is tracked.
|
|
||||||
// If the protocol component includes multiple contracts, the balance change must be aggregated to reflect how much tokens can be traded.
|
|
||||||
bytes component_id = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A struct for following the changes of Total Value Locked (TVL) of a protocol component.
|
|
||||||
// Note that if a ProtocolComponent contains multiple contracts, the TVL is tracked for the component as a whole.
|
|
||||||
// E.g. for UniswapV2 pair WETH/USDC, this tracks the USDC and WETH balance of the pair contract.
|
|
||||||
message BalanceDelta {
|
|
||||||
uint64 ord = 1;
|
|
||||||
// The tx hash of the transaction that caused the balance change.
|
|
||||||
Transaction tx = 2;
|
|
||||||
// The address of the ERC20 token whose balance changed.
|
|
||||||
bytes token = 3;
|
|
||||||
// The delta balance of the token.
|
|
||||||
bytes delta = 4;
|
|
||||||
// The id of the component whose TVL is tracked.
|
|
||||||
// If the protocol component includes multiple contracts, the balance change must be aggregated to reflect how much tokens can be traded.
|
|
||||||
bytes component_id = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BalanceDeltas {
|
|
||||||
repeated BalanceDelta balance_deltas = 1;
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package tycho.evm.v1;
|
|
||||||
|
|
||||||
import "tycho/evm/v1/common.proto";
|
|
||||||
|
|
||||||
// This file contains the definition for the native integration of Substreams.
|
|
||||||
|
|
||||||
// A component is a set of attributes that are associated with a custom entity.
|
|
||||||
message EntityChanges {
|
|
||||||
// A unique identifier of the entity within the protocol.
|
|
||||||
string component_id = 1;
|
|
||||||
// The set of attributes that are associated with the entity.
|
|
||||||
repeated Attribute attributes = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TransactionEntityChanges {
|
|
||||||
Transaction tx = 1;
|
|
||||||
repeated EntityChanges entity_changes = 2;
|
|
||||||
// An array of newly added components.
|
|
||||||
repeated ProtocolComponent component_changes = 3;
|
|
||||||
// An array of balance changes to components.
|
|
||||||
repeated BalanceChange balance_changes = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A set of transaction changes within a single block.
|
|
||||||
message BlockEntityChanges {
|
|
||||||
// The block for which these changes are collectively computed.
|
|
||||||
Block block = 1;
|
|
||||||
// The set of transaction changes observed in the specified block.
|
|
||||||
repeated TransactionEntityChanges changes = 2;
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package tycho.evm.v1;
|
|
||||||
|
|
||||||
import "tycho/evm/v1/common.proto";
|
|
||||||
|
|
||||||
// This file contains proto definitions specific to the VM integration.
|
|
||||||
|
|
||||||
// A key value entry into contract storage.
|
|
||||||
message ContractSlot {
|
|
||||||
// A contract's storage slot.
|
|
||||||
bytes slot = 2;
|
|
||||||
// The new value for this storage slot.
|
|
||||||
bytes value = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Changes made to a single contract's state.
|
|
||||||
message ContractChange {
|
|
||||||
// The contract's address
|
|
||||||
bytes address = 1;
|
|
||||||
// The new native balance of the contract, empty bytes indicates no change.
|
|
||||||
bytes balance = 2;
|
|
||||||
// The new code of the contract, empty bytes indicates no change.
|
|
||||||
bytes code = 3;
|
|
||||||
// The changes to this contract's slots, empty sequence indicates no change.
|
|
||||||
repeated ContractSlot slots = 4;
|
|
||||||
// Whether this is an update, a creation or a deletion.
|
|
||||||
ChangeType change = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A set of changes aggregated by transaction.
|
|
||||||
message TransactionContractChanges {
|
|
||||||
// The transaction instance that results in the changes.
|
|
||||||
Transaction tx = 1;
|
|
||||||
// Contains the changes induced by the above transaction, aggregated on a per-contract basis.
|
|
||||||
// Must include changes to every contract that is tracked by all ProtocolComponents.
|
|
||||||
repeated ContractChange contract_changes = 2;
|
|
||||||
// An array of any component changes.
|
|
||||||
repeated ProtocolComponent component_changes = 3;
|
|
||||||
// An array of balance changes to components.
|
|
||||||
repeated BalanceChange balance_changes = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A set of transaction changes within a single block.
|
|
||||||
message BlockContractChanges {
|
|
||||||
// The block for which these changes are collectively computed.
|
|
||||||
Block block = 1;
|
|
||||||
// The set of transaction changes observed in the specified block.
|
|
||||||
repeated TransactionContractChanges changes = 2;
|
|
||||||
}
|
|
||||||
@@ -1,190 +0,0 @@
|
|||||||
/// This file contains helpers to capture contract changes from the expanded block model. These
|
|
||||||
/// leverage the `code_changes`, `balance_changes`, and `storage_changes` fields available on the
|
|
||||||
/// `Call` type provided by block model in a substream (i.e. `logs_and_calls`, etc).
|
|
||||||
///
|
|
||||||
/// ⚠️ These helpers *only* work if the **expanded block model** is available, more info blow.
|
|
||||||
/// https://streamingfastio.medium.com/new-block-model-to-accelerate-chain-integration-9f65126e5425
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use substreams_ethereum::pb::eth;
|
|
||||||
|
|
||||||
use pb::tycho::evm::v1::{self as tycho};
|
|
||||||
|
|
||||||
use substreams::store::{StoreGet, StoreGetInt64};
|
|
||||||
|
|
||||||
use crate::pb;
|
|
||||||
|
|
||||||
struct SlotValue {
|
|
||||||
new_value: Vec<u8>,
|
|
||||||
start_value: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SlotValue {
|
|
||||||
fn has_changed(&self) -> bool {
|
|
||||||
self.start_value != self.new_value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uses a map for slots, protobuf does not allow bytes in hashmap keys
|
|
||||||
pub struct InterimContractChange {
|
|
||||||
address: Vec<u8>,
|
|
||||||
balance: Vec<u8>,
|
|
||||||
code: Vec<u8>,
|
|
||||||
slots: HashMap<Vec<u8>, SlotValue>,
|
|
||||||
change: tycho::ChangeType,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<InterimContractChange> for tycho::ContractChange {
|
|
||||||
fn from(value: InterimContractChange) -> Self {
|
|
||||||
tycho::ContractChange {
|
|
||||||
address: value.address,
|
|
||||||
balance: value.balance,
|
|
||||||
code: value.code,
|
|
||||||
slots: value
|
|
||||||
.slots
|
|
||||||
.into_iter()
|
|
||||||
.filter(|(_, value)| value.has_changed())
|
|
||||||
.map(|(slot, value)| tycho::ContractSlot {
|
|
||||||
slot,
|
|
||||||
value: value.new_value,
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
change: value.change.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extract_contract_changes(
|
|
||||||
block: ð::v2::Block,
|
|
||||||
contracts: StoreGetInt64,
|
|
||||||
transaction_contract_changes: &mut HashMap<u64, tycho::TransactionContractChanges>,
|
|
||||||
) {
|
|
||||||
let mut changed_contracts: HashMap<Vec<u8>, InterimContractChange> = HashMap::new();
|
|
||||||
|
|
||||||
// Collect all accounts created in this block
|
|
||||||
let created_accounts: HashMap<_, _> = block
|
|
||||||
.transactions()
|
|
||||||
.flat_map(|tx| {
|
|
||||||
tx.calls.iter().flat_map(|call| {
|
|
||||||
call.account_creations
|
|
||||||
.iter()
|
|
||||||
.map(|ac| (&ac.account, ac.ordinal))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
block.transactions().for_each(|block_tx| {
|
|
||||||
let mut storage_changes = Vec::new();
|
|
||||||
let mut balance_changes = Vec::new();
|
|
||||||
let mut code_changes = Vec::new();
|
|
||||||
|
|
||||||
block_tx
|
|
||||||
.calls
|
|
||||||
.iter()
|
|
||||||
.filter(|call| {
|
|
||||||
!call.state_reverted
|
|
||||||
&& contracts
|
|
||||||
.get_last(format!("pool:{0}", hex::encode(&call.address)))
|
|
||||||
.is_some()
|
|
||||||
})
|
|
||||||
.for_each(|call| {
|
|
||||||
storage_changes.extend(call.storage_changes.iter());
|
|
||||||
balance_changes.extend(call.balance_changes.iter());
|
|
||||||
code_changes.extend(call.code_changes.iter());
|
|
||||||
});
|
|
||||||
|
|
||||||
storage_changes.sort_unstable_by_key(|change| change.ordinal);
|
|
||||||
balance_changes.sort_unstable_by_key(|change| change.ordinal);
|
|
||||||
code_changes.sort_unstable_by_key(|change| change.ordinal);
|
|
||||||
|
|
||||||
storage_changes.iter().for_each(|storage_change| {
|
|
||||||
let contract_change = changed_contracts
|
|
||||||
.entry(storage_change.address.clone())
|
|
||||||
.or_insert_with(|| InterimContractChange {
|
|
||||||
address: storage_change.address.clone(),
|
|
||||||
balance: Vec::new(),
|
|
||||||
code: Vec::new(),
|
|
||||||
slots: HashMap::new(),
|
|
||||||
change: if created_accounts.contains_key(&storage_change.address) {
|
|
||||||
tycho::ChangeType::Creation
|
|
||||||
} else {
|
|
||||||
tycho::ChangeType::Update
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let slot_value = contract_change
|
|
||||||
.slots
|
|
||||||
.entry(storage_change.key.clone())
|
|
||||||
.or_insert_with(|| SlotValue {
|
|
||||||
new_value: storage_change.new_value.clone(),
|
|
||||||
start_value: storage_change.old_value.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
slot_value
|
|
||||||
.new_value
|
|
||||||
.copy_from_slice(&storage_change.new_value);
|
|
||||||
});
|
|
||||||
|
|
||||||
balance_changes.iter().for_each(|balance_change| {
|
|
||||||
let contract_change = changed_contracts
|
|
||||||
.entry(balance_change.address.clone())
|
|
||||||
.or_insert_with(|| InterimContractChange {
|
|
||||||
address: balance_change.address.clone(),
|
|
||||||
balance: Vec::new(),
|
|
||||||
code: Vec::new(),
|
|
||||||
slots: HashMap::new(),
|
|
||||||
change: if created_accounts.contains_key(&balance_change.address) {
|
|
||||||
tycho::ChangeType::Creation
|
|
||||||
} else {
|
|
||||||
tycho::ChangeType::Update
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(new_balance) = &balance_change.new_value {
|
|
||||||
contract_change.balance.clear();
|
|
||||||
contract_change
|
|
||||||
.balance
|
|
||||||
.extend_from_slice(&new_balance.bytes);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
code_changes.iter().for_each(|code_change| {
|
|
||||||
let contract_change = changed_contracts
|
|
||||||
.entry(code_change.address.clone())
|
|
||||||
.or_insert_with(|| InterimContractChange {
|
|
||||||
address: code_change.address.clone(),
|
|
||||||
balance: Vec::new(),
|
|
||||||
code: Vec::new(),
|
|
||||||
slots: HashMap::new(),
|
|
||||||
change: if created_accounts.contains_key(&code_change.address) {
|
|
||||||
tycho::ChangeType::Creation
|
|
||||||
} else {
|
|
||||||
tycho::ChangeType::Update
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
contract_change.code.clear();
|
|
||||||
contract_change
|
|
||||||
.code
|
|
||||||
.extend_from_slice(&code_change.new_code);
|
|
||||||
});
|
|
||||||
|
|
||||||
if !storage_changes.is_empty() || !balance_changes.is_empty() || !code_changes.is_empty() {
|
|
||||||
transaction_contract_changes
|
|
||||||
.entry(block_tx.index.into())
|
|
||||||
.or_insert_with(|| tycho::TransactionContractChanges {
|
|
||||||
tx: Some(tycho::Transaction {
|
|
||||||
hash: block_tx.hash.clone(),
|
|
||||||
from: block_tx.from.clone(),
|
|
||||||
to: block_tx.to.clone(),
|
|
||||||
index: block_tx.index as u64,
|
|
||||||
}),
|
|
||||||
contract_changes: vec![],
|
|
||||||
component_changes: vec![],
|
|
||||||
balance_changes: vec![],
|
|
||||||
})
|
|
||||||
.contract_changes
|
|
||||||
.extend(changed_contracts.drain().map(|(_, change)| change.into()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
mod abi;
|
mod abi;
|
||||||
mod contract_changes;
|
|
||||||
mod modules;
|
mod modules;
|
||||||
mod pb;
|
|
||||||
mod pool_factories;
|
mod pool_factories;
|
||||||
|
|||||||
@@ -1,31 +1,30 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use substreams::pb::substreams::StoreDeltas;
|
use itertools::Itertools;
|
||||||
use substreams::store::{
|
use substreams::{
|
||||||
StoreAdd, StoreAddBigInt, StoreAddInt64, StoreGet, StoreGetInt64, StoreGetString, StoreNew,
|
pb::substreams::StoreDeltas,
|
||||||
StoreSet, StoreSetString,
|
store::{
|
||||||
|
StoreAdd, StoreAddBigInt, StoreAddInt64, StoreGet, StoreGetInt64, StoreGetString, StoreNew,
|
||||||
|
StoreSet, StoreSetString,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use substreams::key;
|
use substreams::{key, scalar::BigInt};
|
||||||
use substreams::scalar::BigInt;
|
|
||||||
|
|
||||||
use substreams_ethereum::block_view::LogView;
|
use substreams_ethereum::{block_view::LogView, pb::eth};
|
||||||
use substreams_ethereum::pb::eth;
|
|
||||||
|
|
||||||
use itertools::Itertools;
|
|
||||||
use pb::tycho::evm::v1::{self as tycho};
|
|
||||||
|
|
||||||
use contract_changes::extract_contract_changes;
|
|
||||||
use substreams_ethereum::Event;
|
use substreams_ethereum::Event;
|
||||||
|
|
||||||
use crate::{abi, contract_changes, pb, pool_factories};
|
use crate::{abi, pool_factories};
|
||||||
use std::convert::TryInto;
|
use tycho_substreams::{
|
||||||
|
balances::store_balance_changes, contract::extract_contract_changes, prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
/// This struct purely exists to spoof the `PartialEq` trait for `Transaction` so we can use it in
|
/// This struct purely exists to spoof the `PartialEq` trait for `Transaction` so we can use it in
|
||||||
/// a later groupby operation.
|
/// a later groupby operation.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TransactionWrapper(tycho::Transaction);
|
struct TransactionWrapper(Transaction);
|
||||||
|
|
||||||
impl PartialEq for TransactionWrapper {
|
impl PartialEq for TransactionWrapper {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
@@ -33,8 +32,8 @@ impl PartialEq for TransactionWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tx_from_log(log: &LogView) -> tycho::Transaction {
|
fn tx_from_log(log: &LogView) -> Transaction {
|
||||||
tycho::Transaction {
|
Transaction {
|
||||||
hash: log.receipt.transaction.hash.clone(),
|
hash: log.receipt.transaction.hash.clone(),
|
||||||
from: log.receipt.transaction.from.clone(),
|
from: log.receipt.transaction.from.clone(),
|
||||||
to: log.receipt.transaction.to.clone(),
|
to: log.receipt.transaction.to.clone(),
|
||||||
@@ -43,12 +42,10 @@ fn tx_from_log(log: &LogView) -> tycho::Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[substreams::handlers::map]
|
#[substreams::handlers::map]
|
||||||
pub fn map_pools_created(
|
pub fn map_components(block: eth::v2::Block) -> Result<BlockTransactionProtocolComponents> {
|
||||||
block: eth::v2::Block,
|
|
||||||
) -> Result<tycho::GroupedTransactionProtocolComponents> {
|
|
||||||
// Gather contract changes by indexing `PoolCreated` events and analysing the `Create` call
|
// Gather contract changes by indexing `PoolCreated` events and analysing the `Create` call
|
||||||
// We store these as a hashmap by tx hash since we need to agg by tx hash later
|
// We store these as a hashmap by tx hash since we need to agg by tx hash later
|
||||||
Ok(tycho::GroupedTransactionProtocolComponents {
|
Ok(BlockTransactionProtocolComponents {
|
||||||
tx_components: block
|
tx_components: block
|
||||||
.transactions()
|
.transactions()
|
||||||
.filter_map(|tx| {
|
.filter_map(|tx| {
|
||||||
@@ -57,16 +54,21 @@ pub fn map_pools_created(
|
|||||||
.filter(|(_, call)| !call.call.state_reverted)
|
.filter(|(_, call)| !call.call.state_reverted)
|
||||||
.filter_map(|(log, call)| {
|
.filter_map(|(log, call)| {
|
||||||
Some(pool_factories::address_map(
|
Some(pool_factories::address_map(
|
||||||
call.call.address.as_slice().try_into().ok()?, // this shouldn't fail
|
call.call
|
||||||
|
.address
|
||||||
|
.as_slice()
|
||||||
|
.try_into()
|
||||||
|
.ok()?, // this shouldn't fail
|
||||||
log,
|
log,
|
||||||
call.call,
|
call.call,
|
||||||
|
tx,
|
||||||
)?)
|
)?)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if !components.is_empty() {
|
if !components.is_empty() {
|
||||||
Some(tycho::TransactionProtocolComponents {
|
Some(TransactionProtocolComponents {
|
||||||
tx: Some(tycho::Transaction {
|
tx: Some(Transaction {
|
||||||
hash: tx.hash.clone(),
|
hash: tx.hash.clone(),
|
||||||
from: tx.from.clone(),
|
from: tx.from.clone(),
|
||||||
to: tx.to.clone(),
|
to: tx.to.clone(),
|
||||||
@@ -84,7 +86,7 @@ pub fn map_pools_created(
|
|||||||
|
|
||||||
/// Simply stores the `ProtocolComponent`s with the pool id as the key
|
/// Simply stores the `ProtocolComponent`s with the pool id as the key
|
||||||
#[substreams::handlers::store]
|
#[substreams::handlers::store]
|
||||||
pub fn store_pools_created(map: tycho::GroupedTransactionProtocolComponents, store: StoreAddInt64) {
|
pub fn store_components(map: BlockTransactionProtocolComponents, store: StoreAddInt64) {
|
||||||
store.add_many(
|
store.add_many(
|
||||||
0,
|
0,
|
||||||
&map.tx_components
|
&map.tx_components
|
||||||
@@ -98,7 +100,7 @@ pub fn store_pools_created(map: tycho::GroupedTransactionProtocolComponents, sto
|
|||||||
|
|
||||||
/// Simply stores the `ProtocolComponent`s with the pool id as the key
|
/// Simply stores the `ProtocolComponent`s with the pool id as the key
|
||||||
#[substreams::handlers::store]
|
#[substreams::handlers::store]
|
||||||
pub fn store_pools_tokens(map: tycho::GroupedTransactionProtocolComponents, store: StoreSetString) {
|
pub fn store_component_tokens(map: BlockTransactionProtocolComponents, store: StoreSetString) {
|
||||||
map.tx_components
|
map.tx_components
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|tx_components| &tx_components.components)
|
.flat_map(|tx_components| &tx_components.components)
|
||||||
@@ -118,11 +120,11 @@ pub fn store_pools_tokens(map: tycho::GroupedTransactionProtocolComponents, stor
|
|||||||
/// Since the `PoolBalanceChanged` events administer only deltas, we need to leverage a map and a
|
/// Since the `PoolBalanceChanged` events administer only deltas, we need to leverage a map and a
|
||||||
/// store to be able to tally up final balances for tokens in a pool.
|
/// store to be able to tally up final balances for tokens in a pool.
|
||||||
#[substreams::handlers::map]
|
#[substreams::handlers::map]
|
||||||
pub fn map_balance_deltas(
|
pub fn map_relative_balances(
|
||||||
block: eth::v2::Block,
|
block: eth::v2::Block,
|
||||||
pools_store: StoreGetInt64,
|
pools_store: StoreGetInt64,
|
||||||
tokens_store: StoreGetString,
|
tokens_store: StoreGetString,
|
||||||
) -> Result<tycho::BalanceDeltas, anyhow::Error> {
|
) -> Result<BlockBalanceDeltas, anyhow::Error> {
|
||||||
let mut deltas = block
|
let mut deltas = block
|
||||||
.logs()
|
.logs()
|
||||||
.filter_map(|log| {
|
.filter_map(|log| {
|
||||||
@@ -137,14 +139,14 @@ pub fn map_balance_deltas(
|
|||||||
.flat_map(|(log, event)| {
|
.flat_map(|(log, event)| {
|
||||||
let tokens_bought_delta: BigInt = event.tokens_bought * -1;
|
let tokens_bought_delta: BigInt = event.tokens_bought * -1;
|
||||||
vec![
|
vec![
|
||||||
tycho::BalanceDelta {
|
BalanceDelta {
|
||||||
ord: log.log.ordinal,
|
ord: log.log.ordinal,
|
||||||
tx: Some(tx_from_log(&log)),
|
tx: Some(tx_from_log(&log)),
|
||||||
token: event.sold_id.to_signed_bytes_be(),
|
token: event.sold_id.to_signed_bytes_be(),
|
||||||
delta: event.tokens_sold.to_signed_bytes_be(),
|
delta: event.tokens_sold.to_signed_bytes_be(),
|
||||||
component_id: log.address().into(),
|
component_id: log.address().into(),
|
||||||
},
|
},
|
||||||
tycho::BalanceDelta {
|
BalanceDelta {
|
||||||
ord: log.log.ordinal,
|
ord: log.log.ordinal,
|
||||||
tx: Some(tx_from_log(&log)),
|
tx: Some(tx_from_log(&log)),
|
||||||
token: event.bought_id.to_signed_bytes_be(),
|
token: event.bought_id.to_signed_bytes_be(),
|
||||||
@@ -178,7 +180,7 @@ pub fn map_balance_deltas(
|
|||||||
.token_amounts
|
.token_amounts
|
||||||
.iter()
|
.iter()
|
||||||
.zip(tokens)
|
.zip(tokens)
|
||||||
.map(move |(token_amount, token_id)| tycho::BalanceDelta {
|
.map(move |(token_amount, token_id)| BalanceDelta {
|
||||||
ord: log.log.ordinal,
|
ord: log.log.ordinal,
|
||||||
tx: Some(tx_from_log(&log)),
|
tx: Some(tx_from_log(&log)),
|
||||||
token: token_id.into(),
|
token: token_id.into(),
|
||||||
@@ -216,7 +218,7 @@ pub fn map_balance_deltas(
|
|||||||
.zip(tokens)
|
.zip(tokens)
|
||||||
.map(move |(token_amount, token_id)| {
|
.map(move |(token_amount, token_id)| {
|
||||||
let negative_token_amount: BigInt = token_amount * BigInt::from(-1);
|
let negative_token_amount: BigInt = token_amount * BigInt::from(-1);
|
||||||
tycho::BalanceDelta {
|
BalanceDelta {
|
||||||
ord: log.log.ordinal,
|
ord: log.log.ordinal,
|
||||||
tx: Some(tx_from_log(&log)),
|
tx: Some(tx_from_log(&log)),
|
||||||
token: token_id.into(),
|
token: token_id.into(),
|
||||||
@@ -229,46 +231,33 @@ pub fn map_balance_deltas(
|
|||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(tycho::BalanceDeltas {
|
Ok(BlockBalanceDeltas { balance_deltas: deltas })
|
||||||
balance_deltas: deltas,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// It's significant to include both the `pool_id` and the `token_id` for each balance delta as the
|
/// It's significant to include both the `pool_id` and the `token_id` for each balance delta as the
|
||||||
/// store key to ensure that there's a unique balance being tallied for each.
|
/// store key to ensure that there's a unique balance being tallied for each.
|
||||||
#[substreams::handlers::store]
|
#[substreams::handlers::store]
|
||||||
pub fn store_balance_changes(deltas: tycho::BalanceDeltas, store: StoreAddBigInt) {
|
pub fn store_balance(deltas: BlockBalanceDeltas, store: StoreAddBigInt) {
|
||||||
deltas.balance_deltas.iter().for_each(|delta| {
|
store_balance_changes(deltas, store)
|
||||||
store.add(
|
|
||||||
delta.ord,
|
|
||||||
format!(
|
|
||||||
"pool:{0}:token:{1}",
|
|
||||||
hex::encode(&delta.component_id),
|
|
||||||
hex::encode(&delta.token)
|
|
||||||
),
|
|
||||||
BigInt::from_signed_bytes_be(&delta.delta),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the main map that handles most of the indexing of this substream.
|
/// This is the main map that handles most of the indexing of this substream.
|
||||||
/// Every contract change is grouped by transaction index via the `transaction_contract_changes`
|
/// Every contract change is grouped by transaction index via the `transaction_contract_changes`
|
||||||
/// map. Each block of code will extend the `TransactionContractChanges` struct with the
|
/// map. Each block of code will extend the `TransactionContractChanges` struct with the
|
||||||
/// cooresponding changes (balance, component, contract), inserting a new one if it doesn't exist.
|
/// cooresponding changes (balance, component, contract), inserting a new one if it doesn't exist.
|
||||||
/// At the very end, the map can easily be sorted by index to ensure the final `BlockContractChanges`
|
/// At the very end, the map can easily be sorted by index to ensure the final
|
||||||
/// is ordered by transactions properly.
|
/// `BlockContractChanges` is ordered by transactions properly.
|
||||||
#[substreams::handlers::map]
|
#[substreams::handlers::map]
|
||||||
pub fn map_changes(
|
pub fn map_protocol_changes(
|
||||||
block: eth::v2::Block,
|
block: eth::v2::Block,
|
||||||
grouped_components: tycho::GroupedTransactionProtocolComponents,
|
grouped_components: BlockTransactionProtocolComponents,
|
||||||
deltas: tycho::BalanceDeltas,
|
deltas: BlockBalanceDeltas,
|
||||||
components_store: StoreGetInt64,
|
components_store: StoreGetInt64,
|
||||||
balance_store: StoreDeltas, // Note, this map module is using the `deltas` mode for the store.
|
balance_store: StoreDeltas, // Note, this map module is using the `deltas` mode for the store.
|
||||||
) -> Result<tycho::BlockContractChanges> {
|
) -> Result<BlockContractChanges> {
|
||||||
// We merge contract changes by transaction (identified by transaction index) making it easy to
|
// We merge contract changes by transaction (identified by transaction index) making it easy to
|
||||||
// sort them at the very end.
|
// sort them at the very end.
|
||||||
let mut transaction_contract_changes: HashMap<_, tycho::TransactionContractChanges> =
|
let mut transaction_contract_changes: HashMap<_, TransactionContractChanges> = HashMap::new();
|
||||||
HashMap::new();
|
|
||||||
|
|
||||||
// `ProtocolComponents` are gathered from `map_pools_created` which just need a bit of work to
|
// `ProtocolComponents` are gathered from `map_pools_created` which just need a bit of work to
|
||||||
// convert into `TransactionContractChanges`
|
// convert into `TransactionContractChanges`
|
||||||
@@ -280,7 +269,7 @@ pub fn map_changes(
|
|||||||
|
|
||||||
transaction_contract_changes
|
transaction_contract_changes
|
||||||
.entry(tx.index)
|
.entry(tx.index)
|
||||||
.or_insert_with(|| tycho::TransactionContractChanges {
|
.or_insert_with(|| TransactionContractChanges {
|
||||||
tx: Some(tx.clone()),
|
tx: Some(tx.clone()),
|
||||||
contract_changes: vec![],
|
contract_changes: vec![],
|
||||||
component_changes: vec![],
|
component_changes: vec![],
|
||||||
@@ -303,7 +292,7 @@ pub fn map_changes(
|
|||||||
let token_id = key::segment_at(&store_delta.key, 3);
|
let token_id = key::segment_at(&store_delta.key, 3);
|
||||||
(
|
(
|
||||||
balance_delta.tx.unwrap(),
|
balance_delta.tx.unwrap(),
|
||||||
tycho::BalanceChange {
|
BalanceChange {
|
||||||
token: hex::decode(token_id).expect("Token ID not valid hex"),
|
token: hex::decode(token_id).expect("Token ID not valid hex"),
|
||||||
balance: store_delta.new_value,
|
balance: store_delta.new_value,
|
||||||
component_id: hex::decode(pool_id).expect("Token ID not valid hex"),
|
component_id: hex::decode(pool_id).expect("Token ID not valid hex"),
|
||||||
@@ -318,7 +307,7 @@ pub fn map_changes(
|
|||||||
|
|
||||||
transaction_contract_changes
|
transaction_contract_changes
|
||||||
.entry(tx.index)
|
.entry(tx.index)
|
||||||
.or_insert_with(|| tycho::TransactionContractChanges {
|
.or_insert_with(|| TransactionContractChanges {
|
||||||
tx: Some(tx.clone()),
|
tx: Some(tx.clone()),
|
||||||
contract_changes: vec![],
|
contract_changes: vec![],
|
||||||
component_changes: vec![],
|
component_changes: vec![],
|
||||||
@@ -331,12 +320,20 @@ pub fn map_changes(
|
|||||||
// General helper for extracting contract changes. Uses block, our component store which holds
|
// General helper for extracting contract changes. Uses block, our component store which holds
|
||||||
// all of our tracked deployed pool addresses, and the map of tx contract changes which we
|
// all of our tracked deployed pool addresses, and the map of tx contract changes which we
|
||||||
// output into for final processing later.
|
// output into for final processing later.
|
||||||
extract_contract_changes(&block, components_store, &mut transaction_contract_changes);
|
extract_contract_changes(
|
||||||
|
&block,
|
||||||
|
|addr| {
|
||||||
|
components_store
|
||||||
|
.get_last(format!("pool:0x{0}", hex::encode(addr)))
|
||||||
|
.is_some()
|
||||||
|
},
|
||||||
|
&mut transaction_contract_changes,
|
||||||
|
);
|
||||||
|
|
||||||
// Process all `transaction_contract_changes` for final output in the `BlockContractChanges`,
|
// Process all `transaction_contract_changes` for final output in the `BlockContractChanges`,
|
||||||
// sorted by transaction index (the key).
|
// sorted by transaction index (the key).
|
||||||
Ok(tycho::BlockContractChanges {
|
Ok(BlockContractChanges {
|
||||||
block: Some(tycho::Block {
|
block: Some(Block {
|
||||||
number: block.number,
|
number: block.number,
|
||||||
hash: block.hash.clone(),
|
hash: block.hash.clone(),
|
||||||
parent_hash: block
|
parent_hash: block
|
||||||
@@ -351,9 +348,9 @@ pub fn map_changes(
|
|||||||
.drain()
|
.drain()
|
||||||
.sorted_unstable_by_key(|(index, _)| index.clone())
|
.sorted_unstable_by_key(|(index, _)| index.clone())
|
||||||
.filter_map(|(_, change)| {
|
.filter_map(|(_, change)| {
|
||||||
if change.contract_changes.is_empty()
|
if change.contract_changes.is_empty() &&
|
||||||
&& change.component_changes.is_empty()
|
change.component_changes.is_empty() &&
|
||||||
&& change.balance_changes.is_empty()
|
change.balance_changes.is_empty()
|
||||||
{
|
{
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
// @generated
|
|
||||||
pub mod tycho {
|
|
||||||
pub mod evm {
|
|
||||||
// @@protoc_insertion_point(attribute:tycho.evm.v1)
|
|
||||||
pub mod v1 {
|
|
||||||
include!("tycho.evm.v1.rs");
|
|
||||||
// @@protoc_insertion_point(tycho.evm.v1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,236 +0,0 @@
|
|||||||
// @generated
|
|
||||||
// This file contains the proto definitions for Substreams common to all integrations.
|
|
||||||
|
|
||||||
/// A struct describing a block.
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct Block {
|
|
||||||
/// The blocks hash.
|
|
||||||
#[prost(bytes="vec", tag="1")]
|
|
||||||
pub hash: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The parent blocks hash.
|
|
||||||
#[prost(bytes="vec", tag="2")]
|
|
||||||
pub parent_hash: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The block number.
|
|
||||||
#[prost(uint64, tag="3")]
|
|
||||||
pub number: u64,
|
|
||||||
/// The block timestamp.
|
|
||||||
#[prost(uint64, tag="4")]
|
|
||||||
pub ts: u64,
|
|
||||||
}
|
|
||||||
/// A struct describing a transaction.
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct Transaction {
|
|
||||||
/// The transaction hash.
|
|
||||||
#[prost(bytes="vec", tag="1")]
|
|
||||||
pub hash: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The sender of the transaction.
|
|
||||||
#[prost(bytes="vec", tag="2")]
|
|
||||||
pub from: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The receiver of the transaction.
|
|
||||||
#[prost(bytes="vec", tag="3")]
|
|
||||||
pub to: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The transactions index within the block.
|
|
||||||
/// TODO: should this be uint32? to match the type from the native substream type?
|
|
||||||
#[prost(uint64, tag="4")]
|
|
||||||
pub index: u64,
|
|
||||||
}
|
|
||||||
/// A custom struct representing an arbitrary attribute of a protocol component.
|
|
||||||
/// This is mainly used by the native integration to track the necessary information about the protocol.
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct Attribute {
|
|
||||||
/// The name of the attribute.
|
|
||||||
#[prost(string, tag="1")]
|
|
||||||
pub name: ::prost::alloc::string::String,
|
|
||||||
/// The value of the attribute.
|
|
||||||
#[prost(bytes="vec", tag="2")]
|
|
||||||
pub value: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The type of change the attribute underwent.
|
|
||||||
#[prost(enumeration="ChangeType", tag="3")]
|
|
||||||
pub change: i32,
|
|
||||||
}
|
|
||||||
/// A struct describing a part of the protocol.
|
|
||||||
/// Note: For example this can be a UniswapV2 pair, that tracks the two ERC20 tokens used by the pair,
|
|
||||||
/// the component would represent a single contract. In case of VM integration, such component would
|
|
||||||
/// not need any attributes, because all the relevant info would be tracked via storage slots and balance changes.
|
|
||||||
/// It can also be a wrapping contract, like WETH, that has a constant price, but it allows swapping tokens.
|
|
||||||
/// This is why the name ProtocolComponent is used instead of "Pool" or "Pair".
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct ProtocolComponent {
|
|
||||||
/// A unique identifier for the component within the protocol.
|
|
||||||
/// Can be e.g. a stringified address or a string describing the trading pair.
|
|
||||||
#[prost(string, tag="1")]
|
|
||||||
pub id: ::prost::alloc::string::String,
|
|
||||||
/// Addresses of the ERC20 tokens used by the component.
|
|
||||||
#[prost(bytes="vec", repeated, tag="2")]
|
|
||||||
pub tokens: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec<u8>>,
|
|
||||||
/// Addresses of the contracts used by the component.
|
|
||||||
/// Usually it is a single contract, but some protocols use multiple contracts.
|
|
||||||
#[prost(bytes="vec", repeated, tag="3")]
|
|
||||||
pub contracts: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec<u8>>,
|
|
||||||
/// Attributes of the component. Used mainly be the native integration.
|
|
||||||
/// The inner ChangeType of the attribute has to match the ChangeType of the ProtocolComponent.
|
|
||||||
#[prost(message, repeated, tag="4")]
|
|
||||||
pub static_att: ::prost::alloc::vec::Vec<Attribute>,
|
|
||||||
/// Type of change the component underwent.
|
|
||||||
#[prost(enumeration="ChangeType", tag="5")]
|
|
||||||
pub change: i32,
|
|
||||||
}
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct TransactionProtocolComponents {
|
|
||||||
#[prost(message, optional, tag="1")]
|
|
||||||
pub tx: ::core::option::Option<Transaction>,
|
|
||||||
#[prost(message, repeated, tag="2")]
|
|
||||||
pub components: ::prost::alloc::vec::Vec<ProtocolComponent>,
|
|
||||||
}
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct GroupedTransactionProtocolComponents {
|
|
||||||
#[prost(message, repeated, tag="1")]
|
|
||||||
pub tx_components: ::prost::alloc::vec::Vec<TransactionProtocolComponents>,
|
|
||||||
}
|
|
||||||
/// A struct for following the changes of Total Value Locked (TVL) of a protocol component.
|
|
||||||
/// Note that if a ProtocolComponent contains multiple contracts, the TVL is tracked for the component as a whole.
|
|
||||||
/// E.g. for UniswapV2 pair WETH/USDC, this tracks the USDC and WETH balance of the pair contract.
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct BalanceChange {
|
|
||||||
/// The address of the ERC20 token whose balance changed.
|
|
||||||
#[prost(bytes="vec", tag="1")]
|
|
||||||
pub token: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The new balance of the token.
|
|
||||||
#[prost(bytes="vec", tag="2")]
|
|
||||||
pub balance: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The id of the component whose TVL is tracked.
|
|
||||||
/// If the protocol component includes multiple contracts, the balance change must be aggregated to reflect how much tokens can be traded.
|
|
||||||
#[prost(bytes="vec", tag="3")]
|
|
||||||
pub component_id: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
}
|
|
||||||
/// A struct for following the changes of Total Value Locked (TVL) of a protocol component.
|
|
||||||
/// Note that if a ProtocolComponent contains multiple contracts, the TVL is tracked for the component as a whole.
|
|
||||||
/// E.g. for UniswapV2 pair WETH/USDC, this tracks the USDC and WETH balance of the pair contract.
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct BalanceDelta {
|
|
||||||
#[prost(uint64, tag="1")]
|
|
||||||
pub ord: u64,
|
|
||||||
/// The tx hash of the transaction that caused the balance change.
|
|
||||||
#[prost(message, optional, tag="2")]
|
|
||||||
pub tx: ::core::option::Option<Transaction>,
|
|
||||||
/// The address of the ERC20 token whose balance changed.
|
|
||||||
#[prost(bytes="vec", tag="3")]
|
|
||||||
pub token: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The delta balance of the token.
|
|
||||||
#[prost(bytes="vec", tag="4")]
|
|
||||||
pub delta: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The id of the component whose TVL is tracked.
|
|
||||||
/// If the protocol component includes multiple contracts, the balance change must be aggregated to reflect how much tokens can be traded.
|
|
||||||
#[prost(bytes="vec", tag="5")]
|
|
||||||
pub component_id: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
}
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct BalanceDeltas {
|
|
||||||
#[prost(message, repeated, tag="1")]
|
|
||||||
pub balance_deltas: ::prost::alloc::vec::Vec<BalanceDelta>,
|
|
||||||
}
|
|
||||||
/// Enum to specify the type of a change.
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
|
||||||
#[repr(i32)]
|
|
||||||
pub enum ChangeType {
|
|
||||||
Unspecified = 0,
|
|
||||||
Update = 1,
|
|
||||||
Creation = 2,
|
|
||||||
Deletion = 3,
|
|
||||||
}
|
|
||||||
impl ChangeType {
|
|
||||||
/// String value of the enum field names used in the ProtoBuf definition.
|
|
||||||
///
|
|
||||||
/// The values are not transformed in any way and thus are considered stable
|
|
||||||
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
|
||||||
pub fn as_str_name(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
ChangeType::Unspecified => "CHANGE_TYPE_UNSPECIFIED",
|
|
||||||
ChangeType::Update => "CHANGE_TYPE_UPDATE",
|
|
||||||
ChangeType::Creation => "CHANGE_TYPE_CREATION",
|
|
||||||
ChangeType::Deletion => "CHANGE_TYPE_DELETION",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
|
||||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
|
||||||
match value {
|
|
||||||
"CHANGE_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
|
|
||||||
"CHANGE_TYPE_UPDATE" => Some(Self::Update),
|
|
||||||
"CHANGE_TYPE_CREATION" => Some(Self::Creation),
|
|
||||||
"CHANGE_TYPE_DELETION" => Some(Self::Deletion),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// This file contains proto definitions specific to the VM integration.
|
|
||||||
|
|
||||||
/// A key value entry into contract storage.
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct ContractSlot {
|
|
||||||
/// A contract's storage slot.
|
|
||||||
#[prost(bytes="vec", tag="2")]
|
|
||||||
pub slot: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The new value for this storage slot.
|
|
||||||
#[prost(bytes="vec", tag="3")]
|
|
||||||
pub value: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
}
|
|
||||||
/// Changes made to a single contract's state.
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct ContractChange {
|
|
||||||
/// The contract's address
|
|
||||||
#[prost(bytes="vec", tag="1")]
|
|
||||||
pub address: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The new native balance of the contract, empty bytes indicates no change.
|
|
||||||
#[prost(bytes="vec", tag="2")]
|
|
||||||
pub balance: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The new code of the contract, empty bytes indicates no change.
|
|
||||||
#[prost(bytes="vec", tag="3")]
|
|
||||||
pub code: ::prost::alloc::vec::Vec<u8>,
|
|
||||||
/// The changes to this contract's slots, empty sequence indicates no change.
|
|
||||||
#[prost(message, repeated, tag="4")]
|
|
||||||
pub slots: ::prost::alloc::vec::Vec<ContractSlot>,
|
|
||||||
/// Whether this is an update, a creation or a deletion.
|
|
||||||
#[prost(enumeration="ChangeType", tag="5")]
|
|
||||||
pub change: i32,
|
|
||||||
}
|
|
||||||
/// A set of changes aggregated by transaction.
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct TransactionContractChanges {
|
|
||||||
/// The transaction instance that results in the changes.
|
|
||||||
#[prost(message, optional, tag="1")]
|
|
||||||
pub tx: ::core::option::Option<Transaction>,
|
|
||||||
/// Contains the changes induced by the above transaction, aggregated on a per-contract basis.
|
|
||||||
/// Must include changes to every contract that is tracked by all ProtocolComponents.
|
|
||||||
#[prost(message, repeated, tag="2")]
|
|
||||||
pub contract_changes: ::prost::alloc::vec::Vec<ContractChange>,
|
|
||||||
/// An array of any component changes.
|
|
||||||
#[prost(message, repeated, tag="3")]
|
|
||||||
pub component_changes: ::prost::alloc::vec::Vec<ProtocolComponent>,
|
|
||||||
/// An array of balance changes to components.
|
|
||||||
#[prost(message, repeated, tag="4")]
|
|
||||||
pub balance_changes: ::prost::alloc::vec::Vec<BalanceChange>,
|
|
||||||
}
|
|
||||||
/// A set of transaction changes within a single block.
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct BlockContractChanges {
|
|
||||||
/// The block for which these changes are collectively computed.
|
|
||||||
#[prost(message, optional, tag="1")]
|
|
||||||
pub block: ::core::option::Option<Block>,
|
|
||||||
/// The set of transaction changes observed in the specified block.
|
|
||||||
#[prost(message, repeated, tag="2")]
|
|
||||||
pub changes: ::prost::alloc::vec::Vec<TransactionContractChanges>,
|
|
||||||
}
|
|
||||||
// @@protoc_insertion_point(module)
|
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
use substreams_ethereum::pb::eth::v2::{Call, Log};
|
use substreams_ethereum::{
|
||||||
use substreams_ethereum::{Event, Function};
|
pb::eth::v2::{Call, Log, TransactionTrace},
|
||||||
|
Event, Function,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::abi;
|
use crate::abi;
|
||||||
use crate::pb;
|
|
||||||
use pb::tycho::evm::v1::{self as tycho};
|
|
||||||
use substreams::hex;
|
use substreams::hex;
|
||||||
|
use tycho_substreams::prelude::*;
|
||||||
|
|
||||||
use substreams::scalar::BigInt;
|
use substreams::scalar::BigInt;
|
||||||
|
|
||||||
@@ -42,7 +43,8 @@ pub fn address_map(
|
|||||||
call_address: &[u8; 20],
|
call_address: &[u8; 20],
|
||||||
log: &Log,
|
log: &Log,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
) -> Option<tycho::ProtocolComponent> {
|
tx: &TransactionTrace,
|
||||||
|
) -> Option<ProtocolComponent> {
|
||||||
match *call_address {
|
match *call_address {
|
||||||
CRYPTO_SWAP_REGISTRY => {
|
CRYPTO_SWAP_REGISTRY => {
|
||||||
let pool_added = abi::crypto_swap_registry::events::PoolAdded::match_and_decode(log)?;
|
let pool_added = abi::crypto_swap_registry::events::PoolAdded::match_and_decode(log)?;
|
||||||
@@ -77,9 +79,8 @@ pub fn address_map(
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// We need to perform an eth_call in order to actually get the pool's tokens
|
// We need to perform an eth_call in order to actually get the pool's tokens
|
||||||
let coins_function = abi::crypto_swap_registry::functions::GetCoins {
|
let coins_function =
|
||||||
pool: add_pool.pool,
|
abi::crypto_swap_registry::functions::GetCoins { pool: add_pool.pool };
|
||||||
};
|
|
||||||
|
|
||||||
let coins = coins_function.call(CRYPTO_SWAP_REGISTRY.to_vec())?;
|
let coins = coins_function.call(CRYPTO_SWAP_REGISTRY.to_vec())?;
|
||||||
let trimmed_coins: Vec<_> = coins
|
let trimmed_coins: Vec<_> = coins
|
||||||
@@ -87,29 +88,35 @@ pub fn address_map(
|
|||||||
.unwrap_or(&[])
|
.unwrap_or(&[])
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
Some(tycho::ProtocolComponent {
|
Some(ProtocolComponent {
|
||||||
id: hex::encode(&pool_added.pool),
|
id: hex::encode(&pool_added.pool),
|
||||||
|
tx: Some(Transaction {
|
||||||
|
to: tx.to.clone(),
|
||||||
|
from: tx.from.clone(),
|
||||||
|
hash: tx.hash.clone(),
|
||||||
|
index: tx.index.into(),
|
||||||
|
}),
|
||||||
tokens: trimmed_coins,
|
tokens: trimmed_coins,
|
||||||
contracts: vec![call_address.into(), pool_added.pool],
|
contracts: vec![call_address.into(), pool_added.pool],
|
||||||
static_att: vec![
|
static_att: vec![
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "pool_type".into(),
|
name: "pool_type".into(),
|
||||||
value: "CryptoSwap".into(),
|
value: "CryptoSwap".into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "name".into(),
|
name: "name".into(),
|
||||||
value: add_pool.name.into(),
|
value: add_pool.name.into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "lp_token".into(),
|
name: "lp_token".into(),
|
||||||
value: add_pool.lp_token.into(),
|
value: add_pool.lp_token.into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
change: ChangeType::Creation.into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
MAIN_REGISTRY => {
|
MAIN_REGISTRY => {
|
||||||
@@ -160,9 +167,8 @@ pub fn address_map(
|
|||||||
.or_else(|| abi::main_registry::functions::AddPool::match_and_decode(call))?;
|
.or_else(|| abi::main_registry::functions::AddPool::match_and_decode(call))?;
|
||||||
|
|
||||||
// We need to perform an eth_call in order to actually get the pool's tokens
|
// We need to perform an eth_call in order to actually get the pool's tokens
|
||||||
let coins_function = abi::crypto_swap_registry::functions::GetCoins {
|
let coins_function =
|
||||||
pool: add_pool.pool,
|
abi::crypto_swap_registry::functions::GetCoins { pool: add_pool.pool };
|
||||||
};
|
|
||||||
|
|
||||||
let coins = coins_function.call(CRYPTO_SWAP_REGISTRY.to_vec())?;
|
let coins = coins_function.call(CRYPTO_SWAP_REGISTRY.to_vec())?;
|
||||||
let trimmed_coins: Vec<_> = coins
|
let trimmed_coins: Vec<_> = coins
|
||||||
@@ -170,28 +176,35 @@ pub fn address_map(
|
|||||||
.unwrap_or(&[])
|
.unwrap_or(&[])
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
Some(tycho::ProtocolComponent {
|
Some(ProtocolComponent {
|
||||||
id: hex::encode(&pool_created.pool),
|
id: hex::encode(&pool_created.pool),
|
||||||
|
tx: Some(Transaction {
|
||||||
|
to: tx.to.clone(),
|
||||||
|
from: tx.from.clone(),
|
||||||
|
hash: tx.hash.clone(),
|
||||||
|
index: tx.index.into(),
|
||||||
|
}),
|
||||||
tokens: trimmed_coins,
|
tokens: trimmed_coins,
|
||||||
contracts: vec![call_address.into(), pool_created.pool],
|
contracts: vec![call_address.into(), pool_created.pool],
|
||||||
static_att: vec![
|
static_att: vec![
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "pool_type".into(),
|
name: "pool_type".into(),
|
||||||
value: "MainRegistry".into(),
|
value: "MainRegistry".into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "name".into(),
|
name: "name".into(),
|
||||||
value: add_pool.name.into(),
|
value: add_pool.name.into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "lp_token".into(),
|
name: "lp_token".into(),
|
||||||
value: add_pool.lp_token.into(),
|
value: add_pool.lp_token.into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
CRYPTO_POOL_FACTORY => {
|
CRYPTO_POOL_FACTORY => {
|
||||||
@@ -200,68 +213,87 @@ pub fn address_map(
|
|||||||
let deploy_call =
|
let deploy_call =
|
||||||
abi::crypto_pool_factory::functions::DeployPool::match_and_decode(call)?;
|
abi::crypto_pool_factory::functions::DeployPool::match_and_decode(call)?;
|
||||||
|
|
||||||
Some(tycho::ProtocolComponent {
|
Some(ProtocolComponent {
|
||||||
id: hex::encode(&call.return_data),
|
id: hex::encode(&call.return_data),
|
||||||
|
tx: Some(Transaction {
|
||||||
|
to: tx.to.clone(),
|
||||||
|
from: tx.from.clone(),
|
||||||
|
hash: tx.hash.clone(),
|
||||||
|
index: tx.index.into(),
|
||||||
|
}),
|
||||||
tokens: pool_added.coins.into(),
|
tokens: pool_added.coins.into(),
|
||||||
contracts: vec![call_address.into(), call.return_data.clone()],
|
contracts: vec![call_address.into(), call.return_data.clone()],
|
||||||
static_att: vec![
|
static_att: vec![
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "pool_type".into(),
|
name: "pool_type".into(),
|
||||||
value: "CryptoPool".into(),
|
value: "CryptoPool".into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "name".into(),
|
name: "name".into(),
|
||||||
value: pool_added.a.to_string().into(),
|
value: pool_added.a.to_string().into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "lp_token".into(),
|
name: "lp_token".into(),
|
||||||
value: pool_added.gamma.to_string().into(),
|
value: pool_added.gamma.to_string().into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "mid_fee".into(),
|
name: "mid_fee".into(),
|
||||||
value: deploy_call.mid_fee.to_string().into(),
|
value: deploy_call.mid_fee.to_string().into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "out_fee".into(),
|
name: "out_fee".into(),
|
||||||
value: deploy_call.out_fee.to_string().into(),
|
value: deploy_call.out_fee.to_string().into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "allowed_extra_profit".into(),
|
name: "allowed_extra_profit".into(),
|
||||||
value: deploy_call.allowed_extra_profit.to_string().into(),
|
value: deploy_call
|
||||||
change: tycho::ChangeType::Creation.into(),
|
.allowed_extra_profit
|
||||||
|
.to_string()
|
||||||
|
.into(),
|
||||||
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "fee_gamma".into(),
|
name: "fee_gamma".into(),
|
||||||
value: deploy_call.fee_gamma.to_string().into(),
|
value: deploy_call.fee_gamma.to_string().into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "adjustment_step".into(),
|
name: "adjustment_step".into(),
|
||||||
value: deploy_call.adjustment_step.to_string().into(),
|
value: deploy_call
|
||||||
change: tycho::ChangeType::Creation.into(),
|
.adjustment_step
|
||||||
|
.to_string()
|
||||||
|
.into(),
|
||||||
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "admin_fee".into(),
|
name: "admin_fee".into(),
|
||||||
value: deploy_call.admin_fee.to_string().into(),
|
value: deploy_call.admin_fee.to_string().into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "ma_half_time".into(),
|
name: "ma_half_time".into(),
|
||||||
value: deploy_call.ma_half_time.to_string().into(),
|
value: deploy_call
|
||||||
change: tycho::ChangeType::Creation.into(),
|
.ma_half_time
|
||||||
|
.to_string()
|
||||||
|
.into(),
|
||||||
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "initial_price".into(),
|
name: "initial_price".into(),
|
||||||
value: deploy_call.initial_price.to_string().into(),
|
value: deploy_call
|
||||||
change: tycho::ChangeType::Creation.into(),
|
.initial_price
|
||||||
|
.to_string()
|
||||||
|
.into(),
|
||||||
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
META_POOL_FACTORY => {
|
META_POOL_FACTORY => {
|
||||||
@@ -270,17 +302,15 @@ pub fn address_map(
|
|||||||
{
|
{
|
||||||
let add_pool =
|
let add_pool =
|
||||||
abi::meta_pool_factory::functions::DeployPlainPool1::match_and_decode(call)
|
abi::meta_pool_factory::functions::DeployPlainPool1::match_and_decode(call)
|
||||||
.map(
|
.map(|add_pool| abi::meta_pool_factory::functions::DeployPlainPool3 {
|
||||||
|add_pool| abi::meta_pool_factory::functions::DeployPlainPool3 {
|
name: add_pool.name,
|
||||||
name: add_pool.name,
|
symbol: add_pool.symbol,
|
||||||
symbol: add_pool.symbol,
|
coins: add_pool.coins,
|
||||||
coins: add_pool.coins,
|
a: add_pool.a,
|
||||||
a: add_pool.a,
|
fee: add_pool.fee,
|
||||||
fee: add_pool.fee,
|
asset_type: BigInt::from(0),
|
||||||
asset_type: BigInt::from(0),
|
implementation_idx: BigInt::from(0),
|
||||||
implementation_idx: BigInt::from(0),
|
})
|
||||||
},
|
|
||||||
)
|
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
abi::meta_pool_factory::functions::DeployPlainPool2::match_and_decode(
|
abi::meta_pool_factory::functions::DeployPlainPool2::match_and_decode(
|
||||||
call,
|
call,
|
||||||
@@ -302,69 +332,81 @@ pub fn address_map(
|
|||||||
call,
|
call,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
Some(tycho::ProtocolComponent {
|
Some(ProtocolComponent {
|
||||||
id: hex::encode(&call.return_data),
|
id: hex::encode(&call.return_data),
|
||||||
|
tx: Some(Transaction {
|
||||||
|
to: tx.to.clone(),
|
||||||
|
from: tx.from.clone(),
|
||||||
|
hash: tx.hash.clone(),
|
||||||
|
index: tx.index.into(),
|
||||||
|
}),
|
||||||
tokens: pool_added.coins.into(),
|
tokens: pool_added.coins.into(),
|
||||||
contracts: vec![call_address.into(), call.return_data.clone()],
|
contracts: vec![call_address.into(), call.return_data.clone()],
|
||||||
static_att: vec![
|
static_att: vec![
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "pool_type".into(),
|
name: "pool_type".into(),
|
||||||
value: "PlainPool".into(),
|
value: "PlainPool".into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "name".into(),
|
name: "name".into(),
|
||||||
value: add_pool.name.into(),
|
value: add_pool.name.into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "fee".into(),
|
name: "fee".into(),
|
||||||
value: add_pool.fee.to_string().into(),
|
value: add_pool.fee.to_string().into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
tycho::Attribute {
|
Attribute {
|
||||||
name: "a".into(),
|
name: "a".into(),
|
||||||
value: add_pool.a.to_string().into(),
|
value: add_pool.a.to_string().into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
} else if let Some(pool_added) =
|
} else if let Some(pool_added) =
|
||||||
abi::meta_pool_factory::events::MetaPoolDeployed::match_and_decode(log)
|
abi::meta_pool_factory::events::MetaPoolDeployed::match_and_decode(log)
|
||||||
{
|
{
|
||||||
let add_pool =
|
let add_pool =
|
||||||
abi::meta_pool_factory::functions::DeployMetapool1::match_and_decode(call)
|
abi::meta_pool_factory::functions::DeployMetapool1::match_and_decode(call)
|
||||||
.map(
|
.map(|add_pool| abi::meta_pool_factory::functions::DeployMetapool2 {
|
||||||
|add_pool| abi::meta_pool_factory::functions::DeployMetapool2 {
|
base_pool: add_pool.base_pool,
|
||||||
base_pool: add_pool.base_pool,
|
name: add_pool.name,
|
||||||
name: add_pool.name,
|
symbol: add_pool.symbol,
|
||||||
symbol: add_pool.symbol,
|
coin: add_pool.coin,
|
||||||
coin: add_pool.coin,
|
a: add_pool.a,
|
||||||
a: add_pool.a,
|
fee: add_pool.fee,
|
||||||
fee: add_pool.fee,
|
implementation_idx: BigInt::from(0),
|
||||||
implementation_idx: BigInt::from(0),
|
})
|
||||||
},
|
|
||||||
)
|
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
abi::meta_pool_factory::functions::DeployMetapool2::match_and_decode(
|
abi::meta_pool_factory::functions::DeployMetapool2::match_and_decode(
|
||||||
call,
|
call,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
Some(tycho::ProtocolComponent {
|
Some(ProtocolComponent {
|
||||||
id: hex::encode(&call.return_data),
|
id: hex::encode(&call.return_data),
|
||||||
|
tx: Some(Transaction {
|
||||||
|
to: tx.to.clone(),
|
||||||
|
from: tx.from.clone(),
|
||||||
|
hash: tx.hash.clone(),
|
||||||
|
index: tx.index.into(),
|
||||||
|
}),
|
||||||
tokens: vec![pool_added.coin, add_pool.base_pool.clone()],
|
tokens: vec![pool_added.coin, add_pool.base_pool.clone()],
|
||||||
contracts: vec![
|
contracts: vec![
|
||||||
call_address.into(),
|
call_address.into(),
|
||||||
call.return_data.clone(),
|
call.return_data.clone(),
|
||||||
add_pool.base_pool.clone(),
|
add_pool.base_pool.clone(),
|
||||||
],
|
],
|
||||||
static_att: vec![tycho::Attribute {
|
static_att: vec![Attribute {
|
||||||
name: "pool_type".into(),
|
name: "pool_type".into(),
|
||||||
value: "MetaPool".into(),
|
value: "MetaPool".into(),
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
}],
|
}],
|
||||||
change: tycho::ChangeType::Creation.into(),
|
change: ChangeType::Creation.into(),
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ protobuf:
|
|||||||
- tycho/evm/v1/vm.proto
|
- tycho/evm/v1/vm.proto
|
||||||
- tycho/evm/v1/common.proto
|
- tycho/evm/v1/common.proto
|
||||||
importPaths:
|
importPaths:
|
||||||
- ../../proto/tycho/evm/v1/
|
- ../../proto
|
||||||
- ./proto
|
- ./proto
|
||||||
|
|
||||||
binaries:
|
binaries:
|
||||||
|
|||||||
Reference in New Issue
Block a user