Code Monkey home page Code Monkey logo

acala's People

Contributors

0xthreebody avatar alfellati avatar bette7 avatar brettkolodny avatar cuardaigh avatar dependabot[bot] avatar ermalkaleci avatar ferrell-code avatar fsgegs avatar herryho avatar justinphamnz avatar omahs avatar qwer951123 avatar roynalnaruto avatar sander2 avatar sasha-nechaiev avatar shaunxw avatar shengda avatar shunjizhan avatar strawberryflavor avatar syan095 avatar tolak avatar ukby1234 avatar wangjj9219 avatar warfollowsme avatar xiaolou86 avatar xiaoxianboy avatar xlc avatar zjb0807 avatar zqhxuyuan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

acala's Issues

Accounts module

Accounts module

  • Trait
    • FreeTransferCount: Get<u8>
    • FreeTransferPeriod: Get<Moment>
    • Time: Time
    • Call: Parameter + Dispatchable<Origin=::Origin> + IsSubType<orml_currencies::Module<Self>, Self>;
    • Currency: Currency
  • Storages
    • LastFreeTransfers: map AccountId => Vec<Moment>
      • Store last FreeTransferCount free transfer time for each account
  • Module
    • impl OnReapAccount
      • clear LastFreeTransfers for reaped account
    • try_free_transfer(who: AccountId) -> bool
      • Read LastFreeTransfers, remove all the expired entries (value < now - FreeTransferPeriod), return true and append now to the list if entries count less than FreeTransferCount otherwise return false
  • ChargeTransactionPayment: SignedExtension
    • Similar to ChargeTransactionPayment in pallet-transaction-payment module
    • it additionaly call try_free_transfer and skip the withdraw fee part if the call is currencies.transfer and user still have free transfer
    • check pallet-contracts CheckBlockGasLimit for how to check call type
    • Use transaction_payment::ChargeTransactionPayment::from(tip)::compute_fee to reduce copy & paste

Update runtime to use the new ChargeTransactionPayment instead of the one in transaction payment module

We will still need additional requirements for an account to be able to make free transfer. This is still TBD.

Upgrade Substrate

paritytech/substrate#4820 is a major breaking change that is going to break all SDK, frontend and bots.

Upgrade procedure:

Preparation:

  • ORML still tracking latest Substrate
  • Acala freeze ORML version, unless urgent bug fix is required
  • Mandala freeze runtime upgrade, unless urgent bug fix is required

Update code:

  • Acala upgrade ORML & Substrate version to latest that including the breaking change
  • Deployed to a private testnet
  • Upgrade SDK & console to latest version
  • Upgrade frontend & bots to use latest SDK
  • Perform testing against private testent to ensure it works

Deploy:

  • 🙏
  • Runtime upgrade Mandala
  • Deploy new frontend & console & bots
  • 🎉

ACA Treasury

We cannot mint ACA directly other than the case of debit auction.

So we need an ACA Treasury holding all the not yet released tokens, and rewards should be transferred from treasury.

Details TBD. Needs to match white paper.

ACA Token Allocation

  • Foundation
    • Multi-sig account owned by Acala Foundation members
  • Ecosystem
    • Treasury
    • General Council can spend this
  • Reserved
    • Multi-sig account owned by Acala Foundation members
  • IEO
    • Multi-sig account owned by Acala Foundation members until IEO finishes
  • Reward
    • Collator Reward
    • Oracle Reward
    • IPO Reward

purge-chain panic

Version: 0.2.3-488aeec-x86_64-macos

stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /Users/xiliangchen/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.43/src/backtrace/libunwind.rs:86
      backtrace::backtrace::trace_unsynchronized
             at /Users/xiliangchen/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.43/src/backtrace/mod.rs:66
   1: backtrace::backtrace::trace
             at /Users/xiliangchen/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.43/src/backtrace/mod.rs:53
   2: backtrace::capture::Backtrace::create
             at /Users/xiliangchen/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.43/src/capture.rs:164
   3: backtrace::capture::Backtrace::new
             at /Users/xiliangchen/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.43/src/capture.rs:128
   4: sp_panic_handler::panic_hook
             at /Users/xiliangchen/.cargo/git/checkouts/substrate-7e08433d4c370a21/f3742e7/primitives/panic-handler/src/lib.rs:148
   5: sp_panic_handler::set::{{closure}}
             at /Users/xiliangchen/.cargo/git/checkouts/substrate-7e08433d4c370a21/f3742e7/primitives/panic-handler/src/lib.rs:58
   6: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
   7: std::panicking::continue_panic_fmt
   8: std::panicking::try::do_call
   9: std::panicking::begin_panic
  10: std::panicking::begin_panic
  11: core::option::Option<T>::expect
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/option.rs:345
  12: sc_service::config::Configuration<G,E>::expect_database
             at /Users/xiliangchen/.cargo/git/checkouts/substrate-7e08433d4c370a21/f3742e7/client/service/src/config.rs:255
  13: sc_cli::params::PurgeChainCmd::run
             at /Users/xiliangchen/.cargo/git/checkouts/substrate-7e08433d4c370a21/f3742e7/client/cli/src/params.rs:1128
  14: sc_cli::params::Subcommand::run
             at /Users/xiliangchen/.cargo/git/checkouts/substrate-7e08433d4c370a21/f3742e7/client/cli/src/params.rs:911
  15: sc_cli::run_subcommand
             at /Users/xiliangchen/.cargo/git/checkouts/substrate-7e08433d4c370a21/f3742e7/client/cli/src/lib.rs:263
  16: acala::command::run
             at src/command.rs:14
  17: acala::main
             at src/main.rs:22
  18: std::rt::lang_start::{{closure}}
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
  19: std::panicking::try::do_call
  20: panic_unwind::dwarf::eh::read_encoded_pointer
  21: std::panicking::update_count_then_panic
  22: std::rt::lang_start
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
  23: acala::main


Thread 'main' panicked at 'database must be specified', src/libcore/option.rs:1185

Must be relates to paritytech/substrate#4849

airdrop module

  • module-airdrop

    • Trait
      • CurrencyId
    • Stroage
      • Airdrops: double_map AccountId, CurrencyId => Balance
    • Call
      • airdrop(origin, to: AccountId, currency_id: CurrencyId, amount: Balance)
        • require root
      • update_airdrop(origin, to: AccountId, currency_id: CurrencyId, amount: Balance)
        • require root
  • module-primitives

    • Type
      • enum AirDropCurrencyId
        • KAR
        • ACA

This is used to record airdropped token in Mandala testnet.
The values from this module will be used to generate genesis of Karura / Acala Mainnet.

CurrencyId type convert

pub trait Trait: system::Trait {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
type CurrencyId: From<u8> + Into<CurrencyIdOf<Self>> + Into<DebitCurrencyIdOf<Self>> + Parameter + Copy;
type Price: FullCodec + SimpleArithmetic + Member + Into<u64> + From<Self::Balance>;
type Balance: From<BalanceOf<Self>> + From<DebitBalanceOf<Self>> + Into<Self::Price> + Zero;
type Convert: Convert<(Self::CurrencyId, DebitBalanceOf<Self>), BalanceOf<Self>>;
type Currency: MultiCurrencyExtended<Self::AccountId>;
type DebitCurrency: MultiCurrencyExtended<Self::AccountId>;
type PriceSource: PriceProvider<Self::CurrencyId, Self::Price>;
type RiskManager: RiskManager<Self::AccountId, Self::CurrencyId, AmountOf<Self>, DebitAmountOf<Self>>;
}
type CurrencyIdOf<T> = <<T as Trait>::Currency as MultiCurrency<<T as system::Trait>::AccountId>>::CurrencyId;
type DebitCurrencyIdOf<T> = <<T as Trait>::DebitCurrency as MultiCurrency<<T as system::Trait>::AccountId>>::CurrencyId;
type BalanceOf<T> = <<T as Trait>::Currency as MultiCurrency<<T as system::Trait>::AccountId>>::Balance;
type DebitBalanceOf<T> = <<T as Trait>::DebitCurrency as MultiCurrency<<T as system::Trait>::AccountId>>::Balance;
type AmountOf<T> = <<T as Trait>::Currency as MultiCurrencyExtended<<T as system::Trait>::AccountId>>::Amount;
type DebitAmountOf<T> = <<T as Trait>::DebitCurrency as MultiCurrencyExtended<<T as system::Trait>::AccountId>>::Amount;

