radix_engine/blueprints/pool/v1/
substates.rs

1use crate::blueprints::models::*;
2use crate::internal_prelude::*;
3use radix_engine_interface::prelude::*;
4use radix_native_sdk::resource::*;
5
6pub mod one_resource_pool {
7    use super::*;
8
9    declare_native_blueprint_state! {
10        blueprint_ident: OneResourcePool,
11        blueprint_snake_case: one_resource_pool,
12        features: {
13        },
14        fields: {
15            state:  {
16                ident: State,
17                field_type: {
18                    kind: StaticSingleVersioned,
19                },
20                condition: Condition::Always,
21            }
22        },
23        collections: {
24        }
25    }
26
27    pub type OneResourcePoolStateV1 = Substate;
28
29    #[derive(Debug, PartialEq, Eq, ScryptoSbor)]
30    #[sbor(type_name = "OneResourcePoolSubstate")]
31    pub struct Substate {
32        /// The vault of the resources of the pool.
33        pub vault: Vault,
34
35        /// The resource manager of the pool unit resource that the pool works with.
36        pub pool_unit_resource_manager: ResourceManager,
37    }
38}
39
40pub mod two_resource_pool {
41    use super::*;
42
43    declare_native_blueprint_state! {
44        blueprint_ident: TwoResourcePool,
45        blueprint_snake_case: two_resource_pool,
46        features: {
47        },
48        fields: {
49            state:  {
50                ident: State,
51                field_type: {
52                    kind: StaticSingleVersioned,
53                },
54                condition: Condition::Always,
55            }
56        },
57        collections: {
58        }
59    }
60
61    pub type TwoResourcePoolStateV1 = Substate;
62
63    #[derive(Debug, PartialEq, Eq, ScryptoSbor)]
64    #[sbor(type_name = "TwoResourcePoolSubstate")]
65    pub struct Substate {
66        /// The vaults of the resources of the pool - the maximum number of entries that this map can
67        /// have is two, a single vault for each resource. This is a map as it makes the interactions
68        /// simpler.
69        pub vaults: [(ResourceAddress, Vault); 2],
70
71        /// The resource manager of the pool unit resource that the pool works with.
72        pub pool_unit_resource_manager: ResourceManager,
73    }
74
75    impl Substate {
76        pub fn vault(&self, resource_address: ResourceAddress) -> Option<Vault> {
77            self.vaults
78                .iter()
79                .find(|(vault_resource_address, _)| resource_address == *vault_resource_address)
80                .map(|(_, vault)| Vault(vault.0))
81        }
82    }
83}
84
85pub mod multi_resource_pool {
86    use super::*;
87
88    declare_native_blueprint_state! {
89        blueprint_ident: MultiResourcePool,
90        blueprint_snake_case: multi_resource_pool,
91        features: {
92        },
93        fields: {
94            state:  {
95                ident: State,
96                field_type: {
97                    kind: StaticSingleVersioned,
98                },
99                condition: Condition::Always,
100            }
101        },
102        collections: {
103        }
104    }
105
106    pub type MultiResourcePoolStateV1 = Substate;
107
108    #[derive(Debug, PartialEq, Eq, ScryptoSbor)]
109    #[sbor(type_name = "MultiResourcePoolSubstate")]
110    pub struct Substate {
111        /// The vaults being stored as a `IndexMap` and not as a `KeyValueStore` is intentional here!
112        ///
113        /// All of the operations on the many pool blueprint require loading all of the vaults and doing
114        /// some arithmetic, reading their state (with exception to protected deposit and withdraw).
115        /// Storing this as a `KeyValueStore` only to later read the entire KVStore is pointless.
116        ///
117        /// Also, while protected deposits and withdraws _technically_ do not need to read the entire
118        /// map of vaults they realistically do since the caller needs to know the balances to do the
119        /// arithmetic they need prior to doing a deposit or withdraw. Thus, these two methods are in
120        /// a realistic setting need to read that state.
121        ///
122        /// Additionally, size should not be a serious concern for any realistic application. The vaults
123        /// map in a pool of 10 resources is just 605 bytes with 20 resources its 1205 bytes which is
124        /// still reasonable. Note that most applications that would use a pool of this kind might be
125        /// balancer-esc applications where the maximum number of tokens a pool can hold is 8; thus
126        /// there is no concern that this map would become too big.
127        ///
128        /// Finally, when using this resource pool as part of a dApp all that the dApp would store is a
129        /// reference to the pool. In other words, if the dApp has a method that does not interact with
130        /// the pool, it is not in any way affected by how the pool stores the vaults; cost units and
131        /// fees do not come into the picture there.
132        pub vaults: IndexMap<ResourceAddress, Vault>,
133
134        /// The resource manager of the pool unit resource that the pool works with.
135        pub pool_unit_resource_manager: ResourceManager,
136    }
137}