@@ -55,6 +55,7 @@ use ethereum_types::{H160, U256};
55
55
use frame_support:: pallet;
56
56
use frame_support:: pallet_prelude:: * ;
57
57
use frame_support:: traits:: Contains ;
58
+
58
59
use frame_system:: pallet_prelude:: * ;
59
60
use xcm:: latest:: {
60
61
Asset , AssetId as XcmAssetId , Error as XcmError , Fungibility , Location , Result as XcmResult ,
@@ -247,6 +248,8 @@ pub mod pallet {
247
248
Erc20ContractCreationFail ,
248
249
EvmCallPauseFail ,
249
250
EvmCallUnpauseFail ,
251
+ EvmCallMintIntoFail ,
252
+ EvmCallTransferFail ,
250
253
EvmInternalError ,
251
254
/// Account has insufficient balance for locking
252
255
InsufficientBalance ,
@@ -364,6 +367,29 @@ pub mod pallet {
364
367
. map_err ( Into :: into)
365
368
}
366
369
370
+ /// Transfer an asset from an account to another one
371
+ pub fn transfer (
372
+ asset_id : AssetId ,
373
+ from : T :: AccountId ,
374
+ to : T :: AccountId ,
375
+ amount : U256 ,
376
+ ) -> Result < ( ) , evm:: EvmError > {
377
+ frame_support:: storage:: with_storage_layer ( || {
378
+ EvmCaller :: < T > :: erc20_transfer (
379
+ Self :: contract_address_from_asset_id ( asset_id) ,
380
+ T :: AccountIdToH160 :: convert ( from) ,
381
+ T :: AccountIdToH160 :: convert ( to) ,
382
+ amount,
383
+ )
384
+ } )
385
+ . map_err ( Into :: into)
386
+ }
387
+
388
+ pub fn balance ( asset_id : AssetId , who : T :: AccountId ) -> Result < U256 , evm:: EvmError > {
389
+ EvmCaller :: < T > :: erc20_balance_of ( asset_id, T :: AccountIdToH160 :: convert ( who) )
390
+ . map_err ( Into :: into)
391
+ }
392
+
367
393
/// Aprrove a spender to spend a certain amount of tokens from the owner account
368
394
pub fn approve (
369
395
asset_id : AssetId ,
@@ -754,4 +780,68 @@ pub mod pallet {
754
780
AssetsById :: < T > :: get ( asset_id)
755
781
}
756
782
}
783
+
784
+ #[ cfg( feature = "runtime-benchmarks" ) ]
785
+ impl < T : Config > AssetCreate for Pallet < T > {
786
+ fn create_asset ( id : u128 , xcm_location : Location ) -> DispatchResult {
787
+ use frame_support:: traits:: OriginTrait ;
788
+ use sp_std:: vec;
789
+ Pallet :: < T > :: create_foreign_asset (
790
+ <T as frame_system:: Config >:: RuntimeOrigin :: root ( ) ,
791
+ id,
792
+ xcm_location,
793
+ 12 ,
794
+ vec ! [ b'M' , b'T' ] . try_into ( ) . expect ( "invalid ticker" ) ,
795
+ vec ! [ b'M' , b'y' , b'T' , b'o' , b'k' ]
796
+ . try_into ( )
797
+ . expect ( "invalid name" ) ,
798
+ )
799
+ }
800
+ }
801
+
802
+ impl < T : Config > AssetMutate < T > for Pallet < T > {
803
+ fn transfer_asset (
804
+ id : u128 ,
805
+ from : T :: AccountId ,
806
+ to : T :: AccountId ,
807
+ amount : U256 ,
808
+ ) -> DispatchResult {
809
+ Pallet :: < T > :: transfer ( id, from, to, amount)
810
+ . map_err ( |_| Error :: < T > :: EvmCallTransferFail ) ?;
811
+ Ok ( ( ) )
812
+ }
813
+
814
+ #[ cfg( feature = "runtime-benchmarks" ) ]
815
+ fn mint_asset ( id : u128 , account : T :: AccountId , amount : U256 ) -> DispatchResult {
816
+ Pallet :: < T > :: mint_into ( id, account, amount)
817
+ . map_err ( |_| Error :: < T > :: EvmCallMintIntoFail ) ?;
818
+ Ok ( ( ) )
819
+ }
820
+ }
821
+
822
+ impl < T : Config > AssetInspect for Pallet < T > {
823
+ fn asset_exists ( id : u128 ) -> bool {
824
+ AssetsById :: < T > :: contains_key ( & id)
825
+ }
826
+ }
827
+ }
828
+
829
+ pub trait AssetCreate {
830
+ fn create_asset ( id : u128 , xcm_location : Location ) -> DispatchResult ;
831
+ }
832
+
833
+ pub trait AssetMutate < R : frame_system:: Config > {
834
+ fn transfer_asset (
835
+ id : u128 ,
836
+ from : R :: AccountId ,
837
+ to : R :: AccountId ,
838
+ amount : U256 ,
839
+ ) -> DispatchResult ;
840
+
841
+ #[ cfg( feature = "runtime-benchmarks" ) ]
842
+ fn mint_asset ( id : u128 , account : R :: AccountId , amount : U256 ) -> DispatchResult ;
843
+ }
844
+
845
+ pub trait AssetInspect {
846
+ fn asset_exists ( id : u128 ) -> bool ;
757
847
}
0 commit comments