Withdrawing Collateral
Remove tokens from a Credit Account to an external address.
For SDK implementation, see Withdrawing Collateral.
Why
You need to withdraw collateral when:
- Taking profits - Remove excess collateral while maintaining healthy position
- Rebalancing - Move funds between accounts or protocols
- Closing account - Extract all remaining tokens before closing
Withdrawing collateral decreases your account's total weighted value (TWV), which lowers the health factor.
What
withdrawCollateral transfers tokens from the Credit Account to a specified recipient. On execution:
- Tokens are transferred from the Credit Account to the recipient
- If withdrawing the full balance, the token may be disabled as collateral
- Safe pricing is activated for the collateral check (uses min of main and reserve price feeds)
Important: Withdrawals trigger stricter collateral checks using safe prices, so ensure sufficient buffer above the liquidation threshold.
How
import {ICreditFacadeV3Multicall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3Multicall.sol"; import {MultiCall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol"; address creditFacade; address usdc; address creditAccount; address recipient; MultiCall[] memory calls = new MultiCall[](1); // Withdraw 5,000 USDC calls[0] = MultiCall({ target: creditFacade, callData: abi.encodeCall( ICreditFacadeV3Multicall.withdrawCollateral, (usdc, 5_000 * 10**6, recipient) ) }); ICreditFacadeV3(creditFacade).multicall(creditAccount, calls);
Withdraw Full Balance
Use type(uint256).max to withdraw the entire token balance:
// Withdraw all USDC from the account calls[0] = MultiCall({ target: creditFacade, callData: abi.encodeCall( ICreditFacadeV3Multicall.withdrawCollateral, (usdc, type(uint256).max, recipient) ) });
Withdraw During Closure
When closing an account, you can withdraw all tokens to yourself:
MultiCall[] memory calls = new MultiCall[](2); // Repay all debt first calls[0] = MultiCall({ target: creditFacade, callData: abi.encodeCall( ICreditFacadeV3Multicall.decreaseDebt, (type(uint256).max) ) }); // Withdraw all collateral calls[1] = MultiCall({ target: creditFacade, callData: abi.encodeCall( ICreditFacadeV3Multicall.withdrawCollateral, (token, type(uint256).max, recipient) ) }); ICreditFacadeV3(creditFacade).closeCreditAccount(creditAccount, calls);
Gotchas
Safe Prices Are Used
After withdrawal, collateral checks use safe pricing (minimum of main and reserve feeds). This means:
- Your effective collateral value may be lower than expected
- Maintain buffer above liquidation threshold
- Check safe prices before withdrawing large amounts
Forbidden Tokens Block Withdrawal
If any forbidden token is enabled as collateral on the account, withdrawals are blocked in multicalls:
// This will revert if the account has forbidden tokens enabled ICreditFacadeV3(creditFacade).multicall(creditAccount, withdrawCalls);
Solution: First swap forbidden tokens to allowed ones, then withdraw.
Phantom Token Unwrapping
If the token being withdrawn is a phantom token (e.g., staked position token), it's automatically unwrapped:
- Phantom token is withdrawn from the vault/pool
- The underlying deposited token is sent to the recipient
- No slippage protection - assumed to happen at non-manipulatable rate
Dust Handling
For clean account closure, use type(uint256).max to handle dust amounts:
// This handles any remaining wei callData: abi.encodeCall( ICreditFacadeV3Multicall.withdrawCollateral, (token, type(uint256).max, recipient) )
Recipient Validation
The recipient address must be a valid address. Common patterns:
// Withdraw to account owner withdrawCollateral(token, amount, owner); // Withdraw to another protocol/contract withdrawCollateral(token, amount, anotherContract); // NEVER use address(0) - tokens will be lost!
See Also
- Adding Collateral - The reverse operation
- Debt Management - Repay debt before large withdrawals
- Enabling/Disabling Tokens - Token state management