Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
79bea4b
chore(deps): cargo update --workspace
mattsse Apr 15, 2021
7aacf06
fix(deps): update renamed xcm crate names
mattsse Apr 15, 2021
c3799e4
fix: rename ModuleId to PalletId
mattsse Apr 15, 2021
7b3b477
feat:pallets/orcale: add oracle pallet template
mattsse Apr 9, 2021
9c566a6
feat:pallets/orcale: rename to price feed and include chainlink feed
mattsse Apr 15, 2021
82f4b46
feat:pallets/price-feed: integrate latest chainlink price feed pallet
mattsse Apr 15, 2021
09c2662
rustfmt
mattsse Apr 15, 2021
e5325d5
chore(deps): sync with chainlink deps
mattsse Apr 15, 2021
82ff8c8
chore(deps): sort members
mattsse Apr 16, 2021
39edc21
feat:pallets/price-feed: add types
mattsse Apr 16, 2021
2a07bf4
feat:pallets/price-feed: introduce price feed types and price feed trait
mattsse Apr 16, 2021
f0bd7e8
feat:pallets/price-feed: empty price feed trait implementation
mattsse Apr 16, 2021
6112a62
rustfmt
mattsse Apr 16, 2021
7851a9f
chore(deps): enable std feature for balances
mattsse Apr 16, 2021
ba70d39
feat:pallets/price-feed: add mock config
mattsse Apr 16, 2021
1946262
docs:pallets/price-feed: clarify notes on precision
mattsse Apr 16, 2021
1d609bc
test:pallets/price-feed: add basic feed creation test
mattsse Apr 16, 2021
b7ace6d
rustfmt
mattsse Apr 16, 2021
92bc95e
Update pallets/price-feed/src/lib.rs
mattsse Apr 19, 2021
b36ae3f
feat:pallets/price-feed: add mapping from assetId to feedId
mattsse Apr 19, 2021
d23ca01
feat:pallets/price-feed: add genesis build support
mattsse Apr 19, 2021
b7e8fea
refactor:pallets/price-feed: replace generic price type with FixedU128
mattsse Apr 19, 2021
a23ba9c
feat:pallets/price-feed: implement get_price_pair
mattsse Apr 19, 2021
7007279
rustfmt
mattsse Apr 19, 2021
bb074a6
chore(clippy): make clippy happy
mattsse Apr 19, 2021
f1b60ab
chore(deps): update chainlink feed pallet
mattsse Apr 19, 2021
9763582
feat:pallets/price-feed: drop unused type
mattsse Apr 19, 2021
549f8f0
test:pallets/price-feed: update mock template
mattsse Apr 19, 2021
46aef80
test:pallets/price-feed: add price pair tests
mattsse Apr 19, 2021
70444ee
test:pallets/price-feed: reexport feedbuilder for tests
mattsse Apr 19, 2021
0b3cc33
test:pallets/price-feed: add price feed tests
mattsse Apr 19, 2021
0b62072
chore:pallets/price-feed: remove commented out config typ eartefacts
mattsse Apr 19, 2021
fbf1c66
Merge branch 'main' into matt/add-price-feed
mattsse Apr 22, 2021
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
4,341 changes: 2,681 additions & 1,660 deletions Cargo.lock

Large diffs are not rendered by default.

