Skip to content

Commit

Permalink
feat: Add Bitget exchange (#256)
Browse files Browse the repository at this point in the history
- Add Bitget crypto exchange
  • Loading branch information
nategurian authored Feb 14, 2024
1 parent 064147f commit 2589353
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 105 deletions.
7 changes: 7 additions & 0 deletions src/xrc-tests/src/mock_responses/exchanges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ where
]
}
}),
Exchange::Bitget(_) => json!({
"code":"00000",
"data":[
[timestamp.to_string(), rate,"1.00", "1.00","1.00","1.00","1.00"],
]
}),
};
let bytes = serde_json::to_vec(&json).expect("Failed to build exchange response.");
ResponseBody::Json(bytes)
Expand All @@ -102,5 +108,6 @@ pub fn build_common_responses(
xrc::Exchange::Mexc(_) => Some("46.101"),
xrc::Exchange::Poloniex(_) => Some("46.022"),
xrc::Exchange::CryptoCom(_) => Some("41.96000000"),
xrc::Exchange::Bitget(_) => Some("44.93"),
})
}
6 changes: 6 additions & 0 deletions src/xrc-tests/src/mock_responses/stablecoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ fn sample_stablecoin_json(exchange: &Exchange) -> ResponseBody {
]
}
}),
Exchange::Bitget(_) => json!({
"code":"00000",
"data":[
["1614596340","0.97","1.00", "1.00","1.00","1.00","1.00"],
]
}),
};
ResponseBody::Json(serde_json::to_vec(&json).expect("Failed to encode JSON to bytes"))
}
Expand Down
151 changes: 106 additions & 45 deletions src/xrc-tests/src/tests/basic_exchange_rates.rs

Large diffs are not rendered by default.

