Skip to content

Commit

Permalink
fix: conversion from price to ratio reciprocal error
Browse files Browse the repository at this point in the history
  • Loading branch information
cytadela8 committed Sep 26, 2024
1 parent c654506 commit 3b219d0
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 8 deletions.
9 changes: 6 additions & 3 deletions core/lib/external_price_api/src/coingecko_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl CoinGeckoPriceAPIClient {
}
}

/// returns ETH/BaseToken price of a token by address
async fn get_token_price_by_address(&self, address: Address) -> anyhow::Result<f64> {
let address_str = address_to_string(&address);
let price_url = self
Expand Down Expand Up @@ -87,11 +88,13 @@ impl CoinGeckoPriceAPIClient {
impl PriceAPIClient for CoinGeckoPriceAPIClient {
async fn fetch_ratio(&self, token_address: Address) -> anyhow::Result<BaseTokenAPIRatio> {
let base_token_in_eth = self.get_token_price_by_address(token_address).await?;
let (numerator, denominator) = get_fraction(base_token_in_eth);
let (num_in_eth, denom_in_eth) = get_fraction(base_token_in_eth);
// take reciprocal of price as returned price is ETH/BaseToken and BaseToken/ETH is needed
let (num_in_base, denom_in_base) = (denom_in_eth, num_in_eth);

return Ok(BaseTokenAPIRatio {
numerator,
denominator,
numerator: num_in_base,
denominator: denom_in_base,
ratio_timestamp: Utc::now(),
});
}
Expand Down
2 changes: 1 addition & 1 deletion core/lib/external_price_api/src/forced_price_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use zksync_types::{base_token_ratio::BaseTokenAPIRatio, Address};

use crate::PriceAPIClient;

// Struct for a a forced price "client" (conversion ratio is always a configured "forced" ratio).
// Struct for a forced price "client" (conversion ratio is always a configured "forced" ratio).
#[derive(Debug, Clone)]
pub struct ForcedPriceClient {
ratio: BaseTokenAPIRatio,
Expand Down
1 change: 1 addition & 0 deletions core/lib/external_price_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use zksync_types::{base_token_ratio::BaseTokenAPIRatio, Address};
#[async_trait]
pub trait PriceAPIClient: Sync + Send + fmt::Debug + 'static {
/// Returns the BaseToken<->ETH ratio for the input token address.
/// The returned unit is BaseToken/ETH. Example if 1 BaseToken = 0.002 ETH, then ratio is 500/1
async fn fetch_ratio(&self, token_address: Address) -> anyhow::Result<BaseTokenAPIRatio>;
}

Expand Down
10 changes: 6 additions & 4 deletions core/lib/external_price_api/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@ pub(crate) async fn happy_day_test(setup: SetupFn) {
let server = MockServer::start();
let address_str = "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"; //Uniswap (UNI)
let address = Address::from_str(address_str).unwrap();
let base_token_price = 198.9;
let base_token_price = 0.00269; //ETH costs one token

let SetupResult { client } = setup(&server, address, base_token_price);
let api_price = client.fetch_ratio(address).await.unwrap();

let (numerator, denominator) = get_fraction(base_token_price);
let (num_in_eth, denom_in_eth) = get_fraction(base_token_price);
let (ratio_num, ratio_denom) = (denom_in_eth, num_in_eth);
assert!(((ratio_num.get() as f64) / (ratio_denom.get() as f64) - 371.74).abs() < 0.1);

assert_eq!(
BaseTokenAPIRatio {
numerator,
denominator,
numerator: ratio_num,
denominator: ratio_denom,
ratio_timestamp: api_price.ratio_timestamp,
},
api_price
Expand Down

0 comments on commit 3b219d0

Please sign in to comment.