Market Creation
Complete guide to creating Lotus markets with MarketParams construction, IRM and liquidation parameter encoding, and calling createMarket with examples.
1
MarketParams memory params = MarketParams({
loanToken: 0xA0b8...USDC, // ERC-20 that lenders supply
irm: 0x1234...AdaptiveLinearKinkIrm, // Must be enabled
liquidationModule: 0x5678...OracleIncentiveModule, // Must be enabled
collateralTokens: new address[](3),
oracles: new address[](3),
lltvs: new uint128[](3)
});
// Tranche 0 (senior): WETH collateral, 80% LLTV
params.collateralTokens[0] = 0xC02a...WETH;
params.oracles[0] = 0xABCD...ETH_USDC_Oracle;
params.lltvs[0] = 0.80e18;
// Tranche 1 (mid): wstETH collateral, 85% LLTV
params.collateralTokens[1] = 0x7f39...wstETH;
params.oracles[1] = 0xBCDE...wstETH_USDC_Oracle;
params.lltvs[1] = 0.85e18;
// Tranche 2 (junior): cbBTC collateral, 90% LLTV
params.collateralTokens[2] = 0x2260...cbBTC;
params.oracles[2] = 0xCDEF...cbBTC_USDC_Oracle;
params.lltvs[2] = 0.90e18;Field
Description
2
AdaptiveLinearKinkIrm
import {IAdaptiveLinearKinkIrm} from "lotus/irms/interfaces/IAdaptiveLinearKinkIrm.sol";
AdaptiveConfig[] memory configs = new AdaptiveConfig[](3);
configs[0] = AdaptiveConfig({
targetUtilization: 0.90e18, // 90% target
initialRateAtTarget: 634195839, // ~2% APR in WAD per second
minRateAtTarget: 317097919, // ~1% APR floor
maxRateAtTarget: 3170979198, // ~10% APR ceiling
adjustmentSpeed: 0.5e18, // Adaptation speed
curveParameter: 4e18, // Curve steepness (1e18–10e18)
gracePeriod: 7 days, // No adaptation during grace period
minUpdateInterval: 1 hours, // Minimum time between updates
maxRateChange: 0.10e18 // Max 10% change per update
});
// ... repeat for configs[1], configs[2]
bytes memory irmParams = abi.encode(operatorAddress, configs);FixedRateIrm
uint256[] memory fixedRates = new uint256[](3);
fixedRates[0] = 634195839; // ~2% APR in WAD per second
fixedRates[1] = 1268391679; // ~4% APR
fixedRates[2] = 1902587519; // ~6% APR
bytes memory irmParams = abi.encode(operatorAddress, fixedRates);ManagedLinearKinkIrm
import {IBaseLinearKinkIrm} from "lotus/irms/interfaces/IBaseLinearKinkIrm.sol";
TrancheRateConfig[] memory configs = new TrancheRateConfig[](3);
configs[0] = TrancheRateConfig({
targetUtilization: 0.90e18, // Kink at 90%
baseBorrowRate: 317097919, // ~1% APR at 0% utilization
gentleSlope: 352331021, // Gradual increase below kink
targetBorrowRate: 634195839, // ~2% APR at kink
steepSlope: 3523310216 // Steep increase above kink
});
// ... repeat for configs[1], configs[2]
bytes memory irmParams = abi.encode(operatorAddress, configs);Converting APR to WAD per Second
ratePerSecond = APR_WAD / SECONDS_PER_YEAR3
OracleIncentiveLiquidationModule
uint256[] memory factors = new uint256[](3);
factors[0] = 1.05e18; // 5% incentive for tranche 0 (senior)
factors[1] = 1.08e18; // 8% incentive for tranche 1
factors[2] = 1.10e18; // 10% incentive for tranche 2 (junior)
bytes memory liquidationParams = abi.encode(operatorAddress, factors);4
lotus.createMarket(params, irmParams, liquidationParams);5
import {MarketParamsLib} from "lotus/libraries/MarketParamsLib.sol";
Id marketId = MarketParamsLib.id(params);
MarketParams memory stored = lotus.getMarketParams(marketId);
assert(stored.loanToken == params.loanToken);
uint256 numTranches = lotus.getNumMarketTranches(marketId);
assert(numTranches == 3);TypeScript Example
import { ethers } from "ethers";
const signer = new ethers.Wallet(PRIVATE_KEY, provider);
const lotus = new ethers.Contract(LOTUS_ADDRESS, lotusAbi, signer);
// 1. Build MarketParams
const marketParams = {
loanToken: USDC_ADDRESS,
irm: ADAPTIVE_IRM_ADDRESS,
liquidationModule: ORACLE_INCENTIVE_MODULE_ADDRESS,
collateralTokens: [WETH_ADDRESS, WSTETH_ADDRESS, CBBTC_ADDRESS],
oracles: [ETH_ORACLE, WSTETH_ORACLE, CBBTC_ORACLE],
lltvs: [
ethers.parseUnits("0.80", 18),
ethers.parseUnits("0.85", 18),
ethers.parseUnits("0.90", 18),
],
};
// 2. Encode IRM params (FixedRateIrm example)
const fixedRates = [634195839n, 1268391679n, 1902587519n];
const irmParams = ethers.AbiCoder.defaultAbiCoder().encode(
["address", "uint256[]"],
[OPERATOR_ADDRESS, fixedRates]
);
// 3. Encode liquidation params
const factors = [
ethers.parseUnits("1.05", 18),
ethers.parseUnits("1.08", 18),
ethers.parseUnits("1.10", 18),
];
const liquidationParams = ethers.AbiCoder.defaultAbiCoder().encode(
["address", "uint256[]"],
[OPERATOR_ADDRESS, factors]
);
// 4. Create market
const tx = await lotus.createMarket(marketParams, irmParams, liquidationParams);
await tx.wait();See Also
Last updated