13 changes: 4 additions & 9 deletions pallets/local-treasury/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@ mod tests;
// this is requires as the #[pallet::event] proc macro generates code that violates this lint
#[allow(clippy::unused_unit)]
pub mod pallet {
use frame_support::{
dispatch::DispatchResultWithPostInfo,
pallet_prelude::*,
sp_runtime::{traits::AccountIdConversion, ModuleId},
traits::{Currency, ExistenceRequirement::AllowDeath, Get},
};
use frame_support::{dispatch::DispatchResultWithPostInfo, pallet_prelude::*, sp_runtime::{traits::AccountIdConversion}, traits::{Currency, ExistenceRequirement::AllowDeath, Get}, PalletId};
use frame_system::pallet_prelude::*;

type AccountIdFor<T> = <T as frame_system::Config>::AccountId;
Expand All @@ -30,10 +25,10 @@ pub mod pallet {
pub trait Config: frame_system::Config {
/// Origin that is allowed to manage the treasury balance and initiate withdrawals
type AdminOrigin: EnsureOrigin<Self::Origin>;
/// ModuleId must be an unique 8 character string.
/// PalletId must be an unique 8 character string.
/// It is used to generate the account ID which holds the balance of the treasury.
#[pallet::constant]
type ModuleId: Get<ModuleId>;
type PalletId: Get<PalletId>;
/// The pallet to use as the base currency for this treasury
type Currency: Currency<Self::AccountId>;
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
Expand Down Expand Up @@ -62,7 +57,7 @@ pub mod pallet {
/// Returns the accountID for the treasury balance
/// Transferring balance to this account funds the treasury
pub fn account_id() -> T::AccountId {
T::ModuleId::get().into_account()
T::PalletId::get().into_account()
}
}

Expand Down
8 changes: 4 additions & 4 deletions pallets/local-treasury/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use sp_runtime::{
testing::Header,
traits::AccountIdConversion,
traits::{BlakeTwo256, IdentityLookup},
ModuleId,
PalletId,
};

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
Expand Down Expand Up @@ -86,19 +86,19 @@ impl pallet_balances::Config for Test {
type WeightInfo = ();
}

pub(crate) const LOCAL_TREASURE_MODULE_ID: ModuleId = ModuleId(*b"12345678");
pub(crate) const LOCAL_TREASURE_MODULE_ID: PalletId = PalletId(*b"12345678");
pub(crate) const ADMIN_ACCOUNT_ID: AccountId = 88;

parameter_types! {
pub const TestModuleId: ModuleId = LOCAL_TREASURE_MODULE_ID;
pub const TestPalletId: PalletId = LOCAL_TREASURE_MODULE_ID;
}
ord_parameter_types! {
pub const AdminAccountId: AccountId = ADMIN_ACCOUNT_ID;
}

impl pallet_local_treasury::Config for Test {
type AdminOrigin = frame_system::EnsureSignedBy<AdminAccountId, AccountId>;
type ModuleId = TestModuleId;
type PalletId = TestPalletId;
type Currency = Balances;
type Event = Event;
}
Expand Down
75 changes: 75 additions & 0 deletions pallets/price-feed/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
[package]
authors = ['ChainSafe Systems']
description = 'FRAME pallet to implement PINT price feeds.'
edition = '2018'
license = 'LGPL-3.0-only'
name = 'pallet-price-feed'
readme = 'README.md'
repository = 'https://github.com/ChainSafe/PINT/'
version = '0.0.1'

[features]
default = ['std']
std = [
'codec/std',
'frame-support/std',
'frame-system/std',
'pallet-balances/std',
'pallet-chainlink-feed/std',
]
[dependencies.codec]
default-features = false
features = ['derive']
package = 'parity-scale-codec'
version = '2.0.0'

[dependencies.frame-support]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
branch = 'rococo-v1'
version = '3.0.0'

[dependencies.frame-system]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
branch = 'rococo-v1'
version = '3.0.0'

[dependencies.pallet-chainlink-feed]
default_features = false
package = 'pallet-chainlink-feed'
git = "https://github.com/mattsse/chainlink-polkadot"
# this is substrate v3 branch that is upstreamed with rococo-v1
# and requires https://github.com/ChainSafe/PINT/issues/37
# see also https://github.com/ChainSafe/PINT/pull/39
branch = "substrate-v3"

[dev-dependencies]
serde = { version = "1.0" }

[dev-dependencies.pallet-balances]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
branch = 'rococo-v1'
version = '3.0.0'

[dev-dependencies.sp-core]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
branch = 'rococo-v1'
version = '3.0.0'

[dev-dependencies.sp-io]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
branch = 'rococo-v1'
version = '3.0.0'

[dev-dependencies.sp-runtime]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
branch = 'rococo-v1'
version = '3.0.0'

[package.metadata.docs.rs]
targets = ['x86_64-unknown-linux-gnu']
1 change: 1 addition & 0 deletions pallets/price-feed/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
License: LGPL-3.0-only
99 changes: 99 additions & 0 deletions pallets/price-feed/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2021 ChainSafe Systems
// SPDX-License-Identifier: LGPL-3.0-only

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[cfg(test)]
mod mock;

#[cfg(test)]
mod tests;

/// Additional type used in this pallet
mod traits;
/// Additional structures used in this pallet
mod types;

#[frame_support::pallet]
// this is requires as the #[pallet::event] proc macro generates code that violates this lint
#[allow(clippy::unused_unit)]
pub mod pallet {
pub use crate::traits::PriceFeed;
use crate::types::AssetPricePair;
use frame_support::{pallet_prelude::*, sp_runtime::PerThing, traits::Get};
use frame_system::pallet_prelude::*;
use pallet_chainlink_feed::FeedOracle;

/// Provides access to all the price feeds
/// This is used to determine the equivalent amount of PINT for assets
#[pallet::config]
pub trait Config: frame_system::Config {
/// The unit used to measure the value of assets
type BaseCurrency: Parameter + Member;

/// The asset identifier for the native asset (PINT) price feed in the oracle.
#[pallet::constant]
type SelfAssetFeedId: Get<Self::AssetFeedId>;

/// Used to define the decimal precision when calculating prices
// TODO this needs to be factored in when converting the feed prices with their decimals
type Precision: PerThing + Encode;

/// Type used to identify the asset's feed.
type AssetFeedId: Parameter + Member;

/// The internal oracle that gives access to the asset's price feeds.
///
/// NOTE: this assumes all the feed's provide data in the same base currency.
/// When querying the price of an asset (`quote`/`asset`) from the, its price is given by means of the asset pair `(base / quote)`. (e.g. DOT/PINT)
type Oracle: FeedOracle<Self>;

type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
}

#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);

// TODO here we could track historical price pairs

#[pallet::extra_constants]
impl<T: Config> Pallet<T> {
/// The decimal precision to use when calculating price fractions
pub fn precision() -> T::Precision {
T::Precision::one()
}
}

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {}

#[pallet::error]
pub enum Error<T> {}

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}

#[pallet::call]
impl<T: Config> Pallet<T> {}

impl<T: Config> Pallet<T> {}

impl<T: Config> PriceFeed<T::AssetFeedId, T::Precision> for Pallet<T> {
fn get_price(
quote: T::AssetFeedId,
) -> Result<AssetPricePair<T::AssetFeedId, T::Precision>, DispatchError> {
Self::get_price_pair(T::SelfAssetFeedId::get(), quote)
}

fn get_price_pair(
_base: T::AssetFeedId,
_quote: T::AssetFeedId,
) -> Result<AssetPricePair<T::AssetFeedId, T::Precision>, DispatchError> {
todo!()
}
}
}
147 changes: 147 additions & 0 deletions pallets/price-feed/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Copyright 2021 ChainSafe Systems
// SPDX-License-Identifier: LGPL-3.0-only

// Required as construct_runtime! produces code that violates this lint
#![allow(clippy::from_over_into)]

use crate as pallet_price_feed;
use frame_support::sp_runtime::traits::AccountIdConversion;
use frame_support::{parameter_types, PalletId};
use frame_system as system;
use sp_core::H256;
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
Perbill,
};

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;

// Configure a mock runtime to test the pallet.
frame_support::construct_runtime!(
pub enum Test where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
PriceFeed: pallet_price_feed::{Pallet, Call, Storage, Event<T>},
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
ChainlinkFeed: pallet_chainlink_feed::{Pallet, Call, Storage, Event<T>},
}
);

parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const SS58Prefix: u8 = 42;
}

pub(crate) type Balance = u64;
pub(crate) type AccountId = u64;

impl system::Config for Test {
type BaseCallFilter = ();
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type Origin = Origin;
type Call = Call;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = Event;
type BlockHashCount = BlockHashCount;
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = SS58Prefix;
type OnSetCode = ();
}

parameter_types! {
pub const ExistentialDeposit: u64 = 1;
}

impl pallet_balances::Config for Test {
type MaxLocks = ();
type Balance = Balance;
type Event = Event;
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
}

pub(crate) const MIN_RESERVE: u64 = 100;

parameter_types! {
pub const FeedPalletId: PalletId = PalletId(*b"linkfeed");
pub const MinimumReserve: u64 = MIN_RESERVE;
pub const StringLimit: u32 = 15;
pub const OracleLimit: u32 = 10;
pub const FeedLimit: u16 = 10;
pub const PruningWindow: u32 = 3;
}

type FeedId = u16;
type Value = u64;

impl pallet_chainlink_feed::Config for Test {
type Event = Event;
type FeedId = FeedId;
type Value = Value;
type Currency = Balances;
type PalletId = FeedPalletId;
type MinimumReserve = MinimumReserve;
type StringLimit = StringLimit;
type OracleCountLimit = OracleLimit;
type FeedLimit = FeedLimit;
type PruningWindow = PruningWindow;
type WeightInfo = ();
}

parameter_types! {
pub const PINTFeed: FeedId = 1u16;
}

type BaseCurrency = u128;

impl pallet_price_feed::Config for Test {
type Event = Event;
type Oracle = ChainlinkFeed;
type BaseCurrency = BaseCurrency;
type SelfAssetFeedId = PINTFeed;
type Precision = Perbill;
type AssetFeedId = FeedId;
}

// Build genesis storage according to the mock runtime.
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default()
.build_storage::<Test>()
.unwrap();

let pallet_account: AccountId = FeedPalletId::get().into_account();
pallet_balances::GenesisConfig::<Test> {
balances: vec![(pallet_account, 100 * MIN_RESERVE)],
}
.assimilate_storage(&mut t)
.unwrap();

pallet_chainlink_feed::GenesisConfig::<Test> {
pallet_admin: Some(pallet_account),
feed_creators: vec![1],
}
.assimilate_storage(&mut t)
.unwrap();

t.into()
}
Loading