Repository navigation
Flash Loans
A cash flash loan temporarily lends pool tokens to a receiver contract. The receiver must make principal plus the market fee available for repayment within the same transaction. Failure at any step rolls back the whole transaction.
A cash flash loan creates no lending account or persistent debt. For a callback that leaves an open collateralized borrowing position, see flash positions in Strategies.
The initiator authorizes the controller call and identifies the hub market, amount, receiver, and opaque callback data. The receiver must be a deployed Wasm contract.
The controller must be unpaused, the hub active, and the selected pool market configured to allow flash loans. The requested amount must be positive and fit that market's booked cash. The call runs inside the controller's flash guard, which rejects protected monetary reentry.
Cash flash loans do not value an account or fetch an oracle price. Their repayment proof is the pool's observed balance in the loaned token.
The pool calculates the fee from its current market settings. The initiator does not supply a fee that the pool trusts.
let fee = half_up(principal * fee_bps / BPS);
let fee = if fee_bps > 0 { max(fee, 1) } else { 0 };
let repayment = principal + fee;Principal, fee, and repayment use the token's native base units. The configured fee is limited to 500 BPS, or 5%. A positive fee rate therefore still charges one base unit when the proportional fee rounds to zero.
The pool checks exact balances throughout the call:
- Accrue the market, check flash-loan eligibility and cash, and snapshot the pool's token balance.
- Transfer principal to the receiver. The pool balance must equal the snapshot minus principal.
- Invoke the receiver callback. When it returns, the pool balance must still equal the snapshot minus principal.
- Check that the receiver's allowance to the pool covers principal plus fee.
- Pull exactly principal plus fee from the receiver using the token's
transfer_from. - Require the final pool balance to equal the initial snapshot plus fee, then book the fee as cash and protocol revenue.
let balance_after_payout = balance_before - principal;
let balance_after_callback = balance_before - principal;
let balance_after_repayment = balance_before + fee;These are equality checks. Sending repayment directly to the pool during the callback fails the intermediate check; repayment is collected by the pool's pull. An unrelated donation during the callback also fails that check. A callback return value cannot substitute for token repayment.
sequenceDiagram
actor Initiator
participant Controller
participant Pool
participant Receiver
Initiator->>Controller: Authorize cash flash loan
Controller->>Pool: Enter guarded loan call
Pool->>Pool: Check cash and snapshot token balance
Pool->>Receiver: Send principal
Pool->>Pool: Require exact post-payout balance
Pool->>Receiver: Invoke callback
Receiver->>Receiver: Execute logic and approve repayment
Pool->>Pool: Require unchanged post-payout balance
Pool->>Receiver: Pull principal plus fee
Pool->>Pool: Require exact final balance and book fee
Pool-->>Controller: Return charged fee
Implement this callback:
execute_flash_loan(
initiator: Address,
asset: Address,
amount: i128,
fee: i128,
pool: Address,
data: Bytes,
)The callback's asset is the token address; the controller entry point selects the market with a hub ID and token address. The data bytes pass through unchanged.
The receiver obtains enough of the loaned token to cover the principal and fee, then approves the pool as spender for repayment with a valid allowance expiration. This is a token allowance used by the pool's subsequent pull. It is different from the exact transfer authorization used by the strategy router.
A receiver should validate the expected lending contract and callback terms before using its own funds or permissions. The protocol's repayment checks protect the pool; they do not establish that every receiver's application logic is safe.
Exact public signatures are in the endpoint reference.
Insufficient cash, disabled flash loans, an invalid receiver, insufficient allowance, a callback failure, or any balance mismatch aborts the transaction. Protected controller monetary entry points reject reentry during the callback window.
The checks depend on the loaned token reporting honest balances and enforcing transfers and allowances correctly. They do not support arbitrary fee-on-transfer or rebasing behavior merely because a balance is measured.
See Central Pool for the distinction between booked cash and physical token balances, and Security for external-contract assumptions.
Learn
Use the protocol
- Managing Positions
- Risk and Liquidations
- Flash Loans and Strategies
- Flash Loans
- Strategies
- Vault Integration
Prices and administration
Integration and review
- Controller
- Central Pool
- Oracle Configuration
- Accounting and Numeric Domains
- Protocol Invariants
- Architecture Decisions
Contribute and verify