Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: bug on oracle fetching #1750

Merged
merged 12 commits into from
Mar 1, 2024
12 changes: 0 additions & 12 deletions runtime/centrifuge/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,6 @@ pub type UpgradeCentrifuge1025 = (
burn_unburned::Migration<super::Runtime>,
);

// Copyright 2021 Centrifuge Foundation (centrifuge.io).
//
// This file is part of the Centrifuge chain project.
// Centrifuge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version (see http://www.gnu.org/licenses).
// Centrifuge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

mod burn_unburned {
const LOG_PREFIX: &str = "BurnUnburnedMigration: ";
const LP_ETH_USDC: CurrencyId = CurrencyId::ForeignAsset(100_001);
Expand Down
4 changes: 2 additions & 2 deletions runtime/common/src/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ where
(from, to): &(CurrencyId, CurrencyId),
) -> Result<Option<Self::Value>, DispatchError> {
let locally_coupled_assets = match (from, to) {
(_, &CurrencyId::LocalAsset(_)) => from.is_local_representation_of(to),
(&CurrencyId::LocalAsset(_), _) => to.is_local_representation_of(from),
(_, &CurrencyId::LocalAsset(_)) => to.is_local_representation_of(from),
(&CurrencyId::LocalAsset(_), _) => from.is_local_representation_of(to),
_ => Ok(false),
}?;

Expand Down
22 changes: 11 additions & 11 deletions runtime/integration-tests/src/generic/cases/investments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ mod common {
let mut env = E::from_parachain_storage(
Genesis::<T>::default()
.add(genesis::balances(T::ExistentialDeposit::get() + FOR_FEES))
.add(genesis::assets(vec![Usd6::ID]))
.add(genesis::tokens(vec![(Usd6::ID, Usd6::ED)]))
.add(genesis::assets(vec![Box::new(Usd6)]))
.add(genesis::tokens(vec![(Usd6.id(), Usd6.ed())]))
.storage(),
);

env.parachain_state_mut(|| {
// Create a pool
utils::give_balance::<T>(POOL_ADMIN.id(), T::PoolDeposit::get());
utils::create_empty_pool::<T>(POOL_ADMIN.id(), POOL_A, Usd6::ID);
utils::create_empty_pool::<T>(POOL_ADMIN.id(), POOL_A, Usd6.id());

// Grant permissions
let tranche_id = T::Api::tranche_id(POOL_A, 0).unwrap();
Expand All @@ -73,7 +73,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {

// Invest to have pending pool currency
env.parachain_state_mut(|| {
utils::give_tokens::<T>(INVESTOR.id(), Usd6::ID, EXPECTED_POOL_BALANCE);
utils::give_tokens::<T>(INVESTOR.id(), Usd6.id(), EXPECTED_POOL_BALANCE);
utils::invest::<T>(INVESTOR.id(), POOL_A, tranche_id, EXPECTED_POOL_BALANCE);
assert_eq!(
pallet_investments::InvestOrders::<T>::get(INVESTOR.id(), invest_id)
Expand All @@ -87,7 +87,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6.id())
.with_pending_invest_currency(EXPECTED_POOL_BALANCE)
)]
);
Expand All @@ -102,7 +102,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6.id())
.with_claimable_tranche_tokens(EXPECTED_POOL_BALANCE)
)]
);
Expand All @@ -116,7 +116,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6.id())
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE)
)]
);
Expand All @@ -130,7 +130,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6.id())
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT)
.with_pending_redeem_tranche_tokens(REDEEM_AMOUNT)
)]
Expand All @@ -146,7 +146,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6.id())
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT)
.with_claimable_currency(REDEEM_AMOUNT)
)]
Expand All @@ -161,7 +161,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6.id())
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT)
)]
);
Expand All @@ -181,7 +181,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6.id())
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT - HOLD_AMOUNT)
.with_reserved_tranche_tokens(HOLD_AMOUNT)
)]
Expand Down
24 changes: 16 additions & 8 deletions runtime/integration-tests/src/generic/cases/loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ mod common {
let mut env = E::from_parachain_storage(
Genesis::<T>::default()
.add(genesis::balances(T::ExistentialDeposit::get() + FOR_FEES))
.add(genesis::assets(vec![Usd6::ID]))
.add(genesis::tokens(vec![(Usd6::ID, Usd6::ED)]))
.add(genesis::assets(vec![Box::new(Usd6)]))
.add(genesis::tokens(vec![(Usd6.id(), Usd6.ed())]))
.storage(),
);

env.parachain_state_mut(|| {
// Creating a pool
utils::give_balance::<T>(POOL_ADMIN.id(), T::PoolDeposit::get());
utils::create_empty_pool::<T>(POOL_ADMIN.id(), POOL_A, Usd6::ID);
utils::create_empty_pool::<T>(POOL_ADMIN.id(), POOL_A, Usd6.id());

// Setting borrower
utils::give_pool_role::<T>(BORROWER.id(), POOL_A, PoolRole::Borrower);
Expand All @@ -94,7 +94,7 @@ mod common {
let tranche_id = T::Api::tranche_id(POOL_A, 0).unwrap();
let tranche_investor = PoolRole::TrancheInvestor(tranche_id, Seconds::MAX);
utils::give_pool_role::<T>(INVESTOR.id(), POOL_A, tranche_investor);
utils::give_tokens::<T>(INVESTOR.id(), Usd6::ID, EXPECTED_POOL_BALANCE);
utils::give_tokens::<T>(INVESTOR.id(), Usd6.id(), EXPECTED_POOL_BALANCE);
utils::invest::<T>(INVESTOR.id(), POOL_A, tranche_id, EXPECTED_POOL_BALANCE);
});

Expand Down Expand Up @@ -161,13 +161,13 @@ mod common {
Pricing::External(ExternalPricing {
price_id: PRICE_A,
max_borrow_amount: ExtMaxBorrowAmount::Quantity(QUANTITY),
notional: currency::price_to_currency(PRICE_VALUE_A, Usd6::ID),
notional: currency::price_to_currency(PRICE_VALUE_A, Usd6),
max_price_variation: rate_from_percent(50),
})
}

pub fn price_to_usd6(price: Quantity) -> Balance {
currency::price_to_currency(price, Usd6::ID)
currency::price_to_currency(price, Usd6)
}
}

Expand Down Expand Up @@ -286,7 +286,11 @@ fn internal_priced<T: Runtime>() {
env.parachain_state_mut(|| {
// Give required tokens to the borrower to be able to repay the interest accrued
// until this moment
utils::give_tokens::<T>(BORROWER.id(), Usd6::ID, loan_portfolio.outstanding_interest);
utils::give_tokens::<T>(
BORROWER.id(),
Usd6.id(),
loan_portfolio.outstanding_interest,
);
});

env.submit_now(
Expand Down Expand Up @@ -326,7 +330,11 @@ fn oracle_priced<T: Runtime>() {
env.parachain_state_mut(|| {
// Give required tokens to the borrower to be able to repay the interest accrued
// until this moment
utils::give_tokens::<T>(BORROWER.id(), Usd6::ID, loan_portfolio.outstanding_interest);
utils::give_tokens::<T>(
BORROWER.id(),
Usd6.id(),
loan_portfolio.outstanding_interest,
);

// Oracle modify the value
utils::oracle::feed_from_root::<T>(PRICE_A, PRICE_VALUE_B);
Expand Down
171 changes: 171 additions & 0 deletions runtime/integration-tests/src/generic/cases/oracles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// Copyright 2021 Centrifuge Foundation (centrifuge.io).
//
// This file is part of the Centrifuge chain project.
// Centrifuge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version (see http://www.gnu.org/licenses).
// Centrifuge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

//! Testing setups around our oracles

mod ratio_provider {
use cfg_traits::ValueProvider;
use cfg_types::{
fixed_point::Ratio,
oracles::OracleKey,
tokens::{CrossChainTransferability, CurrencyId, CustomMetadata, LocalAssetId},
};
use frame_support::traits::OriginTrait;
use runtime_common::oracle::Feeder;
use sp_runtime::{traits::One, FixedPointNumber};

use crate::{
generic::{
config::Runtime,
env::Env,
envs::runtime_env::RuntimeEnv,
utils::currency::{register_currency, CurrencyInfo, CONST_DEFAULT_CUSTOM},
},
test_for_runtimes,
};

pub struct OtherLocal;
impl CurrencyInfo for OtherLocal {
fn id(&self) -> CurrencyId {
CurrencyId::LocalAsset(LocalAssetId(2))
}

fn custom(&self) -> CustomMetadata {
CustomMetadata {
pool_currency: true,
transferability: CrossChainTransferability::None,
..CONST_DEFAULT_CUSTOM
}
}
}

pub struct LocalUSDC;
impl CurrencyInfo for LocalUSDC {
fn id(&self) -> CurrencyId {
CurrencyId::LocalAsset(LocalAssetId(1))
}

fn custom(&self) -> CustomMetadata {
CustomMetadata {
pool_currency: true,
transferability: CrossChainTransferability::None,
..CONST_DEFAULT_CUSTOM
}
}
}

pub struct DomainUSDC;
impl CurrencyInfo for DomainUSDC {
fn id(&self) -> CurrencyId {
CurrencyId::ForeignAsset(100_001)
}

fn custom(&self) -> CustomMetadata {
CustomMetadata {
pool_currency: true,
transferability: CrossChainTransferability::LiquidityPools,
local_representation: Some(LocalAssetId(1)),
..CONST_DEFAULT_CUSTOM
}
}
}

fn feeder<T: Runtime>() -> Feeder<T::RuntimeOriginExt> {
pallet_order_book::MarketFeederId::<T>::get().unwrap()
}

fn get_rate_with<T: Runtime>(
key: (CurrencyId, CurrencyId),
setup: impl FnOnce(),
) -> Option<Ratio> {
let mut env = RuntimeEnv::<T>::default();

env.parachain_state_mut(|| {
register_currency::<T>(LocalUSDC, |_| {});
register_currency::<T>(DomainUSDC, |_| {});
register_currency::<T>(OtherLocal, |_| {});

pallet_order_book::Pallet::<T>::set_market_feeder(
T::RuntimeOriginExt::root(),
Feeder::<T::RuntimeOriginExt>::root(),
)
.unwrap();

setup();

<T as pallet_order_book::Config>::RatioProvider::get(&feeder::<T>(), &key).unwrap()
})
}

fn get_rate<T: Runtime>(key: (CurrencyId, CurrencyId)) -> Option<Ratio> {
get_rate_with::<T>(key, || {})
}

fn local_to_variant<T: Runtime>() {
assert_eq!(
get_rate::<T>((LocalUSDC.id(), DomainUSDC.id())),
Some(Ratio::one())
);
}

fn variant_to_local<T: Runtime>() {
assert_eq!(
get_rate::<T>((DomainUSDC.id(), LocalUSDC.id())),
Some(Ratio::one())
);
}

fn variant_to_other_local<T: Runtime>() {
assert_eq!(get_rate::<T>((DomainUSDC.id(), OtherLocal.id())), None);
}

fn other_local_to_variant<T: Runtime>() {
assert_eq!(get_rate::<T>((OtherLocal.id(), DomainUSDC.id())), None);
}

fn variant_to_local_rate_set<T: Runtime>() {
let pair = (LocalUSDC.id(), DomainUSDC.id());
assert_eq!(
get_rate_with::<T>(pair, || {
pallet_oracle_feed::Pallet::<T>::feed(
feeder::<T>().0.into(),
OracleKey::ConversionRatio(pair.1, pair.0),
Ratio::checked_from_rational(1, 5).unwrap(),
)
.unwrap();
}),
Some(Ratio::one())
);
}

fn local_to_variant_rate_set<T: Runtime>() {
let pair = (LocalUSDC.id(), DomainUSDC.id());
assert_eq!(
get_rate_with::<T>(pair, || {
pallet_oracle_feed::Pallet::<T>::feed(
feeder::<T>().0.into(),
OracleKey::ConversionRatio(pair.0, pair.1),
Ratio::checked_from_rational(1, 5).unwrap(),
)
.unwrap();
}),
Some(Ratio::one())
);
}

test_for_runtimes!(all, variant_to_local);
test_for_runtimes!(all, local_to_variant);
test_for_runtimes!(all, variant_to_other_local);
test_for_runtimes!(all, other_local_to_variant);
test_for_runtimes!(all, variant_to_local_rate_set);
test_for_runtimes!(all, local_to_variant_rate_set);
}
Loading
Loading