Post
Share your knowledge.
Build a Lending Protocol on Sui
How do I implement a basic lending protocol using the Move language on the Sui blockchain? Specifically, how should I structure modules and objects to support lending, borrowing, collateral management, and interest accrual? Are there any best practices or reference implementations for this on Sui?
- Sui
- Architecture
- Security Protocols
- Move
Answers
6To implement a basic lending protocol using the Move language on the Sui blockchain, I would recommend starting with the Scallop Lending Protocol, as they’ve open-sourced their implementation, which can serve as a great reference. https://github.com/scallop-io/sui-lending-protocol/tree/main
You can focus on these specific files from their repository:
- Deposit Collateral – deposit_collateral.move
- Borrowing – borrow.move
These modules provide the core functionality needed for deposit collateral and borrowing within the lending protocol. The source code is well-commented, which can help you understand the logic in depth.
While the code itself is a good starting point, the real challenge lies in understanding the system design and flow. You’ll need to know which modules interact with each other to form a complete lending and borrowing ecosystem, including collateral management and interest accrual.
By looking at the existing reference implementation, you can structure your own version by following similar patterns, while simplifying the complexity in terms of business logic and security considerations.
I have found the source code of Suilend which is one of the top ledning protocol on Sui. You can reference here https://github.com/suilend/suilend
Try to find out this file https://github.com/suilend/suilend/blob/devel/contracts/suilend/sources/lending_market.move
/// Borrow tokens of type T. A fee is charged.
public fun borrow<P, T>(
lending_market: &mut LendingMarket<P>,
reserve_array_index: u64,
obligation_owner_cap: &ObligationOwnerCap<P>,
clock: &Clock,
amount: u64,
ctx: &mut TxContext,
): Coin<T> {
let liquidity_request = borrow_request<P, T>(
lending_market,
reserve_array_index,
obligation_owner_cap,
clock,
amount,
);
fulfill_liquidity_request(lending_market, reserve_array_index, liquidity_request, ctx)
}
public fun deposit_liquidity_and_mint_ctokens<P, T>(
lending_market: &mut LendingMarket<P>,
reserve_array_index: u64,
clock: &Clock,
deposit: Coin<T>,
ctx: &mut TxContext,
): Coin<CToken<P, T>> {
let lending_market_id = object::id_address(lending_market);
assert!(lending_market.version == CURRENT_VERSION, EIncorrectVersion);
assert!(coin::value(&deposit) > 0, ETooSmall);
let reserve = vector::borrow_mut(&mut lending_market.reserves, reserve_array_index);
assert!(reserve::coin_type(reserve) == type_name::get<T>(), EWrongType);
reserve::compound_interest(reserve, clock);
let deposit_amount = coin::value(&deposit);
let ctokens = reserve::deposit_liquidity_and_mint_ctokens<P, T>(
reserve,
coin::into_balance(deposit),
);
assert!(balance::value(&ctokens) > 0, ETooSmall);
event::emit(MintEvent {
lending_market_id,
coin_type: type_name::get<T>(),
reserve_id: object::id_address(reserve),
liquidity_amount: deposit_amount,
ctoken_amount: balance::value(&ctokens),
});
coin::from_balance(ctokens, ctx)
}
The contract is bit complicated but it nice for reference about security and architecture.
On Sui, every piece of data is an object, and your protocol logic lives inside modules. To support lending/borrowing, you’ll need to define key object types and entry functions.
struct LendingPool has key {
id: UID,
total_supplied: u64,
total_borrowed: u64,
interest_rate: u64,
token: Type,
}
struct CollateralVault has key {
id: UID,
owner: address,
collateral_amount: u64,
}
struct DebtNote has key {
id: UID,
borrower: address,
borrowed_amount: u64,
interest_index: u64,
}
Reference Implementations: DeepBook: While not a lending protocol, it shows good practices for order books, object structuring, and shared pools. Scallop Lending (WIP): A real lending protocol for Sui — can inspire your architecture. Sui Examples Repo: Sometimes includes toy DeFi or NFT projects for structural ideas.
⸻
🧪 Bonus Tips: Consider using dynamic fields to associate multiple DebtNote objects to a single user address.
To implement a basic lending protocol on Sui, I'd start with a core LendingPool module and object managing overall state and various Reserve objects. Each Reserve would handle a specific asset (SUI, USDC), tracking its deposits, borrows, and an InterestRateModel. Users deposit Coin
Do you know the answer?
Please log in and share it.
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
- How to Maximize Profit Holding SUI: Sui Staking vs Liquid Staking616
- Why does BCS require exact field order for deserialization when Move structs have named fields?65
- Multiple Source Verification Errors" in Sui Move Module Publications - Automated Error Resolution55
- Sui Move Error - Unable to process transaction No valid gas coins found for the transaction419
- Sui Transaction Failing: Objects Reserved for Another Transaction410