Overview
Credit accounts are isolated smart contract wallets that hold collateral and debt. Opening an account requires providing initial collateral and optionally borrowing funds from the pool.
Account Opening Flow
Check Debt Limits
Query the Credit Facade for minimum and maximum debt constraints: ICreditFacadeV3 facade = ICreditFacadeV3 (creditFacadeAddress);
( uint128 minDebt, uint128 maxDebt) = facade. debtLimits ();
// Ensure your planned debt is within limits
require (borrowAmount >= minDebt && borrowAmount <= maxDebt, "Debt out of range" );
If you donβt plan to borrow, you can open an account with zero debt, but you wonβt be able to perform most operations without debt.
Approve Collateral Token
The Credit Manager needs approval to transfer your collateral: address underlying = facade. underlying ();
address creditManager = facade. creditManager ();
IERC20 (underlying). approve (creditManager, collateralAmount);
Construct Opening Multicalls
Build the array of operations to execute when opening: MultiCall[] memory calls = new MultiCall[]( 2 );
// 1. Add collateral
calls[ 0 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.addCollateral,
(underlying, collateralAmount)
)
});
// 2. Increase debt (borrow from pool)
calls[ 1 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.increaseDebt,
(borrowAmount)
)
});
Open the Account
Execute the opening transaction: address creditAccount = facade. openCreditAccount (
msg.sender , // onBehalfOf - account owner
calls, // multicalls to execute
referralCode // optional referral code
);
emit CreditAccountOpened (creditAccount, msg.sender );
The function returns the address of the newly created credit account.
Opening with Permit
For ERC-2612 compliant tokens, you can avoid a separate approval transaction:
MultiCall[] memory calls = new MultiCall[]( 2 );
// Add collateral with permit (no prior approval needed)
calls[ 0 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.addCollateralWithPermit,
(underlying, collateralAmount, deadline, v, r, s)
)
});
calls[ 1 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.increaseDebt,
(borrowAmount)
)
});
address creditAccount = facade. openCreditAccount ( msg.sender , calls, 0 );
Opening with Multiple Collateral Types
Add multiple tokens as collateral during opening:
MultiCall[] memory calls = new MultiCall[]( 4 );
// Add underlying token
calls[ 0 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.addCollateral,
(underlying, underlyingAmount)
)
});
// Increase debt
calls[ 1 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.increaseDebt,
(borrowAmount)
)
});
// Add secondary collateral (e.g., WETH)
calls[ 2 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.addCollateral,
(weth, wethAmount)
)
});
// Update quota for secondary collateral
calls[ 3 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.updateQuota,
(weth, int96 ( uint96 (quotaAmount)), uint96 (quotaAmount))
)
});
address creditAccount = facade. openCreditAccount ( msg.sender , calls, 0 );
Non-underlying tokens must have quota enabled to count as collateral. Holding tokens without quota while having debt puts them at risk during liquidation.
Opening with ETH
When the underlying token is WETH, you can open with native ETH:
address weth = facade. weth ();
require (facade. underlying () == weth, "Not a WETH pool" );
MultiCall[] memory calls = new MultiCall[]( 2 );
// ETH will be automatically wrapped to WETH
calls[ 0 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.addCollateral,
(weth, ethAmount)
)
});
calls[ 1 ] = MultiCall ({
target : address (facade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.increaseDebt,
(borrowAmount)
)
});
// Send ETH with the transaction
address creditAccount = facade.openCreditAccount{value : ethAmount}(
msg.sender ,
calls,
0
);
Complete Example
Full integration example with error handling:
contract GearboxIntegration {
ICreditFacadeV3 public immutable creditFacade;
constructor ( address _creditFacade ) {
creditFacade = ICreditFacadeV3 (_creditFacade);
}
function openAccount (
uint256 collateralAmount ,
uint256 borrowAmount
) external returns ( address creditAccount ) {
// Validate debt limits
( uint128 minDebt, uint128 maxDebt) = creditFacade. debtLimits ();
require (
borrowAmount >= minDebt && borrowAmount <= maxDebt,
"Debt out of range"
);
// Get addresses
address underlying = creditFacade. underlying ();
address creditManager = creditFacade. creditManager ();
// Transfer and approve
IERC20 (underlying). transferFrom (
msg.sender ,
address ( this ),
collateralAmount
);
IERC20 (underlying). approve (creditManager, collateralAmount);
// Build multicalls
MultiCall[] memory calls = new MultiCall[]( 2 );
calls[ 0 ] = MultiCall ({
target : address (creditFacade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.addCollateral,
(underlying, collateralAmount)
)
});
calls[ 1 ] = MultiCall ({
target : address (creditFacade),
callData : abi . encodeCall (
ICreditFacadeV3Multicall.increaseDebt,
(borrowAmount)
)
});
// Open account
creditAccount = creditFacade. openCreditAccount (
msg.sender ,
calls,
0
);
}
}
Permissions and Events
When an account is opened, the OpenCreditAccount event is emitted:
event OpenCreditAccount (
address indexed creditAccount ,
address indexed onBehalfOf ,
address indexed caller ,
uint256 referralCode
);
The onBehalfOf address becomes the account owner and has full control over it.
Available Operations During Opening
The following multicall operations are permitted during account opening:
addCollateral - Add tokens as collateral
addCollateralWithPermit - Add collateral using EIP-2612 permit
increaseDebt - Borrow from the pool
updateQuota - Enable non-underlying tokens as collateral
storeExpectedBalances / compareBalances - Slippage protection
onDemandPriceUpdates - Update oracle prices (must be first call)
Adapter calls to interact with external protocols
decreaseDebt is not available during opening. You cannot close an account in the same transaction itβs opened.
Next Steps
Managing Debt Learn to increase and decrease debt
Working with Adapters Execute DeFi operations via adapters