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

xcm sell structs and enums #834

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ workspace = false

[tasks.run-local-integration-tests-debug]
script = '''
RUST_BACKTRACE=full RUST_LOG=trace,parity-db=warn,trie=warn,runtime=trace,substrate-relay=trace,bridge=trace,xcmp=trace cargo +stable test --package local-integration-tests --features local-integration-tests --features picasso --no-default-features -- --nocapture --test-threads=1
RUST_BACKTRACE=full RUST_LOG=trace,parity-db=warn,trie=warn,runtime=trace,substrate-relay=trace,bridge=trace,xcmp=trace cargo +stable test --package local-integration-tests --features local-integration-tests --features picasso --no-default-features -- --nocapture --test-threads=1
'''
workspace = false

Expand Down
18 changes: 18 additions & 0 deletions frame/bonded-finance/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@
//! Alice may cancel offer and prevent new bonds on offer, she gets her native tokens back.
//! All existing vesting periods continue to be executed.
//!
//! ## Use cases
//!
//! - Staking. User locks amount for some period of time, gets reward in the end or vested. Stake
//! returns to user in the end.
//! - Vesting. User offers amount and ensure that recepients has 'ticket' tokens to bond to get
//! reward.
//! - Sell/Exchange/Trade. User makes bond offer, other users takes offer in exchange for other
//! amount..
//!
//! ## Concerns
//!
//! Protocol is not protected from sniper bots, whales and other attackers.
//! Could lock amounts after into time locked fNFTs, vested, or offer to depend on time and already
//! taken amount.
//!
//! ## Interface
//!
//! This pallet implements the `composable_traits::bonded_finance::BondedFinance`.
Expand Down Expand Up @@ -176,6 +191,9 @@ pub mod pallet {
/// The minimum reward for an offer.
///
/// Must be > T::Vesting::MinVestedTransfer.
// NOTE: can be zero for low amount tokens. either define normalzied (e.g. to stable or
// native token), or better have min per bond setup (if min == total will make Sell type
// setup)
#[pallet::constant]
type MinReward: Get<BalanceOf<Self>>;

Expand Down
1 change: 1 addition & 0 deletions frame/composable-traits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" }
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" }
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.17" }
sp-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" }
Expand Down
1 change: 1 addition & 0 deletions frame/composable-traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ pub mod privilege;
pub mod time;
pub mod vault;
pub mod vesting;
pub mod xcm;
20 changes: 20 additions & 0 deletions frame/composable-traits/src/liquidation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use codec::Encode;
use sp_runtime::DispatchError;
use sp_std::vec::*;

use crate::defi::{DeFiEngine, Sell};

Expand All @@ -17,3 +19,21 @@ pub trait Liquidation: DeFiEngine {
configuration: sp_std::vec::Vec<Self::LiquidationStrategyId>,
) -> Result<Self::OrderId, DispatchError>;
}

/// generic transaction which can target any pallet and any method in any parachain (local or
/// remote)
/// so it must be encoded in format with widest possible values to incoroporate some chains we do
/// now (similar on how XCM is modelled)
#[derive(Encode)]
pub struct XcmLiquidation<AssetId> {
pallet: u8,
method: u8,
order: Sell<AssetId, u128>,
strategy: Vec<u128>,
}

impl<AssetId> XcmLiquidation<AssetId> {
pub fn new(pallet: u8, method: u8, order: Sell<AssetId, u128>, strategy: Vec<u128>) -> Self {
Self { pallet, method, order, strategy }
}
}
100 changes: 100 additions & 0 deletions frame/composable-traits/src/xcm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//! Less general more targeted solution before XCM gets general transactions support and discovery,
//! so at same time it can be more robust for Substate based sibling chains. Also is mor specialised
//! form of `xcm::latest::Junction`.
//!
//! API allow for selling (partial exchange via DEX, OB or Auction) via `engines` on other
//! parachains.
//!
//! Main use case is automatic liquidations of assets.

use xcm::latest::QueryId;

use crate::defi::Sell;
type AccountId = [u8; 32];
type PalletInstance = u8;
type AssetId = u128;
type Balance = u128;
type OrderId = QueryId;

/// Strongly typed sibling location to `Transact` via XCM.
/// Shortcut to more complicate way to set it via `xcm::latest::Junction`.
#[derive(Clone, Debug, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct XcmTransactConfiguration {
pub parachain_id: polkadot_parachain::primitives::Id,
pub pallet_instance: PalletInstance,
pub method_id: u8,
}
/// must be stored on side of protocol which will be asked to sell
#[derive(Clone, Debug, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct XcmSellRequestTransactConfiguration {
/// Used to route XCM message dispatch into right target
pub location: XcmTransactConfiguration,
/// Taken from storage and put as paramter into call.
/// Some preconfigured way of sell on other chain.
/// Example, some specific slippage or amount limits, or number of blocks it should take before
/// cancelation. Must be set by owners of engine and chose by thoose who governs caller side
pub configuraition_id: u128,
/// native token fee to pay on `engine` chain
pub fee: Balance,
}

