mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 13:39:25 +00:00
Tokens pallet (#243)
* Use Monero-compatible additional TX keys This still sends a fingerprinting flare up if you send to a subaddress which needs to be fixed. Despite that, Monero no should no longer fail to scan TXs from monero-serai regarding additional keys. Previously it failed becuase we supplied one key as THE key, and n-1 as additional. Monero expects n for additional. This does correctly select when to use THE key versus when to use the additional key when sending. That removes the ability for recipients to fingerprint monero-serai by receiving to a standard address yet needing to use an additional key. * Add tokens_primitives Moves OutInstruction from in-instructions. Turns Destination into OutInstruction. * Correct in-instructions DispatchClass * Add initial tokens pallet * Don't allow pallet addresses to equal identity * Add support for InInstruction::transfer Requires a cargo update due to modifications made to serai-dex/substrate. Successfully mints a token to a SeraiAddress. * Bind InInstructions to an amount * Add a call filter to the runtime Prevents worrying about calls to the assets pallet/generally tightens things up. * Restore Destination It was meged into OutInstruction, yet it didn't make sense for OutInstruction to contain a SeraiAddress. Also deletes the excessively dated Scenarios doc. * Split PublicKey/SeraiAddress Lets us define a custom Display/ToString for SeraiAddress. Also resolves an oddity where PublicKey would be encoded as String, not [u8; 32]. * Test burning tokens/retrieving OutInstructions Modularizes processor_coinUpdates into a shared testing utility. * Misc lint * Don't use PolkadotExtrinsicParams
This commit is contained in:
83
substrate/tokens/pallet/src/lib.rs
Normal file
83
substrate/tokens/pallet/src/lib.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
pub use tokens_primitives as primitives;
|
||||
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_system::{pallet_prelude::*, RawOrigin};
|
||||
|
||||
use pallet_assets::{Config as AssetsConfig, Pallet as AssetsPallet};
|
||||
|
||||
use serai_primitives::{SubstrateAmount, Coin, Balance, PublicKey, SeraiAddress, AccountLookup};
|
||||
use primitives::{ADDRESS, OutInstruction};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config:
|
||||
frame_system::Config<AccountId = PublicKey, Lookup = AccountLookup>
|
||||
+ AssetsConfig<AssetIdParameter = Coin, Balance = SubstrateAmount>
|
||||
{
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||
}
|
||||
|
||||
#[pallet::event]
|
||||
#[pallet::generate_deposit(fn deposit_event)]
|
||||
pub enum Event<T: Config> {
|
||||
// Mint is technically redundant as the assets pallet has the exact same event already
|
||||
// Providing our own definition here just helps consolidate code
|
||||
Mint { address: SeraiAddress, balance: Balance },
|
||||
Burn { address: SeraiAddress, balance: Balance, instruction: OutInstruction },
|
||||
}
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_store(pub(crate) trait Store)]
|
||||
pub struct Pallet<T>(PhantomData<T>);
|
||||
|
||||
impl<T: Config> Pallet<T> {
|
||||
fn burn_internal(
|
||||
address: SeraiAddress,
|
||||
balance: Balance,
|
||||
instruction: OutInstruction,
|
||||
) -> DispatchResult {
|
||||
AssetsPallet::<T>::burn(
|
||||
RawOrigin::Signed(ADDRESS.into()).into(),
|
||||
balance.coin,
|
||||
address,
|
||||
balance.amount.0,
|
||||
)?;
|
||||
Pallet::<T>::deposit_event(Event::Burn { address, balance, instruction });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn mint(address: SeraiAddress, balance: Balance) {
|
||||
// TODO: Prevent minting when it'd cause an amount exceeding the bond
|
||||
AssetsPallet::<T>::mint(
|
||||
RawOrigin::Signed(ADDRESS.into()).into(),
|
||||
balance.coin,
|
||||
address,
|
||||
balance.amount.0,
|
||||
)
|
||||
.unwrap();
|
||||
Pallet::<T>::deposit_event(Event::Mint { address, balance });
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
#[pallet::call_index(0)]
|
||||
#[pallet::weight((0, DispatchClass::Normal))] // TODO
|
||||
pub fn burn(
|
||||
origin: OriginFor<T>,
|
||||
balance: Balance,
|
||||
instruction: OutInstruction,
|
||||
) -> DispatchResult {
|
||||
Self::burn_internal(ensure_signed(origin)?.into(), balance, instruction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub use pallet::*;
|
||||
Reference in New Issue
Block a user