34 changes: 18 additions & 16 deletions src/xrc-tests/src/tests/caching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,22 @@ use crate::{
///
/// Crypto-pair (retrieve ICP/BTC rate)
/// 0. The XRC retrieves the ICP/USDT rate.
/// a. ICP/USDT rates: [ 3900000000, 3900000000, 3910000000, 3911000000, 3920000000, 3920000000, 4005000000, ]
/// a. ICP/USDT rates: [ 3900000000, 3900000000, 3910000000, 3911000000, 3920000000, 3920000000, 3930000000, 4005000000, ]
/// 1. The XRC retrieves the BTC/USDT rate.
/// a. BTC/USDT rates: [ 41960000000, 42030000000, 42640000000, 44250000000, 44833000000, 46022000000, 46101000000, ]
/// a. BTC/USDT rates: [ 41960000000, 42030000000, 42640000000, 44250000000, 44833000000, 44930000000, 46022000000, 46101000000, ]
/// 2. The XRC divides ICP/USDT by BTC/USDT. The division inverts BTC/USDT to USDT/BTC then multiplies ICP/USDT and USDT/BTC
/// to get the resulting ICP/BTC rate.
/// a. ICP/BTC rates: [ 84596861, 84596861, 84742078, 84742078, 84813776, 84835468, 84959365, 84981094,
/// 85030691, 85030691, 85176652, 85176652, 86874469, 86989492, 86989492, 87023595,
/// 87212542, 87234847, 87435592, 87435592, 88135593, 88135593, 88361581, 88384180,
/// 88587570, 88587570, 89331516, 90508474, 91463412, 91463412, 91697933, 91721386,
/// 91932455, 91932455, 92790863, 92790863, 92945661, 92945661, 93028788, 93052580,
/// 93183984, 93207816, 93266713, 93266713, 93422306, 93422306, 93925888, 95289078,
/// a. ICP/BTC rates: [ 84596861, 84596861, 84742078, 84742078, 84813776, 84835468, 84959365, 84981094, 85030691,
/// 85030691, 85176652, 85176652, 85247608, 85393942, 86801691, 86801691, 86874469, 86989492,
/// 86989492, 87023595, 87024259, 87046516, 87212542, 87234847, 87246828, 87246828, 87435592,
/// 87435592, 87469396, 87658644, 88135593, 88135593, 88361581, 88384180, 88587570, 88587570,
/// 88813559, 89138660, 89331516, 90508474, 91463412, 91463412, 91697933, 91721386, 91932455,
/// 91932455, 92166979, 92790863, 92790863, 92945661, 92945661, 93028788, 93052580, 93183984,
/// 93207816, 93266713, 93266713, 93422306, 93422306, 93925888, 93504639, 93660629, 95289078,
/// 95448045 ]
/// 3. The XRC returns the median rate and the standard deviation from the BTC/ICP rates.
/// a. The median rate from step 2 is 88587570.
/// b. The standard deviation from step 2 is 3483761.
/// a. The median rate from step 2 is 88248587.
/// b. The standard deviation from step 2 is 3320321.
#[ignore]
#[test]
fn caching() {
Expand Down Expand Up @@ -76,14 +77,14 @@ fn caching() {
class: AssetClass::Cryptocurrency,
},
timestamp: timestamp_seconds,
rate: 88_587_570,
rate: 88_248_587,
metadata: ExchangeRateMetadata {
decimals: 9,
base_asset_num_queried_sources: 7,
base_asset_num_received_rates: 7,
quote_asset_num_queried_sources: 7,
quote_asset_num_received_rates: 7,
standard_deviation: 3_483_761,
base_asset_num_queried_sources: 8,
base_asset_num_received_rates: 8,
quote_asset_num_queried_sources: 8,
quote_asset_num_received_rates: 8,
standard_deviation: 3_320_321,
forex_timestamp: None,
},
};
Expand All @@ -99,6 +100,7 @@ fn caching() {
xrc::Exchange::Mexc(_) => Some("3.911"),
xrc::Exchange::Poloniex(_) => Some("4.005"),
xrc::Exchange::CryptoCom(_) => Some("3.91"),
xrc::Exchange::Bitget(_) => Some("3.93"),
},
)
.chain(mock_responses::exchanges::build_common_responses(
Expand Down
62 changes: 33 additions & 29 deletions src/xrc-tests/src/tests/get_icp_xdr_rate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,39 @@ use crate::{
/// i. For all requests in the following test, this should result in a CXDR/USD with the following rates: [ 1336769190, 1336769190 ].
/// 1. The XRC retrieves the ICP/USDT rates from the mock exchange responses (request 1 responses).
/// i. For request 1, this should result in the following rates discovered:
/// GateIo Okx Crypto Mexc Coinbase KuCoin Poloniex
/// [ 3900000000, 3900000000, 3910000000, 3911000000, 3920000000, 3920000000, 4005000000, ]
/// GateIo Okx Crypto Mexc Coinbase KuCoin Bitget Poloniex
/// [ 3900000000, 3900000000, 3910000000, 3911000000, 3920000000, 3920000000, 3930000000, 4005000000]
/// 2. The XRC retrieves the stablecoin rates from the mock exchanges.
/// i. For request 1, DAI: [ 950000000, 990000000, 990000000, 1000000000, 1020000000, 1030927835 ]
/// ii. For request 1, USDC: [ 950000000, 990000000, 990000000, 1000000000, 1020000000, 1030927835 ]
/// ii. For request 1, USDC: [ 950000000, 970000000, 970000000, 990099009, 1010101010, 1010101010, 1020000000 ]
/// 3. The XRC determines if USDT has not depegged. If it has not depegged, it returns the USDT/USD rate.
/// i. For request 1, USDT/USD: [ 970000000, 980392156, 1000000000, 1010101010, 1010101010, 1052631578 ]
/// i. For request 1, USDT/USD: [ 980392156, 990000000, 990000000, 1010000000, 1030927835, 1030927835, 1052631578 ]
/// 4. The XRC then multiplies the USDT/USD rate (step 3) with the ICP/USDT rate (step 1) to get the ICP/USD rate.
/// i. For request 1, this results in the following rates:
/// [ 3783000000, 3783000000, 3792700000, 3793670000, 3802400000, 3802400000, 3823529408, 3823529408,
/// 3833333329, 3834313722, 3843137251, 3843137251, 3884850000, 3900000000, 3900000000, 3910000000,
/// 3911000000, 3920000000, 3920000000, 3926470584, 3939393939, 3939393939, 3939393939, 3939393939,
/// 3949494949, 3949494949, 3950505050, 3950505050, 3959595959, 3959595959, 3959595959, 3959595959,
// 4005000000, 4045454545, 4045454545, 4105263154, 4105263154, 4115789469, 4116842101, 4126315785,
// 4126315785, 4215789469, ]
/// [ 3823529408, 3823529408, 3833333329, 3834313722, 3843137251, 3843137251, 3852941173, 3861000000, 3861000000, 3861000000,
/// 3861000000, 3870900000, 3870900000, 3871890000, 3871890000, 3880800000, 3880800000, 3880800000, 3880800000, 3890700000,
/// 3890700000, 3926470584, 3939000000, 3939000000, 3949100000, 3950110000, 3959200000, 3959200000, 3964950000, 3964950000,
/// 3969300000, 4020618556, 4020618556, 4020618556, 4020618556, 4030927834, 4030927834, 4031958762, 4031958762, 4041237113,
/// 4041237113, 4041237113, 4041237113, 4045050000, 4051546391, 4051546391, 4105263154, 4105263154, 4115789469, 4116842101,
/// 4126315785, 4126315785, 4128865979, 4128865979, 4136842101, 4215789469 ]
/// 5. The XRC divides the ICP/USD by the forex rate CXDR/USD. The division works by inverting CXDR/USD to USD/CXDR then multiplying
/// USD/CXDR and ICP/USD resulting in ICP/CXDR.
/// i. For request 1, this results in the following rates:
/// [ 2829957503, 2829957503, 2829957503, 2829957503, 2837213804, 2837213804, 2837939434, 2837939434,
/// 2844470105, 2844470105, 2844470105, 2844470105, 2860276430, 2860276430, 2860276430, 2860276430,
/// 2867610472, 2867610472, 2868343877, 2868343877, 2874944514, 2874944514, 2874944514, 2874944514,
/// 2906148666, 2906148666, 2917481962, 2917481962, 2917481962, 2917481962, 2924962685, 2924962685,
/// 2925710757, 2925710757, 2932443408, 2932443408, 2932443408, 2932443408, 2937283872, 2937283872,
/// 2947149687, 2947149687, 2947149687, 2947149687, 2947149687, 2947149687, 2947149687, 2947149687,
/// 2954507762, 2954507762, 2954507762, 2954507762, 2955263391, 2955263391, 2955263391, 2955263391,
/// 2962064048, 2962064048, 2962064048, 2962064048, 2962064048, 2962064048, 2962064048, 2962064048,
/// 2996029553, 2996029553, 3026292477, 3026292477, 3026292477, 3026292477, 3071033641, 3071033641,
/// 3071033641, 3071033641, 3078908086, 3078908086, 3079695530, 3079695530, 3086782531, 3086782531,
/// 3086782531, 3086782531, 3153715315, 3153715315, ]
/// [ 2860468811, 2860468811, 2860468811, 2860468811, 2867803346, 2867803346, 2868536800, 2868536800, 2875137882, 2875137882,
/// 2875137882, 2875137882, 2882472418, 2882472418, 2888501408, 2888501408, 2888501408, 2888501408, 2888501408, 2888501408,
/// 2888501408, 2888501408, 2895907822, 2895907822, 2895907822, 2895907822, 2896648464, 2896648464, 2896648464, 2896648464,
/// 2903314236, 2903314236, 2903314236, 2903314236, 2903314236, 2903314236, 2903314236, 2903314236, 2910720650, 2910720650,
/// 2910720650, 2910720650, 2937481433, 2937481433, 2946854972, 2946854972, 2946854972, 2946854972, 2954411010, 2954411010,
/// 2955166614, 2955166614, 2961967049, 2961967049, 2961967049, 2961967049, 2966268754, 2966268754, 2966268754, 2966268754,
/// 2969523087, 2969523087, 3007915659, 3007915659, 3007915659, 3007915659, 3007915659, 3007915659, 3007915659, 3007915659,
/// 3015628263, 3015628263, 3015628263, 3015628263, 3016399524, 3016399524, 3016399524, 3016399524, 3023340868, 3023340868,
/// 3023340868, 3023340868, 3023340868, 3023340868, 3023340868, 3023340868, 3026193375, 3026193375, 3031053472, 3031053472,
/// 3031053472, 3031053472, 3071240197, 3071240197, 3071240197, 3071240197, 3079115172, 3079115172, 3079902669, 3079902669,
/// 3086990147, 3086990147, 3086990147, 3086990147, 3088898004, 3088898004, 3088898004, 3088898004, 3094865122, 3094865122,
/// 3153927433, 3153927433 ]
/// 6. The XRC returns the median rate and the standard deviation from the ICP/CXDR rates.
/// i. For request 1, the median rate is 2947149687.
/// ii. For request 1, the std dev is 81979374.
/// i. For request 1, the median rate is 2964117901.
/// ii. For request 1, the std dev is 77329936.
fn get_icp_xdr_rate() {
let now_seconds = time::OffsetDateTime::now_utc().unix_timestamp() as u64;
let request_1_timestamp_seconds = now_seconds / 60 * 60;
Expand All @@ -75,6 +76,7 @@ fn get_icp_xdr_rate() {
xrc::Exchange::Mexc(_) => Some("3.911"),
xrc::Exchange::Poloniex(_) => Some("4.005"),
xrc::Exchange::CryptoCom(_) => Some("3.91"),
xrc::Exchange::Bitget(_) => Some("3.93"),
},
)
// Request 2 mock exchange responses.
Expand All @@ -89,6 +91,7 @@ fn get_icp_xdr_rate() {
xrc::Exchange::Mexc(_) => Some("4.291"),
xrc::Exchange::Poloniex(_) => Some("4.38"),
xrc::Exchange::CryptoCom(_) => Some("4.29"),
xrc::Exchange::Bitget(_) => Some("4.30"),
},
))
// Request 3 mock exchange responses.
Expand All @@ -103,6 +106,7 @@ fn get_icp_xdr_rate() {
xrc::Exchange::Mexc(_) => Some("5.171"),
xrc::Exchange::Poloniex(_) => Some("5.26"),
xrc::Exchange::CryptoCom(_) => Some("5.17"),
xrc::Exchange::Bitget(_) => Some("5.18"),
},
))
.chain(mock_responses::stablecoin::build_responses(
Expand Down Expand Up @@ -159,8 +163,8 @@ fn get_icp_xdr_rate() {
exchange_rate.metadata.quote_asset_num_received_rates,
NUM_FOREX_SOURCES
);
assert_eq!(exchange_rate.metadata.standard_deviation, 81_979_374);
assert_eq!(exchange_rate.rate, 2_947_149_687);
assert_eq!(exchange_rate.metadata.standard_deviation, 77_329_936);
assert_eq!(exchange_rate.rate, 2_964_117_901);

let request = GetExchangeRateRequest {
base_asset: Asset {
Expand Down Expand Up @@ -197,8 +201,8 @@ fn get_icp_xdr_rate() {
exchange_rate.metadata.quote_asset_num_received_rates,
NUM_FOREX_SOURCES
);
assert_eq!(exchange_rate.metadata.standard_deviation, 88_791_950);
assert_eq!(exchange_rate.rate, 3_234_307_861);
assert_eq!(exchange_rate.metadata.standard_deviation, 83_722_994);
assert_eq!(exchange_rate.rate, 3_246_552_891);

let request = GetExchangeRateRequest {
base_asset: Asset {
Expand Down Expand Up @@ -235,8 +239,8 @@ fn get_icp_xdr_rate() {
exchange_rate.metadata.quote_asset_num_received_rates,
NUM_FOREX_SOURCES
);
assert_eq!(exchange_rate.metadata.standard_deviation, 105_684_510);
assert_eq!(exchange_rate.rate, 3_899_305_739);
assert_eq!(exchange_rate.metadata.standard_deviation, 99_654_513);
assert_eq!(exchange_rate.rate, 3_910_627_669);

Ok(())
})
Expand Down
26 changes: 14 additions & 12 deletions src/xrc-tests/src/tests/misbehavior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ const FIAT_PAIR_COMMON_DATASET_STD_DEV: u64 = 396_623_626;
/// 87023595, 91463412, 91463412, 91721386, 92790863, 92790863, 93052580,
/// 93925888, 95289078]
/// 3. The XRC returns the median rate and the standard deviation from the BTC/ICP rates.
/// a. The median rate from step 2 is 89243503.
/// b. The standard deviation from step 2 is 4044987.
/// a. The median rate from step 2 is 87023595.
/// b. The standard deviation from step 2 is 3644799.
/// Crypto-fiat pair (retrieve BTC/EUR rate)
/// 0. The XRC retrieves rates from the mock forex sources.
/// a. During collection the rates retrieved are normalized to USD.
Expand Down Expand Up @@ -131,13 +131,13 @@ const FIAT_PAIR_COMMON_DATASET_STD_DEV: u64 = 396_623_626;
/// 49615127444, 49700295300, 50145054511, 50231132024, 50651570207, 50651570207, 50738517190, 50738517190, 50751898064, 51420561489,
/// 52784267858, 52874875766]
/// 6. The XRC then returns the median and the standard deviation.
/// a. The median rate from step 5 is 42316582037.
/// b. The standard deviation from step 5 is 3304591113.
/// a. The median rate from step 5 is 43854431680.
/// b. The standard deviation from step 5 is 3219534810.
/// Fiat-crypto pair (retrieve EUR/BTC rate)
/// 0. The instructions are similar to the crypto-fiat pair. The only difference is that the rates are inverted before
/// being returned.
/// a. When inverted, the median rate is 42316582037.
/// b. When inverted, the standard deviation is 1692069.
/// a. When inverted, the median rate is 43854431680.
/// b. When inverted, the standard deviation is 1612334.
/// Fiat pair (retrieve EUR/JPY rate)
/// 0. The XRC retrieves rates from the mock forex sources.
/// a. During collection the rates retrieved are normalized to USD.
Expand Down Expand Up @@ -179,6 +179,7 @@ fn misbehavior() {
xrc::Exchange::Mexc(_) => Some("3.911"),
xrc::Exchange::Poloniex(_) => Some("4.005"),
xrc::Exchange::CryptoCom(_) => Some("100000.0"),
xrc::Exchange::Bitget(_) => Some("3.93"),
},
)
.chain(mock_responses::exchanges::build_responses(
Expand All @@ -192,6 +193,7 @@ fn misbehavior() {
xrc::Exchange::Mexc(_) => Some("46.101"),
xrc::Exchange::Poloniex(_) => Some("46.022"),
xrc::Exchange::CryptoCom(_) => Some("10000.96000000"),
xrc::Exchange::Bitget(_) => Some("45.00"),
},
))
.chain(mock_responses::stablecoin::build_responses(
Expand Down Expand Up @@ -250,14 +252,14 @@ fn misbehavior() {
},
quote_asset: btc_asset.clone(),
timestamp: timestamp_seconds,
rate: 89243503,
rate: 87_023_595,
metadata: ExchangeRateMetadata {
decimals: 9,
base_asset_num_queried_sources: NUM_EXCHANGES,
base_asset_num_received_rates: NUM_EXCHANGES,
quote_asset_num_queried_sources: NUM_EXCHANGES,
quote_asset_num_received_rates: NUM_EXCHANGES,
standard_deviation: 4_044_987,
standard_deviation: 3_644_799,
forex_timestamp: None,
},
};
Expand All @@ -281,14 +283,14 @@ fn misbehavior() {
base_asset: btc_asset.clone(),
quote_asset: eur_asset.clone(),
timestamp: timestamp_seconds,
rate: 43506325069,
rate: 43_854_431_680,
metadata: ExchangeRateMetadata {
decimals: 9,
base_asset_num_queried_sources: NUM_EXCHANGES,
base_asset_num_received_rates: NUM_EXCHANGES,
quote_asset_num_queried_sources: NUM_FOREX_SOURCES,
quote_asset_num_received_rates: NUM_FOREX_SOURCES,
standard_deviation: 3_304_591_113,
standard_deviation: 3_219_534_810,
forex_timestamp: Some(yesterday_timestamp_seconds),
},
};
Expand All @@ -315,14 +317,14 @@ fn misbehavior() {
base_asset: eur_asset.clone(),
quote_asset: btc_asset,
timestamp: timestamp_seconds,
rate: 22985171,
rate: 22_802_720,
metadata: ExchangeRateMetadata {
decimals: 9,
base_asset_num_queried_sources: NUM_FOREX_SOURCES,
base_asset_num_received_rates: NUM_FOREX_SOURCES,
quote_asset_num_queried_sources: NUM_EXCHANGES,
quote_asset_num_received_rates: NUM_EXCHANGES,
standard_deviation: 1_692_069,
standard_deviation: 1_612_334,
forex_timestamp: Some(yesterday_timestamp_seconds),
},
};
Expand Down
Loading

0 comments on commit 2589353

Please sign in to comment.