Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ Thumbs.db
# Environment files
.env
.env.local

# Node.js
node_modules/
dist/
*.tsbuildinfo
10 changes: 9 additions & 1 deletion context/progress-tracker.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ Update this file after every completed contract change, fix, or architectural de

## Recently Fixed

### Bug Fixes (2026-06-27)
- Fixed `calculate_withdrawal` in `liquidity-pool-contract` to return 0 when `total_shares == 0` (empty pool)
- Added `get_loan_counter` public function to `creditline-contract` for frontend loan enumeration
- Fixed frontend `soroban.ts` to call `get_loan_counter` instead of non-existent `all_loans_count`
- Added `vouching-contract` to `deploy-testnet.sh` (build, deploy, initialize, env output, JSON manifest)
- Suppressed unused-function warnings (`#[allow(dead_code)]`) on `div_u64`, `add_u32`, `sub_u32`

### Issue #7 — Follow-up: Missing `approve_vendor` in `RealIntegrationCtx::register_vendor`
- Discovered second `register_vendor` helper in `RealIntegrationCtx` (integration test struct, ~line 2390) that only called `register_vendor` without `approve_vendor`
- All integration tests using `RealIntegrationCtx` created loans with `Pending` vendors → `validate_vendor` → `is_active` returned `false` → `VendorNotActive` (#3)
Expand All @@ -109,8 +116,9 @@ Update this file after every completed contract change, fix, or architectural de

1. **Learner grace period** — Make `grace_period_seconds` per-loan (not just global via parameters)
2. **Reputation rules** — Update `creditline-contract` to call different reputation adjustments for `LoanType::LearnerInstallment`
3. **Testnet deployment** — Deploy all contracts, capture IDs, add to StepFi-API `.env`
3. **Testnet deployment** — Deploy all contracts (including vouching), capture IDs, add to StepFi-API `.env`
4. **End-to-end validation** — Verify loan lifecycle on testnet via Stellar CLI
5. **Frontend pages** — Build borrower dashboard, loan application, and mentor vouching pages

---

Expand Down
4 changes: 4 additions & 0 deletions contracts/creditline-contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ impl CreditLineContract {
storage::get_version(&env).unwrap_or_else(|err| panic_with_error!(&env, err))
}

pub fn get_loan_counter(env: Env) -> u64 {
storage::get_loan_counter(&env).unwrap_or_else(|err| panic_with_error!(&env, err))
}

pub fn initialize(
env: Env,
admin: Address,
Expand Down
1 change: 1 addition & 0 deletions contracts/creditline-contract/src/safe_math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub fn mul_u64(a: u64, b: u64) -> Result<u64, CreditLineError> {
a.checked_mul(b).ok_or(CreditLineError::Overflow)
}

#[allow(dead_code)]
pub fn div_u64(a: u64, b: u64) -> Result<u64, CreditLineError> {
a.checked_div(b).ok_or(CreditLineError::Overflow)
}
1 change: 1 addition & 0 deletions contracts/creditline-contract/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ fn test_admin_upgrade_succeeds_and_bumps_version() {
assert_eq!(upgraded_new, Some(2u32), "CONTRACTUPGRADED new_version should be 2");
}

#[allow(dead_code)]
fn assert_event(env: &Env, expected: soroban_sdk::Symbol) {
use soroban_sdk::IntoVal;

Expand Down
6 changes: 5 additions & 1 deletion contracts/liquidity-pool-contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,10 +483,14 @@ impl LiquidityPoolContract {

/// Calculate how many tokens `shares` are worth at the current share price.
pub fn calculate_withdrawal(env: Env, shares: i128) -> i128 {
let share_price = Self::calculate_share_price_internal(&env).unwrap_or(types::SHARE_PRICE_PRECISION);
if shares == 0 {
return 0;
}
let total_shares = storage::get_total_shares(&env).unwrap_or(0);
if total_shares == 0 {
return 0;
}
let share_price = Self::calculate_share_price_internal(&env).unwrap_or(types::SHARE_PRICE_PRECISION);
safe_math::div_i128(
safe_math::mul_i128(shares, share_price).unwrap_or(0),
types::SHARE_PRICE_PRECISION,
Expand Down
4 changes: 4 additions & 0 deletions contracts/parameters-contract/src/safe_math.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
use crate::errors::ParametersError;

#[allow(dead_code)]
pub fn add_i128(a: i128, b: i128) -> Result<i128, ParametersError> {
a.checked_add(b).ok_or(ParametersError::Overflow)
}

#[allow(dead_code)]
pub fn sub_i128(a: i128, b: i128) -> Result<i128, ParametersError> {
a.checked_sub(b).ok_or(ParametersError::Underflow)
}

#[allow(dead_code)]
pub fn mul_i128(a: i128, b: i128) -> Result<i128, ParametersError> {
a.checked_mul(b).ok_or(ParametersError::Overflow)
}

#[allow(dead_code)]
pub fn div_i128(a: i128, b: i128) -> Result<i128, ParametersError> {
a.checked_div(b).ok_or(ParametersError::Overflow)
}
2 changes: 2 additions & 0 deletions contracts/vendor-registry-contract/src/safe_math.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::errors::Error;

#[allow(dead_code)]
pub fn add_u64(a: u64, b: u64) -> Result<u64, Error> {
a.checked_add(b).ok_or(Error::Overflow)
}

#[allow(dead_code)]
pub fn sub_u64(a: u64, b: u64) -> Result<u64, Error> {
a.checked_sub(b).ok_or(Error::Underflow)
}
4 changes: 2 additions & 2 deletions contracts/vendor-registry-contract/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::*;
use soroban_sdk::{
testutils::{Address as _, Events, Ledger},
Address, Env, IntoVal, String, Val, Vec,
Address, Env, IntoVal, String,
};

/// Helper function to set up the environment, contract, and test addresses.
Expand Down Expand Up @@ -440,7 +440,7 @@ fn test_upgrade_rejected_for_non_admin() {
#[test]
fn test_admin_upgrade_increments_version_and_emits_event() {
let env = Env::default();
let (client, admin, _vendor) = setup(&env);
let (client, _admin, _vendor) = setup(&env);
env.mock_all_auths();

assert_eq!(client.get_version(), 1u32);
Expand Down
2 changes: 2 additions & 0 deletions contracts/vouching-contract/src/safe_math.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::errors::VouchingError;

#[allow(dead_code)]
pub fn add_u32(a: u32, b: u32) -> Result<u32, VouchingError> {
a.checked_add(b).ok_or(VouchingError::Overflow)
}

#[allow(dead_code)]
pub fn sub_u32(a: u32, b: u32) -> Result<u32, VouchingError> {
a.checked_sub(b).ok_or(VouchingError::Underflow)
}
12 changes: 12 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>StepFi</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading
Loading