Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions contracts/locked_in/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ soroban-sdk = "23.0.3"
stellar-xdr = { version = "23.0.0", features = ["curr", "serde"] }
soroban-sdk = { version = "23.0.3", features = ["testutils"] }
mock_pool = { path = "../mock_pool" }
test_utils = { path = "../test_utils" }
8 changes: 3 additions & 5 deletions contracts/locked_in/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use super::*;
use mock_pool::{MockPool, MockPoolClient};
use soroban_sdk::testutils::{Address as _, Ledger};
use soroban_sdk::{token::StellarAssetClient, Env};
use test_utils::{create_token_contract, mint_tokens};

const ONE_YEAR: u64 = 31_536_000;

Expand All @@ -29,11 +30,8 @@ fn setup() -> (Env, Address, Address, Address, LockedInClient<'static>) {
let admin = Address::generate(&env);
let user = Address::generate(&env);

let issuer = Address::generate(&env);
let asset = env.register_stellar_asset_contract_v2(issuer);
let token_addr = asset.address();
let token_admin = StellarAssetClient::new(&env, &token_addr);
token_admin.mint(&user, &10_000_000_000_i128); // 1000 USDC
let (token_addr, token) = create_token_contract(&env, &admin);
mint_tokens(&env, &token, &user, 10_000_000_000_i128); // 1000 USDC

let contract_id = env.register(LockedIn, (admin.clone(), token_addr.clone()));
let client = LockedInClient::new(&env, &contract_id);
Expand Down
1 change: 1 addition & 0 deletions contracts/mock_pool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ soroban-sdk = "23.0.3"
[dev-dependencies]
stellar-xdr = { version = "23.0.0", features = ["curr", "serde"] }
soroban-sdk = { version = "23.0.3", features = ["testutils"] }
test_utils = { path = "../test_utils" }
25 changes: 18 additions & 7 deletions contracts/mock_pool/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ extern crate std;

use super::*;
use soroban_sdk::testutils::{Address as _, Ledger};
use soroban_sdk::{token::StellarAssetClient, Env};
use soroban_sdk::Env;
use test_utils::{assert_solvable, create_token_contract, mint_tokens};

const SECONDS_PER_YEAR_U64: u64 = 31_536_000;

Expand All @@ -15,12 +16,9 @@ fn setup() -> (Env, Address, Address, Address, MockPoolClient<'static>) {
let admin = Address::generate(&env);
let supplier = Address::generate(&env);

let issuer = Address::generate(&env);
let asset = env.register_stellar_asset_contract_v2(issuer.clone());
let token_addr = asset.address();
let token_admin = StellarAssetClient::new(&env, &token_addr);
token_admin.mint(&supplier, &10_000_000_000_i128); // 1000 USDC (7 decimals)
token_admin.mint(&admin, &10_000_000_000_i128); // 1000 USDC for the reserve
let (token_addr, token) = create_token_contract(&env, &admin);
mint_tokens(&env, &token, &supplier, 10_000_000_000_i128); // 1000 USDC (7 decimals)
mint_tokens(&env, &token, &admin, 10_000_000_000_i128); // 1000 USDC for the reserve

// 10% APY (1000 bps)
let contract_id = env.register(MockPool, (admin.clone(), token_addr.clone(), 1000u32));
Expand All @@ -37,6 +35,19 @@ fn test_supply_records_principal() {
assert_eq!(client.get_position(&supplier), 1_000_000_000); // no time elapsed yet
}

#[test]
fn test_multiple_users_remain_solvable() {
let (env, _admin, supplier, token_addr, client) = setup();
let second = Address::generate(&env);
let token = soroban_sdk::token::TokenClient::new(&env, &token_addr);
mint_tokens(&env, &token, &second, 1_000_000_000);

client.supply(&supplier, &1_000_000_000);
client.supply(&second, &1_000_000_000);

assert_solvable(&env, &token_addr, &client.address, 2_000_000_000);
}

#[test]
fn test_yield_accrues_linearly() {
let (env, _admin, supplier, _t, client) = setup();
Expand Down
1 change: 1 addition & 0 deletions contracts/plans/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ soroban-sdk = "23.0.3"
[dev-dependencies]
stellar-xdr = { version = "23.0.0", features = ["curr", "serde"] }
soroban-sdk = { version = "23.0.3", features = ["testutils"] }
test_utils = { path = "../test_utils" }
37 changes: 4 additions & 33 deletions contracts/plans/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
#![cfg(test)]
extern crate std;

use super::*;
use soroban_sdk::{
testutils::{Address as _, Ledger, LedgerInfo},
token::{StellarAssetClient, TokenClient},
Address, Env, String, Vec,
};

// Test token setup helper
fn create_token_contract<'a>(env: &Env, admin: &Address) -> (Address, TokenClient<'a>) {
let stellar_asset = env.register_stellar_asset_contract_v2(admin.clone());
let token_address = stellar_asset.address();
let token = TokenClient::new(env, &token_address);
(token_address, token)
}
use soroban_sdk::{testutils::Address as _, Address, Env, String, Vec};
use test_utils::{create_token_contract, mint_tokens, set_ledger_time};

// Contract setup helper
fn create_plans_contract<'a>(
Expand All @@ -26,25 +16,6 @@ fn create_plans_contract<'a>(
client
}

// Helper to mint tokens to a user
fn mint_tokens(env: &Env, token: &TokenClient, to: &Address, amount: i128) {
let stellar_asset = StellarAssetClient::new(env, &token.address);
stellar_asset.mint(to, &amount);
}

// Helper to set ledger time
fn set_ledger_time(env: &Env, timestamp: u64, sequence: u32) {
env.ledger().set(LedgerInfo {
timestamp,
protocol_version: 23,
sequence_number: sequence,
network_id: Default::default(),
base_reserve: 10,
min_temp_entry_ttl: 10,
min_persistent_entry_ttl: 10,
max_entry_ttl: 3110400,
});
}

#[test]
fn test_initialization() {
Expand Down Expand Up @@ -782,4 +753,4 @@ fn test_recurring_bill_with_recurrence_calendar() {
let bill = client.get_bill(&bill_id);
assert_eq!(bill.is_recurring, true);
assert_eq!(bill.recurrence_calendar.len(), 3);
}
}
1 change: 1 addition & 0 deletions contracts/spend_save/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ soroban-sdk = "23.0.3"
[dev-dependencies]
stellar-xdr = { version = "23.0.0", features = ["curr", "serde"] }
soroban-sdk = { version = "23.0.3", features = ["testutils"] }
test_utils = { path = "../test_utils" }
10 changes: 4 additions & 6 deletions contracts/spend_save/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ extern crate std;

use super::*;
use soroban_sdk::testutils::{Address as _, Ledger};
use soroban_sdk::{token::StellarAssetClient, Env};
use soroban_sdk::Env;
use test_utils::{create_token_contract, mint_tokens};

const SECONDS_PER_DAY: u64 = 86_400;

Expand All @@ -19,11 +20,8 @@ fn setup_at(ts: u64) -> (Env, Address, Address, Address, SpendSaveClient<'static

let admin = Address::generate(&env);
let user = Address::generate(&env);
let issuer = Address::generate(&env);
let asset = env.register_stellar_asset_contract_v2(issuer);
let token_addr = asset.address();
let token_admin = StellarAssetClient::new(&env, &token_addr);
token_admin.mint(&user, &10_000_000_000_i128); // 1000 USDC
let (token_addr, token) = create_token_contract(&env, &admin);
mint_tokens(&env, &token, &user, 10_000_000_000_i128); // 1000 USDC

let contract_id = env.register(SpendSave, (admin.clone(), token_addr.clone()));
let client = SpendSaveClient::new(&env, &contract_id);
Expand Down
1 change: 1 addition & 0 deletions contracts/target_savings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ soroban-sdk = "23.0.3"
stellar-xdr = { version = "23.0.0", features = ["curr", "serde"] }
soroban-sdk = { version = "23.0.3", features = ["testutils"] }
mock_pool = { path = "../mock_pool" }
test_utils = { path = "../test_utils" }
10 changes: 3 additions & 7 deletions contracts/target_savings/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use super::*;
use mock_pool::{MockPool, MockPoolClient};
use soroban_sdk::testutils::{Address as _, Ledger};
use soroban_sdk::{token::StellarAssetClient, Env, String};
use test_utils::{create_token_contract, mint_tokens};

const PERIOD_WEEK: u64 = 604_800;
const ONE_YEAR: u64 = 31_536_000;
Expand All @@ -31,13 +32,8 @@ fn setup() -> (Env, Address, Address, Address, TargetSavingsClient<'static>) {
let user = Address::generate(&env);

// Stellar Asset Contract for the test token
let issuer = Address::generate(&env);
let asset = env.register_stellar_asset_contract_v2(issuer.clone());
let token_addr = asset.address();
let token_admin = StellarAssetClient::new(&env, &token_addr);

// Mint some USDC to the user
token_admin.mint(&user, &10_000_000_000_i128); // 1000 USDC (7 decimals)
let (token_addr, token) = create_token_contract(&env, &admin);
mint_tokens(&env, &token, &user, 10_000_000_000_i128); // 1000 USDC (7 decimals)

let contract_id = env.register(TargetSavings, (admin.clone(), token_addr.clone()));
let client = TargetSavingsClient::new(&env, &contract_id);
Expand Down
10 changes: 10 additions & 0 deletions contracts/test_utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "test_utils"
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
publish = false

[dependencies]
soroban-sdk = { version = "23.0.3", features = ["testutils"] }
52 changes: 52 additions & 0 deletions contracts/test_utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use soroban_sdk::{
testutils::{Address as _, Ledger, LedgerInfo},
token::{StellarAssetClient, TokenClient},
Address, Env, Vec,
};

pub fn create_token_contract<'a>(env: &'a Env, admin: &Address) -> (Address, TokenClient<'a>) {
let asset = env.register_stellar_asset_contract_v2(admin.clone());
let address = asset.address();
(address.clone(), TokenClient::new(env, &address))
}

pub fn create_funded_users(
env: &Env,
token: &TokenClient,
count: u32,
amount: i128,
) -> Vec<Address> {
let issuer = StellarAssetClient::new(env, &token.address);
let mut users = Vec::new(env);
for _ in 0..count {
let user = Address::generate(env);
issuer.mint(&user, &amount);
users.push_back(user);
}
users
}

pub fn mint_tokens(env: &Env, token: &TokenClient, to: &Address, amount: i128) {
StellarAssetClient::new(env, &token.address).mint(to, &amount);
}

pub fn set_ledger_time(env: &Env, timestamp: u64, sequence: u32) {
env.ledger().set(LedgerInfo {
timestamp,
protocol_version: 23,
sequence_number: sequence,
network_id: Default::default(),
base_reserve: 10,
min_temp_entry_ttl: 10,
min_persistent_entry_ttl: 10,
max_entry_ttl: 3_110_400,
});
}

pub fn assert_solvable(env: &Env, token_address: &Address, contract: &Address, total_owed: i128) {
let token = TokenClient::new(env, token_address);
assert!(
token.balance(contract) >= total_owed,
"contract token balance is below the sum of outstanding claims"
);
}