Coming Soon: The Developers section is under active development. Documentation will be available soon.
Overview
The OrderBook contract handles on-chain settlement for Centuari’s fixed-rate lending protocol.
Hybrid Architecture Note: Centuari uses a hybrid orderbook model. Order storage and matching happen off-chain for speed and zero gas costs. The on-chain contract handles settlement, position management, and CBT token operations.
Contract Address
| Network | Address |
|---|
| Arbitrum One | 0x... |
| Arbitrum Sepolia | 0x... |
Functions
placeLendOrder
Create a new lending order.
function placeLendOrder(
address asset,
uint256 amount,
uint256 rate,
uint256 maturity
) external returns (bytes32 orderId)
Parameters:
| Name | Type | Description |
|---|
| asset | address | Token to lend (USDC, etc.) |
| amount | uint256 | Amount to lend (in token decimals) |
| rate | uint256 | Fixed rate in basis points (800 = 8%) |
| maturity | uint256 | Maturity timestamp |
Returns: Order ID (bytes32)
Example:
// Lend 10,000 USDC at 8% for 90 days
bytes32 orderId = orderBook.placeLendOrder(
USDC_ADDRESS,
10000 * 1e6, // 10,000 USDC
800, // 8% APY
block.timestamp + 90 days
);
placeBorrowOrder
Create a new borrowing order.
function placeBorrowOrder(
address asset,
uint256 amount,
uint256 maxRate,
uint256 maturity
) external returns (bytes32 orderId)
Parameters:
| Name | Type | Description |
|---|
| asset | address | Token to borrow |
| amount | uint256 | Amount to borrow |
| maxRate | uint256 | Maximum acceptable rate (basis points) |
| maturity | uint256 | Maturity timestamp |
Requirements:
- Caller must have sufficient collateral deposited
- Health factor must remain > 1 after borrow
cancelOrder
Cancel an unfilled or partially filled order.
function cancelOrder(bytes32 orderId) external
Parameters:
| Name | Type | Description |
|---|
| orderId | bytes32 | ID of order to cancel |
Requirements:
- Caller must be order maker
- Order must not be fully filled
matchOrders
Execute matching between lend and borrow orders.
function matchOrders(
bytes32 lendOrderId,
bytes32 borrowOrderId
) external
Note: Typically called by keeper bots, but permissionless.
View Functions
getOrder
function getOrder(bytes32 orderId) external view returns (Order memory)
getOrderBook
function getOrderBook(
address asset,
uint256 maturity
) external view returns (
Order[] memory lends,
Order[] memory borrows
)
getBestRates
function getBestRates(
address asset,
uint256 maturity
) external view returns (
uint256 bestLendRate,
uint256 bestBorrowRate
)
Data Structures
Order
struct Order {
address maker; // Order creator
address asset; // Token address
uint256 amount; // Original amount
uint256 filledAmount; // Amount already matched
uint256 rate; // Rate in basis points
uint256 maturity; // Maturity timestamp
bool isLend; // true = lend, false = borrow
OrderStatus status; // Current status
uint256 createdAt; // Creation timestamp
}
enum OrderStatus {
Open,
PartiallyFilled,
Filled,
Cancelled
}
Events
event OrderPlaced(
bytes32 indexed orderId,
address indexed maker,
address asset,
uint256 amount,
uint256 rate,
uint256 maturity,
bool isLend
);
event OrderMatched(
bytes32 indexed lendOrderId,
bytes32 indexed borrowOrderId,
uint256 matchedAmount,
uint256 rate,
address cbtAddress
);
event OrderCancelled(
bytes32 indexed orderId,
uint256 unfilledAmount
);
event OrderExpired(
bytes32 indexed orderId
);
Error Codes
error InsufficientBalance();
error InsufficientCollateral();
error OrderNotFound();
error OrderNotCancellable();
error InvalidRate();
error InvalidMaturity();
error MatchingFailed();
Integration Example
import { ethers } from 'ethers';
const orderBook = new ethers.Contract(
ORDER_BOOK_ADDRESS,
ORDER_BOOK_ABI,
signer
);
// Place lend order
const tx = await orderBook.placeLendOrder(
USDC_ADDRESS,
ethers.parseUnits('10000', 6),
800, // 8%
Math.floor(Date.now() / 1000) + 90 * 24 * 60 * 60
);
const receipt = await tx.wait();
const event = receipt.events.find(e => e.event === 'OrderPlaced');
const orderId = event.args.orderId;
console.log(`Order placed: ${orderId}`);