Skip to content

Commit

Permalink
Kensetsu Phase 2 - configurable debt assets (#1005)
Browse files Browse the repository at this point in the history
* feature(kensetsu): do not allow ken and kusd be used as collateral

* feature(kensetsu): stablecoin parameters

* feature(kensetsu): oracle added

* fix(kensetsu): bad debt total supply

* fix(kensetsu): KGOLD added

* fix(kensetsu): update collateral info on cdp creation

* feature(kensetsu): update fee before repay

* fix(kensetsu): pr clippy

* feature(kensetsu): refactor

* feature(kensetsu): migration

* chore(kensetsu): remove cdp_close amount

* feature(kensetsu): check withdrawal asset id

* merge master

* feature(kensetsu): register_stablecoin

* feature(kensetsu): register stablecoin asset

* fix(kensetsu): clippy

* fix clippy

* fix: remove token hard_cap

* feature(kensetsu): kensetsu stable asset ids

* feature(kensetsu): kensetsu reference symbols

* feature(kensetsu): kensetsu reference symbols

* feature(kensetsu): fix clippy

* feature(kensetsu): v2 storage migration

* fix(kensetsu): clippy

* test(kensetsu): migration test

* merge master

* feature(kensetsu): borrow tax

* feature(kensetsu): update migration

* Add new tokens (#1042)

* Add tokens KXOR, KARMA, SB

---------

Co-authored-by: Alexey Chernyshov <alexey.n.chernyshov@gmail.com>

* feature(kensetsu): add buy back for xor/kxor

* feature(kensetsu): fix clippy

* feature(kensetsu): add genesis config for stablecoin infos

* feature(migration): register SB to price-tools

* feature(price-tools): add method is_asset_registered to PriceToolsProvider

* feature(price-tools): registers asset in PriceToolsProvider

* feature(price-tools): rm price tools migration

* fix: merge conflict

* Add KXOR support to XYK pool (#1041)

* Add new tokens

* Add KXOR support in XYK pool

* Fix build

* Add missing tokens

* Remove migrations from prod

* Remove completed migration

* Add more tests

* Fix build

* Fix build

* Fix review issue

* Add function description

* Fix review issues

* Add tests

* fix(kensetsu): do not register XOR in price tools

* fix(kensetsu): migrate v0 and v1

* feature(kensetsu): configurable borrow taxes

* feature(kensetsu): add KGOLD as predefined asset

* feature(kensetsu): collateral info storagemap

* fix(kensetsu): buyback KARMA, TBCD on any collateral

* fix(kensetsu): fix pr issues

* fix(kensetsu): fix pr issues

* Update common/src/primitives.rs

Co-authored-by: Mikhail Tagirov <dev.mikhail.tagirov@outlook.com>

---------

Co-authored-by: Vladimir Stepanenko <vovac12@gmail.com>
Co-authored-by: Mikhail Tagirov <dev.mikhail.tagirov@outlook.com>
  • Loading branch information
3 people committed Jun 10, 2024
1 parent 2432a40 commit 5fe6004
Show file tree
Hide file tree
Showing 56 changed files with 5,105 additions and 2,205 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

26 changes: 25 additions & 1 deletion common/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ pub enum ComicAssetId {
MichaelJacksonCD,
JesterMarotte,
CrackedBrassBell,
Tomato,
Potato,
Mouse,
Table,
}

impl crate::traits::IsRepresentation for ComicAssetId {
Expand Down Expand Up @@ -109,6 +113,10 @@ impl From<PredefinedAssetId> for ComicAssetId {
PredefinedAssetId::KEN => JesterMarotte,
PredefinedAssetId::TBCD => MichaelJacksonCD,
PredefinedAssetId::KUSD => CrackedBrassBell,
PredefinedAssetId::KGOLD => Tomato,
PredefinedAssetId::KXOR => Potato,
PredefinedAssetId::SB => Mouse,
PredefinedAssetId::KARMA => Table,
}
}
}
Expand Down Expand Up @@ -178,6 +186,22 @@ impl<T> orml_traits::get_by_key::GetByKey<T, bool> for GetTradingPairRestrictedF
}
}

parameter_type_with_key! {
pub GetChameleonPoolBaseAssetId: |base_asset_id: AssetId32<PredefinedAssetId>| -> Option<AssetId32<PredefinedAssetId>> {
if base_asset_id == &crate::XOR {
Some(crate::KXOR)
} else {
None
}
};
}

parameter_type_with_key! {
pub GetChameleonPool: |tpair: crate::TradingPair<AssetId32<PredefinedAssetId>>| -> bool {
tpair.base_asset_id == crate::XOR && tpair.target_asset_id == crate::ETH
};
}

