1+ use frame_support:: traits:: fungible:: Inspect as _;
12use frame_support:: {
23 assert_noop,
3- pallet_prelude:: Encode ,
4+ pallet_prelude:: { Decode , Encode } ,
45 traits:: fungibles:: {
56 approvals:: Inspect as _, metadata:: Inspect as _, roles:: Inspect as _, Inspect as _,
67 } ,
78} ;
9+ use pallet_revive:: precompiles:: alloy:: alloy_sol_types:: SolValue ;
810use sp_io:: hashing:: twox_256;
911
1012use super :: * ;
@@ -17,18 +19,42 @@ pallet_revive::precompiles::alloy::sol!(
1719 "interfaces/IERC20.sol"
1820) ;
1921
22+ #[ cfg_attr( feature = "std" , derive( Debug , Encode ) ) ]
23+ pub struct Created {
24+ pub id : AssetId ,
25+ }
26+
27+ #[ test]
28+ fn asset_id_works ( ) {
29+ let token = 42 ;
30+ let endowment = 100 * UNIT ;
31+ ExtBuilder :: new ( )
32+ . with_assets ( vec ! [ ( token, ALICE , false , 1 ) ] )
33+ . with_asset_balances ( vec ! [ ( token, BOB , endowment) ] )
34+ . build ( )
35+ . execute_with ( || {
36+ let contract = Contract :: new ( & BOB , 0 , token) ;
37+
38+ // Test that asset_id returns the correct token ID
39+ assert_eq ! ( contract. asset_id( ) , token) ;
40+ } ) ;
41+ }
42+
2043#[ test]
2144fn total_supply_works ( ) {
22- let token = 1 ;
23- let endowment = 100 ;
45+ let token = 2 ;
46+ let endowment = 100 * UNIT ;
2447 ExtBuilder :: new ( )
2548 . with_assets ( vec ! [ ( token, ALICE , false , 1 ) ] )
2649 . with_asset_balances ( vec ! [ ( token, BOB , endowment) ] )
2750 . build ( )
2851 . execute_with ( || {
2952 let contract = Contract :: new ( & BOB , 0 , token) ;
3053
54+ assert ! ( Assets :: asset_exists( token) ) ;
55+
3156 // Tokens in circulation.
57+ assert_eq ! ( total_supply_precompile( token) , Assets :: total_supply( token) . into( ) ) ;
3258 assert_eq ! ( contract. total_supply( ) , Assets :: total_supply( token) . into( ) ) ;
3359 assert_eq ! ( contract. total_supply( ) , endowment. into( ) ) ;
3460
@@ -45,8 +71,56 @@ struct Contract {
4571 creator : AccountId ,
4672}
4773
74+ /// Calculates the address of a precompile at index `n` and with some additional prefix.
75+ #[ inline]
76+ pub fn fixed_address ( n : u16 ) -> H160 {
77+ let shifted = ( n as u32 ) << 16 ;
78+
79+ let suffix = shifted. to_be_bytes ( ) ;
80+ let mut address = [ 0u8 ; 20 ] ;
81+ let mut i = 16 ;
82+ while i < address. len ( ) {
83+ address[ i] = suffix[ i - 16 ] ;
84+ i = i + 1 ;
85+ }
86+ H160 :: from ( address)
87+ }
88+
89+ /// Calculates the address of a precompile at index `n` and with some additional prefix.
90+ #[ inline]
91+ pub fn prefixed_address ( n : u16 , prefix : u32 ) -> H160 {
92+ let address = fixed_address ( n) ;
93+ let mut address_bytes: [ u8 ; 20 ] = address. into ( ) ;
94+ address_bytes[ ..4 ] . copy_from_slice ( & prefix. to_be_bytes ( ) ) ;
95+ H160 :: from ( address_bytes)
96+ }
97+
98+ fn total_supply_precompile ( token : AssetId ) -> U256 {
99+ let call = totalSupplyCall { } ;
100+ U256 :: from_little_endian ( call_precompile ( & BOB , call, 0 , token) . as_le_slice ( ) )
101+ }
102+
103+ fn call_precompile < T : SolCall > (
104+ origin : & AccountId ,
105+ call : T ,
106+ value : Balance ,
107+ token : AssetId ,
108+ ) -> T :: Return {
109+ let origin = RuntimeOrigin :: signed ( origin. clone ( ) ) ;
110+ let dest = prefixed_address ( 0x0120 , token) ;
111+ // let dest = self.address.clone();
112+ let data = call. abi_encode ( ) ;
113+ let result = bare_call ( origin, dest, value, GAS_LIMIT , STORAGE_DEPOSIT_LIMIT , data)
114+ . expect ( "should work" ) ;
115+
116+ match result. did_revert ( ) {
117+ true => panic ! ( "Contract call reverted: {:?}" , String :: from_utf8_lossy( & result. data) ) ,
118+ false => T :: abi_decode_returns ( & result. data ) . expect ( "unable to decode success value" ) ,
119+ }
120+ }
121+
48122impl Contract {
49- // Create a new instance of the contract through on-chain instantiation.
123+ // Create a new instance of the contract through on-chain instantiation (ink! style) .
50124 fn new ( origin : & AccountId , value : Balance , token : AssetId ) -> Self {
51125 let data = [ blake_selector ( "create" ) . to_vec ( ) , token. encode ( ) ] . concat ( ) ;
52126 let salt = twox_256 ( & value. to_le_bytes ( ) ) ;
@@ -61,6 +135,14 @@ impl Contract {
61135 U256 :: from_little_endian ( self . call ( & self . creator , call, 0 ) . as_le_slice ( ) )
62136 }
63137
138+ fn asset_id ( & self ) -> AssetId {
139+ let call = assetIdCall { } ;
140+ let data = self . call ( & self . creator , call, 0 ) ;
141+ // let bytes: [u8; 4] = data.as_slice().try_into().expect("Expected 4 bytes for u32");
142+ // let result = u32::from_le_bytes(bytes);
143+ AssetId :: from ( data)
144+ }
145+
64146 fn account_id ( & self ) -> AccountId {
65147 to_account_id ( & self . address )
66148 }
0 commit comments