Liquidity
Remove Liquidity
Burn LP shares and withdraw the borrow asset
POST
/
lending-external-securities-v2
/
api
/
positions
/
{marketId}
/
remove-liquidity
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/remove-liquidity" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"shares": "50000", "provider": "0x2b6ed29a95753c3ad948348e3e7b1a251080ffb9"}'
const url = `https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/remove-liquidity`;
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ shares: '50000', provider: await wallet.getAddress() })
});
const { data } = await res.json();
const tx = await wallet.sendTransaction(data.transaction);
await tx.wait();
await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ shares: '50000', txHash: tx.hash })
});
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "removeLiquidity",
"quoteValidForSeconds": 120,
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/remove-liquidity",
"field": "txHash"
}
}
}
{
"success": true,
"data": {
"txHash": "0x9f2c41d8b7e05a3164c2870fbd935e1a4c7802db6135ea9048f7c21b5d3ea41b",
"sharesRedeemed": "50000.0",
"amount": "50082.576"
}
}
{
"success": false,
"error": {
"code": "INSUFFICIENT_LIQUIDITY",
"message": "The market has 0.0 USDC of uncommitted liquidity, which is less than the 50082.576 USDC this redemption is worth once the interest accruing over the next 120 seconds is reserved. Wait for borrowers to repay, then retry."
}
}
Redeems LP shares for the borrow asset at the current share price, which includes accrued interest. No approval is needed, so this is a single transaction signed by the provider.
Any provider holding shares can redeem, including one that deposited before its market limited direct deposits to the operator wallet and registered vaults. A paused market does not block redemption.
A redemption that reached the market through another contract confirms from the market’s
shares is always parsed at 18 decimals, regardless of the market’s borrow asset. Unlike amount on Add Liquidity, it does not follow the borrow asset’s precision. Read a provider’s share balance from Get Provider Balance and pass it through unchanged.Path Parameters
string
required
Body Parameters
string
LP shares to redeem as a positive decimal string with up to 18 decimal places, for example
"50000". Required when building calldata. The confirm call needs only txHash: the redeemed figure comes from the mined transaction, and a shares sent alongside is validated but not used.string
Wallet holding the shares, and the wallet that will sign. Required when building calldata. Two checks run against it: the provider’s own share balance, and whether the pool can pay what those shares are worth. Neither can be asked without the address, so omitting it returns
PROVIDER_REQUIRED.A redemption that fails either check is refused with INSUFFICIENT_SHARES or INSUFFICIENT_LIQUIDITY, instead of handing back calldata that reverts. Not needed on the confirm call, where the provider is taken from the mined transaction.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.
Response Fields
object
Show child attributes
Show child attributes
string
SIGN_TRANSACTION when txHash is omitted.object
Unsigned transaction,
{ to, data, value, chainId }, for the removeLiquidity call. Returned when txHash is omitted.string
removeLiquidity. Returned when txHash is omitted.integer
120, how long the liquidity check behind this payload holds. The check reserves the interest the book accrues over that window, so a payload broadcast inside it is not refused for liquidity that accrual consumed. Absent when the check did not run, because the market metrics could not be read or the provider’s shares are worth nothing.object
{ endpoint, field }: this route, with txHash as the field. Returned when txHash is omitted.string
Transaction hash. Returned when confirming with
txHash.string
Shares actually burned, read from the
LiquidityRemoved event, at 18 decimals. Returned when confirming with txHash.string
Settlement amount that actually left the pool, in borrow asset units.
null when the event could not be read from the receipt. Returned when confirming with txHash.Withdrawal is bounded by uncommitted liquidity, not by share balance. A provider holding shares worth more than the pool’s idle balance cannot exit fully while borrowers hold the difference, and the contract reverts rather than partially filling. The market’s reserve ratio holds liquidity back from borrowing only, so a redemption can draw on the reserved slice. Check
availableLiquidity on Get Market Metrics before redeeming a large position.curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/remove-liquidity" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"shares": "50000", "provider": "0x2b6ed29a95753c3ad948348e3e7b1a251080ffb9"}'
const url = `https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/remove-liquidity`;
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ shares: '50000', provider: await wallet.getAddress() })
});
const { data } = await res.json();
const tx = await wallet.sendTransaction(data.transaction);
await tx.wait();
await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ shares: '50000', txHash: tx.hash })
});
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "removeLiquidity",
"quoteValidForSeconds": 120,
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/remove-liquidity",
"field": "txHash"
}
}
}
{
"success": true,
"data": {
"txHash": "0x9f2c41d8b7e05a3164c2870fbd935e1a4c7802db6135ea9048f7c21b5d3ea41b",
"sharesRedeemed": "50000.0",
"amount": "50082.576"
}
}
{
"success": false,
"error": {
"code": "INSUFFICIENT_LIQUIDITY",
"message": "The market has 0.0 USDC of uncommitted liquidity, which is less than the 50082.576 USDC this redemption is worth once the interest accruing over the next 120 seconds is reserved. Wait for borrowers to repay, then retry."
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
NO_MARKET_ADDRESS | 400 | The market has no on-chain address recorded |
MISSING_MARKET_ID | 400 | marketId is longer than 100 characters |
VALIDATION_ERROR | 400 | shares is missing without txHash, is not a positive decimal string, or carries more than 18 decimal places, or provider or txHash is malformed |
PROVIDER_REQUIRED | 400 | provider was omitted while building calldata |
INSUFFICIENT_SHARES | 400 | shares exceeds the market’s outstanding shares, or the balance held by provider |
INSUFFICIENT_LIQUIDITY | 400 | The redemption is worth more than the pool can pay once accruing interest is reserved. When a smaller redemption would fill, the message names the largest share count that would |
MARKET_NOT_FOUND | 404 | No market with this ID on your instance |
MARKET_STATE_UNAVAILABLE | 503 | The market could not be read to check its outstanding shares or the provider’s balance. Retry shortly |
LiquidityRemoved event in the receipt. Confirming with txHash can also return any transaction verification error.⌘I
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/remove-liquidity" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"shares": "50000", "provider": "0x2b6ed29a95753c3ad948348e3e7b1a251080ffb9"}'
const url = `https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/remove-liquidity`;
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ shares: '50000', provider: await wallet.getAddress() })
});
const { data } = await res.json();
const tx = await wallet.sendTransaction(data.transaction);
await tx.wait();
await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ shares: '50000', txHash: tx.hash })
});
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "removeLiquidity",
"quoteValidForSeconds": 120,
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/remove-liquidity",
"field": "txHash"
}
}
}
{
"success": true,
"data": {
"txHash": "0x9f2c41d8b7e05a3164c2870fbd935e1a4c7802db6135ea9048f7c21b5d3ea41b",
"sharesRedeemed": "50000.0",
"amount": "50082.576"
}
}
{
"success": false,
"error": {
"code": "INSUFFICIENT_LIQUIDITY",
"message": "The market has 0.0 USDC of uncommitted liquidity, which is less than the 50082.576 USDC this redemption is worth once the interest accruing over the next 120 seconds is reserved. Wait for borrowers to repay, then retry."
}
}
