#![cfg_attr(not(feature = "std"), no_std)]
use frame_support::{
dispatch::DispatchResult,
pallet_prelude::{RuntimeDebug, TypeInfo},
traits::UnixTime,
Parameter,
};
use impl_trait_for_tuples::impl_for_tuples;
use orml_traits::asset_registry;
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use sp_runtime::{traits::Member, DispatchError};
use sp_std::{fmt::Debug, marker::PhantomData, vec::Vec};
pub mod changes;
pub mod data;
pub mod ethereum;
pub mod fee;
pub mod fees;
pub mod interest;
pub mod investments;
pub mod liquidity_pools;
pub mod rewards;
pub mod swaps;
#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarking;
pub trait PoolNAV<PoolId, Amount> {
type ClassId;
type RuntimeOrigin;
fn nav(pool_id: PoolId) -> Option<(Amount, u64)>;
fn update_nav(pool_id: PoolId) -> Result<Amount, DispatchError>;
fn initialise(
origin: Self::RuntimeOrigin,
pool_id: PoolId,
class_id: Self::ClassId,
) -> DispatchResult;
}
pub trait PoolInspect<AccountId, CurrencyId> {
type PoolId;
type TrancheId;
type Moment;
fn pool_exists(pool_id: Self::PoolId) -> bool;
fn tranche_exists(pool_id: Self::PoolId, tranche_id: Self::TrancheId) -> bool;
fn account_for(pool_id: Self::PoolId) -> AccountId;
fn currency_for(pool_id: Self::PoolId) -> Option<CurrencyId>;
}
pub trait TrancheTokenPrice<AccountId, CurrencyId> {
type PoolId;
type TrancheId;
type BalanceRatio;
type Moment;
fn get_price(
pool_id: Self::PoolId,
tranche_id: Self::TrancheId,
) -> Option<(Self::BalanceRatio, Self::Moment)>;
}
#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)]
pub enum UpdateState {
NoExecution,
Executed(u32),
Stored(u32),
}
pub trait PoolMutate<AccountId, PoolId> {
type Balance;
type CurrencyId;
type TrancheInput: Encode + Decode + Clone + TypeInfo + Debug + PartialEq;
type PoolChanges: Encode + Decode + Clone + TypeInfo + Debug + PartialEq + MaxEncodedLen;
type PoolFeeInput: Encode + Decode + Clone + TypeInfo + Debug;
fn create(
admin: AccountId,
depositor: AccountId,
pool_id: PoolId,
tranche_inputs: Vec<Self::TrancheInput>,
currency: Self::CurrencyId,
max_reserve: Self::Balance,
pool_fees: Vec<Self::PoolFeeInput>,
) -> DispatchResult;
fn update(pool_id: PoolId, changes: Self::PoolChanges) -> Result<UpdateState, DispatchError>;
fn execute_update(pool_id: PoolId) -> Result<u32, DispatchError>;
}
pub trait PoolMetadata<Balance, VersionedMultiLocation> {
type AssetMetadata;
type CustomMetadata;
type PoolMetadata;
type PoolId: Parameter
+ Member
+ Debug
+ Copy
+ Default
+ TypeInfo
+ Encode
+ Decode
+ MaxEncodedLen;
type TrancheId: Parameter + Member + Debug + Copy + Default + TypeInfo + MaxEncodedLen;
fn get_pool_metadata(pool_id: Self::PoolId) -> Result<Self::PoolMetadata, DispatchError>;
fn set_pool_metadata(pool_id: Self::PoolId, metadata: Vec<u8>) -> DispatchResult;
fn get_tranche_token_metadata(
pool_id: Self::PoolId,
tranche: Self::TrancheId,
) -> Result<Self::AssetMetadata, DispatchError>;
fn create_tranche_token_metadata(
pool_id: Self::PoolId,
tranche: Self::TrancheId,
metadata: Self::AssetMetadata,
) -> DispatchResult;
#[allow(clippy::too_many_arguments)]
fn update_tranche_token_metadata(
pool_id: Self::PoolId,
tranche: Self::TrancheId,
decimals: Option<u32>,
name: Option<Vec<u8>>,
symbol: Option<Vec<u8>>,
existential_deposit: Option<Balance>,
location: Option<Option<VersionedMultiLocation>>,
additional: Option<Self::CustomMetadata>,
) -> DispatchResult;
}
pub trait PoolReserve<AccountId, CurrencyId>: PoolInspect<AccountId, CurrencyId> {
type Balance;
fn withdraw(pool_id: Self::PoolId, to: AccountId, amount: Self::Balance) -> DispatchResult;
fn deposit(pool_id: Self::PoolId, from: AccountId, amount: Self::Balance) -> DispatchResult;
}
pub trait PoolWriteOffPolicyMutate<PoolId> {
type Policy: Parameter;
fn update(pool_id: PoolId, policy: Self::Policy) -> DispatchResult;
#[cfg(feature = "runtime-benchmarks")]
fn worst_case_policy() -> Self::Policy;
}
pub trait Permissions<AccountId> {
type Scope;
type Role;
type Error: Debug;
type Ok: Debug;
fn has(scope: Self::Scope, who: AccountId, role: Self::Role) -> bool;
fn add(scope: Self::Scope, who: AccountId, role: Self::Role) -> Result<Self::Ok, Self::Error>;
fn remove(
scope: Self::Scope,
who: AccountId,
role: Self::Role,
) -> Result<Self::Ok, Self::Error>;
}
pub trait Properties {
type Property;
type Error;
type Ok;
fn exists(&self, property: Self::Property) -> bool;
fn empty(&self) -> bool;
fn rm(&mut self, property: Self::Property) -> Result<Self::Ok, Self::Error>;
fn add(&mut self, property: Self::Property) -> Result<Self::Ok, Self::Error>;
}
pub trait PoolUpdateGuard {
type PoolDetails;
type ScheduledUpdateDetails;
type Moment: Copy;
fn released(
pool: &Self::PoolDetails,
update: &Self::ScheduledUpdateDetails,
now: Self::Moment,
) -> bool;
}
pub trait PreConditions<T> {
type Result;
fn check(t: T) -> Self::Result;
#[cfg(feature = "runtime-benchmarks")]
fn satisfy(_t: T) {}
}
#[impl_for_tuples(1, 10)]
#[tuple_types_custom_trait_bound(PreConditions<T, Result = bool>)]
#[allow(clippy::redundant_clone)]
impl<T> PreConditions<T> for Tuple
where
T: Clone,
{
type Result = bool;
fn check(t: T) -> Self::Result {
for_tuples!( #( <Tuple as PreConditions::<T>>::check(t.clone()) )&* )
}
}
#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)]
pub struct Always;
impl<T> PreConditions<T> for Always {
type Result = bool;
fn check(_t: T) -> bool {
true
}
}
#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)]
pub struct Never;
impl<T> PreConditions<T> for Never {
type Result = bool;
fn check(_t: T) -> bool {
false
}
}
pub trait TransferAllowance<AccountId> {
type CurrencyId;
type Location: Member + Debug + Eq + PartialEq + TypeInfo + Encode + Decode + MaxEncodedLen;
fn allowance(
send: AccountId,
receive: Self::Location,
currency: Self::CurrencyId,
) -> Result<Option<Self::Location>, DispatchError>;
}
pub trait CurrencyInspect {
type CurrencyId;
fn is_tranche_token(currency: Self::CurrencyId) -> bool;
}
pub trait StatusNotificationHook {
type Id;
type Status;
type Error: Debug;
fn notify_status_change(id: Self::Id, status: Self::Status) -> Result<(), Self::Error>;
}
pub trait EpochTransitionHook {
type Balance;
type PoolId;
type Time;
type Error;
fn on_closing_mutate_reserve(
pool_id: Self::PoolId,
assets_under_management: Self::Balance,
reserve: &mut Self::Balance,
) -> Result<(), Self::Error>;
fn on_execution_pre_fulfillments(pool_id: Self::PoolId) -> Result<(), Self::Error>;
}
pub trait IdentityCurrencyConversion {
type Balance;
type Currency;
type Error;
fn stable_to_stable(
currency_in: Self::Currency,
currency_out: Self::Currency,
amount_out: Self::Balance,
) -> Result<Self::Balance, Self::Error>;
}
pub trait TryConvert<A, B> {
type Error;
fn try_convert(a: A) -> Result<B, Self::Error>;
}
pub type Millis = u64;
pub type Seconds = u64;
pub trait TimeAsSecs: UnixTime {
fn now() -> Seconds {
<Self as UnixTime>::now().as_secs()
}
}
impl<T: UnixTime> TimeAsSecs for T {}
pub trait IntoSeconds {
fn into_seconds(self) -> Seconds;
}
impl IntoSeconds for Millis {
fn into_seconds(self) -> Seconds {
self / 1000
}
}
pub trait ValueProvider<Source, Key> {
type Value;
fn get(source: &Source, id: &Key) -> Result<Option<Self::Value>, DispatchError>;
#[cfg(feature = "runtime-benchmarks")]
fn set(_source: &Source, _key: &Key, _value: Self::Value) {}
}
pub struct NoProvider<Value>(PhantomData<Value>);
impl<Source, Key, Value> ValueProvider<Source, Key> for NoProvider<Value> {
type Value = Value;
fn get(_: &Source, _: &Key) -> Result<Option<Self::Value>, DispatchError> {
Err(DispatchError::Other("No value"))
}
}
pub trait HasLocalAssetRepresentation<AssetRegistry> {
fn is_local_representation_of(&self, variant_currency: &Self) -> Result<bool, DispatchError>;
}
pub type AssetMetadataOf<T> = asset_registry::AssetMetadata<
<T as orml_traits::asset_registry::Inspect>::Balance,
<T as orml_traits::asset_registry::Inspect>::CustomMetadata,
StringLimitOf<T>,
>;
pub type StringLimitOf<T> = <T as orml_traits::asset_registry::Inspect>::StringLimit;