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/linear pricing #1812

Merged
merged 25 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3df5900
feat: restrict epoch closing to liquiduty admin
mustermeiszer Apr 15, 2024
e004106
fix: linear pricing
mustermeiszer Apr 15, 2024
7b4ab74
proof: type unsafety
mustermeiszer Apr 15, 2024
9ad611b
revert: type unsafety
mustermeiszer Apr 15, 2024
9dc56e5
fix: tests and adapt logic to allow dyanmic input
mustermeiszer Apr 16, 2024
ca5ab9d
Merge branch 'main' into fix/linear-pricing
mustermeiszer Apr 16, 2024
c002271
chore: generic removal
mustermeiszer Apr 16, 2024
ec1a96b
chore: cleaner logic
mustermeiszer Apr 16, 2024
2c2edc0
fix: Clippy you annoying thing
mustermeiszer Apr 16, 2024
db35635
fix: cliiiiiippyyyyy
mustermeiszer Apr 16, 2024
b1ef424
fix: cliippyy v1m
mustermeiszer Apr 16, 2024
b4854b1
feat: make PoolAdmin configurable
mustermeiszer May 6, 2024
2aca1dd
fix: benchmarks
mustermeiszer May 6, 2024
c978951
feat: make pricing linear optional
mustermeiszer May 6, 2024
e2dd3ca
Merge remote-tracking branch 'origin/main' into fix/linear-pricing
mustermeiszer May 6, 2024
9265bbb
Fix: linear accrual not overpassing maturity (#1842)
lemunozm May 23, 2024
967584d
increment coverage when loan is at maturity date
lemunozm May 23, 2024
2a691e9
fix division_by_zero issue
lemunozm May 23, 2024
45be927
feat: fix linear pricing migration (#1838)
wischli May 23, 2024
8c01edc
Merge remote-tracking branch 'origin/main' into fix/linear-pricing
mustermeiszer May 24, 2024
3001d9d
fix: make mock accept all origins
mustermeiszer May 24, 2024
b831f99
feat: add test for switching between oracle or settlement price
mustermeiszer May 24, 2024
5fee771
fix: not needed where clause
mustermeiszer May 24, 2024
fcddabf
feat: move additional test
mustermeiszer May 24, 2024
b6976c8
fix: nits
mustermeiszer May 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions pallets/loans/src/tests/portfolio_valuation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,63 @@ fn empty_portfolio_with_current_timestamp() {
);
});
}

#[test]
fn no_linear_pricing_either_settlement_or_oracle() {
new_test_ext().execute_with(|| {
let mut external_pricing = util::base_external_pricing();
external_pricing.with_linear_pricing = false;

let loan = LoanInfo {
pricing: Pricing::External(ExternalPricing {
price_id: UNREGISTER_PRICE_ID,
..external_pricing
}),
..util::base_external_loan()
};
let loan_1 = util::create_loan(loan);
const SETTLEMENT_PRICE: Balance = 970;

let amount = ExternalAmount::new(QUANTITY, SETTLEMENT_PRICE);

MockPools::mock_pool_exists(|pool_id| pool_id == POOL_A);
MockPools::mock_withdraw(|_, _, _| Ok(()));
MockPrices::mock_get(|_, _| Err(PRICE_ID_NO_FOUND));
MockPrices::mock_register_id(|_, _| Ok(()));
Loans::borrow(
RuntimeOrigin::signed(util::borrower(loan_1)),
POOL_A,
loan_1,
PrincipalInput::External(amount.clone()),
)
.expect("successful borrowing");
mustermeiszer marked this conversation as resolved.
Show resolved Hide resolved

advance_time(YEAR / 2);

const MARKET_PRICE_VALUE: Balance = 999;
MockPrices::mock_collection(|_| {
Ok(MockDataCollection::new(|_| {
Ok((MARKET_PRICE_VALUE, BLOCK_TIME_MS))
}))
});

update_portfolio();
expected_portfolio(QUANTITY.saturating_mul_int(MARKET_PRICE_VALUE));

MockPrices::mock_collection(|pool_id| {
assert_eq!(*pool_id, POOL_A);
Ok(MockDataCollection::new(|_| Err(PRICE_ID_NO_FOUND)))
});

update_portfolio();
expected_portfolio(QUANTITY.saturating_mul_int(SETTLEMENT_PRICE));

MockPrices::mock_collection(|_| {
Ok(MockDataCollection::new(|_| {
Ok((MARKET_PRICE_VALUE, BLOCK_TIME_MS))
}))
});
update_portfolio();
expected_portfolio(QUANTITY.saturating_mul_int(MARKET_PRICE_VALUE));
lemunozm marked this conversation as resolved.
Show resolved Hide resolved
});
}
78 changes: 78 additions & 0 deletions pallets/loans/src/tests/repay_loan.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use sp_arithmetic::traits::Saturating;

use super::*;

pub fn config_mocks(deposit_amount: Balance) {
Expand Down Expand Up @@ -900,3 +902,79 @@ fn with_external_pricing() {
assert_eq!(current_price(), NOTIONAL);
});
}

