Satoshi Lending Protocol Workflow
This document outlines the high-level workflows and terminology for the Satoshi Lending protocol.
Terminology
| Term | Definition |
|---|---|
| Collateral | Any non-USDC asset deposited to secure a loan. |
| Lenders | Users who supply assets to the pool to earn interest. |
| Borrowers | Users who provide collateral to take loans from the pool. |
| LTV (Loan to Value) | A metric used to assess the health of a borrower’s position. Formula: total_borrow_value.div(total_collateral_value) |
| Insurance Allocation Rate | (Also known as Reserve Factor) The percentage of the liquidation penalty diverted to the protocol’s Insurance Fund. |
| Liquidation Penalty | The amount deducted and sent to the liquidation account when a liquidation occurs. |
System Assumptions & Constraints
- Asset Types:
- Lending and borrowing are restricted to USDC.
- Collateral deposits are restricted to non-USDC assets.
- Contracts:
- There is a single USDC contract for deposits.
- There are currently three non-USDC contracts for collateral deposits.
- The Near intents contract is used exclusively for liquidation.
- Account Roles: A single account cannot function as both a lender and a borrower simultaneously.
Workflows
Lender Actions
Lending (Supply)
Involves the deposit of USDC into the protocol by a lender.
Unlending (Withdraw)
The withdrawal of principal USDC along with any accrued interest by the lender.
Borrower Actions
Collateral Deposit
A borrower deposits non-USDC assets to enable borrowing of USDC.
Repay
The repayment of borrowed USDC along with accrued interest by the borrower.
Withdraw Collateral
The withdrawal of deposited collateral by the borrower.
Borrow
The act of borrowing USDC from the protocol, secured by the deposited collateral.
Parameters of the protocol
This document outlines the key configurable parameters of the LendingProtocol. These values are critical for managing risk and defining the economic model of the protocol.
Interest Rate Model Parameters
These parameters define the interest rate model for USDC borrowing. The borrow rate is calculated based on the utilization of available liquidity.
usdc_base_borrow_rate
- Description: The base borrow rate for USDC, representing the minimum annual percentage rate (APR) when there are zero borrows (0% utilization).
usdc_rate_multiplier
- Description: A multiplier that determines how steeply the borrow rate increases as the utilization ratio increases. The formula is:
borrow_rate = usdc_base_borrow_rate + (utilization_ratio * usdc_rate_multiplier).
Liquidation Parameters
These parameters govern the process of liquidation for undercollateralized loans.
liquidation_penalty
- Description: The percentage fee applied to the value of collateral seized during a liquidation event. This penalty covers potential losses.
insurance_allocation_rate
- Description: The portion of the
liquidation_penaltythat is allocated to the protocol’s insurance fund. The remaining portion of the penalty is paid to the liquidator as a fee.
Loan-to-Value (LTV) Ratio Parameters
LTV ratios are fundamental risk parameters that determine how much can be borrowed against collateral and when a position is considered risky.
Formula: total_borrow_value.div(total_collateral_value)
borrow_threshold
- Description: The maximum Loan-to-Value (LTV) ratio for initiating a new borrow. For example, a value of 0.75 means a user can borrow up to 75% of their collateral’s value.
withdraw_threshold
- Description: The maximum Loan-to-Value (LTV) ratio permitted after a collateral withdrawal. This prevents users from withdrawing collateral if it would leave their position undercollateralized. It is often set to the same value as `borrow_threshold
liquidation_threshold
- Description: The Loan-to-Value (LTV) ratio at which a user’s position becomes eligible for liquidation. This value must be higher than the
borrow_thresholdto provide a safety buffer for borrowers.
Oracle Parameters
oracle_price_staleness_secs
- Description: The maximum age (in seconds) of an asset price from an oracle before it is considered stale and no longer valid for protocol operations. This is a critical safety feature to prevent acting on outdated price information.
Off-Chain Liquidation Process
Introduction
This document outlines the off-chain liquidation process for the protocol. It details the interaction between a liquidation bot and the smart contracts to manage under-collateralized loans, ensuring the solvency of the protocol by efficiently liquidating risky positions.
Core Principles and Assumptions
- Immutable Process: Once a position is marked for liquidation, the process will complete, regardless of any subsequent price movements that might improve the user’s Loan-to-Value (LTV) ratio.
- Account Lock: While a user’s position is being liquidated, they cannot perform any other actions like depositing, withdrawing, or borrowing.
- Full Liquidation: The entire position, including all types of collateral, is liquidated.
- Socialized Loss (v1): In the initial version, the protocol does not use an insurance fund. Any bad debt resulting from a liquidation is socialized among lenders by adjusting the supply index. This is v1 requirement arising from the PRD.
Data Structure Changes
To support the liquidation process, the following changes are made to the smart contract’s state.
The main contract state is updated with:
#![allow(unused)]
fn main() {
/// Account designated to handle collateral swaps.
pub liquidator_account: AccountId,
/// State of any ongoing liquidation.
pub liquidation: Option<LiquidationInfo>,
/// Tracks pending liquidations
pub pending_liquidations: Vector<UserId>
}
The InFlightOperation enum is extended to include liquidation states:
#![allow(unused)]
fn main() {
pub enum InFlightOperation {
Borrowing,
WithdrawingUsdc,
WithdrawingCollateral,
Liquidation
LiquidationFinal(Usdc)
}
}
A new LiquidationInfo struct tracks the state of an ongoing liquidation:
#![allow(unused)]
fn main() {
#[derive(Debug, Clone, PartialEq, Default)]
pub struct LiquidationInfo {
/// The user whose position is being liquidated.
pub user: UserId,
/// The current state of the liquidation process.
pub liquidation_state: LiquidationState,
}
}
The LiquidationState enum tracks the sub-steps within the collateral transfer phase:
#![allow(unused)]
fn main() {
pub enum LiquidationState {
#[default]
MarkedForLiquidation,
OngoingTransfer,
TransferSuccess,
TransferFailure(Vec<CollateralContract>),
}
}
Swap and Hold Account
The protocol uses a “Swap and Hold Account” during the liquidation process. This is a standard NEAR Account ID and does not require any special smart contract code.
This account is used to store the user’s collateral in an intents contract, which facilitates the swap from the collateral asset to USDC.
End-to-End Liquidation Flow
The liquidation process is a multi-stage operation orchestrated by an off-chain bot interacting with the main smart contract.
Stage 1: Position Flagging
- Monitor LTV: The bot continuously monitors each user’s LTV ratio off-chain.
- Initiate Liquidation: If a user’s LTV exceeds the liquidation threshold, the bot calls
liquidate_position(user_id)on the smart contract. This function marks the user for liquidation, records their current borrow value, and locks their account from further operations.
Stage 2: Collateral Transfer
- Iterate and Transfer: The smart contract initiates all collateral transfers at once. The bot calls
perform_transfer_for_liquidation(contracts: Option<Vec<CollateralContract>>)to initiate it.. - On-Chain Transfer: This contract call initiates an async transfer of the specified collateral from the protocol to the designated
liquidator_account. The contract updates the state toOngoingTransfer. - Handle Callbacks: The contract handles the async transfer’s callback:
- On success, the state is updated to
TransferSuccess. - On failure, the state is updated to
TransferFailurewith the collateral info, signaling the bot to retry the transfer for that specific asset.
- On success, the state is updated to
Stage 3: Asset Swapping (Off-Chain)
- Swap to USDC: Once the collateral is in the
liquidator_account, the bot uses an external service (e.g., 1Click API) to swap each collateral asset for USDC. - Hold Funds: The resulting USDC is temporarily held in a “Swap & Hold” contract controlled by the liquidator.
Stage 4: USDC Repatriation
- Transfer Back: After all collateral has been swapped, the bot triggers a transfer of the total accumulated USDC from the “Swap & Hold” contract back to the main protocol contract.
- Record Value: The main contract recognizes the incoming transfer is from the
liquidator_accountand records the amount in theswapped_collateral_valuefield of the user’sLiquidationInfo.
Stage 5: Finalizing Liquidation
- Finalize: With the USDC returned, the bot calls
finalize_liquidation(). - Settle Account: This function performs the final accounting: it repays the user’s debt, calculates and distributes liquidation fees, and handles any surplus or deficit. The user’s account is then unlocked.
Smart Contract Interface
liquidate_account(user_id)
Marks a user’s position for liquidation.
- Authorization: Can only be called by a permissioned liquidator bot account.
- Checks: Verifies that the user’s position is indeed eligible for liquidation based on their LTV.
- Actions:
- Creates a
LiquidationInfostruct for the user. - Sets
liquidation_statetoMarkedForLiquidation. - Stores the user’s current borrow value.
- Sets the user’s
in_flight_operationtoLiquidation, preventing other actions.
- Creates a
transfer_collateral_for_liquidation(ft_contract)
Transfers a specific collateral asset from the user’s position to the liquidator_account.
- Authorization: Callable by any account, allowing for permissionless retries.
- Pre-conditions:
- The user must be in a liquidation state (
MarkedForLiquidationorTransferFailure). - If the state is
TransferFailure(failed_contract), theft_contractparameter must matchfailed_contract. - The user must have a balance of the specified collateral (
ft_contract).
- The user must be in a liquidation state (
- Actions:
- Initiates an async transfer of the user’s full balance of
ft_contractto theliquidator_account. - Sets the
liquidation_statetoOngoingTransfer(ft_contract). - The callback updates the state to
TransferSuccessorTransferFailurebased on the outcome.
- Initiates an async transfer of the user’s full balance of
finalize_liquidation()
Settles the user’s account after collateral has been swapped and USDC has been returned to the contract.
- Authorization: Callable by any account, allowing for permissionless retries.
- Pre-conditions:
- Asserts that all of the user’s collateral has been transferred out (collateral balances are zero).
- Asserts that
swapped_collateral_valueis greater than zero.
- Actions:
- Repay Debt: The user’s borrowed shares are deducted from the protocol’s total.
- Calculate Fees: A liquidation penalty is calculated from
swapped_collatal_valueand split into liquidator and protocol fees. - Calculate Final Balance:
net_collateral = swapped_collateral_value - liquidator_fee - protocol_feefinal_balance = net_collateral - user_borrow_value
- Settlement:
- Surplus (
final_balance > 0): Fees are paid, and the remaining surplus is sent to the liquidated user. - Bad Debt (
final_balance < 0): Fees are paid from the swapped collateral. The shortfall is socialized among lenders by reducing the supply index.
- Surplus (
- Cleanup: The user’s
in_flight_operationis cleared and theLiquidationInfois removed.
Security Considerations
- A 1 yoctoNEAR deposit should be required for these calls to prevent call-based attacks (see NEAR documentation).
System Architecture
Introduction
This document provides a high-level overview of the Satoshi Lending Protocol’s architecture. For terminology and general workflow definitions, please refer to the Workflow Document.
Core Infrastructure
Oracle and Price Feeds
We utilize the Pyth Oracle to obtain real-time price information for collateral assets. Accurate price data is critical for the following operations:
- Borrowing
- Withdrawing collateral
- Liquidation
Note: User operations (and bots during liquidation) accept optional price data to update collateral prices before execution. Providing this data is highly recommended to prevent transaction failures due to stale prices.
Intents Contract
- Purpose: Exclusively handles asset swaps during the liquidation process.
- Interaction: The frontend should not interact with the Intents contract directly.
Frontend Workflows
This section details the interaction flows between the user/frontend and the smart contracts.
General Requirements
- Security Deposit: Most state-changing methods require attaching 1 yoctoNEAR as a security deposit.
- Storage Balance: Before interacting, ensure the user has a sufficient
storage_balanceregistered on the relevant contract (Satoshi contract or Fungible Token contract).
1. Deposit (Lending & Collateral)
Deposits of USDC (lending) and non-USDC assets (collateral) are initiated directly via the Fungible Token (FT) contract.
Workflow:
- Check Storage: Verify the user has a valid
storage_balanceon the Satoshi contract. If not, prompt the user to callstorage_deposit. - Verify Registration: Confirm the user is registered.
- External Deposit: User issues a deposit transaction on the deposit address of the external (non-Near) blockchain.
- Poll Transaction: The system polls the external transaction until it is confirmed successful. This is a two-step process: you have to poll that the external transaction succeeds, and poll that the bridging action occurs on the Near side. However, OmniBridge may provide a single endpoint to query for both.
- Contract Deposit: Once the external transaction is confirmed, the user initiates the deposit to the Satoshi contract.
- Update UI: Poll the transaction about it’s status and if was success/failure.
2. Unlending (Withdraw USDC)
Lenders can withdraw their USDC principal and accrued interest directly to their Near account.
Workflow:
- Check Storage: Verify the user has a valid
storage_balanceon the USDC Fungible Token contract. Register if necessary. - Execute Withdraw: Invoke the withdrawal method on the Satoshi contract (attach 1 yocto).
- Handle Result: Parse the transaction result (success or failure, e.g., insufficient liquidity) and display it to the user.
3. Borrow USDC / Withdraw Collateral
Borrowers can withdraw borrowed USDC or their deposited collateral.
Key Considerations:
- Price Freshness: It is mandatory to submit off-chain hex-encoded Pyth price feed data with the transaction. Failure to do so can cause the transaction to fail.
- Price Update: All price feeds for all collateral assets must be updated during this transaction.
Workflow:
- Check Storage: Verify the user has a valid
storage_balanceon the destination Fungible Token contract. Register if necessary. - Execute Transaction: Invoke the borrow or withdraw collateral method on the Satoshi contract (attach 1 yocto).
- Handle Result: Parse the transaction result and display it to the user.
4. Repay Loan
Borrowers can repay borrowed USDC plus accrued interest.
Key Considerations:
- Overpayment Strategy: The frontend should perform a slight overpayment. Since interest compounds continuously and the exact transaction timestamp is unknown, this ensures the entire debt is covered.
- Excess Refund: Any excess USDC provided beyond the actual debt amount is automatically returned to the borrower.
Workflow:
- Execute Repay: Invoke the repayment method on the Satoshi contract (attach 1 yocto).
- Handle Result: Parse the transaction result and display it to the user.
Off-Chain Services
Bot
The bot handles automated maintenance tasks for the protocol. Responsibilities:
- Monitoring: Track Near token balance of Liquidation bot and raise alerts if they fall below a defined threshold.
- Simulation & Marking: Perform off-chain simulations to identify and “mark” unhealthy positions. This involves calculating:
- Total Borrow Value: Adjusted for continuously accruing interest.
- Total Collateral Value: Based on the latest real-time Pyth price information.
- Liquidation: Execute liquidation on marked users, including passing the necessary off-chain Pyth price data.
Querier
Status: Pending input. (Responsibilities to be defined)
Indexer
Status: Pending input. (Responsibilities to be defined)
Indexer REST API
Status: Pending input. (Responsibilities to be defined)
Integration & Porting Guide
This document outlines the steps required to port the frontend from the old architecture to the new smart contract system.
Goals & Scope
The primary goal is to reach a functional state suitable for audit. The frontend must support the following workflows:
- User Actions:
- USDC Deposit
- Collateral Deposit
- Borrow USDC
- Withdraw USDC
- Withdraw Collateral
- Repayment of USDC
- State Display:
- Show current protocol state information.
Core Smart Contract Methods
To retrieve data, you will primarily interact with two view-only methods. It is essential to understand the data structures they return.
1. get_config
Returns ContractConfigView, which contains protocol configuration parameters.
#![allow(unused)]
fn main() {
pub struct ContractConfigView {
pub owner_id: AccountId,
pub liquidation_threshold: Decimal,
pub borrow_threshold: Decimal,
pub withdraw_threshold: Decimal,
pub liquidation_penalty: Decimal,
pub pyth_oracle_contract: AccountId,
pub usdc_base_borrow_rate: Decimal,
pub usdc_rate_multiplier: Decimal,
pub insurance_allocation_rate: Decimal,
pub liquidator_account: AccountId,
pub intents_contract: AccountId,
pub oracle_price_staleness_secs: u64,
pub supported_collaterals: HashMap<CollateralContract, CollateralMetadata>,
pub supported_usdc_token: Option<UsdcTokenView>,
pub pyth_required_deposit: NearToken,
}
}
2. get_contract_state
Returns ContractState, which contains the dynamic state of the protocol (liquidity, shares, indexes, etc.).
#![allow(unused)]
fn main() {
pub struct ContractState {
/// Protocol's cash-on-hand (available for withdrawal/borrowing).
pub usdc_liquidity: Usdc,
pub collateral_liquidity: IterableMap<CollateralContract, RawAmount>,
/// Total lending shares for USDC.
pub total_supplied_usdc_shares: LendingShare,
/// Total borrow shares for USDC.
pub total_borrowed_usdc_shares: BorrowShare,
/// User data
pub users: near_sdk::store::IterableMap<UserId, User>,
/// Index to track interest accrued for USDC suppliers.
/// User supply balance = `supplied_usdc_shares` * `usdc_supply_index`.
pub usdc_supply_index: LendingIndex,
/// Index to track interest accrued on USDC borrows.
/// User borrow balance = `borrowed_usdc_shares` * `usdc_borrow_index`.
pub usdc_borrow_index: BorrowIndex,
/// Timestamp of the last interest accrual.
pub last_interest_accrual_timestamp: Timestamp,
/// Protocol's accumulated bad debt in USDC.
pub bad_debt_usdc: Usdc,
/// Protocol's insurance fund.
pub insurance_fund: Usdc,
/// Oracle Prices.
pub prices: LookupMap<UsdPythIdentifier, PythPrice>,
/// State of any ongoing liquidation.
pub liquidation: Option<LiquidationInfo>,
/// Tracks pending liquidations.
pub pending_liquidations: Vector<UserId>,
/// Unpaid fees to be paid to the liquidator.
pub unpaid_liquidator_fee: Usdc,
/// Unpaid surplus amounts to be transferred to users after liquidation.
pub pending_surplus_transfers: LookupMap<UserId, Usdc>,
/// The number of users registered with the contract.
pub user_count: u64,
}
}
3. get_user(user_id: UserId)
Returns the User struct, containing specific data for a single user.
#![allow(unused)]
fn main() {
pub struct User {
// Amounts of non-USDC collateral.
pub collateral: HashMap<CollateralContract, RawAmount>,
// User's position in the USDC market (supplier, borrower, or neither).
pub usdc_position: UsdcPosition,
// The current in-flight operation for this user, if any.
pub in_flight_operation: Option<InFlightOperation>,
/// Storage balance
pub storage_balance: NearToken,
}
pub enum UsdcPosition {
#[default]
None,
Supplied(LendingShare),
Borrowed(BorrowShare),
}
}
Backend API Migration (Indexer & Querier)
This section maps old backend endpoints to the new logic using ContractState and ContractConfigView.
Summary Table
| Old Query | Endpoint | New Logic Summary |
|---|---|---|
transactionsQuery | /transactions/account/{accountId} | Deferred to V2 (Indexer API). |
indexerTotalBorrowedQuery | /borrows/total_borrowed | total_borrowed_usdc_shares * usdc_borrow_index |
indexerTotalFeesQuery | /fees/total/interest_and_penalties | insurance_fund + Liquidator Account Balance |
indexerAccountsQuery | /accounts | user_count |
indexerProtocolLtvQuery | /dashboard/ltv | Total Borrowed / Total Collateral Value |
indexerTokenCollateralQuery | /dashboard/token_collateral | Sum of all collateral values (USD). |
indexerTotalStablecoinDepositedQuery | /token_transfers/stablecoin/total_deposited | usdc_liquidity |
indexerTotalCollateralDepositedQuery | /token_transfers/collateral/total_deposited | Same as indexerTokenCollateralQuery. |
querierUtilizationRatioQuery | /utilization_ratio | Total Borrowed / Total Supplied |
querierLendableQuery | /lendable | usdc_liquidity |
Detailed Porting Guide
indexerTotalBorrowedQuery
Represents the total USDC lent out by the protocol.
- Source:
ContractState - Formula:
total_borrowed_usdc_shares * usdc_borrow_index
indexerTotalFeesQuery
Represents total liquidator and insurance fees collected.
- Source:
ContractState(for insurance fund) &ContractConfigView(for liquidator account ID). - Formula:
insurance_fund + (USDC balance of liquidator_account)
indexerAccountsQuery
Total number of registered users.
- Source:
ContractState - Formula:
user_count
indexerProtocolLtvQuery
Protocol Loan-to-Value ratio.
- Formula:
Total Borrowed Value / Total Collateral Value- Total Borrowed Value: See
indexerTotalBorrowedQuery. - Total Collateral Value:
- Get
collateral_liquidityfromContractState. - Fetch USD prices using Hermes.
- Normalize amounts based on token decimals.
- Sum:
(Amount * USD Price)for all collateral types.
- Get
- Total Borrowed Value: See
indexerTokenCollateralQuery & indexerTotalCollateralDepositedQuery
Total collateral present in the protocol (in USD).
- Formula: Same calculation as Total Collateral Value in
indexerProtocolLtvQuery.
indexerTotalStablecoinDepositedQuery
Total USDC present in the protocol.
- Source:
ContractState - Formula:
usdc_liquidity
querierUtilizationRatioQuery
- Source:
ContractState - Formula:
Total Borrowed / Total Supplied- Total Borrowed:
total_borrowed_usdc_shares * usdc_borrow_index - Total Supplied:
total_supplied_usdc_shares * usdc_supply_index
- Total Borrowed:
querierLendableQuery
Available USDC for lending.
- Source:
ContractState - Formula:
usdc_liquidity
Contract View Query Migration
This section maps old smart contract view methods to the new logic.
Summary Table
| Old Query | Old Method | New Logic Summary |
|---|---|---|
spBalanceOfCollateralQuery | balance_of_collateral | User.collateral (converted to USD). |
spBalanceOfBorrowQuery | balance_of_borrow | User.usdc_position (Borrowed) * usdc_borrow_index. |
spGetUserUnlentQuery | get_user_unlent | User.usdc_position (Supplied) * usdc_supply_index. |
spGetUserLentQuery | get_user_lent | Deprecated. (All deposits are now fully lent/supplied). |
spGetBorrowThresholdQuery | get_borrow_threshold | ContractConfigView.borrow_threshold. |
spGetWithdrawThresholdQuery | get_withdraw_threshold | ContractConfigView.withdraw_threshold. |
spGetLiquidationThresholdQuery | get_liquidation_threshold | ContractConfigView.liquidation_threshold. |
spGetLiquidationWarningThresholdQuery | get_liquidation_warning_threshold | Deprecated. Hardcode in frontend. |
spGetMaximumWithdrawableQuery | get_maximum_withdrawable | Client-side calculation (Collateral - Borrowed/Threshold). |
spGetCollateralValueQuery | get_collateral_value | User.collateral * Prices. |
spCalculateLtvQuery | calculate_ltv | User Borrowed Value / User Collateral Value. |
spGetAccumulatedInterestQuery | get_accumulated_interest | Deferred to V2 Indexer. |
spGetAnnualPercentageRateQuery | get_annual_percentage_rate | ContractConfigView.usdc_base_borrow_rate. |
spGetAnnualPercentageYieldQuery | get_annual_percentage_yield | Not Applicable. |
spGetMinimumBorrowableQuery | get_smaller_operations_amount | Hardcode in frontend. |
spGetMaximumBorrowableAmountQuery | composed | Borrowing Power - Current Borrow Value. |
spBalanceOfAllMainCollateralsQuery | composed | Aggregate User.collateral values. |
spIsAccountAtRiskQuery | is_account_at_risk | Client-side check: Current LTV > Hardcoded Limit. |
spGetAccountPendingLiquidationNotificationsQuery | … | Deprecated. |
Detailed Integration Guide
spBalanceOfCollateralQuery
Represents the collateral deposited by a User.
- Source:
Userstruct (collateralfield). - Logic: Iterate through the map. Use Hermes API to convert amounts to USD if total value is needed.
spBalanceOfBorrowQuery
Represents the amount borrowed by a User (including accrued interest).
- Source:
Userstruct (usdc_position) &ContractState(usdc_borrow_index). - Formula:
- If
usdc_positionisBorrowed(shares):shares * usdc_borrow_index.
- If
spGetUserUnlentQuery
Represents the total USDC supplied by the lender that can be withdrawn.
- Source:
Userstruct (usdc_position) &ContractState(usdc_supply_index). - Formula:
- If
usdc_positionisSupplied(shares):shares * usdc_supply_index.
- If
spGetBorrowThresholdQuery, spGetWithdrawThresholdQuery, spGetLiquidationThresholdQuery
- Source:
ContractConfigViewfields:borrow_thresholdwithdraw_thresholdliquidation_threshold
spGetMaximumWithdrawableQuery
Maximum amount (USDC) that can be withdrawn. Do note that this is an approximation of the maximum appoint since the current price fluctuating and interest also gets accumulated as seconds pass.
- Logic (USDC):
- Fetch Pyth/Hermes data.
- Perform client-side interest accrual (refer to Liquidator bot implementation for logic).
- Calculate total supplied balance (like
spGetUserUnlentQuery).
- Logic (Collateral - returned in USDC value):
- Fetch Pyth/Hermes data.
- Perform client-side interest accrual.
- Compute
Total Borrow Valueof user. - Compute
Total Collateral Valueof user. - Formula:
Total Collateral Value - (Total Borrow Value / withdraw_threshold)
spGetMaximumBorrowableAmountQuery
Maximum additional amount that can be borrowed.
- Formula:
Borrowing Power - Current Borrow ValueBorrowing Power:Total Collateral Value * borrow_thresholdCurrent Borrow Value:User Borrow Shares * Borrow Index
spGetAnnualPercentageRateQuery
Borrow rate at zero utilization.
- Source:
ContractConfigView.usdc_base_borrow_rate
User Actions (Transactions)
These are the write operations performed by the user.
Deposit
- USDC: Use
ft_transfer_callon the USDC token contract, passing the protocol contract as the receiver. - Collateral: Use
ft_transfer_callon the specific collateral token contract.
Withdraw
- USDC: Call
withdraw_usdcon the protocol contract. - Collateral: Call
withdraw_collateralon the protocol contract.
Borrow USDC
Call borrow_usdc on the protocol contract.
Repay USDC
Send USDC using ft_transfer_call on the USDC token contract to the protocol contract. The contract will automatically interpret this as a repayment.