pub fn alice() -> AccountId32 {
AccountId32::from([1; 32])
}
Expand Down Expand Up @@ -300,7 +324,7 @@ macro_rules! mock_frame_system_config {
type SystemWeightInfo = ();
type SS58Prefix = ConstU16<42>;
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
type MaxConsumers = frame_support::traits::ConstU32<65536>;
}
};
}
Expand Down
44 changes: 42 additions & 2 deletions common/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ pub const ASSET_CONTENT_SOURCE_MAX_LENGTH: usize = 2048;
/// Max length of asset description, it should be enough to describe everything the user wants
pub const ASSET_DESCRIPTION_MAX_LENGTH: usize = 512;

/// Predefined asset ids start with 0x02...
pub const ASSET_ID_PREFIX_PREDEFINED: u8 = 2;

/// Synthetic asset ids start with 0x03...
pub const ASSET_ID_PREFIX_SYNTHETIC: u8 = 3;

/// Kensetsu asset ids pegged to sora assets start with 0x04...
pub const ASSET_ID_PREFIX_KENSETSU_PEGGED_TO_SORA: u8 = 4;

/// Kensetsu asset ids pegged to oracle start with 0x05...
pub const ASSET_ID_PREFIX_KENSETSU_PEGGED_TO_ORACLE: u8 = 5;

/// Wrapper type which extends Balance serialization, used for json in RPC's.
#[derive(Encode, Decode, Debug, Clone, PartialEq, Eq, scale_info::TypeInfo)]
pub struct BalanceWrapper(pub Balance);
Expand Down Expand Up @@ -185,6 +197,10 @@ mod _allowed_deprecated {
TBCD = 10,
KEN = 11,
KUSD = 12,
KGOLD = 13,
KXOR = 14,
SB = 15,
KARMA = 16,
}
}