#[test]
fn with_more_than_required_external() {
mustermeiszer marked this conversation as resolved.
Show resolved Hide resolved
new_test_ext().execute_with(|| {
let variation = Rate::from_inner(1_000_000_000_000_000_000);
mustermeiszer marked this conversation as resolved.
Show resolved Hide resolved
let mut pricing = util::base_external_pricing();
pricing.max_price_variation = variation;
let mut info = util::base_external_loan();
info.pricing = Pricing::External(pricing);

let loan_id = util::create_loan(info);
let amount = ExternalAmount::new(QUANTITY, PRICE_VALUE);
util::borrow_loan(loan_id, PrincipalInput::External(amount));

let amount = ExternalAmount::new(
QUANTITY.saturating_mul(Quantity::from_rational(2, 1)),
PRICE_VALUE + variation.checked_mul_int(PRICE_VALUE).unwrap(),
);
config_mocks_with_price(amount.balance().unwrap(), PRICE_VALUE);

assert_noop!(
Loans::repay(
RuntimeOrigin::signed(BORROWER),
POOL_A,
loan_id,
RepaidInput {
principal: PrincipalInput::External(amount),
interest: 0,
unscheduled: 0,
},
),
Error::<Runtime>::from(RepayLoanError::MaxPrincipalAmountExceeded)
);

let amount = ExternalAmount::new(QUANTITY, PRICE_VALUE * 2);
config_mocks_with_price(amount.balance().unwrap(), PRICE_VALUE);

assert_ok!(Loans::repay(
RuntimeOrigin::signed(BORROWER),
POOL_A,
loan_id,
RepaidInput {
principal: PrincipalInput::External(amount.clone()),
interest: 0,
unscheduled: 0,
},
));

config_mocks_with_price(0, PRICE_VALUE);
assert_noop!(
Loans::repay(
RuntimeOrigin::signed(BORROWER),
POOL_A,
loan_id,
RepaidInput {
principal: PrincipalInput::External(amount),
interest: 0,
unscheduled: 0,
}
),
Error::<Runtime>::from(RepayLoanError::MaxPrincipalAmountExceeded)
);

MockPrices::mock_unregister_id(move |id, pool_id| {
assert_eq!(*pool_id, POOL_A);
assert_eq!(*id, REGISTER_PRICE_ID);
Ok(())
});

assert_ok!(Loans::close(
RuntimeOrigin::signed(BORROWER),
POOL_A,
loan_id,
));
});
}
26 changes: 4 additions & 22 deletions pallets/pool-system/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,40 +384,22 @@ parameter_types! {
pub const PoolDeposit: Balance = 1 * CURRENCY;
}

pub struct LiquidityAndPoolAdmin;
impl EnsureOriginWithArg<RuntimeOrigin, PoolId> for LiquidityAndPoolAdmin {
pub struct All;
impl EnsureOriginWithArg<RuntimeOrigin, PoolId> for All {
type Success = ();

#[cfg(feature = "runtime-benchmarks")]
fn try_origin(_: RuntimeOrigin, _: &PoolId) -> Result<Self::Success, RuntimeOrigin> {
Ok(())
}

#[cfg(not(feature = "runtime-benchmarks"))]
fn try_origin(o: RuntimeOrigin, _: &PoolId) -> Result<Self::Success, RuntimeOrigin> {
<RuntimeOrigin as Into<Result<RawOrigin<AccountId>, RuntimeOrigin>>>::into(o).and_then(
|r| match r {
RawOrigin::Root => Ok(()),
RawOrigin::Signed(account) => {
if account == DEFAULT_POOL_OWNER {
Ok(())
} else {
Err(RawOrigin::Signed(account).into())
}
}
RawOrigin::None => Err(RawOrigin::None.into()),
},
)
}

#[cfg(feature = "runtime-benchmarks")]
fn try_successful_origin(_: &PoolId) -> Result<RuntimeOrigin, ()> {
Ok(RawOrigin::Signed(DEFAULT_POOL_OWNER).into())
Ok(RawOrigin::Root.into())
}
}

impl Config for Runtime {
type AdminOrigin = LiquidityAndPoolAdmin;
type AdminOrigin = All;
type AssetRegistry = RegistryMock;
type AssetsUnderManagementNAV = FakeNav;
type Balance = Balance;
Expand Down
3 changes: 0 additions & 3 deletions runtime/common/src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ impl<
Role = Role<T::TrancheId>,
> + pallet_pool_system::Config,
> EnsureOriginWithArg<T::RuntimeOrigin, T::PoolId> for LiquidityAndPoolAdminOrRoot<T>
where
<T as frame_system::Config>::RuntimeOrigin: From<RawOrigin<<T as frame_system::Config>::AccountId>>
+ Into<Result<RawOrigin<<T as frame_system::Config>::AccountId>, T::RuntimeOrigin>>,
{
type Success = ();

Expand Down
Loading