Sui.

Post

Share your knowledge.

fomo on Sui.
Jul 13, 2025
Expert Q&A

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
1
6
Share
Comments
.

Answers

6
obito.
Jul 15 2025, 06:55

To 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:

  1. Deposit Collateraldeposit_collateral.move
  2. Borrowingborrow.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.

2
Best Answer
Comments
.
Thorfin.
Jul 19 2025, 02:11

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.

5
Comments
.
0xduckmove.
Jul 14 2025, 04:01

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.

2
Comments
.
Ashford.
Sep 6 2025, 08:25

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 into the LendingPool, receiving a share token (e.g., sCoin). For borrowing, users deposit Coin as collateral, which is tracked, then borrow Coin. Individual Loan objects, potentially as dynamic fields, would record principal, collateral, and last interaction timestamp. Interest accrual is best handled lazily, calculated on user interaction (deposit, borrow, repay) based on elapsed time and current utilization rates. Key best practices include robust oracle integration for collateral valuation, modularizing logic (e.g., oracle_interface, interest_rate_model), and leveraging Sui's object model with dynamic fields for efficient state management. While direct Sui reference implementations are evolving, conceptual patterns from EVM protocols like Aave are highly relevant for architectural design in Move.

0
Comments
.

Do you know the answer?

Please log in and share it.