/// The actualy binary data dispatched into `Call`.
/// Assets to be liqudatied was moved with `xcm::latest::Instruction::TransferReserveAsset` before
/// in same XCM message.
#[derive(Clone, Debug, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct XcmSellRequest {
/// Created on sender side and used to correlate callbacks.
/// Receiver tracks origin and `order_id`.
pub order_id: OrderId,
/// Sovereign account of sender parachain on remote parachain.
/// It was transfered amount to sell before, and
/// Notes:
/// This may be parachain id to get account, but than all protocols parchain will share same
/// account and will be harder to debug. May consider using indices pallet or some sub account
/// for protocol too.
pub from_to: AccountId,
/// Target network asset id, so sender must be aware of remote encoding.
/// If order cannot be filled to some amount, the description of that is sent in
/// `XcmSellResponseTransact`
pub order: Sell<AssetId, Balance>,
pub configuration: u128,
}

/// Optional response if engine did not sold all on first requests
#[derive(Clone, Debug, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct XcmSellInitialResponseTransact {
/// Amount of `base` token which was taken by engine to be sold..
/// Amount remaining was transfered with `xcm::latest::Instruction::TransferReserveAsset` in
/// same XCM message. Must be more than `Balance::zero()`
pub total_amount_taken: Balance,
/// Minimal price in `quote` amount of `amount_taken`
pub minimal_price: Balance,
}

/// Response from enigne, either be first and final, or can be after
/// `XcmSellInitialResponseTransact`
#[derive(Clone, Debug, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct XcmSellFinalResponseTransact {
/// may be less than `XcmSellInitialResponseTransact::total_amount_taken`.
/// Would be `Balance::zero()` if cannot sell anything. So sender can switch to other engine.
pub total_amount_taken: Balance,
/// Price `total_amount_taken` in `quote`. Must be larger or eququal than
/// `XcmSellInitialResponseTransact::minimal_price`
pub price: Balance,
}

#[derive(Clone, Debug, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct SellOrderResponse {
/// sender order_id, way to corellate XCM message (like
/// `xcm::latest::Instruction::QueryResponse`)
pub order_id: OrderId,
pub body: SellResponse,
}

