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}