soroswap_library/
lib.rs

1#![no_std] 
2use soroban_sdk::{
3    contract, contractimpl,
4    Address, Env, Vec, 
5};
6
7mod test;
8mod tokens;
9mod reserves;
10mod quotes;
11mod error;
12mod math;
13
14
15pub use tokens::{
16    sort_tokens,
17    pair_for
18};
19pub use reserves::{
20    get_reserves_with_factory,
21    get_reserves_with_pair
22};
23pub use quotes::{
24    quote, 
25    get_amount_out, 
26    get_amount_in, 
27    get_amounts_out, 
28    get_amounts_in
29};
30pub use error::SoroswapLibraryError;
31
32
33
34
35
36pub trait SoroswapLibraryTrait {
37    
38    /// Sorts two token addresses in a consistent order.
39    ///
40    /// # Arguments
41    ///
42    /// * `token_a` - The address of the first token.
43    /// * `token_b` - The address of the second token.
44    ///
45    /// # Returns
46    ///
47    /// Returns `Result<(Address, Address), SoroswapLibraryError>` where `Ok` contains a tuple with the sorted token addresses, and `Err` indicates an error such as identical tokens.
48    fn sort_tokens(token_a: Address, token_b: Address) -> Result<(Address, Address), SoroswapLibraryError>;
49
50    /// Calculates the deterministic address for a pair without making any external calls.
51    /// check <https://github.com/paltalabs/deterministic-address-soroban>
52    ///
53    /// # Arguments
54    ///
55    /// * `e` - The environment.
56    /// * `factory` - The factory address.
57    /// * `token_a` - The address of the first token.
58    /// * `token_b` - The address of the second token.
59    ///
60    /// # Returns
61    ///
62    /// Returns `Result<Address, SoroswapLibraryError>` where `Ok` contains the deterministic address for the pair, and `Err` indicates an error such as identical tokens or an issue with sorting.
63    fn pair_for(e: Env, factory: Address, token_a: Address, token_b: Address) -> Result<Address, SoroswapLibraryError>;
64
65    /// Fetches and sorts the reserves for a pair of tokens.
66    ///
67    /// # Arguments
68    ///
69    /// * `e` - The environment.
70    /// * `factory` - The factory address.
71    /// * `token_a` - The address of the first token.
72    /// * `token_b` - The address of the second token.
73    ///
74    /// # Returns
75    ///
76    /// Returns `Result<(i128, i128), SoroswapLibraryError>` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting.
77    fn get_reserves_with_factory(e: Env,factory: Address, token_a: Address, token_b: Address) -> Result<(i128, i128), SoroswapLibraryError>;
78
79    /// Fetches and sorts the reserves for a pair of tokens knowing the pair address
80    ///
81    /// # Arguments
82    ///
83    /// * `e` - The environment.
84    /// * `pair` - The pair address.
85    /// * `token_a` - The address of the first token.
86    /// * `token_b` - The address of the second token.
87    ///
88    /// # Returns
89    ///
90    /// Returns `Result<(i128, i128), SoroswapLibraryError>` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting.
91    fn get_reserves_with_pair(e: Env, pair: Address, token_a: Address, token_b: Address) -> Result<(i128, i128), SoroswapLibraryError>;
92
93    /// Given some amount of an asset and pair reserves, returns an equivalent amount of the other asset.
94    ///
95    /// # Arguments
96    ///
97    /// * `amount_a` - The amount of the first asset.
98    /// * `reserve_a` - Reserves of the first asset in the pair.
99    /// * `reserve_b` - Reserves of the second asset in the pair.
100    ///
101    /// # Returns
102    ///
103    /// Returns `Result<i128, SoroswapLibraryError>` where `Ok` contains the calculated equivalent amount, and `Err` indicates an error such as insufficient amount or liquidity
104    fn quote(amount_a: i128, reserve_a: i128, reserve_b: i128) -> Result<i128, SoroswapLibraryError>;
105
106    /// Given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset.
107    ///
108    /// # Arguments
109    ///
110    /// * `amount_in` - The input amount of the asset.
111    /// * `reserve_in` - Reserves of the input asset in the pair.
112    /// * `reserve_out` - Reserves of the output asset in the pair.
113    ///
114    /// # Returns
115    ///
116    /// Returns `Result<i128, SoroswapLibraryError>` where `Ok` contains the calculated maximum output amount, and `Err` indicates an error such as insufficient input amount or liquidity.
117    fn get_amount_out(amount_in: i128, reserve_in: i128, reserve_out: i128) -> Result<i128, SoroswapLibraryError>;
118
119    /// Given an output amount of an asset and pair reserves, returns a required input amount of the other asset.
120    ///
121    /// # Arguments
122    ///
123    /// * `amount_out` - The output amount of the asset.
124    /// * `reserve_in` - Reserves of the input asset in the pair.
125    /// * `reserve_out` - Reserves of the output asset in the pair.
126    ///
127    /// # Returns
128    ///
129    /// Returns `Result<i128, SoroswapLibraryError>` where `Ok` contains the required input amount, and `Err` indicates an error such as insufficient output amount or liquidity.
130    fn get_amount_in(amount_out: i128, reserve_in: i128, reserve_out: i128) -> Result<i128, SoroswapLibraryError>;
131
132    /// Performs chained get_amount_out calculations on any number of pairs.
133    ///
134    /// # Arguments
135    ///
136    /// * `e` - The environment.
137    /// * `factory` - The factory address.
138    /// * `amount_in` - The input amount.
139    /// * `path` - Vector of token addresses representing the path.
140    ///
141    /// # Returns
142    ///
143    /// Returns `Result<Vec<i128>, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path.
144    fn get_amounts_out(e: Env, factory: Address, amount_in: i128, path: Vec<Address>) -> Result<Vec<i128>, SoroswapLibraryError>;
145    
146    /// Performs chained get_amount_in calculations on any number of pairs.
147    ///
148    /// # Arguments
149    ///
150    /// * `e` - The environment.
151    /// * `factory` - The factory address.
152    /// * `amount_out` - The output amount.
153    /// * `path` - Vector of token addresses representing the path.
154    ///
155    /// # Returns
156    ///
157    /// Returns `Result<Vec<i128>, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path.
158    fn get_amounts_in(e: Env, factory: Address, amount_out: i128, path: Vec<Address>) -> Result<Vec<i128>, SoroswapLibraryError>;
159    
160
161
162   
163}
164
165#[contract]
166pub struct SoroswapLibrary;
167
168#[contractimpl]
169impl SoroswapLibraryTrait for SoroswapLibrary {
170
171    /// Sorts two token addresses in a consistent order.
172    ///
173    /// # Arguments
174    ///
175    /// * `token_a` - The address of the first token.
176    /// * `token_b` - The address of the second token.
177    ///
178    /// # Returns
179    ///
180    /// Returns `Result<(Address, Address), SoroswapLibraryError>` where `Ok` contains a tuple with the sorted token addresses, and `Err` indicates an error such as identical tokens.
181    fn sort_tokens(token_a: Address, token_b: Address) ->  Result<(Address, Address), SoroswapLibraryError> {
182        sort_tokens(token_a, token_b)
183    }
184
185
186    /// Calculates the deterministic address for a pair without making any external calls.
187    /// check <https://github.com/paltalabs/deterministic-address-soroban>
188    ///
189    /// # Arguments
190    ///
191    /// * `e` - The environment.
192    /// * `factory` - The factory address.
193    /// * `token_a` - The address of the first token.
194    /// * `token_b` - The address of the second token.
195    ///
196    /// # Returns
197    ///
198    /// Returns `Result<Address, SoroswapLibraryError>` where `Ok` contains the deterministic address for the pair, and `Err` indicates an error such as identical tokens or an issue with sorting.
199    fn pair_for(e: Env, factory: Address, token_a: Address, token_b: Address) -> Result<Address, SoroswapLibraryError> {
200        pair_for(e, factory, token_a, token_b)
201    }
202
203
204    /// Fetches and sorts the reserves for a pair of tokens using the factory address.
205    ///
206    /// # Arguments
207    ///
208    /// * `e` - The environment.
209    /// * `factory` - The factory address.
210    /// * `token_a` - The address of the first token.
211    /// * `token_b` - The address of the second token.
212    ///
213    /// # Returns
214    ///
215    /// Returns `Result<(i128, i128), SoroswapLibraryError>` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting.
216    fn get_reserves_with_factory(e: Env,factory: Address, token_a: Address, token_b: Address) -> Result<(i128, i128), SoroswapLibraryError> {
217        get_reserves_with_factory(e, factory, token_a, token_b)
218
219    }
220
221    /// Fetches and sorts the reserves for a pair of tokens using the pair address.
222    ///
223    /// # Arguments
224    ///
225    /// * `e` - The environment.
226    /// * `pair` - The pair address.
227    /// * `token_a` - The address of the first token.
228    /// * `token_b` - The address of the second token.
229    ///
230    /// # Returns
231    ///
232    /// Returns `Result<(i128, i128), SoroswapLibraryError>` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting.
233    fn get_reserves_with_pair(e: Env,pair: Address, token_a: Address, token_b: Address) -> Result<(i128, i128), SoroswapLibraryError> {
234        get_reserves_with_pair(e, pair, token_a, token_b)
235
236    }
237
238    /// Given some amount of an asset and pair reserves, returns an equivalent amount of the other asset.
239    ///
240    /// # Arguments
241    ///
242    /// * `amount_a` - The amount of the first asset.
243    /// * `reserve_a` - Reserves of the first asset in the pair.
244    /// * `reserve_b` - Reserves of the second asset in the pair.
245    ///
246    /// # Returns
247    ///
248    /// Returns `Result<i128, SoroswapLibraryError>` where `Ok` contains the calculated equivalent amount, and `Err` indicates an error such as insufficient amount or liquidity
249    fn quote(amount_a: i128, reserve_a: i128, reserve_b: i128) -> Result<i128, SoroswapLibraryError> {
250        quote(amount_a, reserve_a, reserve_b)
251    }
252    
253
254    /// Given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset.
255    ///
256    /// # Arguments
257    ///
258    /// * `amount_in` - The input amount of the asset.
259    /// * `reserve_in` - Reserves of the input asset in the pair.
260    /// * `reserve_out` - Reserves of the output asset in the pair.
261    ///
262    /// # Returns
263    ///
264    /// Returns `Result<i128, SoroswapLibraryError>` where `Ok` contains the calculated maximum output amount, and `Err` indicates an error such as insufficient input amount or liquidity.
265    fn get_amount_out(amount_in: i128, reserve_in: i128, reserve_out: i128) -> Result<i128, SoroswapLibraryError> {
266        get_amount_out(amount_in, reserve_in, reserve_out)
267    }
268
269    /// Given an output amount of an asset and pair reserves, returns a required input amount of the other asset.
270    ///
271    /// # Arguments
272    ///
273    /// * `amount_out` - The output amount of the asset.
274    /// * `reserve_in` - Reserves of the input asset in the pair.
275    /// * `reserve_out` - Reserves of the output asset in the pair.
276    ///
277    /// # Returns
278    ///
279    /// Returns `Result<i128, SoroswapLibraryError>` where `Ok` contains the required input amount, and `Err` indicates an error such as insufficient output amount or liquidity.
280    fn get_amount_in(amount_out: i128, reserve_in: i128, reserve_out: i128) -> Result<i128, SoroswapLibraryError> {
281        get_amount_in(amount_out, reserve_in, reserve_out)
282    }
283
284    /// Performs chained get_amount_out calculations on any number of pairs.
285    ///
286    /// # Arguments
287    ///
288    /// * `e` - The environment.
289    /// * `factory` - The factory address.
290    /// * `amount_in` - The input amount.
291    /// * `path` - Vector of token addresses representing the path.
292    ///
293    /// # Returns
294    ///
295    /// Returns `Result<Vec<i128>, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path.
296    fn get_amounts_out(e: Env, factory: Address, amount_in: i128, path: Vec<Address>) -> Result<Vec<i128>, SoroswapLibraryError> {
297        get_amounts_out(e, factory, amount_in, path)
298    }
299
300    /// Performs chained get_amount_in calculations on any number of pairs.
301    ///
302    /// # Arguments
303    ///
304    /// * `e` - The environment.
305    /// * `factory` - The factory address.
306    /// * `amount_out` - The output amount.
307    /// * `path` - Vector of token addresses representing the path.
308    ///
309    /// # Returns
310    ///
311    /// Returns `Result<Vec<i128>, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path.
312    fn get_amounts_in(e: Env, factory: Address, amount_out: i128, path: Vec<Address>) -> Result<Vec<i128>, SoroswapLibraryError> {
313        get_amounts_in(e, factory, amount_out, path)
314    }
315
316
317
318}