1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#[cfg(test)]
use mocktopus::macros::mockable;

#[cfg_attr(test, mockable)]
pub(crate) mod currency {
    use crate::types::CurrencyId;
    use currency::Amount;

    pub fn get_free_balance<T: crate::Config>(currency_id: CurrencyId<T>, id: &T::AccountId) -> Amount<T> {
        currency::get_free_balance::<T>(currency_id, id)
    }

    pub fn get_reserved_balance<T: crate::Config>(currency_id: CurrencyId<T>, id: &T::AccountId) -> Amount<T> {
        currency::get_reserved_balance::<T>(currency_id, id)
    }
}

#[cfg_attr(test, mockable)]
pub(crate) mod security {
    use frame_system::pallet_prelude::BlockNumberFor;

    pub fn active_block_number<T: crate::Config>() -> BlockNumberFor<T> {
        <security::Pallet<T>>::active_block_number()
    }
}

#[cfg_attr(test, mockable)]
pub(crate) mod staking {
    use crate::{types::BalanceOf, DefaultVaultId};
    use currency::Amount;
    use frame_support::dispatch::{DispatchError, DispatchResult};
    use staking::{RewardsApi, StakingApi};

    pub fn deposit_stake<T: crate::Config>(
        vault_id: &DefaultVaultId<T>,
        nominator_id: &T::AccountId,
        amount: &Amount<T>,
    ) -> DispatchResult {
        T::VaultStaking::deposit_stake(&(None, vault_id.clone()), nominator_id, amount.amount())
    }

    pub fn withdraw_stake<T: crate::Config>(
        vault_id: &DefaultVaultId<T>,
        nominator_id: &T::AccountId,
        maybe_amount: Option<Amount<T>>,
        nonce: Option<<T as frame_system::Config>::Nonce>,
    ) -> Result<Amount<T>, DispatchError> {
        if let Some(amount) = maybe_amount {
            T::VaultStaking::withdraw_stake(&(nonce, vault_id.clone()), nominator_id, amount.amount())?;
            Ok(amount)
        } else {
            let balance = T::VaultStaking::withdraw_all_stake(&(nonce, vault_id.clone()), nominator_id)?;
            Ok(Amount::new(balance, vault_id.collateral_currency()))
        }
    }

    pub fn slash_stake<T: crate::Config>(vault_id: &DefaultVaultId<T>, amount: &Amount<T>) -> DispatchResult {
        T::VaultStaking::slash_stake(vault_id, amount.amount())
    }

    pub fn force_refund<T: crate::Config>(vault_id: &DefaultVaultId<T>) -> Result<Amount<T>, DispatchError> {
        let amount = T::VaultStaking::force_refund(vault_id)?;
        Ok(Amount::<T>::new(amount, vault_id.collateral_currency()))
    }

    pub fn compute_stake<T: crate::Config>(
        vault_id: &DefaultVaultId<T>,
        nominator_id: &T::AccountId,
    ) -> Result<BalanceOf<T>, DispatchError> {
        T::VaultStaking::get_stake(&(None, vault_id.clone()), nominator_id)
    }

    pub fn total_current_stake<T: crate::Config>(vault_id: &DefaultVaultId<T>) -> Result<Amount<T>, DispatchError> {
        let amount = T::VaultStaking::get_total_stake(&(None, vault_id.clone()))?;
        Ok(Amount::<T>::new(amount, vault_id.collateral_currency()))
    }
}

#[cfg_attr(test, mockable)]
pub(crate) mod reward {
    use crate::{CurrencyId, DefaultVaultId};
    use currency::Amount;
    use frame_support::dispatch::DispatchError;
    use reward::RewardsApi;

    pub fn set_stake<T: crate::Config>(vault_id: &DefaultVaultId<T>, amount: &Amount<T>) -> Result<(), DispatchError> {
        T::VaultRewards::set_stake(&vault_id.collateral_currency(), vault_id, amount.amount())
    }

    pub fn total_current_stake<T: crate::Config>(currency_id: CurrencyId<T>) -> Result<Amount<T>, DispatchError> {
        let amount = T::VaultRewards::get_total_stake(&currency_id)?;
        Ok(Amount::<T>::new(amount, currency_id))
    }

    #[cfg(feature = "integration-tests")]
    pub fn get_stake<T: crate::Config>(vault_id: &DefaultVaultId<T>) -> Result<crate::BalanceOf<T>, DispatchError> {
        T::VaultRewards::get_stake(&vault_id.collateral_currency(), vault_id)
    }
}

#[cfg_attr(test, mockable)]
pub(crate) mod capacity {
    use crate::types::CurrencyId;
    use currency::Amount;
    use frame_support::dispatch::DispatchError;
    use staking::RewardsApi;

    pub fn set_stake<T: crate::Config>(currency_id: CurrencyId<T>, amount: &Amount<T>) -> Result<(), DispatchError> {
        T::CapacityRewards::set_stake(&(), &currency_id, amount.amount())
    }
}

#[cfg_attr(test, mockable)]
pub(crate) mod oracle {
    use frame_support::dispatch::DispatchError;
    use oracle::{types::UnsignedFixedPoint, OracleKey};

    pub fn get_price<T: crate::Config>(key: OracleKey) -> Result<UnsignedFixedPoint<T>, DispatchError> {
        <oracle::Pallet<T>>::get_price(key)
    }
}

#[cfg_attr(test, mockable)]
pub(crate) mod fee {
    use crate::DefaultVaultId;
    use fee::types::UnsignedFixedPoint;
    use frame_support::dispatch::DispatchResult;

    pub fn distribute_all_vault_rewards<T: crate::Config>(vault_id: &DefaultVaultId<T>) -> DispatchResult {
        <fee::Pallet<T>>::distribute_all_vault_rewards(vault_id)
    }

    pub fn premium_redeem_reward_rate<T: crate::Config>() -> UnsignedFixedPoint<T> {
        <fee::Pallet<T>>::premium_redeem_reward_rate()
    }

    pub fn get_redeem_fee_value<T: crate::Config>() -> UnsignedFixedPoint<T> {
        <fee::Pallet<T>>::get_redeem_fee_value()
    }
}