This repository was archived by the owner on Dec 2, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 8
This repository was archived by the owner on Dec 2, 2025. It is now read-only.
Resolve Contract Circular Dependencies and Architecture Issues #15
Copy link
Copy link
Open
Labels
good first issueGood for newcomersGood for newcomersonlydust-waveContribute to awesome OSS repos during OnlyDust's open source weekContribute to awesome OSS repos during OnlyDust's open source week
Description
Description
Fix the critical circular dependency issues between Pool and Backstop contracts that are preventing proper compilation and testing. Currently, Pool depends on Backstop and Backstop depends on Pool (through Pool Factory), creating a circular dependency that has forced developers to comment out dependencies and exclude contracts from the workspace.
Current Issues Identified
Circular Dependency Chain
Pool Contract → Backstop Contract
↑ ↓
Pool Factory ← Backstop Contract
Evidence of Problems
- Pool and Backstop contracts excluded from main workspace
- Mock dependencies commented out to avoid circular dependencies
- Manual WASM copying required in deployment scripts
- Build process is fragmented and error-prone
What to Fix
- Resolve Pool ↔ Backstop circular dependency
- Include all contracts in main workspace
- Simplify deployment process
- Enable proper testing with mock contracts
- Create clean contract interfaces
Acceptance Criteria
- All contracts compile successfully in single workspace
- No circular dependencies between contracts
- Mock contracts can be used for testing
- Deployment script works without manual WASM copying
- All tests pass without dependency issues
- Clean contract interfaces with minimal coupling
Technical Requirements
Files to Modify
-
Workspace Configuration
- Path:
Cargo.toml(root) - Include all contracts in workspace
- Path:
-
Pool Contract Dependencies
- Path:
contracts/pool/Cargo.toml - Resolve Backstop dependency
- Path:
-
Backstop Contract Dependencies
- Path:
contracts/backstop/Cargo.toml - Resolve Pool dependency
- Path:
-
Deployment Scripts
- Path:
tools/deploy-all.sh - Simplify deployment process
- Path:
Architecture Refactoring Strategy
Option 1: Interface Abstraction
// Create shared trait definitions
pub trait PoolInterface {
fn get_pool_status(&self) -> PoolStatus;
fn validate_pool(&self) -> bool;
}
pub trait BackstopInterface {
fn can_cover_debt(&self, amount: i128) -> bool;
fn request_coverage(&self, pool_id: &Address, amount: i128);
}Option 2: Event-Driven Architecture
// Pool emits events instead of direct calls
pub fn liquidate_position(env: Env, user: Address) {
// Perform liquidation
emit_liquidation_event(&env, user, liquidated_amount);
}
// Backstop listens to events
pub fn handle_liquidation_event(env: Env, event: LiquidationEvent) {
// Process backstop coverage
}Option 3: Mediator Pattern
// Create ProtocolManager contract
pub struct ProtocolManager;
impl ProtocolManager {
pub fn coordinate_liquidation(
&self,
pool: Address,
backstop: Address,
user: Address
) -> Result<(), Error> {
// Coordinate between pool and backstop
}
}Implementation Details
Phase 1: Dependency Analysis and Interface Design
// contracts/shared/src/interfaces.rs
use soroban_sdk::{Address, Env};
pub trait PoolOperations {
fn supply(env: Env, from: Address, asset: Address, amount: i128);
fn borrow(env: Env, from: Address, asset: Address, amount: i128);
fn liquidate(env: Env, liquidator: Address, user: Address);
}
pub trait BackstopOperations {
fn deposit(env: Env, from: Address, amount: i128);
fn cover_loss(env: Env, pool: Address, amount: i128) -> bool;
fn get_coverage_capacity(env: Env, pool: Address) -> i128;
}
pub trait OracleOperations {
fn get_price(env: Env, asset: Address) -> Option<i128>;
fn get_price_with_timestamp(env: Env, asset: Address) -> Option<(i128, u64)>;
}Phase 2: Contract Refactoring
Pool Contract Refactoring
// contracts/pool/src/contract.rs
use shared::interfaces::{BackstopOperations, OracleOperations};
pub struct Pool;
impl Pool {
pub fn liquidate(
env: Env,
liquidator: Address,
user: Address,
backstop_contract: Address
) -> Result<(), Error> {
// Validate liquidation conditions
let liquidation_amount = self.calculate_liquidation_amount(&env, &user)?;
// Request backstop coverage through interface
let backstop_client = BackstopClient::new(&env, &backstop_contract);
let can_cover = backstop_client.get_coverage_capacity(&pool_address);
if can_cover >= liquidation_amount {
// Proceed with liquidation
self.execute_liquidation(&env, &liquidator, &user, liquidation_amount)?;
// Notify backstop of potential loss
backstop_client.cover_loss(&pool_address, liquidation_amount);
}
Ok(())
}
}Backstop Contract Refactoring
// contracts/backstop/src/contract.rs
pub struct Backstop;
impl BackstopOperations for Backstop {
fn cover_loss(env: Env, pool: Address, amount: i128) -> bool {
let pool_data = self.get_pool_data(&env, &pool);
let available_funds = self.get_available_funds(&env, &pool);
if available_funds >= amount {
self.transfer_coverage(&env, &pool, amount);
true
} else {
// Trigger backstop auction or other mechanisms
self.trigger_backstop_mechanism(&env, &pool, amount);
false
}
}
}Phase 3: Shared Components
Create Shared Library
// contracts/shared/src/lib.rs
pub mod interfaces;
pub mod types;
pub mod events;
pub mod errors;
// Shared types
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PoolConfig {
pub oracle: Address,
pub backstop: Address,
pub max_utilization: u32,
pub base_rate: u32,
}
// Shared events
pub fn emit_liquidation(
env: &Env,
pool: Address,
liquidator: Address,
user: Address,
amount: i128
) {
env.events().publish(
("liquidation",),
(pool, liquidator, user, amount)
);
}Phase 4: Updated Workspace Configuration
# Root Cargo.toml
[workspace]
members = [
"contracts/shared",
"contracts/oracle",
"contracts/pool-factory",
"contracts/pool",
"contracts/backstop",
"contracts/tbrg-token",
"contracts/mocks/mock-pool-factory",
"contracts/mocks/mock-pool",
"contracts/mocks/moderc3156",
"testing/test-suites"
]
[workspace.dependencies]
shared = { path = "contracts/shared" }
soroban-sdk = "21.0.0"Testing Strategy
Unit Tests
#[cfg(test)]
mod tests {
use super::*;
use shared::interfaces::*;
#[test]
fn test_pool_backstop_interaction() {
let env = Env::default();
let pool = PoolClient::new(&env, &env.register_contract(None, Pool));
let backstop = BackstopClient::new(&env, &env.register_contract(None, Backstop));
// Test interaction without circular dependency
assert!(backstop.get_coverage_capacity(&pool.address) > 0);
}
}Integration Tests
// testing/test-suites/src/integration_tests.rs
#[test]
fn test_full_liquidation_flow() {
let env = TestEnv::default();
// Deploy all contracts
let contracts = deploy_all_contracts(&env);
// Test complete liquidation flow
let result = execute_liquidation_scenario(&env, &contracts);
assert!(result.is_ok());
}Deployment Improvements
Simplified Deployment Script
#!/bin/bash
# tools/deploy-all.sh
echo "Building all contracts..."
cargo build --release --target wasm32-unknown-unknown
echo "Optimizing WASM files..."
for contract in oracle pool-factory pool backstop tbrg-token; do
soroban contract optimize \
--wasm target/wasm32-unknown-unknown/release/${contract//-/_}.wasm \
--wasm-out target/wasm32-unknown-unknown/release/${contract//-/_}_optimized.wasm
done
echo "Deploying contracts..."
# Deploy in correct order without manual copying
deploy_contract "oracle"
deploy_contract "pool-factory"
deploy_contract "backstop"
deploy_contract "pool"
deploy_contract "tbrg-token"Benefits of This Refactoring
Immediate Benefits
- All contracts compile together
- Proper testing infrastructure
- Simplified deployment process
- Clean dependency management
Long-term Benefits
- Easier to add new contracts
- Better modularity and maintainability
- Reduced deployment complexity
- Improved testing capabilities
Risk Mitigation
Backward Compatibility
- Maintain existing contract interfaces
- Gradual migration approach
- Comprehensive testing before deployment
Deployment Safety
- Test on testnet extensively
- Staged deployment approach
- Rollback plan if issues arise
Dependencies
- Soroban SDK latest version
- Stellar CLI tools
- Rust toolchain with wasm32 target
- Contract optimization tools
Definition of Done
- All contracts included in workspace and compile successfully
- No circular dependencies in contract architecture
- All tests pass including integration tests
- Deployment script works without manual intervention
- Mock contracts work properly for testing
- Documentation updated with new architecture
- Performance benchmarks meet requirements
- Security audit considerations addressed
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
good first issueGood for newcomersGood for newcomersonlydust-waveContribute to awesome OSS repos during OnlyDust's open source weekContribute to awesome OSS repos during OnlyDust's open source week