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:
Luke Parker
2023-01-28 01:47:13 -05:00
committed by GitHub
parent f12cc2cca6
commit 2ace339975
39 changed files with 1213 additions and 594 deletions

View 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::*;