1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
use {
18
    crate::{
19
        xcm_config::{AssetId, ForeignAssetsInstance, XcmConfig},
20
        AccountId, Balances, ForeignAssetsCreator, Runtime,
21
    },
22
    frame_support::parameter_types,
23
    pallet_evm_precompile_balances_erc20::{Erc20BalancesPrecompile, Erc20Metadata},
24
    pallet_evm_precompile_batch::BatchPrecompile,
25
    pallet_evm_precompile_call_permit::CallPermitPrecompile,
26
    pallet_evm_precompile_modexp::Modexp,
27
    pallet_evm_precompile_proxy::{OnlyIsProxyAndProxy, ProxyPrecompile},
28
    pallet_evm_precompile_sha3fips::Sha3FIPS256,
29
    pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256},
30
    pallet_evm_precompile_xcm::PalletXcmPrecompile,
31
    pallet_evm_precompile_xcm_utils::{AllExceptXcmExecute, XcmUtilsPrecompile},
32
    pallet_evm_precompileset_assets_erc20::Erc20AssetsPrecompileSet,
33
    precompile_utils::precompile_set::{
34
        AcceptDelegateCall, AddressU64, CallableByContract, CallableByPrecompile, OnlyFrom,
35
        PrecompileAt, PrecompileSetBuilder, PrecompileSetStartingWith, PrecompilesInRangeInclusive,
36
        SubcallWithMaxNesting,
37
    },
38
    xcm_primitives::location_matcher::{ForeignAssetMatcher, SingleAddressMatcher},
39
};
40

            
41
/// ERC20 metadata for the native token.
42
pub struct NativeErc20Metadata;
43

            
44
impl Erc20Metadata for NativeErc20Metadata {
45
    /// Returns the name of the token.
46
    fn name() -> &'static str {
47
        "UNIT token"
48
    }
49

            
50
    /// Returns the symbol of the token.
51
    fn symbol() -> &'static str {
52
        "UNIT"
53
    }
54

            
55
    /// Returns the decimals places of the token.
56
    fn decimals() -> u8 {
57
        18
58
    }
59

            
60
    /// Must return `true` only if it represents the main native currency of
61
    /// the network. It must be the currency used in `pallet_evm`.
62
    fn is_native_currency() -> bool {
63
        true
64
    }
65
}
66

            
67
/// The asset precompile address prefix. Addresses that match against this prefix will be routed
68
/// to Erc20AssetsPrecompileSet being marked as foreign
69
pub const FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8; 18];
70

            
71
/// Const to identify ERC20_BALANCES_PRECOMPILE address
72
pub const ERC20_BALANCES_PRECOMPILE: u64 = 2048;
73

            
74
parameter_types! {
75
    pub ForeignAssetPrefix: &'static [u8] = FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX;
76
}
77

            
78
type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile);
79

            
80
// Pallet-xcm precompile types.
81
// The pallet-balances address is identified by ERC20_BALANCES_PRECOMPILE const
82
type BalancesPrecompileMatch = SingleAddressMatcher<AccountId, ERC20_BALANCES_PRECOMPILE, Balances>;
83

            
84
// Type that matches an AccountId with a foreign asset address (if any)
85
type ForeignAssetMatch = ForeignAssetMatcher<AccountId, AssetId, Runtime, ForeignAssetsCreator>;
86

            
87
#[precompile_utils::precompile_name_from_address]
88
type TemplatePrecompilesAt<R> = (
89
    // Ethereum precompiles:
90
    // Allow DELEGATECALL to stay compliant with Ethereum behavior.
91
    PrecompileAt<AddressU64<1>, ECRecover, EthereumPrecompilesChecks>,
92
    PrecompileAt<AddressU64<2>, Sha256, EthereumPrecompilesChecks>,
93
    PrecompileAt<AddressU64<3>, Ripemd160, EthereumPrecompilesChecks>,
94
    PrecompileAt<AddressU64<4>, Identity, EthereumPrecompilesChecks>,
95
    PrecompileAt<AddressU64<5>, Modexp, EthereumPrecompilesChecks>,
96
    // Non-template specific nor Ethereum precompiles :
97
    PrecompileAt<AddressU64<1024>, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>,
98
    PrecompileAt<AddressU64<1025>, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>,
99
    // Template specific precompiles:
100
    PrecompileAt<
101
        AddressU64<ERC20_BALANCES_PRECOMPILE>,
102
        Erc20BalancesPrecompile<R, NativeErc20Metadata>,
103
        (CallableByContract, CallableByPrecompile),
104
    >,
105
    PrecompileAt<AddressU64<2049>, BatchPrecompile<R>, SubcallWithMaxNesting<2>>,
106
    PrecompileAt<
107
        AddressU64<2050>,
108
        CallPermitPrecompile<R>,
109
        (SubcallWithMaxNesting<0>, CallableByContract),
110
    >,
111
    PrecompileAt<
112
        AddressU64<2051>,
113
        XcmUtilsPrecompile<R, XcmConfig>,
114
        CallableByContract<AllExceptXcmExecute<R, XcmConfig>>,
115
    >,
116
    PrecompileAt<
117
        AddressU64<2052>,
118
        PalletXcmPrecompile<R, (BalancesPrecompileMatch, ForeignAssetMatch)>,
119
        (CallableByContract, CallableByPrecompile),
120
    >,
121
    PrecompileAt<
122
        AddressU64<2053>,
123
        ProxyPrecompile<R>,
124
        (
125
            CallableByContract<OnlyIsProxyAndProxy<R>>,
126
            SubcallWithMaxNesting<0>,
127
            // Batch is the only precompile allowed to call Proxy.
128
            CallableByPrecompile<OnlyFrom<AddressU64<2049>>>,
129
        ),
130
    >,
131
);
132

            
133
pub type TemplatePrecompiles<R> = PrecompileSetBuilder<
134
    R,
135
    (
136
        PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<4095>), TemplatePrecompilesAt<R>>,
137
        // Prefixed precompile sets (XC20)
138
        PrecompileSetStartingWith<
139
            ForeignAssetPrefix,
140
            Erc20AssetsPrecompileSet<R, ForeignAssetsInstance>,
141
            (CallableByContract, CallableByPrecompile),
142
        >,
143
    ),
144
>;