Pool
Overview
The Pool contract is the main entry point for SparkLend. All user-initiated lending operations (supply, withdraw, borrow, repay, liquidate, flash-loan, e-mode selection, collateral toggle) call into Pool, which delegates to specialised logic libraries.
Pool is deployed behind an InitializableImmutableAdminUpgradeabilityProxy whose admin is the PoolAddressesProvider. Upgrading Pool requires changing the implementation pointer on the provider.
Logic library breakdown
| Library | Responsibilities |
|---|---|
SupplyLogic | executeSupply, executeWithdraw, executeFinalizeTransfer, executeUseReserveAsCollateral |
BorrowLogic | executeBorrow, executeRepay, executeSwapBorrowRateMode, executeRebalanceStableBorrowRate |
LiquidationLogic | executeLiquidationCall |
FlashLoanLogic | executeFlashLoan, executeFlashLoanSimple |
EModeLogic | executeSetUserEMode |
BridgeLogic | executeMintUnbacked, executeBackUnbacked |
PoolLogic | executeInitReserve, executeDropReserve, executeMintToTreasury, executeGetUserAccountData, executeRescueTokens, executeResetIsolationModeTotalDebt |
ValidationLogic | Pure validation helpers used by all of the above |
Access control
Functions on Pool are gated by three modifiers:
onlyPoolConfigurator— caller is thePoolConfiguratorproxy (resolved throughPoolAddressesProvider.getPoolConfigurator()).onlyPoolAdmin— caller holdsPOOL_ADMIN_ROLEon theACLManager.onlyBridge— caller holdsBRIDGE_ROLEon theACLManager.
End-user functions (supply, withdraw, borrow, repay, liquidate, flash-loan) are permissionless.
Constructor and initialization
constructor(IPoolAddressesProvider provider)Caches the PoolAddressesProvider in an immutable. Called on the implementation, not the proxy.
function initialize(IPoolAddressesProvider provider) external initializerCalled once on the proxy. Verifies the passed provider matches the immutable and sets _maxStableRateBorrowSizePercent to 25%.
User-facing write methods
supply
function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) externalTransfers amount of asset from msg.sender to the reserve's AToken contract and mints AToken to onBehalfOf. If this is the recipient's first supply of this asset and the reserve has non-zero LTV and is not an isolation-mode reserve, the asset is automatically enabled as collateral.
| Param | Type | Description |
|---|---|---|
asset | address | Underlying ERC20 being supplied. |
amount | uint256 | Amount in the asset's native units. |
onBehalfOf | address | Receiver of the minted AToken. |
referralCode | uint16 | Emitted in the Supply event for integrator tracking. Pass 0 if unused. |
supplyWithPermit
function supplyWithPermit(
address asset, uint256 amount, address onBehalfOf, uint16 referralCode,
uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS
) externalSame as supply, but consumes an ERC-2612 permit signature from msg.sender before pulling the underlying. Useful for one-tx supply with permit-supporting assets.
withdraw
function withdraw(address asset, uint256 amount, address to) external returns (uint256)Burns the caller's AToken and transfers underlying to to. Pass type(uint256).max to withdraw the full balance. If the caller is borrowing and the asset is used as collateral, the post-withdraw health factor is validated.
| Param | Type | Description |
|---|---|---|
asset | address | Underlying ERC20 being withdrawn. |
amount | uint256 | Amount in native units, or type(uint256).max for full balance. |
to | address | Receiver of the underlying. |
Returns the actual amount withdrawn (relevant when type(uint256).max is used).
borrow
function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) externalOpens a debt position on onBehalfOf (which may be msg.sender or a third party that has granted credit delegation). Funds are transferred to msg.sender.
| Param | Type | Description |
|---|---|---|
asset | address | Underlying ERC20 being borrowed. |
amount | uint256 | Amount in native units. |
interestRateMode | uint256 | 1 = stable, 2 = variable. |
referralCode | uint16 | Emitted in the Borrow event. |
onBehalfOf | address | Address that incurs the debt; must have approved msg.sender via approveDelegation if different from msg.sender. |
repay
function repay(address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf) external returns (uint256)Pulls underlying from msg.sender and burns debt tokens of onBehalfOf. Pass type(uint256).max to repay the full debt of the chosen rate mode (only valid when msg.sender == onBehalfOf).
| Param | Type | Description |
|---|---|---|
asset | address | Underlying borrowed asset. |
amount | uint256 | Amount to repay, or type(uint256).max to clear the debt. |
interestRateMode | uint256 | 1 = stable debt, 2 = variable debt. |
onBehalfOf | address | Whose debt is being reduced. |
Returns the actual amount repaid.
repayWithPermit
function repayWithPermit(
address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf,
uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS
) external returns (uint256)Same as repay, with an ERC-2612 permit over the underlying being consumed before transferFrom.
repayWithATokens
function repayWithATokens(address asset, uint256 amount, uint256 interestRateMode) external returns (uint256)Burns the caller's own AToken balance to repay their own debt — no allowance to Pool required, no underlying transfer. Pass type(uint256).max to repay up to the caller's full AToken balance without leaving dust.
| Param | Type | Description |
|---|---|---|
asset | address | Underlying borrowed asset. |
amount | uint256 | Amount of underlying to credit toward debt, or type(uint256).max. |
interestRateMode | uint256 | 1 = stable, 2 = variable. |
swapBorrowRateMode
function swapBorrowRateMode(address asset, uint256 interestRateMode) externalSwaps the caller's existing debt between stable and variable. The interestRateMode argument is the current mode being switched out of.
Effectively unusable on live SparkLend reserves while stable-rate borrowing is disabled.
rebalanceStableBorrowRate
function rebalanceStableBorrowRate(address asset, address user) externalRe-prices a user's stable debt to the current stable rate, if reserve conditions allow (see ValidationLogic.validateRebalanceStableBorrowRate). Effectively unusable while stable-rate borrowing is disabled.
setUserUseReserveAsCollateral
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) externalToggles whether the caller's AToken balance for asset contributes to their collateral. Disabling reverts if it would drop the caller below the health-factor liquidation threshold. Enabling is rejected if the asset has ltv == 0, or if the user is in isolation mode and the asset has debtCeiling == 0.
liquidationCall
function liquidationCall(
address collateralAsset,
address debtAsset,
address user,
uint256 debtToCover,
bool receiveAToken
) externalRepays up to debtToCover of user's debt in debtAsset and seizes a proportional amount of their collateralAsset plus the liquidation bonus.
| Param | Type | Description |
|---|---|---|
collateralAsset | address | Underlying collateral to seize. |
debtAsset | address | Underlying debt to repay. |
user | address | Borrower being liquidated. |
debtToCover | uint256 | Amount of debt to cover, or type(uint256).max for the maximum allowed by the close factor. |
receiveAToken | bool | true to receive the seized collateral as AToken; false to receive the underlying. |
Constants from LiquidationLogic:
DEFAULT_LIQUIDATION_CLOSE_FACTOR = 0.5e4(50%) — applies when0.95e18 < HF < 1e18.MAX_LIQUIDATION_CLOSE_FACTOR = 1e4(100%) — applies whenHF <= 0.95e18.CLOSE_FACTOR_HF_THRESHOLD = 0.95e18.
flashLoan
function flashLoan(
address receiverAddress,
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata interestRateModes,
address onBehalfOf,
bytes calldata params,
uint16 referralCode
) externalMulti-asset flash loan. Pulls amounts of each asset into receiverAddress, calls IFlashLoanReceiver.executeOperation, then settles each leg.
The flash-loan fee is waived when msg.sender holds FLASH_BORROWER_ROLE on the ACLManager. The reserve being flash-loaned must have its flashLoanEnabled flag set.
flashLoanSimple
function flashLoanSimple(address receiverAddress, address asset, uint256 amount, bytes calldata params, uint16 referralCode) externalSingle-asset flash loan. Cheaper than flashLoan for the common case. Does not waive the fee for FLASH_BORROWER_ROLE holders, and does not support opening a debt position.
setUserEMode
function setUserEMode(uint8 categoryId) externalSets the caller's e-mode category. Reverts if the caller has open debt in an asset whose eModeCategory differs from categoryId, or if the change would drop the caller below the health-factor threshold.
mintToTreasury
function mintToTreasury(address[] calldata assets) externalMints accrued reserve-factor income to the treasury as AToken for the listed assets. Permissionless.
rescueTokens
function rescueTokens(address token, address to, uint256 amount) externalTransfers amount of any ERC20 token accidentally sent to the Pool itself out to to. onlyPoolAdmin.
deposit (deprecated)
function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) externalAlias for supply. Retained for compatibility with older integrations.
Bridge-only methods
These functions are callable only by addresses holding BRIDGE_ROLE on ACLManager.
mintUnbacked
function mintUnbacked(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) externalMints AToken to onBehalfOf without underlying backing. Bound by the reserve's unbackedMintCap.
backUnbacked
function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256)Backs previously-minted unbacked AToken with amount of underlying plus a fee.
PoolConfigurator-only methods
The following are callable only by the PoolConfigurator:
initReserve(asset, aTokenAddress, stableDebtAddress, variableDebtAddress, interestRateStrategyAddress)dropReserve(asset)setReserveInterestRateStrategyAddress(asset, rateStrategyAddress)setConfiguration(asset, configuration)updateBridgeProtocolFee(protocolFee)updateFlashloanPremiums(flashLoanPremiumTotal, flashLoanPremiumToProtocol)configureEModeCategory(id, category)resetIsolationModeTotalDebt(asset)
Their high-level entry points are the corresponding methods on PoolConfigurator.
AToken-only methods
finalizeTransfer(asset, from, to, amount, balanceFromBefore, balanceToBefore)— invoked by anATokenafter every transfer to revalidate the sender's health factor and emit collateral-enable/disable events.
View methods
getReserveData
function getReserveData(address asset) external view returns (DataTypes.ReserveData memory)Returns the full ReserveData struct: bit-packed configuration, indexes, current rates, last update timestamp, reserve ID, the three token addresses, the interest-rate strategy address, accrued-to-treasury, unbacked, and isolation-mode total debt. See contracts/protocol/libraries/types/DataTypes.sol.
getUserAccountData
function getUserAccountData(address user) external view returns (
uint256 totalCollateralBase,
uint256 totalDebtBase,
uint256 availableBorrowsBase,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor
)All values are denominated in the price oracle's base currency (1e8 for USD-denominated oracles). healthFactor is type(uint256).max for users with no debt.
getConfiguration / getUserConfiguration
Return the packed ReserveConfigurationMap and UserConfigurationMap bitmaps. Use the ReserveConfiguration and UserConfiguration libraries (or the AaveProtocolDataProvider helpers) to decode.
ReserveConfigurationMap bit layout (contracts/protocol/libraries/types/DataTypes.sol):
| Bits | Field |
|---|---|
| 0-15 | LTV |
| 16-31 | Liquidation threshold |
| 32-47 | Liquidation bonus |
| 48-55 | Decimals |
| 56 | Active |
| 57 | Frozen |
| 58 | Borrowing enabled |
| 59 | Stable-rate borrowing enabled |
| 60 | Paused |
| 61 | Borrowable in isolation |
| 62 | Siloed borrowing |
| 63 | Flash-loan enabled |
| 64-79 | Reserve factor |
| 80-115 | Borrow cap (whole tokens; 0 = no cap) |
| 116-151 | Supply cap (whole tokens; 0 = no cap) |
| 152-167 | Liquidation protocol fee |
| 168-175 | eMode category |
| 176-211 | Unbacked mint cap (whole tokens; 0 = minting disabled) |
| 212-251 | Debt ceiling (with DEBT_CEILING_DECIMALS = 2; 0 = isolation mode disabled) |
| 252-255 | Unused |
getReserveNormalizedIncome / getReserveNormalizedVariableDebt
Return the current cumulative interest index (in ray, 1e27). A value of 1e27 means no interest accrued; 2e27 means the asset has doubled in claimable value.
getReservesList / getReservesCount / getReserveAddressById
getReservesList()returns the list of underlying-asset addresses, excluding dropped reserves.getReservesCount()returns the total number of historically-initialised reserves, including dropped ones.getReserveAddressById(uint16 id)returns the underlying for a given reserve id.
EMode views
getEModeCategoryData(uint8 id)— returns the category'sltv,liquidationThreshold,liquidationBonus,priceSource, andlabel.getUserEMode(address user)— returns the user's current category (0means no e-mode).
Constants and immutables
| Function | Returns | Source |
|---|---|---|
ADDRESSES_PROVIDER() | IPoolAddressesProvider | Immutable, set in constructor. |
MAX_STABLE_RATE_BORROW_SIZE_PERCENT() | 0.25e4 (25%) | Storage, set in initialize. |
BRIDGE_PROTOCOL_FEE() | bps | Storage, set by PoolConfigurator. |
FLASHLOAN_PREMIUM_TOTAL() | bps | Storage, set by PoolConfigurator. |
FLASHLOAN_PREMIUM_TO_PROTOCOL() | bps | Storage, set by PoolConfigurator. |
MAX_NUMBER_RESERVES() | 128 | ReserveConfiguration.MAX_RESERVES_COUNT. |
POOL_REVISION() | 0x1 | Constant. |
Events
Supply, Withdraw, Borrow, Repay, SwapBorrowRateMode, RebalanceStableBorrowRate, ReserveUsedAsCollateralEnabled, ReserveUsedAsCollateralDisabled, LiquidationCall, FlashLoan, MintUnbacked, BackUnbacked, IsolationModeTotalDebtUpdated, UserEModeSet, ReserveDataUpdated, MintedToTreasury. See the IPool interface for full signatures.
Error codes
See Troubleshooting errors for the full numeric-to-name mapping. The SparkLend-specific deviation is error 91 FLASHLOAN_DISABLED, returned by validateFlashloanSimple when a reserve has its flashLoanEnabled flag set to false.