Stacks-side contracts for StackLend cross-chain lending protocol (Stacks <-> Sui).
Stacks → Manages STX collateral only Sui → Manages all borrowing, lending, and sBTC collateral
User deposits STX on Stacks
↓
Relayer detects event
↓
Relayer registers collateral on Sui
↓
User borrows USDC on Sui
↓
User repays on Sui
↓
User requests withdraw on Stacks
↓
Relayer verifies debt = 0 on Sui
↓
Relayer unlocks STX on Stacks
Purpose: Manage STX collateral deposits and withdrawals
Public Functions (User-facing):
deposit-collateral(amount)- Deposit STX as collateralrequest-withdraw(amount)- Request to withdraw STX
Admin Functions (Relayer-only):
init-admin()- Initialize admin (one-time)admin-unlock-collateral(user, amount)- Unlock collateral after Sui verificationadmin-emergency-withdraw(recipient, amount)- Emergency withdrawal
Read-only Functions:
get-collateral(user)- Get user's collateral balanceget-total-collateral()- Get total protocol collateralget-portfolio(user)- Get user portfolio summaryis-admin(who)- Check if address is admin
{
event: "collateral-deposited",
user: principal,
amount: uint,
new-balance: uint,
block-height: uint
}Trigger: User deposits STX
Relayer Action: Call register_stacks_collateral() on Sui
{
event: "withdraw-requested",
user: principal,
amount: uint,
current-collateral: uint,
block-height: uint
}Trigger: User requests withdrawal Relayer Action:
- Check debt on Sui via
get_position() - If debt = 0: Call
admin-unlock-collateral()on Stacks - If debt > 0: Ignore/reject request
{
event: "collateral-unlocked",
user: principal,
amount: uint,
new-balance: uint,
unlocked-by: principal,
block-height: uint
}Trigger: Relayer unlocks collateral Action: STX sent back to user
- Deploy contract:
clarinet deploy --testnet- Initialize admin:
clarinet console(contract-call? .collateral-v1 init-admin)- Save contract address for relayer configuration
# Run unit tests
clarinet test
# Interactive console
clarinet console1. Deposit Collateral:
stx call ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.collateral-v1 deposit-collateral u10000002. Check Balance:
stx call-read ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.collateral-v1 get-collateral ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM3. Request Withdraw:
stx call ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.collateral-v1 request-withdraw u500000Collateral Registration:
public entry fun register_stacks_collateral(
registry: &mut BorrowRegistry,
borrower: address,
collateral_type: u8, // 1 = STX, 2 = sBTC
amount: u64,
ctx: &mut TxContext
)Check Position (for withdrawal verification):
public fun get_position(
registry: &BorrowRegistry,
borrower: address
): BorrowPositionu100- err-non-positive: Amount must be > 0u101- err-insufficient-funds: Insufficient balanceu105- err-not-admin: Caller is not admin
-
Admin Key Management:
- Admin key controls collateral unlocking
- Must be secured by relayer operator
- Consider multi-sig for production
-
Withdrawal Safety:
- Relayer MUST verify debt = 0 on Sui before unlocking
- User cannot bypass this check
- Emergency admin withdrawal for protocol safety only
-
Cross-Chain Trust:
- System relies on relayer honesty
- For MVP: Admin-controlled relayer
- Future: Decentralized relayer network or ZK proofs
The relayer must:
- ✅ Monitor Stacks events (
collateral-deposited,withdraw-requested) - ✅ Monitor Sui events (withdrawal signals)
- ✅ Maintain mapping: Stacks address ↔ Sui address
- ✅ Have admin privileges on both chains
- ✅ Verify state consistency before unlocking collateral
See /stacklend-relayer for implementation.
- ✅ Simplified collateral-only contract
- ✅ Removed borrow/repay functions (handled on Sui)
- ✅ Added relayer admin functions
- ✅ Enhanced event emissions for monitoring
- ❌ Removed lending-v1.clar (not needed)
MIT