refactor(substreams): Update ambient Substreams
This commit is contained in:
170
substreams/ethereum-ambient/src/contracts/main.rs
Normal file
170
substreams/ethereum-ambient/src/contracts/main.rs
Normal file
@@ -0,0 +1,170 @@
|
||||
use anyhow::{anyhow, bail};
|
||||
use tycho_substreams::models::{
|
||||
Attribute, ChangeType, FinancialType, ImplementationType, ProtocolComponent, ProtocolType,
|
||||
Transaction,
|
||||
};
|
||||
|
||||
use crate::utils::{decode_flows_from_output, encode_pool_hash};
|
||||
use ethabi::{decode, ParamType};
|
||||
use hex_literal::hex;
|
||||
use substreams_ethereum::pb::eth::v2::Call;
|
||||
|
||||
pub const AMBIENT_CONTRACT: [u8; 20] = hex!("aaaaaaaaa24eeeb8d57d431224f73832bc34f688");
|
||||
pub const USER_CMD_FN_SIG: [u8; 4] = hex!("a15112f9");
|
||||
|
||||
const USER_CMD_EXTERNAL_ABI: &[ParamType] = &[
|
||||
// index of the proxy sidecar the command is being called on
|
||||
ParamType::Uint(16),
|
||||
// call data for internal UserCmd method
|
||||
ParamType::Bytes,
|
||||
];
|
||||
const USER_CMD_INTERNAL_ABI: &[ParamType] = &[
|
||||
ParamType::Uint(8), // command
|
||||
ParamType::Address, // base
|
||||
ParamType::Address, // quote
|
||||
ParamType::Uint(256), // pool index
|
||||
ParamType::Uint(128), // price
|
||||
];
|
||||
|
||||
pub const INIT_POOL_CODE: u8 = 71;
|
||||
|
||||
pub const SWAP_ABI_INPUT: &[ParamType] = &[
|
||||
ParamType::Address, // base
|
||||
ParamType::Address, // quote
|
||||
ParamType::Uint(256), // pool index
|
||||
// isBuy - if true the direction of the swap is for the user to send base
|
||||
// tokens and receive back quote tokens.
|
||||
ParamType::Bool,
|
||||
ParamType::Bool, // inBaseQty
|
||||
ParamType::Uint(128), //qty
|
||||
ParamType::Uint(16), // poolTip
|
||||
ParamType::Uint(128), // limitPrice
|
||||
ParamType::Uint(128), // minOut
|
||||
ParamType::Uint(8), // reserveFlags
|
||||
];
|
||||
|
||||
// MicroPaths fn sigs
|
||||
pub const SWAP_FN_SIG: [u8; 4] = hex!("3d719cd9");
|
||||
|
||||
pub fn decode_direct_swap_call(
|
||||
call: &Call,
|
||||
) -> Result<([u8; 32], ethabi::Int, ethabi::Int), anyhow::Error> {
|
||||
if let Ok(external_input_params) = decode(SWAP_ABI_INPUT, &call.input[4..]) {
|
||||
let base_token = external_input_params[0]
|
||||
.to_owned()
|
||||
.into_address()
|
||||
.ok_or_else(|| {
|
||||
anyhow!(
|
||||
"Failed to convert base token to address for direct swap call: {:?}",
|
||||
&external_input_params[0]
|
||||
)
|
||||
})?
|
||||
.to_fixed_bytes()
|
||||
.to_vec();
|
||||
|
||||
let quote_token = external_input_params[1]
|
||||
.to_owned()
|
||||
.into_address()
|
||||
.ok_or_else(|| {
|
||||
anyhow!(
|
||||
"Failed to convert quote token to address for direct swap call: {:?}",
|
||||
&external_input_params[1]
|
||||
)
|
||||
})?
|
||||
.to_fixed_bytes()
|
||||
.to_vec();
|
||||
|
||||
let mut pool_index_buf = [0u8; 32];
|
||||
external_input_params[2]
|
||||
.to_owned()
|
||||
.into_uint()
|
||||
.ok_or_else(|| {
|
||||
anyhow!("Failed to convert pool index to u32 for direct swap call".to_string())
|
||||
})?
|
||||
.to_big_endian(&mut pool_index_buf);
|
||||
let pool_index = pool_index_buf.to_vec();
|
||||
|
||||
let (base_flow, quote_flow) = decode_flows_from_output(call)?;
|
||||
let pool_hash = encode_pool_hash(base_token, quote_token, pool_index);
|
||||
Ok((pool_hash, base_flow, quote_flow))
|
||||
} else {
|
||||
bail!("Failed to decode swap call inputs.".to_string());
|
||||
}
|
||||
}
|
||||
pub fn decode_pool_init(
|
||||
call: &Call,
|
||||
tx: Transaction,
|
||||
) -> Result<Option<ProtocolComponent>, anyhow::Error> {
|
||||
// Decode external call to UserCmd
|
||||
if let Ok(external_params) = decode(USER_CMD_EXTERNAL_ABI, &call.input[4..]) {
|
||||
let cmd_bytes = external_params[1]
|
||||
.to_owned()
|
||||
.into_bytes()
|
||||
.ok_or_else(|| anyhow!("Failed to convert to bytes: {:?}", &external_params[1]))?;
|
||||
|
||||
// Call data is structured differently depending on the cmd code, so only
|
||||
// decode if this is an init pool code.
|
||||
if cmd_bytes[31] == INIT_POOL_CODE {
|
||||
// Decode internal call to UserCmd
|
||||
if let Ok(internal_params) = decode(USER_CMD_INTERNAL_ABI, &cmd_bytes) {
|
||||
let base = internal_params[1]
|
||||
.to_owned()
|
||||
.into_address()
|
||||
.ok_or_else(|| {
|
||||
anyhow!("Failed to convert to address: {:?}", &internal_params[1])
|
||||
})?
|
||||
.to_fixed_bytes()
|
||||
.to_vec();
|
||||
|
||||
let quote = internal_params[2]
|
||||
.to_owned()
|
||||
.into_address()
|
||||
.ok_or_else(|| {
|
||||
anyhow!("Failed to convert to address: {:?}", &internal_params[2])
|
||||
})?
|
||||
.to_fixed_bytes()
|
||||
.to_vec();
|
||||
|
||||
let mut pool_index_buf = [0u8; 32];
|
||||
internal_params[3]
|
||||
.to_owned()
|
||||
.into_uint()
|
||||
.ok_or_else(|| anyhow!("Failed to convert to u32".to_string()))?
|
||||
.to_big_endian(&mut pool_index_buf);
|
||||
let pool_index = pool_index_buf.to_vec();
|
||||
let pool_hash = encode_pool_hash(base.clone(), quote.clone(), pool_index.clone());
|
||||
|
||||
let static_attribute = Attribute {
|
||||
name: String::from("pool_index"),
|
||||
value: pool_index,
|
||||
change: ChangeType::Creation.into(),
|
||||
};
|
||||
|
||||
let mut tokens: Vec<Vec<u8>> = vec![base.clone(), quote.clone()];
|
||||
tokens.sort();
|
||||
|
||||
let new_component = ProtocolComponent {
|
||||
id: hex::encode(pool_hash),
|
||||
tokens,
|
||||
contracts: vec![AMBIENT_CONTRACT.to_vec()],
|
||||
static_att: vec![static_attribute],
|
||||
change: ChangeType::Creation.into(),
|
||||
protocol_type: Some(ProtocolType {
|
||||
name: "ambient_pool".to_string(),
|
||||
attribute_schema: vec![],
|
||||
financial_type: FinancialType::Swap.into(),
|
||||
implementation_type: ImplementationType::Vm.into(),
|
||||
}),
|
||||
tx: Some(tx.clone()),
|
||||
};
|
||||
Ok(Some(new_component))
|
||||
} else {
|
||||
bail!("Failed to decode ABI internal call.".to_string());
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
bail!("Failed to decode ABI external call.".to_string());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user