Osito Protocol API Documentation

This document provides technical reference for developers integrating with Osito Protocol, focusing on the smart contract interfaces and key patterns.

Core Contracts

OsitoToken

The contract responsible for token verification and eligibility checks against the objective criteria.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IOsitoToken {
    // Check if a token is eligible for use in the protocol
    function isEligibleToken(address token) external view returns (bool);
    
    // Get the total fixed supply of a token
    function getTokenTotalSupply(address token) external view returns (uint256);
    
    // Get the amount of tokens in the Kodiak pool
    function getTokensInPool(address token) external view returns (uint256);
    
    // Get the amount of wBERA in the Kodiak pool
    function getWberaInPool(address token) external view returns (uint256);
    
    // Get the percentage of LP tokens burned
    function getBurnedLpPercentage(address token) external view returns (uint256);
    
    // Get the Kodiak pool address for a token
    function getPoolAddress(address token) external view returns (address);
}

OsitoLending

The main contract handling all lending, borrowing, staking, and liquidation operations.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IOsitoLending {
    struct Position {
        address owner;
        address token;
        uint256 tokenAmount;
        uint256 borrowedAmount;
        uint256 lastUpdateTimestamp;
    }
    
    struct TokenData {
        uint256 totalDeposited;
        uint256 totalBorrowed;
        uint256 tokenRate;
        uint256 lastUpdateTimestamp;
        uint256 totalStaked;
    }
    
    // Create a new position by depositing token
    // Returns the ID of the newly created position
    function createPosition(address token, uint256 amount) external returns (uint256);
    
    // Close a position and withdraw collateral
    function closePosition(uint256 positionId) external;
    
    // Borrow wBERA against a position
    function borrow(uint256 positionId, uint256 amount) external;
    
    // Repay a loan (use type(uint256).max for full repayment)
    function repay(uint256 positionId, uint256 amount) external;
    
    // Liquidate a position
    function liquidate(uint256 positionId) external;
    
    // Stake tokens to earn yield
    function stake(address token, uint256 amount) external;
    
    // Unstake tokens
    function unstake(address token, uint256 amount) external;
    
    // Supply wBERA to the lending pool
    function supplyWbera(uint256 amount) external;
    
    // Withdraw wBERA from the lending pool
    function withdrawWbera(uint256 amount) external;
    
    // Calculate global maximum borrowable amount for a token
    function calculateMaxBorrow(address token) external view returns (uint256);
    
    // Calculate position-specific maximum borrowable amount
    function calculatePositionMaxBorrow(uint256 positionId) external view returns (uint256);
}

Key Functions Reference

Position Management

createPosition(address token, uint256 amount)

Creates a new lending position with token collateral.

Parameters:

  • token: Address of the token to deposit as collateral (must be eligible)
  • amount: Amount of tokens to deposit (minimum 0.1% of total supply)

Returns: Position ID (uint256)

Reverts When:

  • Token is not eligible
  • Amount is zero
  • Amount is too small relative to token supply (< 0.1% of total)
  • Token transfer fails

closePosition(uint256 positionId)

Closes a position and returns the collateral to the owner.

Parameters:

  • positionId: ID of the position to close

Reverts When:

  • Caller is not the position owner
  • Position still has outstanding debt

borrow(uint256 positionId, uint256 amount)

Borrows wBERA against the token collateral in a position.

Parameters:

  • positionId: ID of the position to borrow against
  • amount: Amount of wBERA to borrow

Reverts When:

  • Amount is below minimum threshold (0.001 wBERA)
  • Caller is not the position owner
  • Amount exceeds position's borrowing capacity
  • Insufficient wBERA in the protocol

repay(uint256 positionId, uint256 amount)

Repays borrowed wBERA against a position.

Parameters:

  • positionId: ID of the position to repay
  • amount: Amount of wBERA to repay (use type(uint256).max for full repayment)

Reverts When:

  • Caller is not the position owner
  • Transfer of wBERA fails

Staking Functions

stake(address token, uint256 amount)

Stakes tokens to earn yield.

Parameters:

  • token: Address of the token to stake (must be eligible)
  • amount: Amount of tokens to stake

Reverts When:

  • Token is not eligible
  • Amount is zero
  • Token transfer fails

unstake(address token, uint256 amount)

Unstakes tokens and collects yield.

Parameters:

  • token: Address of the token to unstake
  • amount: Amount of tokens to unstake

Reverts When:

  • Amount exceeds staked amount
  • Unstaking would make total borrowed exceed max borrow

Lending Functions

supplyWbera(uint256 amount)

Supplies wBERA to the lending pool to earn interest.

Parameters:

  • amount: Amount of wBERA to supply

