Copy #[tokio::test]
async fn proper_stability_widthdrawl() {
let (contracts, admin, _wallets) = setup_protocol(4, false, false).await;
token_abi::mint_to_id(
&contracts.asset_contracts[0].asset,
5_000 * PRECISION,
Identity::Address(admin.address().into()),
)
.await;
oracle_abi::set_debug_timestamp(&contracts.asset_contracts[0].oracle, PYTH_TIMESTAMP).await;
pyth_oracle_abi::update_price_feeds(
&contracts.asset_contracts[0].mock_pyth_oracle,
pyth_price_feed(1),
)
.await;
borrow_operations_abi::open_trove(
&contracts.borrow_operations,
&contracts.asset_contracts[0].oracle,
&contracts.asset_contracts[0].mock_pyth_oracle,
&contracts.asset_contracts[0].mock_redstone_oracle,
&contracts.asset_contracts[0].asset,
&contracts.usdf,
&contracts.fpt_staking,
&contracts.sorted_troves,
&contracts.asset_contracts[0].trove_manager,
&contracts.active_pool,
1_200 * PRECISION,
600 * PRECISION,
Identity::Address(Address::zeroed()),
Identity::Address(Address::zeroed()),
)
.await
.unwrap();
stability_pool_abi::provide_to_stability_pool(
&contracts.stability_pool,
&contracts.community_issuance,
&contracts.usdf,
&contracts.asset_contracts[0].asset,
600 * PRECISION,
)
.await
.unwrap();
let withdraw_amount = 300 * PRECISION;
let res = stability_pool_abi::withdraw_from_stability_pool(
&contracts.stability_pool,
&contracts.community_issuance,
&contracts.usdf,
&contracts.asset_contracts[0].asset,
&contracts.sorted_troves,
&contracts.asset_contracts[0].oracle,
&contracts.asset_contracts[0].mock_pyth_oracle,
&contracts.asset_contracts[0].mock_redstone_oracle,
&contracts.asset_contracts[0].trove_manager,
withdraw_amount,
)
.await
.unwrap();
let logs = res.decode_logs();
let withdraw_event = logs
.results
.iter()
.find(|log| {
log.as_ref()
.unwrap()
.contains("WithdrawFromStabilityPoolEvent")
})
.expect("WithdrawFromStabilityPoolEvent not found")
.as_ref()
.unwrap();
assert!(
withdraw_event.contains(&admin.address().hash().to_string()),
"WithdrawFromStabilityPoolEvent should contain user address"
);
assert!(
withdraw_event.contains(&withdraw_amount.to_string()),
"WithdrawFromStabilityPoolEvent should contain withdraw amount"
);
stability_pool_utils::assert_pool_asset(
&contracts.stability_pool,
0,
contracts.asset_contracts[0].asset_id.into(),
)
.await;
stability_pool_utils::assert_total_usdf_deposits(&contracts.stability_pool, withdraw_amount)
.await;
stability_pool_utils::assert_compounded_usdf_deposit(
&contracts.stability_pool,
Identity::Address(admin.address().into()),
withdraw_amount,
)
.await;
stability_pool_utils::assert_depositor_asset_gain(
&contracts.stability_pool,
Identity::Address(admin.address().into()),
0,
contracts.asset_contracts[0].asset_id.into(),
)
.await;
}
#[tokio::test]
async fn proper_one_sp_depositor_position() {
let (contracts, admin, mut wallets) = setup_protocol(4, false, false).await;
oracle_abi::set_debug_timestamp(&contracts.asset_contracts[0].oracle, PYTH_TIMESTAMP).await;
pyth_oracle_abi::update_price_feeds(
&contracts.asset_contracts[0].mock_pyth_oracle,
pyth_price_feed(10),
)
.await;
let liquidated_wallet = wallets.pop().unwrap();
token_abi::mint_to_id(
&contracts.asset_contracts[0].asset,
6_000 * PRECISION,
Identity::Address(admin.address().into()),
)
.await;
token_abi::mint_to_id(
&contracts.asset_contracts[0].asset,
5_000 * PRECISION,
Identity::Address(liquidated_wallet.address().into()),
)
.await;
borrow_operations_abi::open_trove(
&contracts.borrow_operations,
&contracts.asset_contracts[0].oracle,
&contracts.asset_contracts[0].mock_pyth_oracle,
&contracts.asset_contracts[0].mock_redstone_oracle,
&contracts.asset_contracts[0].asset,
&contracts.usdf,
&contracts.fpt_staking,
&contracts.sorted_troves,
&contracts.asset_contracts[0].trove_manager,
&contracts.active_pool,
6_000 * PRECISION,
3_000 * PRECISION,
Identity::Address(Address::zeroed()),
Identity::Address(Address::zeroed()),
)
.await
.unwrap();
let liq_borrow_operations = ContractInstance::new(
BorrowOperations::new(
contracts.borrow_operations.contract.contract_id().clone(),
liquidated_wallet.clone(),
),
contracts.borrow_operations.implementation_id.clone(),
);
borrow_operations_abi::open_trove(
&liq_borrow_operations,
&contracts.asset_contracts[0].oracle,
&contracts.asset_contracts[0].mock_pyth_oracle,
&contracts.asset_contracts[0].mock_redstone_oracle,
&contracts.asset_contracts[0].asset,
&contracts.usdf,
&contracts.fpt_staking,
&contracts.sorted_troves,
&contracts.asset_contracts[0].trove_manager,
&contracts.active_pool,
1_100 * PRECISION,
1_000 * PRECISION,
Identity::Address(Address::zeroed()),
Identity::Address(Address::zeroed()),
)
.await
.unwrap();
let init_stability_deposit = 1_500 * PRECISION;
stability_pool_abi::provide_to_stability_pool(
&contracts.stability_pool,
&contracts.community_issuance,
&contracts.usdf,
&contracts.asset_contracts[0].asset,
init_stability_deposit,
)
.await
.unwrap();
oracle_abi::set_debug_timestamp(&contracts.asset_contracts[0].oracle, PYTH_TIMESTAMP + 1).await;
pyth_oracle_abi::update_price_feeds(
&contracts.asset_contracts[0].mock_pyth_oracle,
pyth_price_feed_with_time(1, PYTH_TIMESTAMP + 1, PYTH_PRECISION.into()),
)
.await;
trove_manager_abi::liquidate(
&contracts.asset_contracts[0].trove_manager,
&contracts.community_issuance,
&contracts.stability_pool,
&contracts.asset_contracts[0].oracle,
&contracts.asset_contracts[0].mock_pyth_oracle,
&contracts.asset_contracts[0].mock_redstone_oracle,
&contracts.sorted_troves,
&contracts.active_pool,
&contracts.default_pool,
&contracts.coll_surplus_pool,
&contracts.usdf,
Identity::Address(liquidated_wallet.address().into()),
Identity::Address(Address::zeroed()),
Identity::Address(Address::zeroed()),
)
.await
.unwrap();
// Since the entire debt is liquidated including the borrow fee,
// the asset recieved includes the 0.5% fee
let mut asset_with_fee_adjustment = 1_100 * PRECISION;
let gas_coll_fee = asset_with_fee_adjustment / 200;
asset_with_fee_adjustment -= gas_coll_fee;
let debt_with_fee_adjustment = with_min_borrow_fee(1_000 * PRECISION);
stability_pool_utils::assert_pool_asset(
&contracts.stability_pool,
asset_with_fee_adjustment,
contracts.asset_contracts[0].asset_id,
)
.await;
stability_pool_utils::assert_total_usdf_deposits(
&contracts.stability_pool,
init_stability_deposit - debt_with_fee_adjustment,
)
.await;
stability_pool_utils::assert_depositor_asset_gain(
&contracts.stability_pool,
Identity::Address(admin.address().into()),
asset_with_fee_adjustment,
contracts.asset_contracts[0].asset_id,
)
.await;
// 500 - 0.5% fee
stability_pool_utils::assert_compounded_usdf_deposit(
&contracts.stability_pool,
Identity::Address(admin.address().into()),
init_stability_deposit - debt_with_fee_adjustment,
)
.await;
// Makes a 2nd deposit to the Stability Pool
let second_deposit = 1_000 * PRECISION;
stability_pool_abi::provide_to_stability_pool(
&contracts.stability_pool,
&contracts.community_issuance,
&contracts.usdf,
&contracts.asset_contracts[0].asset,
second_deposit,
)
.await
.unwrap();
stability_pool_utils::assert_compounded_usdf_deposit(
&contracts.stability_pool,
Identity::Address(admin.address().into()),
init_stability_deposit - debt_with_fee_adjustment + second_deposit,
)
.await;
// Gain has been withdrawn and resset
stability_pool_utils::assert_depositor_asset_gain(
&contracts.stability_pool,
Identity::Address(admin.address().into()),
0,
contracts.asset_contracts[0].asset_id,
)
.await;
let provider = admin.provider().unwrap();
let mock_asset_id: AssetId = contracts.asset_contracts[0].asset_id;
let mock_balance = provider
.get_asset_balance(admin.address(), mock_asset_id)
.await
.unwrap();
assert_within_threshold(
mock_balance,
asset_with_fee_adjustment + gas_coll_fee,
"Mock balance is not correct",
)
}