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
#![cfg_attr(not(feature = "std"), no_std)]
18

            
19
use xcm::latest::prelude::*;
20
trait Parse {
21
    /// Returns the "chain" location part. It could be parent, sibling
22
    /// parachain, or child parachain.
23
    fn chain_part(&self) -> Option<Location>;
24
}
25

            
26
impl Parse for Location {
27
550
    fn chain_part(&self) -> Option<Location> {
28
550
        match (self.parents, self.first_interior()) {
29
            // sibling parachain
30
150
            (1, Some(Parachain(id))) => Some(Location::new(1, [Parachain(*id)])),
31
            // parent
32
375
            (1, _) => Some(Location::parent()),
33
            // children parachain
34
            (0, Some(Parachain(id))) => Some(Location::new(0, [Parachain(*id)])),
35
25
            _ => None,
36
        }
37
550
    }
38
}
39

            
40
pub struct NativeAssetReserve;
41
impl frame_support::traits::ContainsPair<Asset, Location> for NativeAssetReserve {
42
800
    fn contains(asset: &Asset, origin: &Location) -> bool {
43
800
        log::trace!(target: "xcm::contains", "NativeAssetReserve asset: {:?}, origin: {:?}", asset, origin);
44
800
        let reserve = if asset.id.0.parents == 0
45
250
            && !matches!(asset.id.0.first_interior(), Some(Parachain(_)))
46
        {
47
250
            Some(Location::here())
48
        } else {
49
550
            asset.id.0.chain_part()
50
        };
51

            
52
800
        if let Some(ref reserve) = reserve {
53
775
            if reserve == origin {
54
500
                return true;
55
275
            }
56
25
        }
57
300
        false
58
800
    }
59
}