// Nex relation must hold:
// Sell minimal price <= initial price <= final price
#[derive(Clone, Debug, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub enum SellResponse {
Initial(XcmSellInitialResponseTransact),
Final(XcmSellInitialResponseTransact),
}
1 change: 1 addition & 0 deletions frame/dutch-auction/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ sp-std = { default-features = false, git = "https://github.com/paritytech/substr

[dev-dependencies]
composable-tests-helpers = { path = "../composable-tests-helpers" }
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" }
hex-literal = { version = "0.3.3" }
orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "9e041dc9d213f843b18b3008f32f3acabb287dcb" }
pallet-assets = { path = '../assets' }
Expand Down
3 changes: 3 additions & 0 deletions frame/dutch-auction/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ where
T: Config,
<T as Config>::MultiCurrency:
Mutate<T::AccountId, Balance = T::Balance, AssetId = T::MayBeAssetId>,
<T as Config>::NativeCurrency: frame_support::traits::tokens::currency::Currency<T::AccountId>,
{
let treasury = &T::PalletId::get().into_account();
let native_token_amount = <T as pallet::Config>::NativeCurrency::minimum_balance()
Expand All @@ -57,6 +58,8 @@ benchmarks! {
where
<T as Config>::MultiCurrency:
Mutate<T::AccountId, Balance = T::Balance, AssetId = T::MayBeAssetId>,
<T as Config>::NativeCurrency : frame_support::traits::tokens::currency::Currency<T::AccountId>,

}
ask {
let sell = sell_identity::<T>();
Expand Down
42 changes: 10 additions & 32 deletions frame/dutch-auction/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
clippy::panic
)
)] // allow in tests
#![warn(clippy::unseparated_literal_suffix, clippy::disallowed_type)]
#![deny(clippy::unseparated_literal_suffix, clippy::disallowed_type)]
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(
#![deny(
bad_style,
bare_trait_objects,
const_err,
Expand All @@ -64,7 +64,7 @@ pub mod math;
#[cfg(test)]
mod tests;

#[cfg(feature = "runtime-benchmarks")]
#[cfg(any(feature = "runtime-benchmarks", test))]
mod benchmarking;
mod mock;

Expand All @@ -84,7 +84,6 @@ pub mod pallet {
use frame_support::{
pallet_prelude::*,
traits::{tokens::fungible::Transfer as NativeTransfer, IsType, UnixTime},
weights::WeightToFeePolynomial,
PalletId,
};
use frame_system::{
Expand All @@ -101,7 +100,6 @@ pub mod pallet {

#[pallet::config]
#[pallet::disable_frame_system_supertrait_check]
#[cfg(not(feature = "runtime-benchmarks"))]
pub trait Config: DeFiComposableConfig + frame_system::Config {
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
type UnixTime: UnixTime;
Expand All @@ -119,29 +117,10 @@ pub mod pallet {
#[pallet::constant]
type PalletId: Get<PalletId>;
type NativeCurrency: NativeTransfer<Self::AccountId, Balance = Self::Balance>;
/// Convert a weight value into a deductible fee based on the currency type.
type WeightToFee: WeightToFeePolynomial<Balance = Self::Balance>;
}
#[cfg(feature = "runtime-benchmarks")]
pub trait Config: DeFiComposableConfig + frame_system::Config {
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
type UnixTime: UnixTime;
type OrderId: OrderIdLike + WrappingNext + Zero;
type MultiCurrency: MultiCurrency<
Self::AccountId,
CurrencyId = Self::MayBeAssetId,
Balance = <Self as DeFiComposableConfig>::Balance,
> + MultiReservableCurrency<
Self::AccountId,
CurrencyId = Self::MayBeAssetId,
Balance = <Self as DeFiComposableConfig>::Balance,
>;
type WeightInfo: WeightInfo;
type PalletId: Get<PalletId>;
type NativeCurrency: NativeTransfer<Self::AccountId, Balance = Self::Balance>
+ Currency<Self::AccountId>;
/// Convert a weight value into a deductible fee based on the currency type.
type WeightToFee: WeightToFeePolynomial<Balance = Self::Balance>;

/// ED taken to create position. Part of if returned when position is liqudated.
#[pallet::constant]
type PositionExistentialDeposit: Get<Self::Balance>;
}

#[derive(Encode, Decode, MaxEncodedLen, Default, TypeInfo, Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -279,7 +258,7 @@ pub mod pallet {
treasury,
&order.from_to,
order.context.deposit,
true,
false,
)?;

<SellOrders<T>>::remove(order_id);
Expand All @@ -303,11 +282,10 @@ pub mod pallet {
*x
});
let treasury = &T::PalletId::get().into_account();
let deposit = T::WeightToFee::calc(&T::WeightInfo::liquidate());
let deposit = T::PositionExistentialDeposit::get();
<T::NativeCurrency as NativeTransfer<T::AccountId>>::transfer(
from_to, treasury, deposit, true,
)
.map_err(|_| Error::<T>::NotEnoughNativeCurrentyToPayForAuction)?;
)?;

let now = T::UnixTime::now().as_secs();
let order = SellOf::<T> {
Expand Down
25 changes: 4 additions & 21 deletions frame/dutch-auction/src/mock/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
self as pallet_dutch_auction,
mock::currency::{CurrencyId, NativeAssetId},
weights::SubstrateWeight,
};

use composable_traits::defi::DeFiComposableConfig;
Expand Down Expand Up @@ -84,7 +85,7 @@ impl frame_system::Config for Runtime {
}

parameter_types! {
pub const NativeExistentialDeposit: Balance = 0;
pub const NativeExistentialDeposit: Balance = 1_000_000_000;
}

impl pallet_balances::Config for Runtime {
Expand Down Expand Up @@ -169,31 +170,13 @@ impl DeFiComposableConfig for Runtime {
type Balance = Balance;
}

parameter_types! {
pub static WeightToFee: Balance = 1;
}

impl WeightToFeePolynomial for WeightToFee {
type Balance = Balance;

fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
let one = WeightToFeeCoefficient {
degree: 1,
coeff_frac: Perbill::zero(),
coeff_integer: WEIGHT_TO_FEE.with(|v| *v.borrow()),
negative: false,
};
smallvec![one]
}
}

impl pallet_dutch_auction::Config for Runtime {
type Event = Event;
type UnixTime = Timestamp;
type OrderId = OrderId;
type MultiCurrency = Assets;
type WeightInfo = ();
type WeightToFee = WeightToFee;
type WeightInfo = SubstrateWeight<Self>;
type PositionExistentialDeposit = NativeExistentialDeposit;
type PalletId = DutchAuctionPalletId;
type NativeCurrency = Balances;
}
Expand Down
Loading