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

feat: integrate staking pallet into vault-registry and nomination #165

Merged
merged 2 commits into from Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions crates/fee/Cargo.toml
Expand Up @@ -22,16 +22,18 @@ frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch =

# Parachain dependencies
currency = { path = "../currency", default-features = false }
sla = { path = "../sla", default-features = false }
security = { path = "../security", default-features = false }
reward = { path = "../reward", default-features = false }
staking = { path = "../staking", default-features = false }

[dev-dependencies]
mocktopus = "0.7.0"
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.5", default-features = false }
pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.5", default-features = false }
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.5", default-features = false }

sla = { path = "../sla", default-features = false }

# Orml dependencies
orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "bb6ad7a", default-features = false }
orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "bb6ad7a", default-features = false }
Expand All @@ -54,8 +56,8 @@ std = [

"currency/std",
"security/std",
"sla/std",
"reward/std"
"reward/std",
"staking/std",
]
runtime-benchmarks = [
"frame-benchmarking",
Expand Down
21 changes: 5 additions & 16 deletions crates/fee/src/benchmarking.rs
@@ -1,25 +1,14 @@
use super::*;
use frame_benchmarking::{account, benchmarks};
use crate::Pallet as Fee;
use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite};
use frame_system::RawOrigin;

const SEED: u32 = 0;

benchmarks! {
withdraw_vault_rewards {
withdraw_rewards {
let recipient: T::AccountId = account("recipient", 0, SEED);
}: _(RawOrigin::Signed(recipient))
}: _(RawOrigin::Signed(recipient.clone()), recipient.clone())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::mock::{ExtBuilder, Test};
use frame_support::assert_ok;

#[test]
fn test_benchmarks() {
ExtBuilder::build().execute_with(|| {
assert_ok!(test_benchmark_withdraw_vault_rewards::<Test>());
});
}
}
impl_benchmark_test_suite!(Fee, crate::mock::ExtBuilder::build(), crate::mock::Test);
2 changes: 1 addition & 1 deletion crates/fee/src/default_weights.rs
Expand Up @@ -6,7 +6,7 @@
use frame_support::weights::{constants::RocksDbWeight as DbWeight, Weight};

