Skip to content

Commit

Permalink
liquid-crowdloan (#2503)
Browse files Browse the repository at this point in the history
* liquid-crowdloan

* impl liquid crowdloan transfer

* fix RelayChainCall encode/decode

* liquid crowdloan module unit tests

* integration tests

* more docstring

* update gov origin for liquid crowdloan module

* benchmarking

* fix benchmarking tests

* docstring for proxytype

* /bench module module_liquid_crowdloan

* /bench runtime acala module_liquid_crowdloan

* /bench runtime mandala module_liquid_crowdloan

* add weight info

* fix

* /bench module module_liquid_crowdloan

* /bench runtime mandala module_liquid_crowdloan

* Update modules/liquid-crowdloan/src/lib.rs

* /bench runtime acala module_liquid_crowdloan

* trigger CI

---------

Co-authored-by: Shaun Wang <[email protected]>
Co-authored-by: Acala Github Action Bot <[email protected]>
Co-authored-by: wangjj9219 <[email protected]>
  • Loading branch information
4 people authored Jun 5, 2023
1 parent 5c10543 commit 98ead77
Show file tree
Hide file tree
Showing 27 changed files with 1,260 additions and 43 deletions.
22 changes: 22 additions & 0 deletions Cargo.lock

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

43 changes: 43 additions & 0 deletions modules/liquid-crowdloan/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[package]
name = "module-liquid-crowdloan"
version = "2.16.0"
authors = ["Acala Developers"]
edition = "2021"

[dependencies]
scale-info = { version = "2.2.0", default-features = false, features = ["derive"] }
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false }

sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false }
sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false }

orml-traits = { path = "../../orml/traits", default-features = false }
primitives = { package = "acala-primitives", path = "../../primitives", default-features = false }
support = { package = "module-support", path = "../support", default-features = false }

[dev-dependencies]
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" }
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" }
module-currencies = { path = "../currencies" }
orml-tokens = { path = "../../orml/tokens" }

[features]
default = ["std"]
std = [
"codec/std",
"scale-info/std",
"sp-runtime/std",
"sp-std/std",
"frame-support/std",
"frame-system/std",
"orml-traits/std",
"primitives/std",
"support/std",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
]
135 changes: 135 additions & 0 deletions modules/liquid-crowdloan/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// This file is part of Acala.

// Copyright (C) 2020-2023 Acala Foundation.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

//! # Liquid Crowdloan Module
//!
//! Allow people to redeem lcDOT for DOT.
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(clippy::unused_unit)]

use frame_support::{pallet_prelude::*, traits::EnsureOrigin, PalletId};
use frame_system::pallet_prelude::*;
use orml_traits::MultiCurrency;
use primitives::{Balance, CurrencyId};
use sp_runtime::traits::AccountIdConversion;

use support::CrowdloanVaultXcm;

mod mock;
mod tests;
pub mod weights;

pub use module::*;
pub use weights::WeightInfo;

#[frame_support::pallet]
pub mod module {
use super::*;

#[pallet::config]
pub trait Config: frame_system::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

type Currency: MultiCurrency<Self::AccountId, CurrencyId = CurrencyId, Balance = Balance>;

/// Liquid crowdloan currency Id, i.e. LCDOT for Polkadot.
#[pallet::constant]
type LiquidCrowdloanCurrencyId: Get<CurrencyId>;

/// Relay chain currency Id, i.e. DOT for Polkadot.
#[pallet::constant]
type RelayChainCurrencyId: Get<CurrencyId>;

/// Pallet Id for liquid crowdloan module.
#[pallet::constant]
type PalletId: Get<PalletId>;

/// The governance origin for liquid crowdloan module. For instance for DOT cross-chain
/// transfer DOT from relay chain crowdloan vault to liquid crowdloan module account.
type GovernanceOrigin: EnsureOrigin<Self::RuntimeOrigin>;

/// The crowdloan vault account on relay chain.
#[pallet::constant]
type CrowdloanVault: Get<Self::AccountId>;

/// XCM transfer impl.
type XcmTransfer: CrowdloanVaultXcm<Self::AccountId, Balance>;

/// Weight information for the extrinsics in this module.
type WeightInfo: WeightInfo;
}

#[pallet::event]
#[pallet::generate_deposit(fn deposit_event)]
pub enum Event<T: Config> {
/// Liquid Crowdloan asset was redeemed.
Redeemed { amount: Balance },
/// The transfer from relay chain crowdloan vault was requested.
TransferFromCrowdloanVaultRequested { amount: Balance },
}

#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Redeem liquid crowdloan currency for relay chain currency.
#[pallet::call_index(0)]
#[pallet::weight(<T as Config>::WeightInfo::redeem())]
pub fn redeem(origin: OriginFor<T>, #[pallet::compact] amount: Balance) -> DispatchResult {
let who = ensure_signed(origin)?;

T::Currency::withdraw(T::LiquidCrowdloanCurrencyId::get(), &who, amount)?;

T::Currency::transfer(T::RelayChainCurrencyId::get(), &Self::account_id(), &who, amount)?;

Self::deposit_event(Event::Redeemed { amount });

Ok(())
}

/// Send an XCM message to cross-chain transfer DOT from relay chain crowdloan vault to
/// liquid crowdloan module account.
///
/// This call requires `GovernanceOrigin`.
#[pallet::call_index(1)]
#[pallet::weight(<T as Config>::WeightInfo::transfer_from_crowdloan_vault())]
pub fn transfer_from_crowdloan_vault(
origin: OriginFor<T>,
#[pallet::compact] amount: Balance,
) -> DispatchResult {
T::GovernanceOrigin::ensure_origin(origin)?;

T::XcmTransfer::transfer_to_liquid_crowdloan_module_account(
T::CrowdloanVault::get(),
Self::account_id(),
amount,
)?;

Self::deposit_event(Event::TransferFromCrowdloanVaultRequested { amount });

Ok(())
}
}
}

impl<T: Config> Pallet<T> {
pub fn account_id() -> T::AccountId {
T::PalletId::get().into_account_truncating()
}
}
Loading

0 comments on commit 98ead77

Please sign in to comment.