vaults的trait的中有两个handler都有各自的CurrencyId,vaults在调用DebitCurrency的函数时,要做两个CurrencyId的类型转化,避免传参类型错误 。vaults实现中是新增了一个CurrencyId 关联类型 , trait bond 中加上了 Into From 方便操作。

cdp_engine 要继承 vaults,auction_manager,三个模块里定义CurrencyIdOf 的来源handler都不一样

pub type CurrencyIdOf<T> = <<T as Trait>::Currency as MultiCurrency<<T as system::Trait>::AccountId>>::CurrencyId;
pub type AuctionIdOf<T> =
<<T as Trait>::Auction as Auction<<T as system::Trait>::AccountId, <T as system::Trait>::BlockNumber>>::AuctionId;
pub trait Trait: system::Trait {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
type Currency: MultiCurrencyExtended<Self::AccountId>;

pub type CurrencyIdOf<T> = <<T as Trait>::Currency as MultiCurrency<<T as system::Trait>::AccountId>>::CurrencyId;
pub type DebitBalanceOf<T> =
<<T as vaults::Trait>::DebitCurrency as MultiCurrency<<T as system::Trait>::AccountId>>::Balance;
pub type AmountOf<T> = <<T as vaults::Trait>::Currency as MultiCurrencyExtended<<T as system::Trait>::AccountId>>::Amount;
pub type DebitAmountOf<T> =
<<T as vaults::Trait>::DebitCurrency as MultiCurrencyExtended<<T as system::Trait>::AccountId>>::Amount;
pub trait Trait: system::Trait + auction_manager::Trait + vaults::Trait {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
type Currency: MultiCurrencyExtended<Self::AccountId>;

如果按照vaults的实现来做,那也是挺麻烦的。 可以在通用trait MultiCurrency 的 CurrencyId 的trait bonds 中,加上From 吗, 同一个参数在不同handler之间传递时都先转成u8, 再into():

https://github.com/laminar-protocol/open-runtime-module-library/blob/feb24f52cb5522329b0cbb6203591c398650a6a8/traits/src/lib.rs#L18-L20

或者有什么更好的办法?

Basic governance setup

Add and configure following modules:

  • pallet-democracy
  • pallet-collective
    • Instance1: Board
    • Instance2: FinancialCouncil
    • Instance3: OperatorCollective
  • pallet-membership
    • Instance1: BoardMembership
      • Managed by Board, EnsureProportionAtLeast 3/4
    • Instance2: FinancialCouncilMembership
      • Managed by Board, EnsureProportionAtLeast 1/2
    • Instance3: OperatorMembership
      • Managed by Board, EnsureProportionAtLeast 1/3

Meta: 账户系统

  • 为了减少复杂度,不针对 aUSD 做特别处理
  • 交易费单位为 aUSD,保证交易费用的稳定性
  • 转账交易费收取货币为交易货币,系统自动从DEX中购买 aUSD 支付手续费 #59
  • 手续费 5:3:2 (?) 比率分给国库,IPO参与者,收集人
  • 免费转账每24小时每个账号3次 #58
  • 所有币种账户都有尘埃额度,低于该额度的金额进入国库 open-web3-stack/open-runtime-module-library#70
  • 每个账号都有开户费用,当为开户的账号收取金额时,自动扣除开户费用进行开户
    • 开户费用为 ACA
    • 自动使用DEX购买相应ACA来开户
  • 所有账号都必须开户后才可以发送交易
  • 提供销户功能
    • 转出所有剩余ACA加上返回额度到指定账号
    • 清除Nonce
    • 清除短地址
    • 用户需要自己保证没有其他资产,不然都会被冻结无法使用,需要重新开户才可以转账

Panic with "Transaction has a bad signature"

sentry_1       | ====================
sentry_1       |
sentry_1       | Version: 0.3.1-83c13dc-x86_64-linux-gnu
sentry_1       |
sentry_1       |    0: sp_panic_handler::set::{{closure}}
sentry_1       |    1: std::panicking::rust_panic_with_hook
sentry_1       |              at src/libstd/panicking.rs:475
sentry_1       |    2: std::panicking::begin_panic
sentry_1       |    3: frame_executive::Executive<System,Block,Context,UnsignedValidator,AllModules>::execute_block
sentry_1       |    4: <acala_runtime::Runtime as sp_api::runtime_decl_for_Core::Core<sp_runtime::generic::block::Block<sp_runtime::generic::header::Header<u32,sp_runtime::traits::BlakeTwo256>,sp_runtime::generic::unchecked_extrinsic::UncheckedExtrinsic<<pallet_indices::Module<acala_runtime::Runtime> as sp_runtime::traits::StaticLookup>::Source,acala_runtime::Call,sp_runtime::MultiSignature,(frame_system::CheckVersion<acala_runtime::Runtime>, frame_system::CheckGenesis<acala_runtime::Runtime>, frame_system::CheckEra<acala_runtime::Runtime>, frame_system::CheckNonce<acala_runtime::Runtime>, frame_system::CheckWeight<acala_runtime::Runtime>, orml_oracle::CheckOperator<acala_runtime::Runtime>, module_accounts::ChargeTransactionPayment<acala_runtime::Runtime>)>>>>::execute_block
sentry_1       |    5: sp_api::runtime_decl_for_Core::execute_block_native_call_generator::{{closure}}
sentry_1       |    6: std::panicking::try::do_call
sentry_1       |    7: __rust_maybe_catch_panic
sentry_1       |              at src/libpanic_unwind/lib.rs:78
sentry_1       |    8: std::thread::local::LocalKey<T>::with
sentry_1       |    9: std::thread::local::LocalKey<T>::with
sentry_1       |   10: sp_state_machine::StateMachine<B,H,N,Exec>::execute_aux
sentry_1       |   11: sp_state_machine::StateMachine<B,H,N,Exec>::execute_using_consensus_failure_handler
sentry_1       |   12: <sc_client::call_executor::LocalCallExecutor<B,E> as sc_client_api::call_executor::CallExecutor<Block>>::contextual_call
sentry_1       |   13: <sc_client::client::Client<B,E,Block,RA> as sp_api::CallApiAt<Block>>::call_api_at
sentry_1       |   14: sp_api::runtime_decl_for_Core::execute_block_call_api_at
sentry_1       |   15: sp_api::Core::execute_block
sentry_1       |   16: <&sc_client::client::Client<B,E,Block,RA> as sp_consensus::block_import::BlockImport<Block>>::import_block
sentry_1       |   17: <sc_finality_grandpa::import::GrandpaBlockImport<BE,Block,Client,SC> as sp_consensus::block_import::BlockImport<Block>>::import_block
sentry_1       |   18: <sc_consensus_babe::BabeBlockImport<Block,Client,Inner> as sp_consensus::block_import::BlockImport<Block>>::import_block
sentry_1       |   19: sp_consensus::import_queue::import_single_block
sentry_1       |   20: <futures_util::future::poll_fn::PollFn<F> as core::future::future::Future>::poll
sentry_1       |   21: futures_util::future::future::chain::Chain<Fut1,Fut2,Data>::poll
sentry_1       |   22: <futures_util::future::poll_fn::PollFn<F> as core::future::future::Future>::poll
sentry_1       |   23: futures_executor::thread_pool::PoolState::work
sentry_1       |   24: std::sys_common::backtrace::__rust_begin_short_backtrace
sentry_1       |   25: std::panicking::try::do_call
sentry_1       |   26: __rust_maybe_catch_panic
sentry_1       |              at src/libpanic_unwind/lib.rs:78
sentry_1       |   27: core::ops::function::FnOnce::call_once{{vtable.shim}}
sentry_1       |   28: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once
sentry_1       |              at rustc/f3e1a954d2ead4e2fc197c7da7d71e6c61bad196/src/liballoc/boxed.rs:1022
sentry_1       |   29: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once
sentry_1       |              at rustc/f3e1a954d2ead4e2fc197c7da7d71e6c61bad196/src/liballoc/boxed.rs:1022
sentry_1       |       std::sys_common::thread::start_thread
sentry_1       |              at src/libstd/sys_common/thread.rs:13
sentry_1       |       std::sys::unix::thread::Thread::new::thread_start
sentry_1       |              at src/libstd/sys/unix/thread.rs:80
sentry_1       |   30: start_thread
sentry_1       |   31: clone
sentry_1       |
sentry_1       |
sentry_1       | Thread 'import-queue-worker-0' panicked at 'Transaction has a bad signature', /root/.cargo/git/checkouts/substrate-7e08433d4c370a21/29cee59/frame/executive/src/lib.rs:272
sentry_1       |
sentry_1       | This is a bug. Please report it at:
sentry_1       |
sentry_1       | 	https://github.com/AcalaNetwork/Acala/issues
sentry_1       |
sentry_1       | 2020-03-01 09:49:49.712 import-queue-worker-0 WARN sc_client::client  Block prepare storage changes error:
sentry_1       | Execution(RuntimePanicked("Transaction has a bad signature"))

I believe this is the reason of stopped finality

Acala roadmaps