impl crate::WeightInfo for () {
fn withdraw_vault_rewards() -> Weight {
fn withdraw_rewards() -> Weight {
(124_557_000 as Weight)
.saturating_add(DbWeight::get().reads(5 as Weight))
.saturating_add(DbWeight::get().writes(4 as Weight))
Expand Down
89 changes: 33 additions & 56 deletions crates/fee/src/lib.rs
Expand Up @@ -36,7 +36,6 @@ use frame_support::{
PalletId,
};
use frame_system::ensure_signed;
use reward::RewardPool;
use sp_arithmetic::{traits::*, FixedPointNumber, FixedPointOperand};
use sp_runtime::traits::{AccountIdConversion, AtLeast32BitUnsigned};
use sp_std::{
Expand All @@ -47,7 +46,7 @@ use sp_std::{
use types::{Collateral, SignedFixedPoint, UnsignedFixedPoint, UnsignedInner, Version, Wrapped};

pub trait WeightInfo {
fn withdraw_vault_rewards() -> Weight;
fn withdraw_rewards() -> Weight;
}

pub use pallet::*;
Expand All @@ -62,9 +61,6 @@ pub mod pallet {
/// The pallet's configuration trait.
#[pallet::config]
pub trait Config: frame_system::Config + security::Config {
/// The overarching event type.
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;

/// The fee module id, used for deriving its sovereign account ID.
#[pallet::constant]
type PalletId: Get<PalletId>;
Expand Down Expand Up @@ -97,20 +93,16 @@ pub mod pallet {
/// Vault reward pool for the wrapped currency.
type VaultRewards: reward::Rewards<Self::AccountId, SignedFixedPoint = SignedFixedPoint<Self>>;

/// Vault staking pool for the wrapped currency.
type VaultStaking: staking::Staking<Self::AccountId, SignedFixedPoint = SignedFixedPoint<Self>>;

/// Collateral currency, e.g. DOT/KSM.
type Collateral: ParachainCurrency<Self::AccountId, Balance = Self::UnsignedInner>;

/// Wrapped currency, e.g. InterBTC.
type Wrapped: ParachainCurrency<Self::AccountId, Balance = Self::UnsignedInner>;
}

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
#[pallet::metadata(T::AccountId = "AccountId", Wrapped<T> = "Wrapped", Collateral<T> = "Collateral")]
pub enum Event<T: Config> {
WithdrawWrapped(T::AccountId, Wrapped<T>),
}

#[pallet::error]
pub enum Error<T> {
ArithmeticOverflow,
Expand Down Expand Up @@ -268,32 +260,17 @@ pub mod pallet {
// The pallet's dispatchable functions.
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Withdraw vault rewards.
///
/// # Arguments
///
/// * `origin` - signing account
#[pallet::weight(<T as Config>::WeightInfo::withdraw_vault_rewards())]
#[transactional]
pub fn withdraw_vault_rewards(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
ext::security::ensure_parachain_status_not_shutdown::<T>()?;
let signer = ensure_signed(origin)?;
Self::withdraw_from_pool::<T::VaultRewards>(RewardPool::Global, &signer)?;
Ok(().into())
}

/// Withdraw nominator rewards.
/// Withdraw all rewards from the `origin` account in the `vault_id` staking pool.
///
/// # Arguments
///
/// * `origin` - signing account
/// * `vault_id` - vault whose reward pool to reward from
#[pallet::weight(<T as Config>::WeightInfo::withdraw_vault_rewards())]
#[pallet::weight(<T as Config>::WeightInfo::withdraw_rewards())]
#[transactional]
pub fn withdraw_nominator_rewards(origin: OriginFor<T>, vault_id: T::AccountId) -> DispatchResultWithPostInfo {
pub fn withdraw_rewards(origin: OriginFor<T>, vault_id: T::AccountId) -> DispatchResultWithPostInfo {
ext::security::ensure_parachain_status_not_shutdown::<T>()?;
let signer = ensure_signed(origin)?;
Self::withdraw_from_pool::<T::VaultRewards>(RewardPool::Local(vault_id), &signer)?;
let nominator_id = ensure_signed(origin)?;
Self::withdraw_from_reward_pool::<T::VaultRewards, T::VaultStaking>(&vault_id, &nominator_id)?;
Ok(().into())
}
}
Expand Down Expand Up @@ -417,7 +394,7 @@ impl<T: Config> Pallet<T> {
}

pub fn withdraw_all_vault_rewards(account_id: &T::AccountId) -> DispatchResult {
Self::withdraw_from_pool::<T::VaultRewards>(RewardPool::Global, account_id)?;
Self::distribute_from_reward_pool::<T::VaultRewards, T::VaultStaking>(account_id)?;
Ok(())
}

Expand Down Expand Up @@ -453,39 +430,34 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Withdraw collateral rewards from a pool and transfer to `account_id`.
fn withdraw_from_pool<R: reward::Rewards<T::AccountId, SignedFixedPoint = SignedFixedPoint<T>>>(
reward_pool: RewardPool<T::AccountId>,
account_id: &T::AccountId,
/// Withdraw rewards from a pool and transfer to `account_id`.
fn withdraw_from_reward_pool<
Rewards: reward::Rewards<T::AccountId, SignedFixedPoint = SignedFixedPoint<T>>,
Staking: staking::Staking<T::AccountId, SignedFixedPoint = SignedFixedPoint<T>>,
>(
vault_id: &T::AccountId,
nominator_id: &T::AccountId,
) -> DispatchResult {
match reward_pool {
RewardPool::Global => {
Self::withdraw_from_pool::<R>(RewardPool::Local(account_id.clone()), account_id)?;
}
RewardPool::Local(pool_account_id) => {
Self::distribute_global_pool::<R>(&pool_account_id)?;
let wrapped_rewards = R::withdraw_reward(RewardPool::Local(pool_account_id), account_id)?
.try_into()
.map_err(|_| Error::<T>::TryIntoIntError)?;
ext::treasury::transfer::<T>(&Self::fee_pool_account_id(), account_id, wrapped_rewards)?;
Self::deposit_event(<Event<T>>::WithdrawWrapped(account_id.clone(), wrapped_rewards));
}
}
Self::distribute_from_reward_pool::<Rewards, Staking>(&vault_id)?;
let rewards = Staking::withdraw_reward(vault_id, nominator_id)?
.try_into()
.map_err(|_| Error::<T>::TryIntoIntError)?;
ext::treasury::transfer::<T>(&Self::fee_pool_account_id(), nominator_id, rewards)?;
Ok(())
}

fn distribute<
Currency: TryInto<SignedInner>,
SignedInner: TryInto<Currency> + CheckedDiv,
SignedFixedPoint: FixedPointNumber<Inner = SignedInner>,
Reward: reward::Rewards<T::AccountId, SignedFixedPoint = SignedFixedPoint>,
Rewards: reward::Rewards<T::AccountId, SignedFixedPoint = SignedFixedPoint>,
>(
reward: Currency,
) -> Result<Currency, DispatchError> {
let reward_as_inner = reward.try_into().ok().ok_or(Error::<T>::TryIntoIntError)?;
let reward_as_fixed =
SignedFixedPoint::checked_from_integer(reward_as_inner).ok_or(Error::<T>::TryIntoIntError)?;
Ok(Reward::distribute(RewardPool::Global, reward_as_fixed)?
Ok(Rewards::distribute(reward_as_fixed)?
.into_inner()
.checked_div(&SignedFixedPoint::accuracy())
.ok_or(Error::<T>::ArithmeticUnderflow)?
Expand All @@ -494,11 +466,16 @@ impl<T: Config> Pallet<T> {
.ok_or(Error::<T>::TryIntoIntError)?)
}

pub fn distribute_global_pool<Reward: reward::Rewards<T::AccountId>>(account_id: &T::AccountId) -> DispatchResult {
let reward_as_inner = Reward::withdraw_reward(RewardPool::Global, account_id)?;
pub fn distribute_from_reward_pool<
Rewards: reward::Rewards<T::AccountId, SignedFixedPoint = SignedFixedPoint<T>>,
Staking: staking::Staking<T::AccountId, SignedFixedPoint = SignedFixedPoint<T>>,
>(
account_id: &T::AccountId,
) -> DispatchResult {
let reward_as_inner = Rewards::withdraw_reward(account_id)?;
let reward_as_fixed =
Reward::SignedFixedPoint::checked_from_integer(reward_as_inner).ok_or(Error::<T>::TryIntoIntError)?;
Reward::distribute(RewardPool::Local(account_id.clone()), reward_as_fixed)?;
Rewards::SignedFixedPoint::checked_from_integer(reward_as_inner).ok_or(Error::<T>::TryIntoIntError)?;
Staking::distribute_reward(account_id, reward_as_fixed)?;
Ok(())
nud3l marked this conversation as resolved.
Show resolved Hide resolved
}
}
12 changes: 10 additions & 2 deletions crates/fee/src/mock.rs
Expand Up @@ -29,10 +29,11 @@ frame_support::construct_runtime!(
Tokens: orml_tokens::{Pallet, Storage, Config<T>, Event<T>},

Rewards: reward::{Pallet, Call, Storage, Event<T>},
Staking: staking::{Pallet, Storage, Event<T>},

// Operational
Security: security::{Pallet, Call, Storage, Event<T>},
Fee: fee::{Pallet, Call, Config<T>, Storage, Event<T>},
Fee: fee::{Pallet, Call, Config<T>, Storage},
}
);

Expand Down Expand Up @@ -117,6 +118,13 @@ impl reward::Config for Test {
type CurrencyId = CurrencyId;
}

impl staking::Config for Test {
type Event = TestEvent;
type SignedFixedPoint = SignedFixedPoint;
type SignedInner = SignedInner;
type CurrencyId = CurrencyId;
}

parameter_types! {
pub const MinimumPeriod: Moment = 5;
}
Expand All @@ -138,13 +146,13 @@ parameter_types! {

impl Config for Test {
type PalletId = FeePalletId;
type Event = TestEvent;
type WeightInfo = ();
type SignedFixedPoint = SignedFixedPoint;
type SignedInner = SignedInner;
type UnsignedFixedPoint = UnsignedFixedPoint;
type UnsignedInner = UnsignedInner;
type VaultRewards = reward::RewardsCurrencyAdapter<Test, (), GetWrappedCurrencyId>;
type VaultStaking = staking::StakingCurrencyAdapter<Test, GetWrappedCurrencyId>;
type Collateral = CurrencyAdapter<Test, GetCollateralCurrencyId>;
type Wrapped = CurrencyAdapter<Test, GetWrappedCurrencyId>;
}
Expand Down
1 change: 1 addition & 0 deletions crates/issue/Cargo.toml
Expand Up @@ -38,6 +38,7 @@ frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch =
pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.5", default-features = false }

reward = { path = "../reward", default-features = false }
staking = { path = "../staking", default-features = false }

# Orml dependencies
orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "bb6ad7a", default-features = false }
Expand Down
5 changes: 1 addition & 4 deletions crates/issue/src/ext.rs
Expand Up @@ -63,10 +63,7 @@ pub(crate) mod vault_registry {

pub fn get_active_vault_from_id<T: crate::Config>(
vault_id: &T::AccountId,
) -> Result<
Vault<T::AccountId, T::BlockNumber, Wrapped<T>, Collateral<T>, <T as vault_registry::Config>::SignedFixedPoint>,
DispatchError,
> {
) -> Result<Vault<T::AccountId, T::BlockNumber, Wrapped<T>, Collateral<T>>, DispatchError> {
<vault_registry::Pallet<T>>::get_active_vault_from_id(vault_id)
}

Expand Down