Functions
General Execution Flow
Helios exposes a small set of user-facing entry points in Pool.sol—supply
, withdraw
, borrow
, repay
, liquidate
, and so on.
Although each function has its own validation rules, almost every call follows the same five-step template shown below. Understanding this pattern makes it much easier to reason about gas costs, interest updates, and edge-case protections when you integrate Helios into a dApp or trading bot.
1 · Standard Path for State-Changing Calls
cache
Load frequently used storage slots (e.g., reserve configuration, user data) into stack variables.
Minimises SLOADs and keeps later checks cheap.
updateState
Accrue interest for every reserve by updating the liquidity and borrow indexes.
Ensures all subsequent checks use up-to-date debt & collateral figures.
validate
Confirm the action is allowed after the state refresh (caps, health-factor, isolation-mode, etc.).
Guarantees protocol invariants before any tokens move.
changeState
Mint/burn hTokens or debt tokens, move BTC in / out of the pool, toggle collateral flags, etc.
Executes the user’s intent once it is proven safe.
updateRates
Re-compute borrow & supply APRs based on the new utilisation.
Keeps the next transaction priced correctly.
2 · Flash-Loan Exception
Flash-loans invert the first part of the sequence to defend against re-entrancy and rate manipulation inside the borrower’s callback:
validate ensures the loan amount is available and fee parameters are sane.
userPayload executes the borrower’s arbitrary logic (swaps, arbitrage, etc.).
The usual cache → updateState → changeState → updateRates steps then settle the loan and apply fees, all in the same transaction.
3 · Common Helper Functions
Most state-changing flows rely on the following internal helpers, which are documented in separate sections of this book:
cache()
Pull reserve & user data into memory.
updateState()
Accrue interest and bump the global indexes.
updateRates()
Re-price borrow & supply APRs after an action.
getFlags()
Return bit-packed reserve configuration flags.
getDecimals()
Fetch token decimals once, reuse everywhere.
getSupplyCap()
/ getBorrowCap()
Enforce governance-set caps on liquidity.
4 · Why the Pattern Matters
Predictability — Every high-level action hits the same checkpoints, so auditors and integrators have a single mental model.
Gas efficiency — Caching and batched index updates avoid redundant storage reads/writes.
Safety — Interest is always up-to-date before collateral or debt checks, preventing time-skew exploits.
Extensibility — Because the rate update is last, new interest-rate strategies can be swapped in without touching earlier logic.
5 · Takeaways for Builders
Call any Pool function with confidence that interest and caps are refreshed inside the tx.
If you use flash-loans, design your callback with the ordering reversal in mind—re-entrancy guards come from the routing, not your payload.
For advanced analytics, hook into the
ReserveDataUpdated
event emitted during updateRates to track real-time APR changes.
Last updated