Skip to content

Commit

Permalink
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
Browse files Browse the repository at this point in the history
mootz12 committed Apr 9, 2024
1 parent 5ebc77a commit 36d7fd5
Showing 26 changed files with 338 additions and 71 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/cargo_publish.yml
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 }}
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ resolver = "2"

members = [
"backstop",
"blend-interfaces",
"blend-contract-sdk",
"emitter",
"pool",
"mocks/mock-pool-factory",
@@ -40,6 +40,3 @@ version = "1.0.0"

[workspace.dependencies.sep-41-token]
version = "1.0.0"

[workspace.dependencies.blend-interfaces]
path = "./blend-interfaces"
13 changes: 9 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ test: build
cargo test --all --tests

build:
cargo build -p blend-contract-sdk
cargo rustc --manifest-path=emitter/Cargo.toml --crate-type=cdylib --target=wasm32-unknown-unknown --release
cargo rustc --manifest-path=pool-factory/Cargo.toml --crate-type=cdylib --target=wasm32-unknown-unknown --release
cargo rustc --manifest-path=backstop/Cargo.toml --crate-type=cdylib --target=wasm32-unknown-unknown --release
@@ -35,13 +36,17 @@ clean:
generate-js:
soroban contract bindings typescript --overwrite \
--contract-id CBWH54OKUK6U2J2A4J2REJEYB625NEFCHISWXLOPR2D2D6FTN63TJTWN \
--wasm ./target/wasm32-unknown-unknown/optimized/backstop.wasm --output-dir ./js/js-backstop/
--wasm ./target/wasm32-unknown-unknown/optimized/backstop.wasm --output-dir ./js/js-backstop/ \
--rpc-url http://localhost:8000 --network-passphrase "Standalone Network ; February 2017" --network Standalone
soroban contract bindings typescript --overwrite \
--contract-id CBWH54OKUK6U2J2A4J2REJEYB625NEFCHISWXLOPR2D2D6FTN63TJTWN \
--wasm ./target/wasm32-unknown-unknown/optimized/emitter.wasm --output-dir ./js/js-emitter/
--wasm ./target/wasm32-unknown-unknown/optimized/emitter.wasm --output-dir ./js/js-emitter/ \
--rpc-url http://localhost:8000 --network-passphrase "Standalone Network ; February 2017" --network Standalone
soroban contract bindings typescript --overwrite \
--contract-id CBWH54OKUK6U2J2A4J2REJEYB625NEFCHISWXLOPR2D2D6FTN63TJTWN \
--wasm ./target/wasm32-unknown-unknown/optimized/pool_factory.wasm --output-dir ./js/js-pool-factory/
--wasm ./target/wasm32-unknown-unknown/optimized/pool_factory.wasm --output-dir ./js/js-pool-factory/ \
--rpc-url http://localhost:8000 --network-passphrase "Standalone Network ; February 2017" --network Standalone
soroban contract bindings typescript --overwrite \
--contract-id CBWH54OKUK6U2J2A4J2REJEYB625NEFCHISWXLOPR2D2D6FTN63TJTWN \
--wasm ./target/wasm32-unknown-unknown/optimized/pool.wasm --output-dir ./js/js-pool/
--wasm ./target/wasm32-unknown-unknown/optimized/pool.wasm --output-dir ./js/js-pool/ \
--rpc-url http://localhost:8000 --network-passphrase "Standalone Network ; February 2017" --network Standalone
25 changes: 25 additions & 0 deletions blend-contract-sdk/Cargo.toml
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"] }
86 changes: 86 additions & 0 deletions blend-contract-sdk/README.md
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`
17 changes: 17 additions & 0 deletions blend-contract-sdk/src/lib.rs
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;
182 changes: 182 additions & 0 deletions blend-contract-sdk/src/testutils.rs
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 added blend-contract-sdk/wasm/backstop.wasm
Binary file not shown.
Binary file added blend-contract-sdk/wasm/comet.wasm
Binary file not shown.
Binary file added blend-contract-sdk/wasm/comet_factory.wasm
Binary file not shown.
Binary file added blend-contract-sdk/wasm/emitter.wasm
Binary file not shown.
Binary file added blend-contract-sdk/wasm/pool.wasm
Binary file not shown.
Binary file added blend-contract-sdk/wasm/pool_factory.wasm
Binary file not shown.
Loading

0 comments on commit 36d7fd5

Please sign in to comment.