multiversx_sc_modules/bonding_curve/utils/
owner_endpoints.rs1multiversx_sc::imports!();
2multiversx_sc::derive_imports!();
3
4use multiversx_sc::contract_base::ManagedSerializer;
5
6use crate::bonding_curve::{
7 curves::curve_function::CurveFunction,
8 utils::{
9 events, storage,
10 structs::{BondingCurve, TokenOwnershipData},
11 },
12};
13
14use super::structs::CurveArguments;
15
16#[multiversx_sc::module]
17pub trait OwnerEndpointsModule: storage::StorageModule + events::EventsModule {
18 #[endpoint(setLocalRoles)]
19 fn set_local_roles(
20 &self,
21 address: ManagedAddress,
22 token_identifier: TokenIdentifier,
23 roles: MultiValueEncoded<EsdtLocalRole>,
24 ) {
25 self.send()
26 .esdt_system_sc_proxy()
27 .set_special_roles(&address, &token_identifier, roles.into_iter())
28 .async_call_and_exit()
29 }
30
31 #[endpoint(unsetLocalRoles)]
32 fn unset_local_roles(
33 &self,
34 address: ManagedAddress,
35 token_identifier: TokenIdentifier,
36 roles: MultiValueEncoded<EsdtLocalRole>,
37 ) {
38 self.send()
39 .esdt_system_sc_proxy()
40 .unset_special_roles(&address, &token_identifier, roles.into_iter())
41 .async_call_and_exit()
42 }
43
44 fn set_bonding_curve<T>(
45 &self,
46 identifier: TokenIdentifier,
47 function: T,
48 sell_availability: bool,
49 ) where
50 T: CurveFunction<Self::Api>
51 + TopEncode
52 + TopDecode
53 + NestedEncode
54 + NestedDecode
55 + TypeAbi
56 + PartialEq
57 + Default,
58 {
59 require!(
60 !self.token_details(&identifier).is_empty(),
61 "Token is not issued yet!"
62 );
63
64 let caller = self.blockchain().get_caller();
65
66 let details = self.token_details(&identifier).get();
67 require!(
68 details.owner == caller,
69 "The price function can only be set by the seller."
70 );
71 self.bonding_curve(&identifier).update(|buffer| {
72 let serializer = ManagedSerializer::new();
73
74 let mut bonding_curve: BondingCurve<Self::Api, T> =
75 serializer.top_decode_from_managed_buffer(buffer);
76 bonding_curve.curve = function;
77 bonding_curve.sell_availability = sell_availability;
78 *buffer = serializer.top_encode_to_managed_buffer(&bonding_curve);
79 });
80 }
81
82 fn deposit<T>(&self, payment_token: OptionalValue<TokenIdentifier>)
83 where
84 T: CurveFunction<Self::Api>
85 + TopEncode
86 + TopDecode
87 + NestedEncode
88 + NestedDecode
89 + TypeAbi
90 + PartialEq
91 + Default,
92 {
93 let esdt_payment = self.call_value().single_esdt();
94 let identifier = &esdt_payment.token_identifier;
95 let nonce = esdt_payment.token_nonce;
96 let amount = &esdt_payment.amount;
97 let caller = self.blockchain().get_caller();
98 let mut set_payment = EgldOrEsdtTokenIdentifier::egld();
99
100 if self.bonding_curve(identifier).is_empty() {
101 match payment_token {
102 OptionalValue::Some(token) => set_payment = EgldOrEsdtTokenIdentifier::esdt(token),
103 OptionalValue::None => {
104 sc_panic!("Expected provided accepted_payment for the token");
105 },
106 };
107 }
108 if self.token_details(identifier).is_empty() {
109 let nonces = ManagedVec::from_single_item(nonce);
110 self.token_details(identifier).set(&TokenOwnershipData {
111 token_nonces: nonces,
112 owner: caller.clone(),
113 });
114 } else {
115 let mut details = self.token_details(identifier).get();
116 require!(
117 details.owner == caller,
118 "The token was already deposited by another address"
119 );
120 if !details.token_nonces.contains(&nonce) {
121 details.token_nonces.push(nonce);
122 self.token_details(identifier).set(&details);
123 }
124 }
125
126 self.set_curve_storage::<T>(identifier, amount.clone(), set_payment);
127 self.owned_tokens(&caller).insert(identifier.clone());
128 self.nonce_amount(identifier, nonce)
129 .update(|current_amount| *current_amount += amount);
130 }
131
132 fn claim<T>(&self)
133 where
134 T: CurveFunction<Self::Api>
135 + TopEncode
136 + TopDecode
137 + NestedEncode
138 + NestedDecode
139 + TypeAbi
140 + PartialEq
141 + Default,
142 {
143 let caller = self.blockchain().get_caller();
144 require!(
145 !self.owned_tokens(&caller).is_empty(),
146 "You have nothing to claim"
147 );
148
149 let mut tokens_to_claim = ManagedVec::<Self::Api, EsdtTokenPayment<Self::Api>>::new();
150 let mut egld_to_claim = BigUint::zero();
151 let serializer = ManagedSerializer::new();
152 for token in self.owned_tokens(&caller).iter() {
153 let nonces = self.token_details(&token).get().token_nonces;
154 for nonce in &nonces {
155 tokens_to_claim.push(EsdtTokenPayment::new(
156 token.clone(),
157 nonce,
158 self.nonce_amount(&token, nonce).get(),
159 ));
160
161 self.nonce_amount(&token, nonce).clear();
162 }
163
164 let bonding_curve: BondingCurve<Self::Api, T> =
165 serializer.top_decode_from_managed_buffer(&self.bonding_curve(&token).get());
166
167 if let Some(esdt_token_identifier) =
168 bonding_curve.payment.token_identifier.into_esdt_option()
169 {
170 tokens_to_claim.push(EsdtTokenPayment::new(
171 esdt_token_identifier,
172 bonding_curve.payment.token_nonce,
173 bonding_curve.payment.amount,
174 ));
175 } else {
176 egld_to_claim += bonding_curve.payment.amount;
177 }
178
179 self.token_details(&token).clear();
180 self.bonding_curve(&token).clear();
181 }
182 self.owned_tokens(&caller).clear();
183 self.tx().to(&caller).multi_esdt(tokens_to_claim).transfer();
184 if egld_to_claim > BigUint::zero() {
185 self.tx().to(&caller).egld(&egld_to_claim).transfer();
186 }
187 }
188
189 fn set_curve_storage<T>(
190 &self,
191 identifier: &TokenIdentifier,
192 amount: BigUint,
193 payment_token_identifier: EgldOrEsdtTokenIdentifier,
194 ) where
195 T: CurveFunction<Self::Api>
196 + TopEncode
197 + TopDecode
198 + NestedEncode
199 + NestedDecode
200 + TypeAbi
201 + PartialEq
202 + Default,
203 {
204 let mut curve: T = T::default();
205 let mut arguments;
206 let payment;
207 let sell_availability: bool;
208 let serializer = ManagedSerializer::new();
209
210 if self.bonding_curve(identifier).is_empty() {
211 arguments = CurveArguments {
212 available_supply: amount.clone(),
213 balance: amount,
214 };
215 payment = EgldOrEsdtTokenPayment::new(payment_token_identifier, 0, BigUint::zero());
216 sell_availability = false;
217 } else {
218 let bonding_curve: BondingCurve<Self::Api, T> =
219 serializer.top_decode_from_managed_buffer(&self.bonding_curve(identifier).get());
220
221 payment = bonding_curve.payment;
222 curve = bonding_curve.curve;
223 arguments = bonding_curve.arguments;
224 arguments.balance += &amount;
225 arguments.available_supply += amount;
226 sell_availability = bonding_curve.sell_availability;
227 }
228 let encoded_curve = serializer.top_encode_to_managed_buffer(&BondingCurve {
229 curve,
230 arguments,
231 sell_availability,
232 payment,
233 });
234 self.bonding_curve(identifier).set(encoded_curve);
235 }
236}