Expand All @@ -199,6 +215,10 @@ pub const XST: AssetId32<PredefinedAssetId> = AssetId32::from_asset_id(Predefine
pub const TBCD: AssetId32<PredefinedAssetId> = AssetId32::from_asset_id(PredefinedAssetId::TBCD);
pub const KEN: AssetId32<PredefinedAssetId> = AssetId32::from_asset_id(PredefinedAssetId::KEN);
pub const KUSD: AssetId32<PredefinedAssetId> = AssetId32::from_asset_id(PredefinedAssetId::KUSD);
pub const KGOLD: AssetId32<PredefinedAssetId> = AssetId32::from_asset_id(PredefinedAssetId::KGOLD);
pub const KXOR: AssetId32<PredefinedAssetId> = AssetId32::from_asset_id(PredefinedAssetId::KXOR);
pub const SB: AssetId32<PredefinedAssetId> = AssetId32::from_asset_id(PredefinedAssetId::SB);
pub const KARMA: AssetId32<PredefinedAssetId> = AssetId32::from_asset_id(PredefinedAssetId::KARMA);
pub const CERES_ASSET_ID: AssetId32<PredefinedAssetId> = AssetId32::from_bytes(hex!(
"008bcfd2387d3fc453333557eecb0efe59fcba128769b2feefdd306e98e66440"
));
Expand Down Expand Up @@ -342,7 +362,7 @@ impl<AssetId> AssetId32<AssetId> {

pub const fn from_asset_id(asset_id: PredefinedAssetId) -> Self {
let mut bytes = [0u8; 32];
bytes[0] = 2;
bytes[0] = ASSET_ID_PREFIX_PREDEFINED;
bytes[2] = asset_id as u8;
Self::from_bytes(bytes)
}
Expand All @@ -356,10 +376,25 @@ impl<AssetId> AssetId32<AssetId> {
return Self::from_asset_id(PredefinedAssetId::XSTUSD);
}

Self::from_reference_symbol(ASSET_ID_PREFIX_SYNTHETIC, reference_symbol)
}

/// Construct asset id for Kensetsu debt asset using its `peg_symbol` on Sora network
pub fn from_kensetsu_sora_peg_symbol<Symbol: Encode>(reference_symbol: &Symbol) -> Self {
Self::from_reference_symbol(ASSET_ID_PREFIX_KENSETSU_PEGGED_TO_SORA, reference_symbol)
}

/// Construct asset id for Kensetsu debt asset using its `peg_symbol` from Oracle
pub fn from_kensetsu_oracle_peg_symbol<Symbol: Encode>(reference_symbol: &Symbol) -> Self {
Self::from_reference_symbol(ASSET_ID_PREFIX_KENSETSU_PEGGED_TO_ORACLE, reference_symbol)
}

/// Constructs Asset id from symbol with provided zero byte.
fn from_reference_symbol<Symbol: Encode>(zero_byte: u8, reference_symbol: &Symbol) -> Self {
let mut bytes = [0u8; 32];
let symbol_bytes = reference_symbol.encode();
let symbol_hash = sp_io::hashing::blake2_128(&symbol_bytes);
bytes[0] = 3;
bytes[0] = zero_byte;
bytes[2..18].copy_from_slice(&symbol_hash);

Self::from_bytes(bytes)
Expand Down Expand Up @@ -662,6 +697,11 @@ impl SymbolName {
pub fn usd() -> Self {
Self::from_str("USD").expect("`USD` is a valid symbol name")
}

/// Troy ounce of gold
pub fn xau() -> Self {
Self::from_str("XAU").expect("`XAU` is a valid symbol name")
}
}

impl FromStr for SymbolName {
Expand Down
7 changes: 7 additions & 0 deletions common/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,9 @@ pub trait OnPoolCreated {
}

pub trait PriceToolsProvider<AssetId> {
/// Checks if asset is registered in PriceTools.
fn is_asset_registered(asset_id: &AssetId) -> bool;

/// Get amount of `output_asset_id` corresponding to a unit (1) of `input_asset_id`.
/// `price_variant` specifies the correction for price, either for buy or sell.
fn get_average_price(
Expand All @@ -894,6 +897,10 @@ pub trait PriceToolsProvider<AssetId> {
}

impl<AssetId> PriceToolsProvider<AssetId> for () {
fn is_asset_registered(_asset_id: &AssetId) -> bool {
unimplemented!()
}

fn get_average_price(
_: &AssetId,
_: &AssetId,
Expand Down
108 changes: 104 additions & 4 deletions node/chain_spec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
use common::prelude::{Balance, DEXInfo, FixedWrapper};
use common::{
balance, fixed, hash, our_include, our_include_bytes, vec_push, BalancePrecision, DEXId, Fixed,
TechPurpose, APOLLO_ASSET_ID, DAI, DEFAULT_BALANCE_PRECISION, ETH, HERMES_ASSET_ID, KEN, KUSD,
PSWAP, TBCD, USDT, VAL, XOR, XST, XSTUSD,
TechPurpose, APOLLO_ASSET_ID, DAI, DEFAULT_BALANCE_PRECISION, ETH, HERMES_ASSET_ID, KEN, KGOLD,
KUSD, PSWAP, TBCD, USDT, VAL, XOR, XST, XSTUSD,
};
use frame_support::sp_runtime::Percent;
use framenode_runtime::eth_bridge::{AssetConfig, BridgeAssetData, NetworkConfig};
Expand All @@ -56,7 +56,7 @@ use framenode_runtime::{
BabeConfig, BalancesConfig, BeefyConfig, BeefyId, BridgeMultisigConfig, CouncilConfig,
DEXAPIConfig, DEXManagerConfig, DemocracyConfig, EthBridgeConfig, GenesisConfig,
GetBaseAssetId, GetParliamentAccountId, GetPswapAssetId, GetSyntheticBaseAssetId,
GetValAssetId, GetXorAssetId, GrandpaConfig, ImOnlineId, IrohaMigrationConfig,
GetValAssetId, GetXorAssetId, GrandpaConfig, ImOnlineId, IrohaMigrationConfig, KensetsuConfig,
LiquiditySourceType, MulticollateralBondingCurvePoolConfig, PermissionsConfig,
PswapDistributionConfig, RewardsConfig, Runtime, SS58Prefix, SessionConfig, Signature,
StakerStatus, StakingConfig, SystemConfig, TechAccountId, TechnicalCommitteeConfig,
Expand Down Expand Up @@ -896,7 +896,7 @@ fn testnet_genesis(
technical_committee_accounts: Vec<AccountId>,
validator_count: u32,
) -> GenesisConfig {
use common::XSTUSD;
use common::{KARMA, KXOR, SB, XSTUSD};

// Initial balances
let initial_staking = balance!(1000000000);
Expand Down Expand Up @@ -1449,6 +1449,50 @@ fn testnet_genesis(
None,
None,
),
(
KGOLD,
assets_and_permissions_account_id.clone(),
AssetSymbol(b"KGOLD".to_vec()),
AssetName(b"Kensetsu ounce of gold".to_vec()),
DEFAULT_BALANCE_PRECISION,
Balance::zero(),
true,
None,
None,
),
(
KXOR,
assets_and_permissions_account_id.clone(),
AssetSymbol(b"KXOR".to_vec()),
AssetName(b"Kensetsu XOR".to_vec()),
DEFAULT_BALANCE_PRECISION,
Balance::zero(),
true,
None,
None,
),
(
SB,
assets_and_permissions_account_id.clone(),
AssetSymbol(b"SB".to_vec()),
AssetName(b"SORA Builders".to_vec()),
DEFAULT_BALANCE_PRECISION,
Balance::zero(),
true,
None,
None,
),
(
KARMA,
assets_and_permissions_account_id.clone(),
AssetSymbol(b"KARMA".to_vec()),
AssetName(b"Chameleon".to_vec()),
DEFAULT_BALANCE_PRECISION,
Balance::zero(),
true,
None,
None,
),
],
},
permissions: PermissionsConfig {
Expand Down Expand Up @@ -1630,6 +1674,12 @@ fn testnet_genesis(
burn_info: (fixed!(0.1), fixed!(0.000357), fixed!(0.65)),
},
iroha_migration: iroha_migration_config,
kensetsu: KensetsuConfig {
predefined_stablecoin_infos: vec![
(KUSD, DAI, balance!(1)),
(KXOR, XOR, balance!(100000))
],
},
rewards: rewards_config,
council: CouncilConfig {
members: council_accounts,
Expand Down Expand Up @@ -2123,6 +2173,50 @@ fn mainnet_genesis(
None,
None,
),
(
KGOLD,
assets_and_permissions_account_id.clone(),
AssetSymbol(b"KGOLD".to_vec()),
AssetName(b"Kensetsu ounce of gold".to_vec()),
DEFAULT_BALANCE_PRECISION,
Balance::zero(),
true,
None,
None,
),
(
KXOR,
assets_and_permissions_account_id.clone(),
AssetSymbol(b"KXOR".to_vec()),
AssetName(b"Kensetsu XOR".to_vec()),
DEFAULT_BALANCE_PRECISION,
Balance::zero(),
true,
None,
None,
),
(
SB,
assets_and_permissions_account_id.clone(),
AssetSymbol(b"SB".to_vec()),
AssetName(b"SORA Builders".to_vec()),
DEFAULT_BALANCE_PRECISION,
Balance::zero(),
true,
None,
None,
),
(
KARMA,
assets_and_permissions_account_id.clone(),
AssetSymbol(b"KARMA".to_vec()),
AssetName(b"Chameleon".to_vec()),
DEFAULT_BALANCE_PRECISION,
Balance::zero(),
true,
None,
None,
),
];
let bridge_assets_data: Vec<BridgeAssetData<Runtime>> = Vec::new();
bridge_assets.extend(bridge_assets_data.iter().map(|x| {
Expand Down Expand Up @@ -2437,6 +2531,12 @@ fn mainnet_genesis(
iroha_accounts: Vec::new(),
account_id: Some(iroha_migration_account_id),
},
kensetsu: KensetsuConfig {
predefined_stablecoin_infos: vec![
(KUSD, DAI, balance!(1)),
(KXOR, XOR, balance!(100000)),
],
},
rewards: rewards_config,
council: CouncilConfig {
members: council_accounts,
Expand Down
9 changes: 9 additions & 0 deletions pallets/apollo-platform/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ impl liquidity_proxy::Config for Runtime {
type ADARCommissionRatioUpdateOrigin = EnsureRoot<AccountId>;
type MaxAdditionalDataLengthXorlessTransfer = ConstU32<128>;
type MaxAdditionalDataLengthSwapTransferBatch = ConstU32<2000>;
type GetChameleonPool = common::mock::GetChameleonPool;
type GetChameleonPoolBaseAssetId = common::mock::GetChameleonPoolBaseAssetId;
type AssetInfoProvider = assets::Pallet<Runtime>;
}

Expand Down Expand Up @@ -305,6 +307,8 @@ impl pool_xyk::Config for Runtime {
type OnPoolReservesChanged = ();
type XSTMarketInfo = ();
type GetTradingPairRestrictedFlag = GetTradingPairRestrictedFlag;
type GetChameleonPool = common::mock::GetChameleonPool;
type GetChameleonPoolBaseAssetId = common::mock::GetChameleonPoolBaseAssetId;
type AssetInfoProvider = assets::Pallet<Runtime>;
type IrreducibleReserve = GetXykIrreducibleReservePercent;
type WeightInfo = ();
Expand All @@ -327,6 +331,7 @@ impl pswap_distribution::Config for Runtime {
type PoolXykPallet = PoolXYK;
type BuyBackHandler = ();
type DexInfoProvider = dex_manager::Pallet<Runtime>;
type GetChameleonPoolBaseAssetId = common::mock::GetChameleonPoolBaseAssetId;
type AssetInfoProvider = assets::Pallet<Runtime>;
}

Expand Down Expand Up @@ -362,6 +367,10 @@ impl price_tools::Config for Runtime {
pub struct MockPriceTools;

impl PriceToolsProvider<AssetId> for MockPriceTools {
fn is_asset_registered(_asset_id: &AssetId) -> bool {
unimplemented!()
}

fn get_average_price(
input_asset_id: &AssetId,
output_asset_id: &AssetId,
Expand Down
2 changes: 2 additions & 0 deletions pallets/assets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ pub mod weights;

mod benchmarking;

pub mod migration;

#[cfg(test)]
mod mock;

Expand Down
Loading

0 comments on commit 5fe6004

Please sign in to comment.