Skip to content
This repository was archived by the owner on Mar 13, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions bin/node/runtime/pangolin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -971,16 +971,20 @@ impl darwinia_crab_backing::Trait for Runtime {
}

parameter_types! {
pub const EthBackingModuleId: ModuleId = ModuleId(*b"da/ethbk");
pub const EthereumBackingModuleId: ModuleId = ModuleId(*b"da/ethbk");
pub const EthereumBackingFeeModuleId: ModuleId = ModuleId(*b"da/ethfe");
pub const AdvancedFee: Balance = 50 * COIN;
}
impl darwinia_ethereum_backing::Trait for Runtime {
type ModuleId = EthBackingModuleId;
type ModuleId = EthereumBackingModuleId;
type EthereumBackingFeeModuleId = EthereumBackingFeeModuleId;
type Event = Event;
type RedeemAccountId = AccountId;
type EthereumRelay = EthereumRelay;
type OnDepositRedeem = Staking;
type RingCurrency = Ring;
type KtonCurrency = Kton;
type AdvancedFee = AdvancedFee;
type WeightInfo = ();
}

Expand Down
98 changes: 83 additions & 15 deletions frame/bridge/ethereum/backing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ mod types {
pub type Balance = u128;
pub type DepositId = U256;

pub type RingBalance<T> =
<<T as Trait>::RingCurrency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
#[cfg(feature = "std")]
pub type KtonBalance<T> =
<<T as Trait>::KtonCurrency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
pub type AccountId<T> = <T as frame_system::Trait>::AccountId;
pub type RingBalance<T> = <<T as Trait>::RingCurrency as Currency<AccountId<T>>>::Balance;
pub type KtonBalance<T> = <<T as Trait>::KtonCurrency as Currency<AccountId<T>>>::Balance;

pub type EthereumReceiptProofThing<T> = <<T as Trait>::EthereumRelay as EthereumReceipt<
<T as frame_system::Trait>::AccountId,
AccountId<T>,
RingBalance<T>,
>>::EthereumReceiptProofThing;
}
Expand All @@ -41,12 +39,12 @@ use frame_support::{
};
use frame_system::{ensure_root, ensure_signed};
use sp_runtime::{
traits::{AccountIdConversion, SaturatedConversion, Saturating},
traits::{AccountIdConversion, SaturatedConversion, Saturating, Zero},
DispatchError, DispatchResult, ModuleId, RuntimeDebug,
};
#[cfg(not(feature = "std"))]
use sp_std::borrow::ToOwned;
use sp_std::{convert::TryFrom, vec};
use sp_std::{convert::TryFrom, prelude::*};
// --- darwinia ---
use array_bytes::array_unchecked;
use darwinia_support::{
Expand All @@ -57,9 +55,11 @@ use ethereum_primitives::{receipt::EthereumTransactionIndex, EthereumAddress, U2
use types::*;

pub trait Trait: frame_system::Trait {
/// The backing's module id, used for deriving its sovereign account ID.
/// The ethereum backing module id, used for deriving its sovereign account ID.
type ModuleId: Get<ModuleId>;

type EthereumBackingFeeModuleId: Get<ModuleId>;

type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;

type RedeemAccountId: From<[u8; 32]> + Into<Self::AccountId>;
Expand All @@ -72,6 +72,8 @@ pub trait Trait: frame_system::Trait {

type KtonCurrency: LockableCurrency<Self::AccountId, Moment = Self::BlockNumber>;

type AdvancedFee: Get<RingBalance<Self>>;

/// Weight information for the extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
Expand All @@ -83,15 +85,20 @@ impl WeightInfo for () {}
decl_event! {
pub enum Event<T>
where
<T as frame_system::Trait>::AccountId,
AccountId = AccountId<T>,
RingBalance = RingBalance<T>,
KtonBalance = KtonBalance<T>,
{
/// Some one redeem some *RING*. [account, amount, transaction index]
/// Someone redeem some *RING*. [account, amount, transaction index]
RedeemRing(AccountId, Balance, EthereumTransactionIndex),
/// Some one redeem some *KTON*. [account, amount, transaction index]
/// Someone redeem some *KTON*. [account, amount, transaction index]
RedeemKton(AccountId, Balance, EthereumTransactionIndex),
/// Some one redeem a deposit. [account, deposit id, amount, transaction index]
/// Someone redeem a deposit. [account, deposit id, amount, transaction index]
RedeemDeposit(AccountId, DepositId, RingBalance, EthereumTransactionIndex),
/// Someone lock some *RING*. [account, amount]
LockRing(AccountId, RingBalance),
/// Someone lock some *KTON*. [account, amount]
LockKton(AccountId, KtonBalance),
}
}

Expand Down Expand Up @@ -140,6 +147,10 @@ decl_storage! {
pub KtonTokenAddress get(fn kton_token_address) config(): EthereumAddress;

pub RedeemStatus get(fn redeem_status): bool = true;

pub LockAssetEvents
get(fn lock_asset_events)
: Vec<<T as frame_system::Trait>::Event>;
}
add_extra_genesis {
config(ring_locked): RingBalance<T>;
Expand All @@ -150,11 +161,14 @@ decl_storage! {
&<Module<T>>::account_id(),
T::RingCurrency::minimum_balance() + config.ring_locked,
);

let _ = T::KtonCurrency::make_free_balance_be(
&<Module<T>>::account_id(),
T::KtonCurrency::minimum_balance() + config.kton_locked,
);
let _ = T::RingCurrency::make_free_balance_be(
&<Module<T>>::fee_account_id(),
T::RingCurrency::minimum_balance(),
);
});
}
}
Expand All @@ -166,11 +180,20 @@ decl_module! {
{
type Error = Error<T>;

/// The treasury's module id, used for deriving its sovereign account ID.
/// The ethereum backing module id, used for deriving its sovereign account ID.
const ModuleId: ModuleId = T::ModuleId::get();

fn deposit_event() = default;

fn on_runtime_upgrade() -> frame_support::weights::Weight {
let _ = T::RingCurrency::make_free_balance_be(
&<Module<T>>::fee_account_id(),
T::RingCurrency::minimum_balance(),
);

0
}

/// Redeem balances
///
/// # <weight>
Expand All @@ -190,6 +213,47 @@ decl_module! {
}
}

/// Lock some balances into the module account
/// which very similar to lock some assets into the contract on ethereum side
#[weight = 10_000_000]
pub fn lock(
origin,
#[compact] ring_value: RingBalance<T>,
#[compact] kton_value: KtonBalance<T>,
) {
let user = ensure_signed(origin)?;
let fee_account = Self::fee_account_id();

// 50 Ring for fee
// https://github.com/darwinia-network/darwinia-common/pull/377#issuecomment-730369387
T::RingCurrency::transfer(&user, &fee_account, T::AdvancedFee::get(), KeepAlive)?;

if !ring_value.is_zero() {
let ring_to_lock = ring_value.min(T::RingCurrency::usable_balance(&user));

T::RingCurrency::transfer(&user, &fee_account, ring_to_lock, KeepAlive)?;

let raw_event = RawEvent::LockRing(user.clone(), ring_to_lock);
let module_event: <T as Trait>::Event = raw_event.clone().into();
let system_event: <T as frame_system::Trait>::Event = module_event.into();

<LockAssetEvents<T>>::append(system_event);
Self::deposit_event(raw_event);
}
if !kton_value.is_zero() {
let kton_to_lock = kton_value.min(T::KtonCurrency::usable_balance(&user));

T::KtonCurrency::transfer(&user, &fee_account, kton_to_lock, KeepAlive)?;

let raw_event = RawEvent::LockKton(user, kton_to_lock);
let module_event: <T as Trait>::Event = raw_event.clone().into();
let system_event: <T as frame_system::Trait>::Event = module_event.into();

<LockAssetEvents<T>>::append(system_event);
Self::deposit_event(raw_event);
}
}

// --- Root Call ---

/// Set a new ring redeem address.
Expand Down Expand Up @@ -244,6 +308,10 @@ impl<T: Trait> Module<T> {
T::ModuleId::get().into_account()
}

pub fn fee_account_id() -> T::AccountId {
T::EthereumBackingFeeModuleId::get().into_account()
}

pub fn account_id_try_from_bytes(bytes: &[u8]) -> Result<T::AccountId, DispatchError> {
ensure!(bytes.len() == 32, <Error<T>>::AddrLenMis);

Expand Down
7 changes: 5 additions & 2 deletions frame/bridge/ethereum/backing/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,19 @@ macro_rules! decl_tests {
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Test;
parameter_types! {
pub const EthBackingModuleId: ModuleId = ModuleId(*b"da/backi");
pub const EthereumBackingModuleId: ModuleId = ModuleId(*b"da/backi");
pub const EthereumBackingFeeModuleId: ModuleId = ModuleId(*b"da/ethfe");
}
impl Trait for Test {
type ModuleId = EthBackingModuleId;
type ModuleId = EthereumBackingModuleId;
type EthereumBackingFeeModuleId = EthereumBackingFeeModuleId;
type Event = ();
type RedeemAccountId = AccountId;
type EthereumRelay = EthereumRelay;
type OnDepositRedeem = Staking;
type RingCurrency = Ring;
type KtonCurrency = Kton;
type AdvancedFee = ();
type WeightInfo = ();
}

Expand Down