Hooks
API reference for the Lotus hooks system covering ILotusHooks interface, permission flags, AllowlistHook, and BorrowHealthGuardHook parameters.
The hooks system consists of the ILotusHooks interface (which hook contracts implement), the Hooks.sol library (which the core protocol uses to manage and invoke hooks), and two production implementations: AllowlistHook and BorrowHealthGuardHook.
ILotusHooks Interface
All hooks are invoked via staticcall. Each method must return its own function selector (bytes4) on success. Any revert causes the parent operation to revert.
afterSupply
afterSupplyfunction afterSupply(SupplyParams calldata params) external view returns (bytes4);Called after supply state changes, before token transfer.
SupplyParams
id
Id
Market identifier
trancheIndex
uint256
Tranche being supplied to
sender
address
Address that initiated the supply call
onBehalf
address
Address credited with supply shares
assets
uint256
Amount of loan tokens supplied
shares
uint256
Amount of supply shares minted
afterBorrow
afterBorrowfunction afterBorrow(BorrowParams calldata params) external view returns (bytes4);Called after borrow state changes and health checks, before token transfer.
BorrowParams
id
Id
Market identifier
trancheIndex
uint256
Tranche being borrowed from
sender
address
Address that initiated the borrow call
onBehalf
address
Address whose position is debited
receiver
address
Address receiving the borrowed tokens
assets
uint256
Amount of loan tokens borrowed
shares
uint256
Amount of borrow shares created
afterSupplyCollateral
afterSupplyCollateralCalled after collateral supply state changes, before token transfer.
SupplyCollateralParams
id
Id
Market identifier
trancheIndex
uint256
Tranche receiving collateral
sender
address
Address that initiated the collateral supply
onBehalf
address
Address credited with the collateral
assets
uint256
Amount of collateral tokens deposited
afterWithdraw
afterWithdrawCalled after withdrawal state changes, before token transfer.
WithdrawParams
id
Id
Market identifier
trancheIndex
uint256
Tranche being withdrawn from
sender
address
Address that initiated the withdrawal
onBehalf
address
Address whose supply shares are burned
receiver
address
Address receiving the withdrawn tokens
assets
uint256
Amount of loan tokens withdrawn
shares
uint256
Amount of supply shares burned
shouldAccrueInterest
bool
Whether interest was accrued before withdrawal
afterWithdrawCollateral
afterWithdrawCollateralCalled after collateral withdrawal state changes, before token transfer.
WithdrawCollateralParams
id
Id
Market identifier
trancheIndex
uint256
Tranche from which collateral is withdrawn
sender
address
Address that initiated the collateral withdrawal
onBehalf
address
Address whose collateral is being withdrawn
receiver
address
Address receiving the collateral tokens
assets
uint256
Amount of collateral tokens withdrawn
Hooks Library
The Hooks.sol library provides permission flags, configuration validation, and the internal call mechanism used by Lotus core.
Permission Flags
AFTER_SUPPLY_FLAG
1 << 0 (1)
supply()
AFTER_BORROW_FLAG
1 << 1 (2)
borrow()
AFTER_SUPPLY_COLLATERAL_FLAG
1 << 2 (4)
supplyCollateral()
AFTER_WITHDRAW_FLAG
1 << 3 (8)
withdraw()
AFTER_WITHDRAW_COLLATERAL_FLAG
1 << 4 (16)
withdrawCollateral()
Combine flags with bitwise OR. For example, a hook that fires on both supply and borrow uses AFTER_SUPPLY_FLAG | AFTER_BORROW_FLAG (3).
HookConfig
Stored per-market. The hook address is the deployed hook contract; permissions is the bitmask of active flags.
validateHookConfig
validateHookConfigValidates a hook configuration. If hook is the zero address, returns an empty config (hooks disabled). If hook is non-zero but contains no code, reverts with InvalidHook(hook).
hasPermission
hasPermissionReturns true if the given flag is set in the permissions bitmask.
Errors
HookCallFailed(address hook, bytes4 selector)
The hook's staticcall reverted
InvalidHookResponse(address hook, bytes4 expected, bytes4 received)
The hook returned an unexpected selector
InvalidHook(address hook)
The hook address has no deployed code
AllowlistHook
Restricts market operations to whitelisted addresses. Checks both the transaction sender and the on-behalf address on all five hook points.
Storage
constructor
constructor_owner
address
Initial owner of the hook
Yes
Reverts: ZeroAddress() if _owner is the zero address.
setOwner
setOwnernewOwner
address
New owner address
Yes
Reverts: NotOwner() if caller is not the current owner. ZeroAddress() if newOwner is the zero address.
setSenderAllowed
setSenderAllowedid
Id
Market identifier
Yes
trancheIndex
uint256
Tranche index
Yes
who
address
Address to allow or disallow as sender
Yes
allowed
bool
Whether the address is allowed
Yes
Reverts: NotOwner() if caller is not the current owner.
setOnBehalfAllowed
setOnBehalfAllowedid
Id
Market identifier
Yes
trancheIndex
uint256
Tranche index
Yes
who
address
Address to allow or disallow as on-behalf target
Yes
allowed
bool
Whether the address is allowed
Yes
Reverts: NotOwner() if caller is not the current owner.
Hook Behavior
All five hook methods (afterSupply, afterBorrow, afterSupplyCollateral, afterWithdraw, afterWithdrawCollateral) perform the same check:
Verify
isSenderAllowed[id][trancheIndex][sender]istrue. Reverts withSenderNotAllowed(sender)otherwise.Verify
isOnBehalfAllowed[id][trancheIndex][onBehalf]istrue. Reverts withOnBehalfNotAllowed(onBehalf)otherwise.
Errors
SenderNotAllowed(address sender)
Sender is not on the allowlist for this market/tranche
OnBehalfNotAllowed(address onBehalf)
On-behalf address is not on the allowlist for this market/tranche
NotOwner()
Caller is not the hook owner
ZeroAddress()
Zero address provided where non-zero is required
BorrowHealthGuardHook
Enforces a stricter health requirement on borrowers by applying a multiplier (factor) to the protocol's LLTV. Only hooks into afterBorrow; all other hook points use the default pass-through from BaseLotusHook.
Storage
The factor is in WAD format (1e18 = 100%). A factor of 0.9e18 means the borrower can only borrow up to 90% of the protocol maximum.
constructor
constructor_owner
address
Initial owner of the hook
Yes
_lotus
ILotus
Address of the Lotus core contract
Yes
Reverts: ZeroAddress() if either parameter is the zero address.
setOwner
setOwnernewOwner
address
New owner address
Yes
Reverts: NotOwner() if caller is not the current owner. ZeroAddress() if newOwner is the zero address.
setFactor
setFactorid
Id
Market identifier
Yes
trancheIndex
uint256
Tranche index
Yes
newFactor
uint256
Health factor multiplier in WAD (must be ≤ 1e18)
Yes
Reverts: NotOwner() if caller is not the current owner. InvalidFactor(newFactor) if newFactor > 1e18.
A factor of 0 means the guard is not configured for that tranche (no check performed). Setting a factor effectively tightens the borrowing limit: strictMaxBorrow = protocolMaxBorrow * factor / WAD.
afterBorrow Behavior
afterBorrow BehaviorLoad the factor for the market and tranche. If zero, return immediately (unconfigured).
Fetch market parameters, tranche state, and borrower position from Lotus.
Convert the borrower's borrow shares to assets:
borrowed = borrowShares.toAssetsUp(trancheBorrowAssets, trancheBorrowShares).Compute the protocol maximum borrow:
protocolMaxBorrow = collateral * oraclePrice / ORACLE_PRICE_SCALE * LLTV / WAD.Apply the factor:
strictMaxBorrow = protocolMaxBorrow * factor / WAD.If
borrowed > strictMaxBorrow, revert withHealthFactorTooLow(borrowed, strictMaxBorrow).
Errors
HealthFactorTooLow(uint256 borrowed, uint256 maxAllowed)
Borrow exceeds the guard-adjusted maximum
InvalidFactor(uint256 factor)
Factor exceeds 1e18
NotOwner()
Caller is not the hook owner
ZeroAddress()
Zero address provided in constructor
See Also
Last updated

