Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

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

LibraryResponsibilities
SupplyLogicexecuteSupply, executeWithdraw, executeFinalizeTransfer, executeUseReserveAsCollateral
BorrowLogicexecuteBorrow, executeRepay, executeSwapBorrowRateMode, executeRebalanceStableBorrowRate
LiquidationLogicexecuteLiquidationCall
FlashLoanLogicexecuteFlashLoan, executeFlashLoanSimple
EModeLogicexecuteSetUserEMode
BridgeLogicexecuteMintUnbacked, executeBackUnbacked
PoolLogicexecuteInitReserve, executeDropReserve, executeMintToTreasury, executeGetUserAccountData, executeRescueTokens, executeResetIsolationModeTotalDebt
ValidationLogicPure validation helpers used by all of the above

Access control

Functions on Pool are gated by three modifiers:

  • onlyPoolConfigurator — caller is the PoolConfigurator proxy (resolved through PoolAddressesProvider.getPoolConfigurator()).
  • onlyPoolAdmin — caller holds POOL_ADMIN_ROLE on the ACLManager.
  • onlyBridge — caller holds BRIDGE_ROLE on the ACLManager.

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 initializer

Called 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) external

Transfers 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.

ParamTypeDescription
assetaddressUnderlying ERC20 being supplied.
amountuint256Amount in the asset's native units.
onBehalfOfaddressReceiver of the minted AToken.
referralCodeuint16Emitted 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
) external

Same 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.

ParamTypeDescription
assetaddressUnderlying ERC20 being withdrawn.
amountuint256Amount in native units, or type(uint256).max for full balance.
toaddressReceiver 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) external

Opens 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.

ParamTypeDescription
assetaddressUnderlying ERC20 being borrowed.
amountuint256Amount in native units.
interestRateModeuint2561 = stable, 2 = variable.
referralCodeuint16Emitted in the Borrow event.
onBehalfOfaddressAddress 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).

ParamTypeDescription
assetaddressUnderlying borrowed asset.
amountuint256Amount to repay, or type(uint256).max to clear the debt.
interestRateModeuint2561 = stable debt, 2 = variable debt.
onBehalfOfaddressWhose 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.

ParamTypeDescription
assetaddressUnderlying borrowed asset.
amountuint256Amount of underlying to credit toward debt, or type(uint256).max.
interestRateModeuint2561 = stable, 2 = variable.

swapBorrowRateMode

function swapBorrowRateMode(address asset, uint256 interestRateMode) external

Swaps 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) external

Re-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) external

Toggles 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
) external

Repays up to debtToCover of user's debt in debtAsset and seizes a proportional amount of their collateralAsset plus the liquidation bonus.

ParamTypeDescription
collateralAssetaddressUnderlying collateral to seize.
debtAssetaddressUnderlying debt to repay.
useraddressBorrower being liquidated.
debtToCoveruint256Amount of debt to cover, or type(uint256).max for the maximum allowed by the close factor.
receiveATokenbooltrue to receive the seized collateral as AToken; false to receive the underlying.

Constants from LiquidationLogic:

  • DEFAULT_LIQUIDATION_CLOSE_FACTOR = 0.5e4 (50%) — applies when 0.95e18 < HF < 1e18.
  • MAX_LIQUIDATION_CLOSE_FACTOR = 1e4 (100%) — applies when HF <= 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
) external

Multi-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) external

Single-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) external

Sets 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) external

Mints accrued reserve-factor income to the treasury as AToken for the listed assets. Permissionless.

rescueTokens

function rescueTokens(address token, address to, uint256 amount) external

Transfers 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) external

Alias 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) external

Mints 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 an AToken after 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):

BitsField
0-15LTV
16-31Liquidation threshold
32-47Liquidation bonus
48-55Decimals
56Active
57Frozen
58Borrowing enabled
59Stable-rate borrowing enabled
60Paused
61Borrowable in isolation
62Siloed borrowing
63Flash-loan enabled
64-79Reserve factor
80-115Borrow cap (whole tokens; 0 = no cap)
116-151Supply cap (whole tokens; 0 = no cap)
152-167Liquidation protocol fee
168-175eMode category
176-211Unbacked mint cap (whole tokens; 0 = minting disabled)
212-251Debt ceiling (with DEBT_CEILING_DECIMALS = 2; 0 = isolation mode disabled)
252-255Unused

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's ltv, liquidationThreshold, liquidationBonus, priceSource, and label.
  • getUserEMode(address user) — returns the user's current category (0 means no e-mode).

Constants and immutables

FunctionReturnsSource
ADDRESSES_PROVIDER()IPoolAddressesProviderImmutable, set in constructor.
MAX_STABLE_RATE_BORROW_SIZE_PERCENT()0.25e4 (25%)Storage, set in initialize.
BRIDGE_PROTOCOL_FEE()bpsStorage, set by PoolConfigurator.
FLASHLOAN_PREMIUM_TOTAL()bpsStorage, set by PoolConfigurator.
FLASHLOAN_PREMIUM_TO_PROTOCOL()bpsStorage, set by PoolConfigurator.
MAX_NUMBER_RESERVES()128ReserveConfiguration.MAX_RESERVES_COUNT.
POOL_REVISION()0x1Constant.

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.

SparkLend Pool interaction map: users, BRIDGE_ROLE holders, and the PoolConfigurator all call into Pool, which delegatecalls the logic libraries, drives the AToken / VariableDebtToken / StableDebtToken contracts, and reads AaveOracle and the PriceOracleSentinel