Files
serai/substrate/tokens/pallet/src/lib.rs

83 lines
2.4 KiB
Rust
Raw Normal View History

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
2023-01-28 01:47:13 -05:00
#![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]
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::*;