Manage
Manage a leveraged position in an existing Credit Account with the SDK. Find your wallet's leveraged positions, then select the account you want to change. These operations update that account; they do not open a second leveraged position.
| Action | Effect on HF | Requirements and dependencies | Side effects |
|---|---|---|---|
| Repay | Increases HF by reducing debt while retaining collateral | Underlying tokens held in your wallet, or the supported unwrapped asset for an RWA market; partial repayment must respect minimum debt | Spends wallet funds and reduces future debt interest; partial repayment does not automatically reduce quotas |
| Adjust leverage | Increasing leverage generally lowers HF; decreasing leverage generally raises it | Available swap or redemption paths; increasing leverage also requires borrowing and quota capacity | Slippage, price impact, and fees; deleveraging can require delayed settlement |
| Deposit | Approximately preserves HF when keeping current leverage | Wallet funds; increases position size by adding collateral and borrowing more, requiring routes and available capacity | Slippage and fees can change HF; increases exposure, debt, and potentially quota costs |
| Withdraw | Approximately preserves HF for a proportional partial withdrawal | Decreases position net value by selling assets and repaying debt; requires an available withdrawal route | Slippage and fees; may trigger delayed operations, during which debt continues accruing costs |
| Add collateral | Can increase HF at fixed debt; no increase if the added value is excluded or already capped by quota | The position's collateral token held in your wallet; sufficient quota for its value to count where required | Commits more wallet funds without increasing debt; a direct token transfer has no swap slippage, but any associated quota increase can add costs |
| Withdraw collateral | Lowers HF if it removes value counted for solvency; may leave HF unchanged while the remaining value still exceeds the quota cap | A directly withdrawable token and sufficient remaining collateral coverage | Returns tokens without reducing debt; reduces equity and generally increases leverage; a direct transfer has no swap slippage |
| Increase quota | Raises HF only while quota caps the token's LT-weighted value | Active quota market and available quota capacity | More quota increases quota interest expense and may incur a quota-increase fee; the applicable quota rate can also change over time |
| Decrease quota | Leaves HF unchanged until quota falls below the token's LT-weighted value; further reduction lowers HF | Remaining quota must provide sufficient collateral coverage | Reduces quota interest expense without changing balances or repaying debt |
HF effects assume unchanged prices and liquidation thresholds. Deposit and withdraw preserve leverage by default, but quota caps and execution costs can prevent exact HF preservation. Preview the proposed action to check its actual effect before executing it.
Find your leveraged positions
Follow Connect SDK first. Using the connected sdk,
list the leveraged positions owned by owner. Supply this address directly;
no wallet connection is needed:
const positions = await sdk.positions.list(owner, { kind: "strategy" });
positions.data contains your leveraged positions on the networks configured in the SDK.
positions.meta.chains reports each chain's read status, block, and timestamp;
a failed read does not mean that you have no leveraged positions on that chain.
Select an entry from positions.data. Its chainId and creditAccount
identify the leveraged position to pass to the operations below. The creditManager
identifies its strategy, not the individual account. See
Monitor for the position's balances, debt,
leverage, and health factor.
Amounts are bigint token
base units: convert a user's decimal string using that token's decimals, as in
the opening example. Leverage uses hundredths (300n = 3×), and slippage uses
basis points (5 = 0.05%). The SDK checks the chosen account and market limits.
Select the leveraged position once:
import type { StrategyPosition } from "@gearbox-protocol/sdk/model"; const selectedIndex = 0; // Index of the account to manage const position = positions.data[selectedIndex] as StrategyPosition;
The operation snippets below are alternatives. Run the one you need, then use
its successful sim, position, and owner in
Build, preview, and check.
Quota updates build tx directly and continue at
Preview and check.
The variables in each call are the inputs you supply, described by its table.
All preparation methods accept these shared settings. Fields tagged Optional can be omitted.
| Field | Type | Meaning |
|---|---|---|
slippage Optional | number | Swap slippage in basis points: 5 = 0.05%; defaults to 0 |
quotaReserve Optional | number | Extra quota buffer in basis points: 100 = 1%; defaults to 0 |
Deposit
Use depositStrategy to grow a leveraged position using funds from the wallet. The
SDK borrows additional funds and routes the combined amount into the position
token.
| Field | Type | Meaning |
|---|---|---|
token | Address | Funding token: market underlying or supported unwrapped RWA asset |
amount | bigint | Deposit in funding token base units |
targetLeverage Optional | bigint | Target leverage in hundredths; defaults to current leverage |
positionToken Optional | Address | Token to buy; defaults to the largest non-phantom, non-underlying holding |
value Optional | bigint | Native value in wei when funding a wrapped-native market with the native coin |
const sim = await sdk.opportunities.prepare.depositStrategy(position, { token, amount, slippage, }); if (!sim.ok) throw sim.error;
Check the new borrowing requirement against current capacity.
This differs from addCollateral, which adds the position token at fixed debt
and lowers leverage.
Quota. The SDK includes quota updates for changed balances, using their
value, liquidation thresholds, and quotaReserve. Increases require available
quota capacity and can increase quota costs. Inspect sim.data.state.quotas;
no separate quota transaction is normally needed.
Approval. For an ERC-20 deposit, resolve the spender:
const spender = await sdk.onchain.chain(position.chainId).accounts.getApprovalAddress({ creditManager: position.creditManager, creditAccount: position.creditAccount, });
Check token's allowance from owner to spender against amount, in token
base units. If insufficient, call approve(spender, amount) on that token and
wait for confirmation. Approve your deposit only, not the borrowed funds or
total exposure. Reprepare and preview after approval.
Withdraw
Use withdrawStrategy to withdraw part of the position's equity. The SDK sells
position assets and repays debt proportionally.
| Field | Type | Meaning |
|---|---|---|
amount | bigint | Amount to receive in tokenOut base units |
to | Address | Recipient of the withdrawn tokens |
tokenOut Optional | Address | Output token; defaults to underlying or the unwrapped RWA asset |
sourceToken Optional | Address | Token to sell; defaults to the largest non-phantom holding |
const prepared = await sdk.opportunities.prepare.withdrawStrategy(position, { amount, to, slippage, }); if (!prepared.ok) throw prepared.error;
Route. A successful preparation means at least one route is available; it does not guarantee instant withdrawal. Choose the route explicitly:
const route = "instant"; // Choose "delayed" for redemption with later settlement const selected = prepared.data[route]; if (!selected) throw prepared.data.errors[route] ?? new Error("Route unavailable"); const sim = { ok: true as const, data: selected };
For a delayed route, the transaction only requests redemption. selected.state
projects the result after completion; selected.delayed.afterRequest describes
the account immediately after the request. Debt remains outstanding while it
settles. Save the delayed route result with the confirmed request transaction,
then follow Delayed withdrawals to monitor
maturity and complete the operation.
Quota. The SDK recalculates quotas for balances changed by the withdrawal,
using their value, liquidation thresholds, and quotaReserve. Inspect the
selected route's state.quotas; no separate quota transaction is normally
needed. No wallet ERC-20 approval is required.
Use prepare.maxWithdraw(position) to obtain withdrawal ceilings in underlying
units. Do not compare those raw values to an amount in a different tokenOut.
A partial withdrawal can be refused if the remaining loan falls below minimum
debt, even when a full exit is possible.
Passing MAX_UINT256 from @gearbox-protocol/sdk/onchain requests an exit:
settle all debt and transfer the remaining balances. The Credit Account remains
open and empty. An amount at or above net value also selects the exit flow.
For an exit, tokenOut is ignored: proceeds use the market underlying,
unwrapped on RWA markets.
The caller must review this change of intent before submitting.
Repay
Use repayStrategy to pay down debt with funds from the wallet while retaining
the position assets. This reduces leverage rather than withdrawing equity.
| Field | Type | Meaning |
|---|---|---|
token | Address | Funding token: underlying or supported unwrapped RWA asset |
amount | bigint | Payment in funding token base units; MAX_UINT256 requests full repayment |
value Optional | bigint | Native value in wei when funding a wrapped-native market with the native coin |
const sim = await sdk.opportunities.prepare.repayStrategy(position, { token, amount, }); if (!sim.ok) throw sim.error;
prepare.maxRepay(position) reads the currently outstanding debt. Interest can
accrue before the transaction lands. To settle in full, amount: MAX_UINT256
asks the SDK to size funding with a 10-basis-point interest buffer; unused funds
remain as collateral in the Credit Account. Show the actual funding requirement
from the preview before approval. Partial repayments must respect minimum debt.
Quota. Partial repayment leaves quotas unchanged. Full repayment clears the account's quotas automatically.
Approval. For ERC-20 repayment, resolve the spender:
const spender = await sdk.onchain.chain(position.chainId).accounts.getApprovalAddress({ creditManager: position.creditManager, creditAccount: position.creditAccount, });
Check the funding token's allowance from owner to spender. For a fixed
repayment, approve amount in funding token base units. For MAX_UINT256,
approve the actual required payment including the interest buffer; use
required.value from an insufficientAllowance issue when approval is needed.
Do not use the sentinel as the approval amount. If allowance is insufficient,
call approve(spender, approvalAmount) on the funding token, wait for
confirmation, then reprepare and preview.
Add collateral
Use addCollateral to transfer the position's collateral token from your
wallet into the Credit Account. It does not borrow more or swap tokens.
Unlike a leveraged deposit, it increases equity at fixed debt and lowers
leverage. The HF improvement depends on how much of the added value counts
after liquidation thresholds and quota limits.
| Field | Type | Meaning |
|---|---|---|
token | Address | Position collateral token to add; this method does not accept arbitrary deposit tokens |
amount | bigint | Amount in that token's base units |
value Optional | bigint | Native value in wei when depositing the native coin into a wrapped-native position |
const sim = await sdk.opportunities.prepare.addCollateral(position, { token, amount, }); if (!sim.ok) throw sim.error;
Quota. The SDK can increase quota for the added token based on its resulting
value, liquidation threshold, and quotaReserve. Existing quota may already
cover it. An increase requires available quota capacity and can add quota costs
even though no swap is performed. Inspect sim.data.state.quotas; no separate
quota transaction is normally needed. Transferring tokens alone does not adjust
quota.
Approval. The wallet must hold the tokens. For ERC-20 collateral, resolve the spender:
const spender = await sdk.onchain.chain(position.chainId).accounts.getApprovalAddress({ creditManager: position.creditManager, creditAccount: position.creditAccount, });
Check token's allowance from owner to spender against amount, in that
token's base units. If insufficient, call approve(spender, amount) on the
token and wait for confirmation. Reprepare and preview after approval.
Withdraw collateral
Use withdrawCollateral to transfer a token already held in the Credit Account
to a recipient without repaying debt.
Remaining collateral must support the debt; this action increases leverage.
| Field | Type | Meaning |
|---|---|---|
token | Address | Held token to withdraw |
amount | bigint | Amount in that token's base units |
to | Address | Recipient of the tokens |
const sim = await sdk.opportunities.prepare.withdrawCollateral(position, { token, amount, to, }); if (!sim.ok) throw sim.error;
Use sdk.opportunities.prepare.withdrawableCollaterals(position) to list
withdrawable tokens from the selected position. This excludes assets that
cannot be transferred directly, such as pending-redemption phantom tokens.
Use prepare.maxWithdrawCollateral(position, token) for a current ceiling,
then prepare the requested amount again before submitting.
Quota. The SDK can reduce the withdrawn token's quota based on its remaining
value, liquidation threshold, and quotaReserve. Inspect
sim.data.state.quotas; no separate quota transaction is normally needed.
No wallet ERC-20 approval is required.
Adjust leverage
Use adjustLeverage to change exposure without depositing or withdrawing wallet
funds. Increasing leverage borrows and buys; decreasing leverage sells or
redeems assets and repays debt.
| Field | Type | Meaning |
|---|---|---|
targetLeverage | bigint | Target leverage in hundredths: 300n = 3×; 100n requests no debt |
token Optional | Address | Token to buy or sell; defaults to the largest non-phantom, non-underlying holding |
const prepared = await sdk.opportunities.prepare.adjustLeverage(position, { targetLeverage, slippage, }); if (!prepared.ok) throw prepared.error;
Route. Increasing leverage has only an instant route. Decreasing leverage can also use delayed redemption. Successful preparation means at least one route is available; choose it explicitly:
const route = "instant"; // Choose "delayed" for redemption with later settlement const selected = prepared.data[route]; if (!selected) throw prepared.data.errors[route] ?? new Error("Route unavailable"); const sim = { ok: true as const, data: selected };
For a delayed decrease, the transaction only requests redemption; it does not
repay debt yet. selected.state projects the completed operation, while
selected.delayed.afterRequest describes the account after the request alone.
Inspect both states and save the delayed route result with the confirmed
request transaction. Continue with Delayed withdrawals
to monitor maturity and complete the leverage decrease.
Quota. The SDK updates quotas for changed balances. Increasing exposure
can require more quota capacity and increase quota costs; reducing exposure
can reduce quota. Inspect the selected route's state.quotas.
No wallet ERC-20 approval is required.
Update quota
Use the connected SDK to build a quota update for the selected position.
There is no high-level prepare.adjustQuota() method; the Credit Facade
provides prepareUpdateQuotas().
| Variable | Type | Meaning |
|---|---|---|
quotaToken | Address | Collateral token whose quota you want to change |
quotaChange | bigint | Signed quota change: positive to increase, negative to decrease, in pool underlying base units |
minQuota | bigint | Minimum acceptable resulting quota, in pool underlying base units |
These amounts use the pool underlying's decimals, not the collateral token's
decimals. Quota changes are rounded down by the Credit Facade to a multiple
of 10000 base units; account for that when setting minQuota.
const chainId = position.chainId; const chain = sdk.onchain.chain(chainId); const account = await chain.accounts.getCreditAccountData(position.creditAccount); if (!account || !account.success) throw new Error("Credit Account data unavailable"); const suite = chain.marketRegister.findCreditManager(account.creditManager); const calls = suite.creditFacade.prepareUpdateQuotas({ averageQuota: [{ token: quotaToken, balance: quotaChange }], minQuota: [{ token: quotaToken, balance: minQuota }], }); const tx = await chain.accounts.executeCaUpdate(account, calls);
Continue with this tx, chainId, and owner at
Preview and check.
Increasing quota uses available quota capacity and can increase quota costs.
Decreasing quota can reduce the position's health factor. This changes the account's quota;
quotaReserve is a buffer used when preparing other operations.