  • Testnet

    • Lock ACA to enable free transfer
      • Implementation
      • Integration tests
      • Docs
    • Operate oracle to earn rewards
    • Validator Staking
      • Implementation #65
    • Faucet
      • Implementation
      • Docs
    • DEX
      • Implementation
      • Integration tests
      • Docs
    • Honzon
      • Implementation
      • Integration tests
      • Docs
  • Kusama Parachain

    • IPO reward
      • Implementation
      • Integration tests
      • Docs
    • Collector reward
      • Implementation
      • Integration tests
      • Docs
    • Governance
      • Implementation
      • Docs
    • Collector Staking
      • Implementation
      • Integration tests
      • Docs
    • Oracle Operator Staking
      • Implementation
      • Integration tests
      • Docs
    • Offline detection for oracle
      • Implementation
      • Integration tests
      • Docs
    • aUSD saving rates
      • Specification
      • Implementation
      • Integration tests
      • Docs
    • ACA DEX liquidity incentive
      • Specification
      • Implementation
      • Integration tests
      • Docs
    • Open CDP incentive (should be inversely proportional to total issued aUSD)
      • Specification
      • Implementation
      • Docs

CDP Treasury V1

  • primitive
    • Trait
      • CDPTreasury
        • type Balance
        • fn on_debit(amount: Balance)
        • fn on_surplus(amount: Balance)
  • auction_manager
    • Trait
      • Treasury: CDPTreasury
    • storage
      • BadDebtPool
        • 删除,由 Treasury::on_debit 来代替
      • SurplusPool
        • 删除,由 Treasury::on_surplus 来代替
  • cdp_treasury
    • Trait
      • Currency: MultiCurrency
    • Storage
      • DebitPool: Balance
      • SurplusPool: Balance
    • Module: CDPTreasury
      • on_finalize
        • 抵消负债和盈余(之前在AuctionManager中实现)

初版,没有新功能,就是AuctionManager的重构
下个版本应该会添加两个配置 MAX_DEBIT MAX_SURPLUS,当负债 / 盈余太多的时候,铸造ACA并拍卖取得aUSD抵债 / 拍卖aUSD购买ACA并销毁,具体细节还需要考虑

Update CurrencyId

Change existing ACA to MAC, and add ACA and KAR

ACA and KAR will be used to record airdropped tokens in the followup candy events

Use Saturating / UniqueSaturatedFrom / UniqueSaturatedInto to simplify code

Review the code and do following changes:

  • Change x.unwrap_or(0.into)
    • To x.unwrap_or_default()
  • Change let x = TryInto::<u128>::try_into(x).unwrap_or(Bounded::max_value());
    • To let x: u128 = x.unique_saturated_into();
  • Change x.checked_mul(&y).unwrap_or(Bounded::max_value())
    • To x. saturating_mul(y)
  • Same for checked_div / checked_add / checked_sub / checked_mul_int

Relates: #41

Chain stop finalizing blocks

Have a problem in acala testnet now that chain stoped to finalize block, The node log is:

2020-02-28 10:34:56 Handler initialization process is too long with PeerId("QmSveKjM2cY2VNoZ6Lq7w71XmDzPSUFpZsoXrgtP3myn49")
2020-02-28 10:34:59 Idle (12 peers), best: #21962 (0xeec4…cf2c), finalized #15553 (0x8275…58ff), ⬇ 4.4kiB/s ⬆ 5.6kiB/s

====================

Version: 0.3.0-f887701-x86_64-linux-gnu

