I am working developing Soroswap.Finance, an AMM in Soroban and we write our Smart Contracts based on the UniswapV2 Smart Contracts written in Solidity.
In Solidity we can write an smart contract, deploy it and use it as an smart contract and also use the same code as a library, so another smart contract can inherit its logic.
Common usage is:
contract MyContract is ContractFather
Another usage is to use a Solidity library like:
import './libraries/UniswapV2Library.sol';
...
// and then use the library like:
uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB);
How can we do something similar with rust and soroban-sdk?
The Library Contract
I wrote the SoroswapLibrary Smart Contract and it was working perfectly: Here is the code I had at the moment:
https://github.com/soroswap/core/tree/c65cebcfe69f05b38567158610dab25a941d4e6a/contracts/library
Publishing into crates.io
In order to transform this "pure" Smart Contract into a Library that can be imported by another Smart Contract I did the following:
1.- Edit the Cargo.toml to add some information necessary to publish into crates.io
[package]
name = "soroswap-library"
version = "0.1.1"
description = "Library that enables efficient and optimized code execution across different contracts on the Soroswap.Finance protocol"
homepage = "https://github.com/soroswap/core/tree/main/contracts/library"
repository = "https://github.com/soroswap/core/tree/main/contracts/library"
authors = ["esteblock <esteblock@paltalabs.io>"]
readme = "README.md"
license = "GPL-3.0"
edition = "2021"
keywords = ["no_std", "wasm", "soroswap", "amm", "soroban"]
rust-version = "1.73"
publish = true
2.- Create an account in crates.io and login
cargo login
3.- Publish:
cargo publish
If everything goes well, your contract will be published in crates.io and you can use it
Importing it into your code:
In my Router contract I can use it as a library, editing Cargo.toml
[dependencies]
soroban-sdk = { version = "20.0.0-rc2" }
num-integer = { version = "0.1.45", default-features = false, features = ["i128"] }
soroswap-library = "0.1.1"
And I should be able to use it inside my lib.rs
as
use soroswap_library;
The "no external crate" error
When I complile the Router
contract I had the following error:
error[E0432]: unresolved import `soroswap_library`
--> src/lib.rs:9:5
|
9 | use soroswap_library;
| ^^^^^^^^^^^^^^^^ no external crate `soroswap_library`
Very strange... But I found that I could solve it, adding the rlib
crate type in the library contract... So it stays like this:
[lib]
crate-type = ["cdylib", "rlib"]
Moving out your desired functions.
Also, in order to use a function as a crate library, you'll need to move them out from the contract Trait... and re-export them:
In my case, the Library's lib.rs
has:
mod test;
mod tokens;
mod reserves;
mod quotes;
pub use tokens::{
sort_tokens,
pair_for
};
pub use reserves::{
get_reserves
};
pub use quotes::{
quote,
get_amount_out,
get_amount_in,
get_amounts_out,
get_amounts_in
};
Check the final code here: https://github.com/soroswap/core/tree/main/contracts/library
Using the library
With this change (and of course after publishing a new version of the library in crates.io), I could use in my Router
use soroswap_library;
// and then
let amount_b_optimal = soroswap_library::quote(amount_a_desired.clone(), reserve_a.clone(), reserve_b.clone());
Top comments (1)
Hey, fantastic post !! Thanks!