Reverts When:

  • Amount is zero
  • Transfer fails

withdrawWbera(uint256 amount)

Withdraws wBERA from the lending pool along with accrued interest.

Parameters:

  • amount: Amount of wBERA to withdraw

Reverts When:

  • Amount exceeds available balance
  • Withdrawal would make total borrowed exceed total supplied

Liquidation Functions

liquidate(uint256 positionId)

Liquidates an underwater position by repaying its debt and claiming its collateral.

Parameters:

  • positionId: ID of the position to liquidate

Reverts When:

  • Position is not liquidatable (borrowed ≤ max borrow)
  • Liquidator doesn't have enough wBERA to cover the debt

Key Events

// Position events
event PositionCreated(uint256 indexed positionId, address indexed owner, address token, uint256 amount);
event PositionClosed(uint256 indexed positionId);
event Borrowed(uint256 indexed positionId, uint256 amount);
event Repaid(uint256 indexed positionId, uint256 amount);
event Liquidated(uint256 indexed positionId, address liquidator, address token, uint256 tokenAmount, uint256 wberaAmount);

// Staking events
event Staked(address indexed staker, address indexed token, uint256 amount);
event Unstaked(address indexed staker, address indexed token, uint256 amount);
event YieldCollected(address indexed staker, address indexed token, uint256 yieldAmount);

// wBERA events
event WberaSupplied(address indexed supplier, uint256 amount);
event WberaWithdrawn(address indexed supplier, uint256 amount);
event YieldCollectedWbera(address indexed supplier, uint256 yieldAmount);

Integration Patterns

Token Eligibility Verification

// Check if a token is eligible for use
bool isEligible = ositoToken.isEligibleToken(tokenAddress);
if (!isEligible) {
    // Handle ineligible token
    return;
}

// For eligible tokens, you can get additional info
uint256 totalSupply = ositoToken.getTokenTotalSupply(tokenAddress);
uint256 tokensInPool = ositoToken.getTokensInPool(tokenAddress);
uint256 wberaInPool = ositoToken.getWberaInPool(tokenAddress);
uint256 burnedLpPercentage = ositoToken.getBurnedLpPercentage(tokenAddress);

Creating and Managing Positions

// First approve the token transfer
await tokenContract.approve(ositoLendingAddress, amount);

// Create a position
uint256 positionId = await ositoLending.createPosition(tokenAddress, amount);

// Calculate borrowing capacity
uint256 maxBorrow = await ositoLending.calculatePositionMaxBorrow(positionId);

// Borrow wBERA against the position
await ositoLending.borrow(positionId, borrowAmount);

// Repay the loan
await wberaContract.approve(ositoLendingAddress, repayAmount);
await ositoLending.repay(positionId, repayAmount);

// Close the position after full repayment
await ositoLending.closePosition(positionId);

Working with Liquidations

// Check if a position is liquidatable
const position = await ositoLending.positions(positionId);
const maxBorrow = await ositoLending.calculatePositionMaxBorrow(positionId);
const isLiquidatable = position.borrowedAmount > maxBorrow;

if (isLiquidatable) {
    // Approve wBERA for repayment
    await wberaContract.approve(ositoLendingAddress, position.borrowedAmount);
    
    // Liquidate the position
    await ositoLending.liquidate(positionId);
}

Error Handling

All Osito contracts use revert with descriptive error messages. Common errors include:

// Token verification errors
"OsitoToken: Not from verified deployer"
"OsitoToken: No LP burn detected"

// Position management errors
"OsitoLending: Token not eligible"
"OsitoLending: Amount must be greater than 0"
"OsitoLending: Amount too small relative to token supply"
"OsitoLending: Not position owner"
"OsitoLending: Position has debt"
"OsitoLending: Exceeds position max borrow"
"OsitoLending: Insufficient wBERA"

// Liquidation errors
"OsitoLending: Position not liquidatable"

// Staking errors
"OsitoLending: Not enough staked tokens"
"OsitoLending: Unstaking would make total borrowed exceed max borrow"

// wBERA errors
"OsitoLending: Not enough supplied wBERA"
"OsitoLending: Withdrawal would make total borrowed exceed total supplied"

Gas Optimization Tips

  1. Batch operations where possible to save on gas costs
  2. Monitor state updates - the protocol updates state at each critical operation
  3. Use view functions like calculateMaxBorrow to estimate capacity before transactions
  4. Approve exact amounts rather than unlimited approvals for better security
  5. Check position capacity before attempting to borrow to avoid failed transactions

Additional Resources


This documentation is maintained by the Osito Protocol development team. For questions or support, join our Discord or create an issue in our GitHub repository.