   0: sp_panic_handler::set::{{closure}}
   1: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:475
   2: std::panicking::begin_panic
   3: frame_executive::Executive<System,Block,Context,UnsignedValidator,AllModules>::execute_block
   4: <acala_runtime::Runtime as sp_api::runtime_decl_for_Core::Core<sp_runtime::generic::block::Block<sp_runtime::generic::header::Header<u32,sp_runtime::traits::BlakeTwo256>,sp_runtime::generic::unchecked_extrinsic::UncheckedExtrinsic<<pallet_indices::Module<acala_runtime::Runtime> as sp_runtime::traits::StaticLookup>::Source,acala_runtime::Call,sp_runtime::MultiSignature,(frame_system::CheckVersion<acala_runtime::Runtime>, frame_system::CheckGenesis<acala_runtime::Runtime>, frame_system::CheckEra<acala_runtime::Runtime>, frame_system::CheckNonce<acala_runtime::Runtime>, frame_system::CheckWeight<acala_runtime::Runtime>, orml_oracle::CheckOperator<acala_runtime::Runtime>, module_accounts::ChargeTransactionPayment<acala_runtime::Runtime>, module_cdp_engine::AutomaticLiquidationValidation<acala_runtime::Runtime>)>>>>::execute_block
   5: sp_api::runtime_decl_for_Core::execute_block_native_call_generator::{{closure}}
   6: std::panicking::try::do_call
   7: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:78
   8: std::thread::local::LocalKey<T>::with
   9: std::thread::local::LocalKey<T>::with
  10: sp_state_machine::StateMachine<B,H,N,Exec>::execute_aux
  11: sp_state_machine::StateMachine<B,H,N,Exec>::execute_using_consensus_failure_handler
  12: <sc_client::call_executor::LocalCallExecutor<B,E> as sc_client_api::call_executor::CallExecutor<Block>>::contextual_call
  13: <sc_client::client::Client<B,E,Block,RA> as sp_api::CallApiAt<Block>>::call_api_at
  14: sp_api::Core::execute_block
  15: <&sc_client::client::Client<B,E,Block,RA> as sp_consensus::block_import::BlockImport<Block>>::import_block
  16: <sc_finality_grandpa::import::GrandpaBlockImport<B,E,Block,RA,SC> as sp_consensus::block_import::BlockImport<Block>>::import_block
  17: <sc_consensus_babe::BabeBlockImport<Block,Client,Inner> as sp_consensus::block_import::BlockImport<Block>>::import_block
  18: sp_consensus::import_queue::import_single_block
  19: <futures_util::future::poll_fn::PollFn<F> as core::future::future::Future>::poll
  20: futures_util::future::future::chain::Chain<Fut1,Fut2,Data>::poll
  21: <futures_util::future::poll_fn::PollFn<F> as core::future::future::Future>::poll
  22: futures_executor::thread_pool::PoolState::work
  23: std::sys_common::backtrace::__rust_begin_short_backtrace
  24: std::panicking::try::do_call
  25: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:78
  26: core::ops::function::FnOnce::call_once{{vtable.shim}}
  27: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/liballoc/boxed.rs:1022
  28: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/liballoc/boxed.rs:1022
      std::sys_common::thread::start_thread
             at src/libstd/sys_common/thread.rs:13
      std::sys::unix::thread::Thread::new::thread_start
             at src/libstd/sys/unix/thread.rs:80
  29: start_thread
  30: __clone


Thread 'import-queue-worker-0' panicked at 'Transaction has a bad signature', /root/.cargo/git/checkouts/substrate-7e08433d4c370a21/41bb219/frame/executive/src/lib.rs:272

This is a bug. Please report it at:

	https://github.com/AcalaNetwork/Acala/issues

2020-02-28 10:34:59 Block prepare storage changes error:
Execution(RuntimePanicked("Transaction has a bad signature"))
2020-02-28 10:35:04 Idle (12 peers), best: #21962 (0xeec4…cf2c), finalized #15553 (0x8275…58ff), ⬇ 4.9kiB/s ⬆ 4.9kiB/s
2020-02-28 10:35:08 offchain worker start at block: 21962 execute automatic liquidation for collateral: CurrencyId::DOT

We think this problem may be caused by an unsigned transaction submitted by offchain worker.

As we have not yet designed a reward mechanism of running offchain worker, there's no Authority,and no signature verification by Authority for unsigned tx :

fn submit_unsigned_liquidation_tx(currency_id: CurrencyIdOf<T>, who: T::AccountId) -> Result<(), OffchainErr> {
let call = Call::<T>::liquidate(currency_id, who);
T::SubmitTransaction::submit_unsigned(call).map_err(|_| OffchainErr::SubmitTransaction)?;
Ok(())
}

And the validation for submitted tx we use SingedExtension instead of deprecated unsigned::ValidateUnsigned :

impl<T: Trait + Send + Sync> SignedExtension for AutomaticLiquidationValidation<T> {
const IDENTIFIER: &'static str = "AutomaticLiquidationValidation";
type AccountId = T::AccountId;
type Call = <T as Trait>::Call;
type AdditionalSigned = ();
type DispatchInfo = DispatchInfo;
type Pre = ();
fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> {
Ok(())
}
fn validate(
&self,
_who: &Self::AccountId,
call: &Self::Call,
_info: Self::DispatchInfo,
_len: usize,
) -> TransactionValidity {
let call = match call.is_sub_type() {
Some(call) => call,
None => return Ok(ValidTransaction::default()),
};
match call {
Call::<T>::liquidate(currency_id, account_id) => {
// check cdp is unsafe
if !<Module<T>>::is_unsafe_cdp(*currency_id, account_id) {
InvalidTransaction::Stale.into()
} else {
let mut valid_tx = ValidTransaction::default();
valid_tx.priority = TransactionPriority::max_value();
Ok(valid_tx)
}
}
_ => Ok(ValidTransaction::default()),
}
}
}

There's no InvalidTransaction::BadProof will be throughed by above code.

Is the lack of sign verification by Authority or the incorrect validation for unsigned tx cause this problem? or something else

Code cleanup

