Skip to main content

🫴 Lending Module

Chiss lending enables users to access exotic currencies in Chiss-native stablecoins with popular USD stablecoins as collateral. This module integrates Position contracts, stability pools, oracle pricing and keepers, simply known as liquidators for Collateral and debt management. The system architecture highlights the lending & stability module runs on the Chiss operation engines & reserve as simplified below;

For a simple guide on how to use Chiss Lending on the Chiss Webdapp, see the Guide section. At the contract level, the loan interface is primarily powered by the Stablecoin lending contract also known as the PositionManager.

Position Manager

The PositionManager is the core smart contract of Chiss Protocol’s borrowing system. It acts as a factory that deploys and configures individual Position contracts. Each Position contract is an isolated vault responsible for:

  • Holding a borrower’s deposited collateral.
  • Managing risk parameters.
  • Facilitating the borrowing of Stablecoin assets from the Stability Pool funded by lenders.

Creating and Managing Positions

User interaction with Chiss Protocol begins by opening a new position. This is handled through the createPosition(), which deploys a dedicated smart contract to represent the user’s borrowing position.

function createPosition(
uint256 _positionType,
uint256 _collateralAmount,
uint256 _debtAmount
) external returns (uint256 _positionId)

Position Creation Flow

  1. Position Deployment The PositionManager deploys a new Position contract for the user, using the Clones library for a gas-efficient minimal proxy implementation.

  2. Collateral Deposit The specified _collateralAmount is transferred from the user’s wallet into the new Position contract. The Position now securely holds this collateral.

  3. Initialization The Position contract is initialized with key parameters, including: a. Liquidation ratio b. Reserve Factor c. Stability Pool address

  4. Delegated Borrow The PositionManager delegates the borrow request to the Position contract by calling its internal borrow function with `_debtAmount``.

  5. Borrowing from the Pool The Position contract requests directly from the linked Stability Pool. The Stability Pool transfers the borrowed amount to the user’s wallet.

  6. Indexing & Events The PositionManager assigns a unique ID. A PositionCreated event is emitted for transparency and tracking.

Debt Cycle Contract Flow

Initiating a Borrow Position

Borrowing begins with createPosition() in the PositionManager contract. Chiss sources liquidity directly from the Stability Pool. The call is atomic, handling both:

  1. Collateral deposit (user locks assets into a newly created Position).
  2. Initial borrow request (user receives Stablecoin from the Stability Pool).

Once the position is created, the user’s debt is denominated in Stablecoin and accrues interest according to the protocol’s dynamic rate model.

Borrow Flow

PositionManager → Position

// Delegates borrowing to the Position contract
Position(_position).borrow(_debtAmount);

Position → Stability Pool

The Position contract validates the borrow request and ensures that total debt after borrowing must not exceed the collateral’s allowed maximum. If valid, the Position updates its internal state and then calls

// Position contract requests liquidity from Stability Pool
function borrow(uint256 _debtAmount) external onlyFactoryOrOwner nonReentrant {
...
stabilityPool.borrow(_owner, _debtAmount);
...
}

Stability Pool → User

The Stability Pool executes the asset transfer (Transfers the requested Stablecoin directly to the borrower’s wallet.)

// Stability Pool transfers the Stablecoin directly to the user
function borrow(address _user, uint256 assets) public
whenNotPaused
nonReentrant
onlyRole(POSITION_ROLE)
{
...
IERC20(asset()).safeTransfer(_user, assets);
...
}

This guarantees that all debt is backed by real liquidity.

Repaying a Loan

Borrowers can repay debt fully or partially at any time to improve the health of their loan position or free up some collateral.

On a smart contract level, this is the flow of the debt clearing.

Initiating a Repayment

Debt settlement begins with clearDebt() in the PositionManager contract. The borrower initiates repayment by transferring Stablecoin back into the system.

The call is atomic, handling both stablecoin transfer (user pays back borrowed assets to reduce or close their debt) & accounting updates (principal reduction, interest settlement, protocol reserve allocation).

Once repayment is processed, the position’s outstanding debt decreases, and the system rebalances the Stability Pool and interest model in real time.

Repayment Flow

PositionManager → Position

Borrower calls the clearDebt() function on the PositionManager, which delegates repayment logic to the Position contract.

// Delegates repayment to the Position contract
Position(_position).repay(_repayAmount);

Position → Stability Pool

The Position contract validates the repayment request, ensuring the user has sufficient debt to repay and that no protocol limits are violated. If valid, it updates its internal state, it reduces the principal balance, settles accrued interest up to the repayment timestamp and allocates protocol reserves as defined by the model.

Then, it transfers the repayment Stablecoin to the Stability Pool:

// Position contract requests repayment settlement in Stability Pool
function repay(uint256 _repayAmount) external onlyFactoryOrOwner nonReentrant {
...
stabilityPool.repay(_owner, _repayAmount);
...
}

Stability Pool → Protocol Accounting

The StabilityPool finalizes the repayment. It credits the returned Stablecoin back into pool liquidity, updates global asset balances, recalculates utilization ratio (debt vs. liquidity) and triggers real-time borrow rate adjustment for all active positions.

// Stability Pool processes repayment and updates system balances
function repay(address _user, uint256 assets) public
whenNotPaused
nonReentrant
onlyRole(POSITION_ROLE)
{
...
IERC20(asset()).safeTransferFrom(_user, address(this), assets); _updateReservesAndUtilization(assets);
...
}

System Guarantees

  • Principal Reduction: User’s outstanding debt decreases immediately.
  • Interest Settlement: Accrued interest is captured at repayment.
  • Liquidity Backing: Stability Pool liquidity increases by the repaid amount.
  • Dynamic Adjustments: Utilization and borrow rate recalculate in real time, ensuring fairness and stability across the protocol.