Risk and Access
Update Market Config
Set the on-chain risk parameters for a market
POST
/
lending-external-securities-v2
/
api
/
markets
/
{marketId}
/
config
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/markets/{marketId}/config" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"config": {
"collateralFactor": 7000,
"liquidationThreshold": 8000,
"liquidationPenalty": 500,
"protocolFeeRate": 1000,
"minBorrowAmount": "1000",
"closeFactor": 5000,
"maxTotalCollateral": "0",
"maxUserCollateral": "0",
"useDutchAuction": false,
"auctionDuration": 3600,
"auctionStartPremium": 13000,
"auctionMinPremium": 9500
}
}'
const base = `https://api.trusset.org/lending-external-securities-v2/api/markets/${marketId}`;
const headers = { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' };
const current = (await (await fetch(`${base}/config`, { headers })).json()).data;
const config = {
collateralFactor: 7000,
liquidationThreshold: Number(current.liquidationThreshold),
liquidationPenalty: Number(current.liquidationPenalty),
protocolFeeRate: Number(current.protocolFeeRate),
minBorrowAmount: current.minBorrowAmount,
closeFactor: Number(current.closeFactor),
maxTotalCollateral: current.maxTotalCollateral,
maxUserCollateral: current.maxUserCollateral,
useDutchAuction: current.useDutchAuction,
auctionDuration: Number(current.auctionDuration),
auctionStartPremium: Number(current.auctionStartPremium),
auctionMinPremium: Number(current.auctionMinPremium)
};
const build = await fetch(`${base}/config`, {
method: 'POST',
headers,
body: JSON.stringify({ config })
});
const { data: calldata } = await build.json();
const tx = await wallet.sendTransaction(calldata.transaction);
await tx.wait();
const confirm = await fetch(`${base}/config`, {
method: 'POST',
headers,
body: JSON.stringify({ config, txHash: tx.hash })
});
const { data } = await confirm.json();
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "setConfig",
"requiredRole": "ISSUER_ROLE",
"heldByThisInstance": true,
"signerAddress": "0x5ad87a0621175206b72d10e4b8577b192e7f40ab"
}
}
{
"success": true,
"data": {
"txHash": "0x9f2c41d8b7e05a3164c2870fbd935e1a4c7802db6135ea9048f7c21b5d3ea41b",
"publicListingWithdrawn": false
}
}
{
"success": false,
"error": {
"code": "CONFIG_CHANGE_TOO_LARGE",
"message": "The liquidation threshold can move at most 10 percentage points per update; it is 8500 bps now. Stage the change across multiple updates."
}
}
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": [
{ "field": "config.collateralFactor", "message": "Number must be less than or equal to 9500" }
]
}
}
Writes the market’s full
The venue admission check is the API’s own. The contract does not test it, but a venue the collateral token refuses makes every realization revert when seized collateral is delivered to it.
A check that has to read the chain, such as the current threshold or the term penalty, is skipped when that read fails. The contract still enforces every rule in the table except venue admission, so a violation that slips through reverts on-chain instead.
A market whose
Confirming with
config struct. Every field is required on every call, so read the current values with Get Market Config first and send them back with your changes applied. Partial updates are not supported: an omitted field fails validation rather than retaining its current value.
Requires ISSUER_ROLE on the market contract. The lender of record names the wallet that holds it when it takes the market, so that wallet may sit outside your instance. heldByThisInstance on the calldata response says whether it does.
The market brings its interest accrual up to date under the old values before the new ones apply.
Changing
liquidationThreshold moves the point at which existing loans become liquidatable. Lowering it immediately puts loans at risk that were healthy a moment earlier. The contract caps each change at 10 percent per call. That cap is counted in percentage points of the threshold: from 8500, one call reaches anywhere from 7500 to 9500.Path Parameters
string
required
Body Parameters
object
required
Show child attributes
Show child attributes
integer
required
Maximum loan to value for new borrowing, in basis points. The schema accepts 1000 to 9500, but anything above 9000 is refused with
INVALID_CONFIG, because the contract caps it at 90 percent.integer
required
Loan to value at which a loan becomes liquidatable, in basis points. The schema accepts 1000 to 9800, but anything above 9500 is refused with
INVALID_CONFIG. Must exceed collateralFactor to leave borrowers any buffer, and may move at most 1000 from its current value in one call.integer
required
Penalty on liquidated debt in basis points. 0 to 5000. It cannot drop below the market’s term penalty, set with Set Term Config.
integer
required
The insurance-fund rate, in basis points. 0 to 10000, and 0 on a new market. Repaid interest first loses Trusset’s 15 percent infrastructure fee, then the fixed 8 percent operator and 5 percent distributor shares of the remainder. This rate of what is left goes to the market’s insurance fund, and the rest to liquidity providers.
string
required
Minimum borrow per loan, as a decimal string in borrow asset units.
integer
required
Maximum fraction of a loan’s debt repayable in one liquidation, in basis points. 1000 to 5000.
string
required
Global collateral cap as a decimal string in collateral token units.
"0" means uncapped.string
required
Per-borrower collateral cap as a decimal string in collateral token units.
"0" means uncapped.boolean
required
Whether liquidations open a Dutch auction. Rejected on-chain when the market’s
priceSource is MARKET. Turning it on also needs an auction venue wired to the market and admitted on the collateral token.integer
required
Auction length in seconds. 600 to 86400. The schema applies this range even while
useDutchAuction is false.integer
required
Opening price multiplier in basis points. 10000 to 20000, where 10000 is oracle price. Must exceed
auctionMinPremium while auctions are on.integer
required
Floor price multiplier in basis points. 8000 to 10000. Floored at 9800 on-chain when
priceSource is MARKET.string
Hash of the transaction you broadcast for this operation. Send it to confirm the transaction and record the result. Omit it to receive the calldata. The confirm call must repeat the full
config object, because the body is validated before txHash is read.maxPriceAge is not part of this struct. It is an oracle setting, not a market setting, and it is read from Get Oracle Status rather than written here. It still interacts directly with your NAV publication cadence. A fund that publishes NAV daily needs maxPriceAge above 86400 seconds. Otherwise opening loans, drawing more, withdrawing collateral against open debt and liquidating revert against a stale price between publications. A FIXED market’s oracle never reports its price as stale, so the window does not apply there.Checks Run Before a Signature
The per-field ranges above are what the request schema accepts. Before building calldata, the API also runs the contract’s cross-field rules and two checks on the auction venue. No signature is asked for a tuple that would revert with a bare selector.| Rule | Refused with |
|---|---|
collateralFactor at most 9000, whatever the schema allows | INVALID_CONFIG |
liquidationThreshold at most 9500, whatever the schema allows | INVALID_CONFIG |
liquidationThreshold strictly greater than collateralFactor | INVALID_CONFIG |
auctionStartPremium strictly greater than auctionMinPremium, when auctions are on | INVALID_CONFIG |
liquidationPenalty not below the market’s term penalty | INVALID_CONFIG |
liquidationThreshold within 1000 of its current value | CONFIG_CHANGE_TOO_LARGE |
An auction venue is wired before useDutchAuction turns on | AUCTION_MODULE_NOT_SET |
| That venue is admitted on the collateral token | AUCTION_VENUE_NOT_ADMITTED |
priceSource is MARKET cannot run Dutch auctions at all, and needs an auctionMinPremium of at least 9800, refused otherwise with INVALID_CONFIG. Turning auctions on there is refused with AUCTION_MODULE_NOT_SET while no venue is wired, and the API never wires one on such a market. A venue wired by other means leads to AUCTION_UNSUPPORTED_PRICE_SOURCE instead.
Confirming a configuration with
useDutchAuction off withdraws the market from the public liquidation feed. Auctions are what makes a realization publicly actionable, so a market without them would otherwise keep advertising a participation route that no longer exists. The confirm response reports it as publicListingWithdrawn. The API decides from the configuration read back from the chain after the transaction, and falls back to the config you sent when that read fails.Response Fields
object
Show child attributes
Show child attributes
string
SIGN_TRANSACTION. Returned when txHash is omitted.object
Unsigned transaction for the
setConfig call, { to, data, value, chainId }, targeting the market contract. Returned when txHash is omitted.string
setConfig. Returned when txHash is omitted.string
ISSUER_ROLE, the role the signing wallet must hold on the market. Returned when txHash is omitted.boolean
true when a verified wallet of your instance holds ISSUER_ROLE, false when every wallet was checked and none does, null when the check could not be completed. A false means another party has to sign. The build is never refused on it. Returned when txHash is omitted.string
The wallet of your instance found holding
ISSUER_ROLE, or null when none was. Returned when txHash is omitted.string
Transaction hash. Returned when confirming.
boolean
true when this confirm took the market off the public liquidation feed because Dutch auctions are off. false when auctions are on, or the market was not listed. Returned when confirming.curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/markets/{marketId}/config" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"config": {
"collateralFactor": 7000,
"liquidationThreshold": 8000,
"liquidationPenalty": 500,
"protocolFeeRate": 1000,
"minBorrowAmount": "1000",
"closeFactor": 5000,
"maxTotalCollateral": "0",
"maxUserCollateral": "0",
"useDutchAuction": false,
"auctionDuration": 3600,
"auctionStartPremium": 13000,
"auctionMinPremium": 9500
}
}'
const base = `https://api.trusset.org/lending-external-securities-v2/api/markets/${marketId}`;
const headers = { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' };
const current = (await (await fetch(`${base}/config`, { headers })).json()).data;
const config = {
collateralFactor: 7000,
liquidationThreshold: Number(current.liquidationThreshold),
liquidationPenalty: Number(current.liquidationPenalty),
protocolFeeRate: Number(current.protocolFeeRate),
minBorrowAmount: current.minBorrowAmount,
closeFactor: Number(current.closeFactor),
maxTotalCollateral: current.maxTotalCollateral,
maxUserCollateral: current.maxUserCollateral,
useDutchAuction: current.useDutchAuction,
auctionDuration: Number(current.auctionDuration),
auctionStartPremium: Number(current.auctionStartPremium),
auctionMinPremium: Number(current.auctionMinPremium)
};
const build = await fetch(`${base}/config`, {
method: 'POST',
headers,
body: JSON.stringify({ config })
});
const { data: calldata } = await build.json();
const tx = await wallet.sendTransaction(calldata.transaction);
await tx.wait();
const confirm = await fetch(`${base}/config`, {
method: 'POST',
headers,
body: JSON.stringify({ config, txHash: tx.hash })
});
const { data } = await confirm.json();
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "setConfig",
"requiredRole": "ISSUER_ROLE",
"heldByThisInstance": true,
"signerAddress": "0x5ad87a0621175206b72d10e4b8577b192e7f40ab"
}
}
{
"success": true,
"data": {
"txHash": "0x9f2c41d8b7e05a3164c2870fbd935e1a4c7802db6135ea9048f7c21b5d3ea41b",
"publicListingWithdrawn": false
}
}
{
"success": false,
"error": {
"code": "CONFIG_CHANGE_TOO_LARGE",
"message": "The liquidation threshold can move at most 10 percentage points per update; it is 8500 bps now. Stage the change across multiple updates."
}
}
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": [
{ "field": "config.collateralFactor", "message": "Number must be less than or equal to 9500" }
]
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
MISSING_MARKET_ID | 400 | The marketId path segment is longer than 100 characters |
NO_MARKET_ADDRESS | 400 | The market has no on-chain address recorded |
VALIDATION_ERROR | 400 | A config field is missing or outside its accepted range, or txHash is malformed. error.details names each offending field |
INVALID_CONFIG | 400 | A cross-field rule the contract enforces was broken. The message names which one |
CONFIG_CHANGE_TOO_LARGE | 400 | liquidationThreshold would move more than 1000 from its current value. Stage the change across several calls |
AUCTION_UNSUPPORTED_PRICE_SOURCE | 400 | Dutch auctions were turned on for a market whose priceSource is MARKET |
CONFIG_UPDATE_FAILED | 400 | The calldata could not be built, for example because an amount carries more decimal places than its token supports. On the confirm call, the receipt could not be read |
MARKET_NOT_FOUND | 404 | No market with this ID on your instance |
AUCTION_MODULE_NOT_SET | 409 | useDutchAuction is true and no auction venue is wired to the market. Wire one with Wire Auction Module first |
AUCTION_VENUE_NOT_ADMITTED | 409 | The wired auction venue is not admitted on the collateral token, so every realization delivering to it would revert |
MARKET_PENDING_CURATOR | 409 | The market has no lender of record yet, so nobody holds the ISSUER_ROLE this change requires. Skipped when confirming with txHash |
txHash can also return any transaction verification error. On this endpoint every one of them answers 400, including TX_NOT_FOUND.⌘I
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/markets/{marketId}/config" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"config": {
"collateralFactor": 7000,
"liquidationThreshold": 8000,
"liquidationPenalty": 500,
"protocolFeeRate": 1000,
"minBorrowAmount": "1000",
"closeFactor": 5000,
"maxTotalCollateral": "0",
"maxUserCollateral": "0",
"useDutchAuction": false,
"auctionDuration": 3600,
"auctionStartPremium": 13000,
"auctionMinPremium": 9500
}
}'
const base = `https://api.trusset.org/lending-external-securities-v2/api/markets/${marketId}`;
const headers = { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' };
const current = (await (await fetch(`${base}/config`, { headers })).json()).data;
const config = {
collateralFactor: 7000,
liquidationThreshold: Number(current.liquidationThreshold),
liquidationPenalty: Number(current.liquidationPenalty),
protocolFeeRate: Number(current.protocolFeeRate),
minBorrowAmount: current.minBorrowAmount,
closeFactor: Number(current.closeFactor),
maxTotalCollateral: current.maxTotalCollateral,
maxUserCollateral: current.maxUserCollateral,
useDutchAuction: current.useDutchAuction,
auctionDuration: Number(current.auctionDuration),
auctionStartPremium: Number(current.auctionStartPremium),
auctionMinPremium: Number(current.auctionMinPremium)
};
const build = await fetch(`${base}/config`, {
method: 'POST',
headers,
body: JSON.stringify({ config })
});
const { data: calldata } = await build.json();
const tx = await wallet.sendTransaction(calldata.transaction);
await tx.wait();
const confirm = await fetch(`${base}/config`, {
method: 'POST',
headers,
body: JSON.stringify({ config, txHash: tx.hash })
});
const { data } = await confirm.json();
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "setConfig",
"requiredRole": "ISSUER_ROLE",
"heldByThisInstance": true,
"signerAddress": "0x5ad87a0621175206b72d10e4b8577b192e7f40ab"
}
}
{
"success": true,
"data": {
"txHash": "0x9f2c41d8b7e05a3164c2870fbd935e1a4c7802db6135ea9048f7c21b5d3ea41b",
"publicListingWithdrawn": false
}
}
{
"success": false,
"error": {
"code": "CONFIG_CHANGE_TOO_LARGE",
"message": "The liquidation threshold can move at most 10 percentage points per update; it is 8500 bps now. Stage the change across multiple updates."
}
}
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": [
{ "field": "config.collateralFactor", "message": "Number must be less than or equal to 9500" }
]
}
}