  • cdp_engine
    • Add DefaultLiquidationPenalty
    • Implement custom getter that returning non-option type
      • e.g. fn liquidation_ratio(currency: CurrencyId) -> Ratio
  • cdp_treasury
    • add fn set_collateral_auction_maximum_size
    • and remove collateral auction maximum size from set_debit_and_surplus_handle_params

Validation for unsinged Tx doesn't work.

I did some tests, I dont know why the SignedExtension doesn't work to validate unsigned tx,
In fact, the offchain worker successfully submit the unsigned tx, no errors are thrown during the submission process. But tx pool report errors:

WARN txpool  (offchain call) Error submitting a transaction to the pool: Pool(UnknownTransaction(UnknownTransaction::NoUnsignedValidator))

Then I switch deprecated ValidateUnsigned just like im-online module in polkadot, It works.

There is no example that use SignedExtension to validate unsigned tx submitted by offchain worker in srml at the moment , I will switch to ValidateUnsigned first.

FinancialCouncil

Depends on #60

Update all the CDP related modules to add type UpdateOrigin: EnsureOrigin and update all the set_xxx method to use this to enforce origin:

T:: UpdateOrigin::try_origin(origin).map(|_| ()).or_else(ensure_root)?;

And in runtime set UpdateOrigin to FinancialCouncil with EnsureProportionAtLeast 1/2

AuctionManager: change withdraw / deposit

let _ = T::Currency::withdraw(T::GetNativeCurrencyId::get(), &(new_bid.0), payment);

let _ = T::Currency::deposit(T::GetNativeCurrencyId::get(), &(previous_bidder), refund);

let _ = T::Currency::deposit(auction_item.currency_id, &(auction_item.owner), deduct_amount);

The return values cannot be ignored because they may fail (shouldn't fail for deposit, but will fail on withdraw on malicious transaction).

Also better to use transfer over withdraw / deposit to avoid modify token total issuance.
The money should be transfer into / from the module's account, something like

https://github.com/paritytech/substrate/blob/73f4c118c07ff4a45c3acbbf62e8be96af96c28a/paint/treasury/src/lib.rs#L262-L264

Should have tests to ensure making bids without enough money won't be accepted.

Accounts module update

  • Trait
    • type FreeTransferDeposit: Get<Balance>
    • type DepositCurrency: LockableCurrency
  • Storages
    • FreeTransferEnabledAccounts: map AccountId => Option<()>
  • Calls
    • fn enable_free_transfer(origin)
      • set lock with FreeTransferDeposit amount, max expire date, all reasons
      • FreeTransferEnabledAccounts::put(origin, ())
    • fn disable_free_transfers(origin)
      • remove lock
      • FreeTransferEnabledAccounts::kill(origin)
  • Module
    • update try_free_transfer
      • Check FreeTransferEnabledAccounts::exists(who) and return false if did not exist

Also

if <Module<T>>::try_free_transfer(who) {
true
} else {
false
}

is same as <Module<T>>::try_free_transfer(who)

Claim module

Hold funds for IPO and allow IPO participants to submit their proof of participation to claim their ACA.

Proof verification needs to wait for child storage proof generation.

Details TBD.

Impl RPC api for dex module

The calculation related to exchange in dex is complicated, impl rpc api for dex module so that front-end developers don't need to know the specific calculation rules

The result of `dex::get_supply_amount` is not correct

Because the div will discard the remainder, the result of the dex::get_supply_amount is not correct. use the incorrect result as supply amount to exchange with dex, the actual maxmum avalible target amount are most likely less than the specified target amount, lead to trading failed.

For each div in the calculation process, if there is a remainder, the quotient needs to be increased by 1 to ensure that the final result is sufficient for trading.

Homa Protocol Design

homa

  • module-homa

    • Type
      • enum RedeemStrategy
        • Immedately
        • Target(EraIndex)
        • WaitForUnbonding
    • Trait: module_staking_pool::Trait
    • Storage
    • Constant
    • Call
      • mint(origin, amount: StakingBalance)
        • Lock DOT and mint LDOT
      • redeem(origin, amount: LiquidBalance, strategy: RedeemStrategy)
    • Module

module-homa-council

  • Type

    • struct UnlockChunk
      • value: Balance
      • era: EraIndex
    • struct BondingLedger
      • total: Balance
        • total amount of locked LDOT
      • active: Balance
        • total amount of bonded LDOT considered for nomination
      • unlocking: Vec<UnlockChunk>
        • unlocking chunks, ordered by unlocking block
        • i.e. new unlocking chunk always added to end, unlocked chunk removed from front
  • Trait

    • type Currency: BasicLockableCurrency
    • type PolkadotAccountId
    • type Bridge: PolkadotBridgeState
  • Storage

    • Nominations: map AccountId => Vec<PolkadotAccountId>
    • Ledger: map AccountId => BondingLedger
    • Votes: map PolkadotAccountId => Balance
    • Nominees: Vec<PolkadotAccountId>
  • Constant

    • NominateesCount: Get<u32>
    • MinBondThreshold: Get<Balance>
  • Call

    • bond(origin, amount: Balance)
      • lock LDOT
      • total bonded amount must be more than MinBondThreshold
    • unbond(origin, amount: Balance)
      • move LDOT to unlocking
      • total bonded amount after unbond must be more than MinBondThreshold or zero
      • if all fund are unbonded, remove nomination
    • rebond(origin, amount: Balance)
    • withdraw_unbond(origin)
      • withdraw unlocked LDOT
    • nominate(origin, targets: Vec<PolkadotAccountId>)
      • ensure_signed
      • ensure have bonded LDOT
    • chill(origin)
      • remove nominations
  • Module

    • rebalance()
    • impl NomineesProvider
      • Read all Votes and find top NominateesCount
    • impl OnNewEra
      • rebalance()
  • module-staking-pool

    • Type
      • trait NomineesProvider
        • nominees(): Vec<AccountId>
      • struct UnlockChunk
        • value: StakingBalance
        • era: EraIndex
        • claimed: StakingBalance
      • struct StakingLedger
        • total_bonded: StakingBalance
        • active: StakingBalance
        • unlocking: Vec<UnlockChunk>
        • free: StakingBalance
      • trait OnCommission
        • on_commission(amount: Balance)
    • Trait
      • type StakingCurrency: BasicCurrency
      • type LiquidCurrencyId: BasicCurrency
      • type Bridge: PolkadotBridge
      • type Nominees: NomineesProvider
      • type OnCommission: OnCommission
    • Storage
      • ClaimedUnlockChunk: double_map EraIndex, AccountId => Amount
      • Ledger: StakingLedger
    • Constant
      • MaxBondRatio: Ratio
      • MinBondRatio: Ratio
      • MaxClaimFee: Rate
      • Commission: Rate
    • Call
      • claim_payout(origin, amount: StakingBalance, proof: Vec<u8>)
        • claim a payout by submiting payout amount and a proof
        • during testnet phase, ensure_root, our bot will submit this every era
        • with real Polkadot bridge, verify proof matches to amount
        • comission is taken from amount
    • Module
      • rebalance()
        • bonded_percent = Ledger.total_bonded / (Ledger.total_bonded + Ledger.free)
        • if bonded_percent < MinBondPercent
          • bond more
        • if bonded_percent > MaxBondPercent
          • unbond some
      • bond(amount: StakingBalance)
      • unbond(amount: StakingBalance)
      • claim(amount: LiquidBalance, era: EraIndex)
      • claim_amount_percent(amount: StakingBalance, era: EraIndex) -> Ratio
        • free = Bridge::balance() - Bridge::ledger().total
        • available = Bridge::ledger().unlocking.map(|x| x.era <= era).sum()
        • amount / (free + available)
      • claim_period_percent(era: EraIndex) -> Ratio
        • (era - Bridge::current_era()) / BondingDuration
      • claim_fee(amount: StakingBalance, era: EraIndex)
        • TODO
      • impl OnNewEra
        • on_new_era
          • rebalance()
          • Bridge::nominate()
  • module-polkadot-bridge

    • Type
      • trait PolkadotBridgeType
        • type BondingDuration: Get<EraIndex>
        • type EraLength: Get<BlockNumber>
        • type PolkadotAccountId
      • trait PolkadotBridgeCall: PolkadotBridgeType
        • bond_extra(amount: Balance)
        • unbond(amount: Balance)
        • rebond(amount: Balance)
        • withdraw_unbonded()
        • nominate(targets: Vec<PolkadotAccountId>)
        • transfer(to: PolkadotAccountId, amount: Balance)
        • payout_nominator()
      • trait PolkadotBridgeState
        • ledger(): StakingLedger
        • balance(): Balance
        • current_era(): EraIndex
      • trait PolkadotBridge: PolkadotBridgeCall + PolkadotBridgeState
      • trait OnNewEra
        • on_new_era(era: EraIndex)
    • Trait
      • type DotCurrency: BasicCurrency
      • type OnNewEra: OnNewEra
      • type MockRewardPercent: Get<Permill>
      • type BondingDuration: Get<EraIndex>
      • type EraLength: Get<BlockNumber>
    • Constants
      • MockRewardPercent: Permill
      • BondingDuration: EraIndex
      • EraLength: BlockNumber
    • Storage
      • Bonded: Balance
      • Available: Balance
      • Unbonding: Vec<(Balance, BlockNumber)>
      • CurrentEra: EraIndex
      • ForcedEra: Option<BlockNumber>
    • Call
      • simulate_slash(origin, amount: Balance)
        • ensure_root
        • Bonded -= amount
        • for testing only
      • simualte_receive(origin, to: AccountId, balance: Amount)
        • ensure_root
        • DotCurrency::deposit(to, balance)
      • simulate_redeem(origin, to: PolkadotAccountId, balance: Amount)
        • ensure_signed
        • DotCurrency::withdraw(origin, balance)
      • force_era(origin, at: BlockNumber)
        • ensure_root
        • ForcedEra = at
    • Module
      • impl PolkadotBridge
      • on_finalize
        • if now % EraLength == 0 || if now === ForcedEra
          • CurrentEra++
          • OnNewEra::on_new_era(CurrenrEra)

Make all financial parameters configurable in chain spec.

This is required to ensure a newly launched network is in a working state from block one.

Like those, and maybe few more

pub SurplusAuctionFixedSize get(fn surplus_auction_fixed_size): BalanceOf<T>;
pub SurplusBufferSize get(fn surplus_buffer_size): BalanceOf<T>;
pub InitialAmountPerDebitAuction get(fn initial_amount_per_debit_auction): BalanceOf<T>;
pub DebitAuctionFixedSize get(fn debit_auction_fixed_size): BalanceOf<T>;
pub CollateralAuctionMaximumSize get(fn collateral_auction_maximum_size): map hasher(blake2_256) CurrencyIdOf<T> => BalanceOf<T>;

Emergency shutdown

这里只考虑关停流程,如何启动关停流程属于治理设计的一部分,另行考虑

关停单一资产:

当某单个资产因为某些风险太高,可以启动关停单一资产流程

流程:

  • 停止接受资产
    • 通过调整资产债务硬顶,不再接受更多该资产的抵押
    • 用户可以在这个阶段赎回资产
  • 提升liquidation ratio
    • 每个block都提升liquidation ratio
    • 如果用户不主动关闭仓位的话,渐渐的所有仓位都会根据抵押率先后被平仓
  • 强制清仓
    • 一定时间后,自动拍卖掉所有剩下的仓位

全局关停:

因为某种恶性原因,比如严重资金安全漏洞,恶意治理提案被通过等,可以启用全局关停流程避免情况恶化

流程:

  • 快照最新Oracle价格
  • 停止接受资产
    • 不再接受更多该资产的抵押
    • 仓位持有者可以将超额抵押的资产取回,不可直接赎回剩余部分
  • 清算系统盈余 / 亏损
  • aUSD持有者根据持有比率,按比例兑换全局抵押资产
  • (以后)过渡为平行线程,只保留赎回资产功能

Validator node panicked

Running the docker container for validators, I had the following panic in my logs:

====================

Version: 0.2.8-36e791e-x86_64-linux-gnu

   0: sp_panic_handler::set::{{closure}}
   1: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:475
   2: rust_begin_unwind
             at src/libstd/panicking.rs:375
   3: core::panicking::panic_fmt
             at src/libcore/panicking.rs:84
   4: core::option::expect_failed
             at src/libcore/option.rs:1188
   5: core::option::Option<T>::expect
             at rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/option.rs:348
      std::time::Instant::duration_since
             at src/libstd/time.rs:261
      <std::time::Instant as core::ops::arith::Sub>::sub
             at src/libstd/time.rs:388
   6: <sc_network::protocol::legacy_proto::behaviour::LegacyProto<TSubstream> as libp2p_swarm::behaviour::NetworkBehaviour>::poll
   7: <sc_network::protocol::Protocol<B,S,H> as libp2p_swarm::behaviour::NetworkBehaviour>::poll
   8: <sc_network::behaviour::Behaviour<B,S,H> as libp2p_swarm::behaviour::NetworkBehaviour>::poll
   9: libp2p_swarm::ExpandedSwarm<TTransport,TBehaviour,TInEvent,TOutEvent,THandler,THandlerErr,TConnInfo>::poll_next_event
  10: futures_util::future::future::FutureExt::poll_unpin
  11: <sc_network::service::NetworkWorker<B,S,H> as core::future::future::Future>::poll
  12: futures_util::future::future::FutureExt::poll_unpin
  13: <futures_util::future::select::Select<A,B> as core::future::future::Future>::poll
  14: <futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll
  15: tokio::task::core::Core<T>::poll
  16: std::panicking::try::do_call
  17: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:78
  18: tokio::task::harness::Harness<T,S>::poll
  19: tokio::runtime::thread_pool::worker::GenerationGuard::run_task
  20: tokio::runtime::thread_pool::worker::GenerationGuard::run
  21: std::thread::local::LocalKey<T>::with
  22: tokio::runtime::thread_pool::worker::Worker::run
  23: tokio::task::core::Core<T>::poll
  24: std::panicking::try::do_call
  25: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:78
  26: tokio::task::harness::Harness<T,S>::poll
  27: tokio::runtime::blocking::pool::Inner::run
  28: tokio::runtime::context::enter
  29: std::sys_common::backtrace::__rust_begin_short_backtrace
  30: std::panicking::try::do_call
  31: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:78
  32: core::ops::function::FnOnce::call_once{{vtable.shim}}
  33: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once
             at rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/liballoc/boxed.rs:1022
  34: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once
             at rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/liballoc/boxed.rs:1022
      std::sys_common::thread::start_thread
             at src/libstd/sys_common/thread.rs:13
      std::sys::unix::thread::Thread::new::thread_start
             at src/libstd/sys/unix/thread.rs:80
  35: start_thread
  36: clone


Thread 'main-tokio-' panicked at 'supplied instant is later than self', src/libcore/option.rs:1188

Dex Module Design Draft

dex module

参考uniswap的交易模式, 以aUSD为base token进行资产的去中心化交易

Trait

  • Currency: MultiCurrency
  • Share
  • GetBaseCurrencyId: Get
  • GetExchangeFee: Get

Storage

  • LiquidityPool: double_map CurrencyId, CurrencyId => (Balance, Balance) 流动性池子
  • TotalShares: map CurrencyId => Share
  • Shares: double_map AccountId, CurrencyId => Share

Call

  • swap_tokens(origin, supply: (CurrencyId, Balance), target: (CurrencyId, Balance))
    • 用supply资产交换 target 资产, target.1 为能接受的换回的最低数量。
  • inject_liquidity(origin, currency_id: CurrencyId, amount: Balance, base_currency_amount: Balance)
    • 向流动性池子注入资金,获得股权,amount 与 base_currency_amount分别是能够支付的other token 和 base token的上限
  • extract_liquidity(origin, currency_id: CurrencyId, extract_amount: T::Share)
    • 用股权赎回流动池资金

Module: DexManager

实现 DexManager 以供拍卖模块调用

债务管理

债务管理

债务分为三种:

  • 全局债务
  • CDP债务
  • 系统债务 / 盈余

其中全局债务和系统债务都由 CDP Treasury 来管理,用户债务由 Vaults 管理

  • 全局债务
    • 由 CDP Treasury 模块管理
    • 增发 aUSD 增加全局债务
    • 销毁 aUSD 减少全局债务
    • 所有 aUSD 的增发烧毁都必须由国库来完成
  • 用户债务
    • 由 Vaults 模块管理
    • Valuts 管理用户债务和抵押品资产
    • 用户抵押资产铸造aUSD的流程
      • Vaults 把用户资产转移给模块账号,记录添加抵押品
      • Vaults 向 Treasury 申请资产
        • 添加全局债务
        • 铸造 aUSD
      • Vaults 添加CDP债务
    • 清偿债务赎回抵押资产流程
      • Vaults 通过 Treasury 销毁用户 aUSD
        • 减少全局债务
        • 销毁 aUSD
      • Vaults 转回抵押品给用户
  • 系统债务 / 盈余
    • 每区块收取稳定费率利息
      • 通过增加债务单位汇率来增加所有CDP债务
      • 增加的部分计入系统盈余
    • 拍卖危险资产流程
      • 没收用户CDP资产
      • 转移CDP债务进入系统债务
      • 拍卖用户资产
      • 还回多余资产
      • 拍卖所得金额作为系统盈余
    • 每周期系统盈余和债务互相对抵

全局债务金额应等于:所有CDP债务金额 + 系统债务 - 系统盈余

回购ACA流程:

  • 当系统盈余大于一定值的时候,发起回购ACA流程
  • 系统盈余(一部分?)转换成 aUSD,同时添加全局债务
  • 卖出aUSD,购买ACA
    • 具体方法待定,可以是拍卖,或者通过DEX
  • 销毁回购的ACA

增发ACA流程:

  • 当系统债务大于一定值的时候,发起增发ACA流程
  • 增发卖出ACA,购买相当于系统债务的 aUSD
    • 具体方法待定,可以是拍卖,或者通过DEX
  • 销毁 aUSD,减少相对应的全局债务
  • 减少相对应的系统债务

Add accounts module to runtime

FreeTransferCount: 3
FreeTransferPerioid: 24 hours
FreeTransferDeposit: 1 DOLLAR

Make sure replace ChargeTransactionPayment as well

Acala Runtime Design

Acala Runtime Design

注:

  • 很多类型的泛型参数我跳过了,实现的时候按需求添加
  • 完全没有考虑事件,这个可以最后根据前端和看护机的需求添加
  • 我们会使用 offchain_worker 来实现看护机,这部分设计会陆续添加
  • 第二版会加入 uniswap 类型的 DEX,作为价钱来源之一,参与竞拍,无缝转换各种手续费
  • 各种需要 root 权限来修改链上变量参数的方法我就不细写了,每个变量提供一个 set_xxx 就好

模块结构:

每个模块都分为这些部分:

  • Types
    • 所有模块定义的 Rust 类型,包括了 trait, struct, enum, type
  • Trait
    • Substrate Runtime Module Trait 部分,所有可以传入的类型参数
  • Storage
    • decl_storage 部分,链上存储
  • Call
    • decl_module 中的 dispatchable call 部分,用户可以调用发起的交易
  • Module
    • impl Module 部分,对其他模块的 Rust 接口,还有 module hooks (on_initialize / on_finalize / offchain_worker)
    • Module: TraitName, TraitNameTwo 的意思是实现了 TraitName 和 TraitNameTwo 这两个接口
  • Event
    • decl_event 部分,定义链上可以发生的事件

Common Modules (ORML)

  • utilities
  • traits
    • 包含了所有通用接口定义
    • Types
      • trait BasicCurrency
        • 简化版单资产管理接口
        • type Balance
        • fn transfer
        • fn deposit
        • fn withdraw
      • trait BasicCurrencyExtended: MultiCurrency
        • 增加了 Amount,支持负数
        • type Amount: TryInto<Balance> + TryFrom<Balance>
        • fn update_balance(who: AccountId, amount: Amount)
      • trait MultiCurrency
        • 多资产管理接口
        • type CurrencyId
        • type Balance
        • fn transfer
        • fn deposit
        • fn withdraw
      • trait MultiCurrencyExtended: MultiCurrency
        • 增加了 Amount,支持负数
        • type Amount: TryInto<Balance>, TryFrom<Balance>
        • fn update_balance(who: AccountId, currency_id: CurrencyId, amount: Amount)
      • trait OnNewData<Key, Value>
        • 通用新数据钩子
        • fn on_new_data(key: Key, value: Value)
      • trait DataProvider<Key, Value>
        • 通用数据读取接口
        • fn get(key: Key) -> Option<Value>
      • trait PriceProvider<CurrencyId, Price>
        • 价钱数据接口
        • fn get_price(base: CurrencyId, quote: CurrencyId): Option<Price>
      • struct AuctionInfo
        • 拍卖信息
        • bid: Option<(AccountId, Balance)>
        • end: Option<BlockNumber>
      • trait Auction
        • 通用拍卖接口
        • type AuctionId
        • type Balance
        • fn auction_info(id: AuctionId): AuctionInfo
        • fn update_auction(id: AuctionId, info: AuctionInfo)
        • fn new_auction(start: BlockNumber, end: Option<BlockNumber>): AuctionId
      • struct OnNewBidResult
        • accept_bid: bool
          • 是否接受出价,比如如果增加金额低于要求
        • auction_end: Option<Option<BlockNumber>>
          • 是否修改拍卖结束时间
      • trait AuctionHandler
        • 拍卖接口钩子
        • fn on_new_bid(now: BlockNumber, id: AuctionId, new_bid: (AccountId, Balance), last_bid: Option<(AccountId, Balance)>): OnNewBidResult
          • 接收到新竞价,通过返回值决定是否接受竞价和修改拍卖截止时间
          • 这里要预先提取当前赢家资金,返回上个赢家资金
        • fn on_auction_ended(id: AuctionId, winner: Option<(AccountId, Balance)>)
          • 拍卖结束
  • tokens
    • 多资产接口实现
    • Trait
      • CurrencyId
    • Call
      • transfer(origin, currency_id: CurrencyId, to: AccountId, value: Balance)
    • Module: MultiCurrencyExtended
  • currencies
    • 用来聚合 srml-balances 和 orml-tokens
    • Trait
      • NativeCurrency: Currency
      • NativeCurrencyId: Get<CurrencyId>
      • MultiCurrency: MultiCurrencyExtended<CurrencyId = Self::MultiCurrencyId>
    • Call
      • transfer(origin, currency_id: CurrencyId, to: AccountId, value: Balance)
    • Module: MultiCurrencyExtended
  • oracle
    • 预言机模块,实现通用数据接口
    • Trait
      • Key
      • Value
      • OperatorOrigin: EnsureOrigin
      • OnNewData: OnNewData<Key, Value>
    • Call
      • feed_data(origin, key: Key, value: Value)
    • Module: DataProvider<Key, Value>
  • prices
    • 价钱模块,价钱数据接口实现
    • Trait
      • CurrencyId
      • Source: DataProvider<CurrencyId, Price>
    • Module: PriceProvider<CurrencyId, Price>
  • auction
    • 通用拍卖接口实现。具体的货品交割由 AuctionHandler 的实现来执行
    • Trait
      • Balance
      • Handler: AuctionHandler
    • Storage
      • Actions: map AuctionId => Option<AuctionInfo>
      • AuctionEndTime: map (BlockNumber, Option<AuctionId>) => Option<LinkedItem<AuctionId>>
        • 每个区块中会截止的拍卖,用链表存储
      • AuctionCounts: AuctionId
    • Call
      • bid(origin, id: AuctionId, value: Balance)
    • Module: Auction
      • on_finalize
        • 遍历 AuctionEndTime ,结束拍卖

Acala Runtime Modules

  • support
    • 辅助模块,包含同样帮助方法和常用类型
    • Types
      • trait RiskManager<CurrencyId, Balance, DebitBalance>
        • 风险评估接口
        • fn requiredCollateralRatio(currency_id: CurrencyId): Ratio
          • 要求抵押率,用户开仓,调整仓位,不能让抵押率低于这个值
        • fn check_position_adjuestment(currency_id: CurrencyId, collaterals: SignedBalance<Balance>, debits: SignedBalance<DebitBalance>): Result
          • 检验这个操作后抵押率是否足够,足够的话 Ok, 不够的话 Err
      • type Price = Fixed128
      • type ExchangeRate = Fixed128
      • type Ratio = Fixed128
  • debits
    • 债务管理模块,负责处理债务单位的增减
    • Trait
      • Currency: BasicCurrencyExtended
        • 稳定币资产
      • DebitBalance
        • 债务资产单位
      • Convert: Convert<(CurrencyId, Balance), DebitBalance> + Convert<(CurrencyId, DebitBalance), Balance>
        • 负责不同资产的债务单位和稳定币直接的转换
    • Module: MultiCurrencyExtended
      • 实现了多资产接口,但所有交易都会根据债务单位和稳定币的汇率转换成稳定币资产,然后交易稳定币资产
  • vaults
    • 负载与资产管理模块
    • Trait
      • Currency: MultiCurrencyExtended
        • 多资产接口
      • DebitCurrency: MultiCurrencyExtended
        • 债务资产接口
      • PriceSource: PriceProvider<CurrencyId, Price>
        • 价钱来源
      • RickManager: RickManager<CurrencyId>
        • 风控接口
    • Storage
      • Debits: double_map AccountId, CurrencyId => DebitBalance
        • 用户对映资产 CDP 的债务金额
      • Collaterals: double_map AccountId, CurrencyId => Balance
        • 用户对映资产的 CDP 的抵押物金额
      • TotalDebits: map CurrencyId => DebitBalance
      • TotalCollaterals: map CurrencyId => Balance
    • Module
      • collateral_ratio(who: AccountId, currency_id: CurrencyId): Option<Fixed128>
        • 用户对映资产的 CDP 的抵押率
      • update_position(who: AccountId, currency_id: CurrencyId, collaterals: SignedBalance<Balance>, debits: SignedBalance<DebitBalance>): Result
        • 修改 CDP。对债务的变动会直接修改用户 aUSD 余额,对抵押物的变动也会直接修改用户抵押物的余额
  • auction_manager
    • 负责管理不同类型的拍卖
    • 需要讨论的几个点
      • 拍卖时长硬顶软顶
      • 大量抵押物同时拍卖的时候是否需要把时间稍微分离,防止对市场过大的冲击
    • 需要添加的功能
      • 盈余拍卖
      • 负债拍卖
    • Types
      • struct AuctionItem
        • 不会变的信息放在这个结构里面,会变的单独放,比如截止时间
        • owenr: AccountId
        • currency_id: CurrencyId
        • amount: Balance
        • target: Balance
        • start_time: BlockNumber
      • trait AuctionManagerHandler
        • on_auction_end(currency_id: CurrencyId, target: Balance, bid: Balance)
          • 反馈拍卖结果,这个主要是用来报告债务的。如果达标了,auction_manager 自己处理相关的所有资产转移
    • Trait
      • Currency: MultiCurrencyExtended
      • Auction: Auction
      • Handler: AuctionManagerHandler
    • Storage
      • MaximumAuctionSize: map CurrencyId => Balance
        • 一次拍卖最大数额,超过这个的会被拆分为多次拍卖
      • Auctions: map AuctionId => Option<AuctionItem>
        • 所有当前拍卖,结束的清空
      • AuctionWinner: map AuctionId => Option<AccountId, Balance>
        • 当前竞拍赢家,拍卖结束后清空
    • Constants
      • MinimumIncrementSize: Permill
        • 每次拍卖最低增加幅度百分比,两次竞拍价格至少要增加 max(target, last_bid) * MinimumIncrementSize
      • AuctionTimeToClose: BlockNumber
        • 每次成功竞拍后,拍卖截止时间调整为当前时间加上这个值
      • AuctionDurationSoftCap: BlockNumber
        • 如果拍卖持续了这么久还未结束,竞价最低增加金额翻倍,截止延长时间减半
        • 这个机制实现前可以详细讨论下,看看需不需要调整
    • Module: AuctionHandler
      • new_collateral_auction(who: AccountId, currency_id: CurrencyId, amount: Balance, target: Balance)
        • 转移用户CDP中抵押品
        • 转移债务
        • 如果数额太大,拆分成多个拍卖
  • cdp_engine
    • CDP 引擎
    • Types
      • struct DebitExchangeRateConvertor: Convert<(CurrencyId, Balance), DebitBalance> + Convert<(CurrencyId, DebitBalance), Balance>
        • 进行不同资产的债务单位和稳定币直接的转换
    • Trait: auction_manager::Trait + vaults::Trait
      • Currency: MultiCurrencyExtended
      • PriceSource: PriceProvider<CurrencyId, Price>
        • 价钱来源
      • CollateralCurrencyIds: Get<static '&[CurrencyId]>
        • 可抵押资产编号
      • StableCurrencyId: Get<CurrencyId>
        • 稳定币编号
      • Auction: Auction
        • 拍卖模块接口
    • Constants
      • GlobalStabilityFee: Permill
        • 全局稳定费率
      • DefaultLiquidationRatio: Ratio
        • 默认触发清算抵押率
    • DefaultLiquidationPenalty: Permill
      • 默认清算惩罚费率
      • DefaultDebitExchangeRate: ExchangeRate
        • 默认起始负债汇率
      • MinimumDebitValue: Balance
        • 债务下限,单位为 aUSD。CDP 通过操作后,要么债务为0,要么 aUSD 价值必须大于这个数值
    • Storage
      • StabilityFee: map CurrencyId => Option<Permill>
        • 对映资产的稳定费率,加上全局稳定费率得到真正费率
      • LiquidationRatio: map CurrencyId => Option<Ratio>
        • 对映资产的触发清算抵押率
      • LiquidationPenalty: map CurrencyId => Option<Permill>
        • 对映资产的清算惩罚费率
      • RequiredCollateralRatio: map CurrencyId => Option<Ratio>
        • 对映资产的要求抵押率,用户无法主动把抵押率降低与这个值
      • DebitExchangeRate: map CurrencyId => Option<ExchangeRate>
        • 对映资产的负债汇率
      • MaximumTotalDebitValue: map CurrencyId => Balance
        • 对映资产的总共债务上限
    • Module: RiskManager, AuctionManagerHandler
      • 实现了风控接口,验证CDP抵押率,债务上限,债务下限
      • 实现了拍卖钩子,结算处理拍卖结果
      • on_finalize
        • 根据当前 StabilityFee 更新每个 DebitExchangeRate
  • honzon
    • Trait: cdp_engine::Trait
    • Storage
      • Authorizations: double_map AccountId, (CurrencyId, AccountId) => bool
        • 仓位权限授权
    • Call
      • update_vault(origin, currency_id: CurrencyId, collateral: Amount, debits: Amount)
        • 修改仓位
        • 添加 / 减少 抵押品会从用户账上 转入 / 转出 抵押品
        • 添加 / 减少 债务会从用户稳定币账户执行对映的 铸币 / 烧币
      • transfer_vault(origin, currency_id: CurrencyId, to: AccountId, collateral: Amount, debits: Amount)
        • 转移仓位,必须有对方授权
      • authorize(origin, currency_id: CurrencyId, to: AccountId)
        • 授权给对方
      • unauthorize(origin, currency_id: CurrencyId, to: AccountId)
        • 取消授权
      • unauthorize_all(origin)
        • 取消全部授权
  • primitives
    • Types
      • enum TokensCurrencyId
        • AUSD = 1
        • DOT
        • XBTC
      • enum CurrencyId
        • ACA = 0
        • AUSD
        • DOT
        • XBTC
  • Runtime
    • Balances
    • Tokens
      • CurrencyId = CurrencyId
    • Currencies
      • NativeCurrency = Balances
      • NativeCurrencyId = Get<CurrencyId::ACA>
      • MultiCurrency = Tokens
    • Oracle
    • Auction
      • Handler = AuctionManager
    • Prices
      • CurrencyId = CurrencyId
      • Source = Oracle
    • Debits
      • Currency = tokens::NativeCurrency
      • DebitBalance = Balance
      • Convert = cdp_engine::DebitExchangeRateConvertor
    • Vaults
      • Currency = Tokens
      • DebitCurrency = Debits
      • PriceSource = Prices
      • RickManager = CDPEngine
    • AuctionManager
      • Auction = Auction
      • Handler = CDPEngine
    • CDPEngine
      • Currency = Currencies
      • PriceSource = Prices
      • CollateralCurrencyIds = [CurrencyId::DOT, CurrencyId::XBTC]
    • StableCurrencyId: Currency::AUSD
      • Auction: Auction
    • Honzon

Meta: Tx Fee & DEX integration

Depends on #58

First stage:

  • Use ACA as tx fee unit.
  • Use ACA to pay tx fee.
  • For transfer, fallback to transferred currency to pay fee using DEX for conversion.

Second stage:

  • New Signed Extension with a byte to indicate which currency to pay for fees and use DEX for conversion.

Final stage:

  • Use AUSD as tx fee unit.
    • Still use ACA for payment.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.