Skip to content

Commit

Permalink
[Native Bridge] Support other vault balances
Browse files Browse the repository at this point in the history
  • Loading branch information
williampsmith committed Nov 26, 2024
1 parent a139ef2 commit 8002ff0
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 40 deletions.
28 changes: 23 additions & 5 deletions crates/sui-bridge-indexer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ use mysten_metrics::start_prometheus_server;

use sui_bridge::metrics::BridgeMetrics;
use sui_bridge::sui_bridge_watchdog::{
eth_bridge_status::EthBridgeStatus, eth_vault_balance::EthVaultBalance,
metrics::WatchdogMetrics, sui_bridge_status::SuiBridgeStatus, BridgeWatchDog,
eth_bridge_status::EthBridgeStatus,
eth_vault_balance::{EthereumVaultBalance, VaultAsset},
metrics::WatchdogMetrics,
sui_bridge_status::SuiBridgeStatus,
BridgeWatchDog,
};
use sui_bridge_indexer::config::IndexerConfig;
use sui_bridge_indexer::metrics::BridgeIndexerMetrics;
Expand Down Expand Up @@ -143,15 +146,29 @@ async fn start_watchdog(
let watchdog_metrics = WatchdogMetrics::new(registry);
let eth_provider =
Arc::new(new_metered_eth_provider(&config.eth_rpc_url, bridge_metrics.clone()).unwrap());
let (_committee_address, _limiter_address, vault_address, _config_address, weth_address) =
get_eth_contract_addresses(eth_bridge_proxy_address, &eth_provider).await?;
let (
_committee_address,
_limiter_address,
vault_address,
_config_address,
weth_address,
usdt_address,
) = get_eth_contract_addresses(eth_bridge_proxy_address, &eth_provider).await?;

let eth_vault_balance = EthVaultBalance::new(
let eth_vault_balance = EthereumVaultBalance::new(
eth_provider.clone(),
vault_address,
weth_address,
VaultAsset::WETH,
watchdog_metrics.eth_vault_balance.clone(),
);
let usdt_vault_balance = EthereumVaultBalance::new(
eth_provider.clone(),
vault_address,
usdt_address,
VaultAsset::USDT,
watchdog_metrics.usdt_vault_balance.clone(),
);

let eth_bridge_status = EthBridgeStatus::new(
eth_provider,
Expand All @@ -163,6 +180,7 @@ async fn start_watchdog(
SuiBridgeStatus::new(sui_client, watchdog_metrics.sui_bridge_paused.clone());
let observables: Vec<Box<dyn Observable + Send + Sync>> = vec![
Box::new(eth_vault_balance),
Box::new(usdt_vault_balance),
Box::new(eth_bridge_status),
Box::new(sui_bridge_status),
];
Expand Down
37 changes: 25 additions & 12 deletions crates/sui-bridge-watchdog/eth_vault_balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,43 @@ use sui_bridge::metered_eth_provider::MeteredEthHttpProvier;
use tokio::time::Duration;
use tracing::{error, info};

const TEN_ZEROS: u64 = 10_u64.pow(10);
pub enum VaultAsset {
WETH,
USDT,
}

pub struct EthVaultBalance {
pub struct EthereumVaultBalance {
coin_contract: EthERC20<Provider<MeteredEthHttpProvier>>,
asset: VaultAsset,
decimals: u32,
vault_address: EthAddress,
ten_zeros: U256,
metric: IntGauge,
}

impl EthVaultBalance {
impl EthereumVaultBalance {
pub fn new(
provider: Arc<Provider<MeteredEthHttpProvier>>,
vault_address: EthAddress,
coin_address: EthAddress, // for now this only support one coin which is WETH
asset: VaultAsset,
metric: IntGauge,
) -> Self {
let ten_zeros = U256::from(TEN_ZEROS);
let coin_contract = EthERC20::new(coin_address, provider);
let decimals = coin_contract.decimals().call().await?;
Self {
coin_contract,
vault_address,
ten_zeros,
decimals,
asset,
metric,
}
}
}

#[async_trait]
impl Observable for EthVaultBalance {
impl Observable for EthereumVaultBalance {
fn name(&self) -> &str {
"EthVaultBalance"
"EthereumVaultBalance"
}

async fn observe_and_report(&self) {
Expand All @@ -55,13 +61,20 @@ impl Observable for EthVaultBalance {
Ok(balance) => {
// Why downcasting is safe:
// 1. On Ethereum we only take the first 8 decimals into account,
// meaning the trailing 10 digits can be ignored
// meaning the trailing 10 digits can be ignored. For other assets,
// we will also assume this max level of precision for metrics purposes.
// 2. i64::MAX is 9_223_372_036_854_775_807, with 8 decimal places is
// 92_233_720_368. We likely won't see any balance higher than this
// in the next 12 months.
let balance = (balance / self.ten_zeros).as_u64() as i64;
self.metric.set(balance);
info!("Eth Vault Balance: {:?}", balance);
// For USDT, for example, this will be 10^6 - 8 = 10^(-2) = 0.01,
// therefore we will add 2 zeroes of precision.
let denom = U256::from(10).pow(self.decimals - 8);
let normalized_balance = (balance / denom).as_u64() as i64;
self.metric.set(normalized_balance);
info!(
"{} Vault Balance: {:?} (${:?} {})",
self.asset, balance, normalized_balance, denom
);
}
Err(e) => {
error!("Error getting balance from vault: {:?}", e);
Expand Down
27 changes: 21 additions & 6 deletions crates/sui-bridge/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::config::WatchdogConfig;
use crate::crypto::BridgeAuthorityPublicKeyBytes;
use crate::metered_eth_provider::MeteredEthHttpProvier;
use crate::sui_bridge_watchdog::eth_bridge_status::EthBridgeStatus;
use crate::sui_bridge_watchdog::eth_vault_balance::EthVaultBalance;
use crate::sui_bridge_watchdog::eth_vault_balance::{EthereumVaultBalance, VaultAsset};
use crate::sui_bridge_watchdog::metrics::WatchdogMetrics;
use crate::sui_bridge_watchdog::sui_bridge_status::SuiBridgeStatus;
use crate::sui_bridge_watchdog::total_supplies::TotalSupplies;
Expand Down Expand Up @@ -158,17 +158,31 @@ async fn start_watchdog(
sui_client: Arc<SuiBridgeClient>,
) {
let watchdog_metrics = WatchdogMetrics::new(registry);
let (_committee_address, _limiter_address, vault_address, _config_address, weth_address) =
get_eth_contract_addresses(eth_bridge_proxy_address, &eth_provider)
.await
.unwrap_or_else(|e| panic!("get_eth_contract_addresses should not fail: {}", e));
let (
_committee_address,
_limiter_address,
vault_address,
_config_address,
weth_address,
usdt_address,
) = get_eth_contract_addresses(eth_bridge_proxy_address, &eth_provider)
.await
.unwrap_or_else(|e| panic!("get_eth_contract_addresses should not fail: {}", e));

let eth_vault_balance = EthVaultBalance::new(
let eth_vault_balance = EthereumVaultBalance::new(
eth_provider.clone(),
vault_address,
weth_address,
VaultAsset::WETH,
watchdog_metrics.eth_vault_balance.clone(),
);
let usdt_vault_balance = EthereumVaultBalance::new(
eth_provider.clone(),
vault_address,
usdt_address,
VaultAsset::USDT,
watchdog_metrics.usdt_vault_balance.clone(),
);

let eth_bridge_status = EthBridgeStatus::new(
eth_provider,
Expand All @@ -183,6 +197,7 @@ async fn start_watchdog(

let mut observables: Vec<Box<dyn Observable + Send + Sync>> = vec![
Box::new(eth_vault_balance),
Box::new(usdt_vault_balance),
Box::new(eth_bridge_status),
Box::new(sui_bridge_status),
];
Expand Down
45 changes: 29 additions & 16 deletions crates/sui-bridge/src/sui_bridge_watchdog/eth_vault_balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,43 @@ use std::sync::Arc;
use tokio::time::Duration;
use tracing::{error, info};

const TEN_ZEROS: u64 = 10_u64.pow(10);
pub enum VaultAsset {
WETH,
USDT,
}

pub struct EthVaultBalance {
pub struct EthereumVaultBalance {
coin_contract: EthERC20<Provider<MeteredEthHttpProvier>>,
asset: VaultAsset,
decimals: u32,
vault_address: EthAddress,
ten_zeros: U256,
metric: IntGauge,
}

impl EthVaultBalance {
pub fn new(
impl EthereumVaultBalance {
pub async fn new(
provider: Arc<Provider<MeteredEthHttpProvier>>,
vault_address: EthAddress,
coin_address: EthAddress, // for now this only support one coin which is WETH
asset: VaultAsset,
metric: IntGauge,
) -> Self {
let ten_zeros = U256::from(TEN_ZEROS);
) -> Result<Self> {
let coin_contract = EthERC20::new(coin_address, provider);
Self {
let decimals = coin_contract.decimals().call().await?;
Ok(Self {
coin_contract,
vault_address,
ten_zeros,
decimals,
asset,
metric,
}
})
}
}

#[async_trait]
impl Observable for EthVaultBalance {
impl Observable for EthereumVaultBalance {
fn name(&self) -> &str {
"EthVaultBalance"
"EthereumVaultBalance"
}

async fn observe_and_report(&self) {
Expand All @@ -55,13 +61,20 @@ impl Observable for EthVaultBalance {
Ok(balance) => {
// Why downcasting is safe:
// 1. On Ethereum we only take the first 8 decimals into account,
// meaning the trailing 10 digits can be ignored
// meaning the trailing 10 digits can be ignored. For other assets,
// we will also assume this max level of precision for metrics purposes.
// 2. i64::MAX is 9_223_372_036_854_775_807, with 8 decimal places is
// 92_233_720_368. We likely won't see any balance higher than this
// in the next 12 months.
let balance = (balance / self.ten_zeros).as_u64() as i64;
self.metric.set(balance);
info!("Eth Vault Balance: {:?}", balance);
// For USDT, for example, this will be 10^6 - 8 = 10^(-2) = 0.01,
// therefore we will add 2 zeroes of precision.
let denom = U256::from(10).pow(self.decimals - 8);
let normalized_balance = (balance / denom).as_u64() as i64;
self.metric.set(normalized_balance);
info!(
"{} Vault Balance: {:?} (${:?} {})",
self.asset, balance, normalized_balance, denom
);
}
Err(e) => {
error!("Error getting balance from vault: {:?}", e);
Expand Down
7 changes: 7 additions & 0 deletions crates/sui-bridge/src/sui_bridge_watchdog/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use prometheus::{
#[derive(Clone, Debug)]
pub struct WatchdogMetrics {
pub eth_vault_balance: IntGauge,
pub usdt_vault_balance: IntGauge,
pub total_supplies: IntGaugeVec,
pub eth_bridge_paused: IntGauge,
pub sui_bridge_paused: IntGauge,
Expand All @@ -23,6 +24,12 @@ impl WatchdogMetrics {
registry,
)
.unwrap(),
usdt_vault_balance: register_int_gauge_with_registry!(
"bridge_usdt_vault_balance",
"Current balance of usdt eth vault",
registry,
)
.unwrap(),
total_supplies: register_int_gauge_vec_with_registry!(
"bridge_total_supplies",
"Current total supplies of coins on Sui based on Treasury Cap",
Expand Down
11 changes: 10 additions & 1 deletion crates/sui-bridge/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,21 @@ pub fn generate_bridge_client_key_and_write_to_file(
pub async fn get_eth_contract_addresses<P: ethers::providers::JsonRpcClient + 'static>(
bridge_proxy_address: EthAddress,
provider: &Arc<Provider<P>>,
) -> anyhow::Result<(EthAddress, EthAddress, EthAddress, EthAddress, EthAddress)> {
) -> anyhow::Result<(
EthAddress,
EthAddress,
EthAddress,
EthAddress,
EthAddress,
EthAddress,
)> {
let sui_bridge = EthSuiBridge::new(bridge_proxy_address, provider.clone());
let committee_address: EthAddress = sui_bridge.committee().call().await?;
let limiter_address: EthAddress = sui_bridge.limiter().call().await?;
let vault_address: EthAddress = sui_bridge.vault().call().await?;
let vault = EthBridgeVault::new(vault_address, provider.clone());
let weth_address: EthAddress = vault.w_eth().call().await?;
let usdt_address: EthAddress = vault.usdt().call().await?;
let committee = EthBridgeCommittee::new(committee_address, provider.clone());
let config_address: EthAddress = committee.config().call().await?;

Expand All @@ -123,6 +131,7 @@ pub async fn get_eth_contract_addresses<P: ethers::providers::JsonRpcClient + 's
vault_address,
config_address,
weth_address,
usdt_address,
))
}

Expand Down

0 comments on commit 8002ff0

Please sign in to comment.