-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: set v1 WASMs in a blend-contract-sdk and share build method
Showing
26 changed files
with
338 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
name: Cargo Publish | ||
|
||
on: | ||
release: | ||
types: [published] | ||
|
||
jobs: | ||
|
||
publish: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- run: rustup update | ||
- run: cargo publish -p blend-contract-sdk | ||
env: | ||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[package] | ||
name = "blend-contract-sdk" | ||
version = "1.0.0" | ||
description = "Traits, clients, types, and WASMs for the Blend Protocol for use in Soroban contract development." | ||
homepage = "https://github.com/blend-capital/blend-contracts" | ||
repository = "https://github.com/blend-capital/blend-contracts" | ||
license = "MIT" | ||
edition = "2021" | ||
readme = "README.md" | ||
keywords = ["no_std", "wasm", "soroban"] | ||
|
||
[lib] | ||
crate-type = ["cdylib", "rlib"] | ||
doctest = false | ||
|
||
[features] | ||
testutils = [ | ||
"soroban-sdk/testutils", | ||
] | ||
|
||
[dependencies] | ||
soroban-sdk = { workspace = true } | ||
|
||
[dev_dependencies] | ||
soroban-sdk = { workspace = true, features = ["testutils"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# Blend Contract SDK | ||
|
||
This repository contains interfaces, clients, and WASM blobs for the Blend Protocol as implemented in the [Blend Contracts](https://github.com/blend-capital/blend-contracts) repository. | ||
|
||
## Documentation | ||
|
||
To learn more about the Blend Protocol, visit the the docs: | ||
* [Blend Docs](https://docs.blend.capital/) | ||
|
||
## Modules | ||
|
||
The Blend Contract SDK generates modules from the `contractimport` [Soroban SDK macro](). Each module exposes a Client, WASM, and the respective types needed to interact with the Blend Protocol. The following Blend contracts are exposed as a module: | ||
|
||
* `backstop` - Contract import for the backstop contract | ||
* `emitter`- Contract import for the emitter contract | ||
* `pool` - Contract import for the pool contract | ||
* `pool_factory` - Contract import for the pool factory contract | ||
|
||
## Testing (testutils) | ||
|
||
### External Dependencies | ||
|
||
The Blend Contract SDK includes `contractimport`'s of the [Comet Contracts](https://github.com/CometDEX/comet-contracts) when compiled for test purposes via the `testutils` feature. | ||
|
||
This includes: | ||
* `comet` - Contract import for the comet pool contract | ||
* `comet_factory` - Contract import for the comet pool factory contract | ||
|
||
NOTE: These contracts were used for testing the Blend Protocol and should not be considered to be the latest version of the Comet Protocol. Please verify any non-test usage of the Comet contracts against the [Comet GitHub](https://github.com/CometDEX/comet-contracts). | ||
|
||
### Setup | ||
|
||
The `testutils` module allows for easy deployment of Blend Contracts to be used in a unit test. The following example shows how to use the `testutils` to deploy a set of Blend Contracts and set up a pool. | ||
|
||
If you require using the pool, please look at the following [sep-41-oracle]() crate to deploy a mock oracle contract: | ||
|
||
```rust | ||
use soroban_sdk::{symbol_short, testutils::{Address as _, BytesN as _}, Address, BytesN, Env}; | ||
|
||
use blend_contract_sdk::{pool, testutils::{default_reserve_config, BlendFixture}}; | ||
|
||
let env = Env::default(); | ||
let deployer = Address::generate(&env); | ||
let blnd = env.register_stellar_asset_contract(deployer.clone()); | ||
let usdc = env.register_stellar_asset_contract(deployer.clone()); | ||
let blend = BlendFixture::deploy(&env, &deployer, &blnd, &usdc); | ||
|
||
let token = env.register_stellar_asset_contract(deployer.clone()); | ||
let pool = blend.pool_factory.mock_all_auths().deploy( | ||
&deployer, | ||
&symbol_short!("test"), | ||
&BytesN::<32>::random(&env), | ||
&Address::generate(&env), | ||
&0_1000000, // 10% | ||
&4, // 4 max positions | ||
); | ||
let pool_client = pool::Client::new(&env, &pool); | ||
let reserve_config = default_reserve_config(); | ||
pool_client.mock_all_auths().queue_set_reserve(&token, &reserve_config); | ||
pool_client.mock_all_auths().set_reserve(&token); | ||
|
||
blend.backstop.mock_all_auths().deposit(&deployer, &pool, &50_000_0000000); | ||
pool_client.mock_all_auths().set_status(&3); // remove pool from setup status | ||
pool_client.mock_all_auths().update_status(); // update status based on backstop | ||
``` | ||
|
||
## WASM Verification | ||
|
||
The WASM files included will align with the GitHub release the SDK was published with (the version numbers will match). The WASM files were generated with the Makefile. | ||
|
||
Since WASM builds can vary based on factors like OS, here are the details of the machine that built the WASMs included in this package: | ||
|
||
* Ubuntu 22.04.4 LTS | ||
* x86 | ||
* rustc 1.77.1 (7cf61ebde 2024-03-27) | ||
* soroban 20.3.1 (ae5446f63ca8a275e61912019199254d598f3bd5) | ||
* soroban-env 20.2.1 (18a10592853d9edf4e341b565b0b1638f95f0393) | ||
* soroban-env interface version 85899345920 | ||
* stellar-xdr 20.1.0 (8b9d623ef40423a8462442b86997155f2c04d3a1) | ||
* xdr curr (b96148cd4acc372cc9af17b909ffe4b12c43ecb6) | ||
|
||
The SHA256 Checksums: | ||
* backstop - `ac3dfcdbaff35d1b6da24096e2d67486336cd33232cf73682fca3844feb36ebd` | ||
* emitter - `0daab61baabfb15de1f1b23ea1b8ff1744169b45257c9e3fade0cf06c543d813` | ||
* pool_factory - `c93274926c28b7aedd294c3f8eacaa1e407c469419c0055edf4dba6dac87be6b` | ||
* pool - `2609ae9150344ac6b54852b4490493a63ac796620a3f4161912a7358229b9db7` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#![no_std] | ||
|
||
pub mod backstop { | ||
soroban_sdk::contractimport!(file = "./wasm/backstop.wasm"); | ||
} | ||
pub mod emitter { | ||
soroban_sdk::contractimport!(file = "./wasm/emitter.wasm"); | ||
} | ||
pub mod pool_factory { | ||
soroban_sdk::contractimport!(file = "./wasm/pool_factory.wasm"); | ||
} | ||
pub mod pool { | ||
soroban_sdk::contractimport!(file = "./wasm/pool.wasm"); | ||
} | ||
|
||
#[cfg(any(test, feature = "testutils"))] | ||
pub mod testutils; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
use soroban_sdk::{testutils::Address as _, token::StellarAssetClient, vec, Address, Env, Map}; | ||
|
||
use crate::{backstop, emitter, pool, pool_factory}; | ||
|
||
pub mod comet { | ||
soroban_sdk::contractimport!(file = "./wasm/comet.wasm"); | ||
} | ||
|
||
pub mod comet_factory { | ||
soroban_sdk::contractimport!(file = "./wasm/comet_factory.wasm"); | ||
} | ||
|
||
/// Create a "good enough" ReserveConfig for most testing usecases | ||
/// | ||
/// Can be used when creating reserves for a pool. | ||
pub fn default_reserve_config() -> pool::ReserveConfig { | ||
pool::ReserveConfig { | ||
decimals: 7, | ||
c_factor: 0_7500000, | ||
l_factor: 0_7500000, | ||
util: 0_7500000, | ||
max_util: 0_9500000, | ||
r_base: 0_0100000, | ||
r_one: 0_0500000, | ||
r_two: 0_5000000, | ||
r_three: 1_5000000, | ||
reactivity: 0_0000020, // 2e-6 | ||
index: 0, | ||
} | ||
} | ||
|
||
/// Fixture for deploying and interacting with the Blend Protocol contracts in Rust tests. | ||
pub struct BlendFixture<'a> { | ||
pub backstop: backstop::Client<'a>, | ||
pub emitter: emitter::Client<'a>, | ||
pub backstop_token: comet::Client<'a>, | ||
pub pool_factory: pool_factory::Client<'a>, | ||
} | ||
|
||
impl<'a> BlendFixture<'a> { | ||
/// Deploy a new set of Blend Protocol contracts. Mints 200k backstop | ||
/// tokens to the deployer that can be used in the future to create up to 4 | ||
/// reward zone pools (50k tokens each). | ||
/// | ||
/// This function also resets the env budget via `reset_unlimited`. | ||
/// | ||
/// ### Arguments | ||
/// * `env` - The environment to deploy the contracts in | ||
/// * `deployer` - The address of the deployer | ||
/// * `blnd` - The address of the BLND token | ||
/// * `usdc` - The address of the USDC token | ||
pub fn deploy( | ||
env: &Env, | ||
deployer: &Address, | ||
blnd: &Address, | ||
usdc: &Address, | ||
) -> BlendFixture<'a> { | ||
env.budget().reset_unlimited(); | ||
let backstop = env.register_contract_wasm(None, backstop::WASM); | ||
let emitter = env.register_contract_wasm(None, emitter::WASM); | ||
let comet = env.register_contract_wasm(None, comet::WASM); | ||
let pool_factory = env.register_contract_wasm(None, pool_factory::WASM); | ||
let blnd_client = StellarAssetClient::new(env, &blnd); | ||
let usdc_client = StellarAssetClient::new(env, &usdc); | ||
blnd_client | ||
.mock_all_auths() | ||
.mint(deployer, &(1_000_0000000 * 2001)); | ||
usdc_client | ||
.mock_all_auths() | ||
.mint(deployer, &(25_0000000 * 2001)); | ||
|
||
let comet_client: comet::Client<'a> = comet::Client::new(env, &comet); | ||
comet_client | ||
.mock_all_auths() | ||
.init(&Address::generate(env), deployer); | ||
|
||
comet_client.mock_all_auths().bundle_bind( | ||
&vec![env, blnd.clone(), usdc.clone()], | ||
&vec![env, 1_000_0000000, 25_0000000], | ||
&vec![env, 8_0000000, 2_0000000], | ||
); | ||
comet_client | ||
.mock_all_auths() | ||
.set_swap_fee(&30000_i128, deployer); | ||
comet_client | ||
.mock_all_auths() | ||
.set_public_swap(deployer, &true); | ||
comet_client.mock_all_auths().finalize(); | ||
|
||
comet_client.mock_all_auths().join_pool( | ||
&199_900_0000000, // finalize mints 100 | ||
&vec![env, 1_000_0000000 * 2000, 25_0000000 * 2000], | ||
deployer, | ||
); | ||
|
||
blnd_client.mock_all_auths().set_admin(&emitter); | ||
let emitter_client: emitter::Client<'a> = emitter::Client::new(env, &emitter); | ||
emitter_client | ||
.mock_all_auths() | ||
.initialize(&blnd, &backstop, &comet); | ||
|
||
let backstop_client: backstop::Client<'a> = backstop::Client::new(env, &backstop); | ||
backstop_client.mock_all_auths().initialize( | ||
&comet, | ||
&emitter, | ||
&usdc, | ||
&blnd, | ||
&pool_factory, | ||
&Map::new(env), | ||
); | ||
|
||
let pool_hash = env.deployer().upload_contract_wasm(pool::WASM); | ||
|
||
let pool_factory_client = pool_factory::Client::new(env, &pool_factory); | ||
pool_factory_client | ||
.mock_all_auths() | ||
.initialize(&pool_factory::PoolInitMeta { | ||
backstop, | ||
blnd_id: blnd.clone(), | ||
pool_hash, | ||
}); | ||
backstop_client.update_tkn_val(); | ||
|
||
BlendFixture { | ||
backstop: backstop_client, | ||
emitter: emitter_client, | ||
backstop_token: comet_client, | ||
pool_factory: pool_factory_client, | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use soroban_sdk::{ | ||
symbol_short, | ||
testutils::{Address as _, BytesN as _}, | ||
Address, BytesN, Env, | ||
}; | ||
|
||
use crate::{ | ||
pool, | ||
testutils::{default_reserve_config, BlendFixture}, | ||
}; | ||
|
||
#[test] | ||
fn test_deploy() { | ||
let env = Env::default(); | ||
let deployer = Address::generate(&env); | ||
let blnd = env.register_stellar_asset_contract(deployer.clone()); | ||
let usdc = env.register_stellar_asset_contract(deployer.clone()); | ||
let blend = BlendFixture::deploy(&env, &deployer, &blnd, &usdc); | ||
assert_eq!(blend.backstop_token.balance(&deployer), 200_000_0000000); | ||
|
||
// deploy a pool, verify adding reserves, and backstop reward zone | ||
let token = env.register_stellar_asset_contract(deployer.clone()); | ||
let pool = blend.pool_factory.mock_all_auths().deploy( | ||
&deployer, | ||
&symbol_short!("test"), | ||
&BytesN::<32>::random(&env), | ||
&Address::generate(&env), | ||
&0_1000000, // 10% | ||
&4, // 4 max positions | ||
); | ||
let pool_client = pool::Client::new(&env, &pool); | ||
let reserve_config = default_reserve_config(); | ||
pool_client | ||
.mock_all_auths() | ||
.queue_set_reserve(&token, &reserve_config); | ||
pool_client.mock_all_auths().set_reserve(&token); | ||
|
||
blend | ||
.backstop | ||
.mock_all_auths() | ||
.deposit(&deployer, &pool, &50_000_0000000); | ||
pool_client.mock_all_auths().set_status(&3); // remove pool from setup status | ||
pool_client.mock_all_auths().update_status(); | ||
|
||
assert_eq!(pool_client.update_status(), 1); // pool is active | ||
assert!(blend.pool_factory.is_pool(&pool)); // pool factory knows about the pool | ||
} | ||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.