Liquidity Hooks

Similar to Uniswap's v4 hooks, here we document how ZeroLend One executes liquidity hooks

Inspired by Uniswap V4, ZeroLend one introduces a similar concept called as liquidity hooks. Liquidity hooks allow pool creators to create custom logic and extend the functionalities of a normal lending pool.

Some interesting functionalities for a hook are:

  • Auto-manage a user position based on utilisation rates

  • Automatically close a user position based on a stop loss or some other condition.

  • Re-stake collateral from a pool into a staking contract whenever a user deposits

Besides hooks written by the ZeroLend core team, pool creators can also write their own custom hooks. The possibilities are endless.

3rd-party Hooks are not governed nor are they monitored. A malicious hook can introduce unwanted risks to a pool. However any risk brought a malicious hook is isolated to the pool only.

Available Hooks

The following table lists the various hooks that get executed when some action (such as supply, borrow, withdraw etc...) happens within the pool.

Hook FunctionDescription

beforeRepay(...)

Executed before a user repays his debt.

afterRepay(...)

Executed after a user repays his debt.

beforeSupply(...)

Executed before a user supplies an asset.

afterSupply(...)

Executed after a user supplise an asset.

beforeWithdraw(...)

Executed before a user withdraws an asset.

afterWithdraw(...)

Executed after a user withdraws an asset.

beforeBorrow(...)

Executed before a user borrows an asset

afterBorrow(...)

Executed after a user borrows an asset

beforeLiquidate(...)

Executed before a liquidation occurs.

afterLiquidate(...)

Executed after a liquidation occurs.

Technical Specification

To understand deeper about the liquidity hook, review the Hook interface that describes the various functions available to a hook.

An example of how a hook executes is shown below. The below is sample code taken from the repay function.

  function _repay(/** params **/) internal returns (uint256 paybackAmount) {  
    // This is pre-call hook
    if (address(_hook) != address(0))
      _hook.beforeRepay(msg.sender, pos, asset, address(this), amount, data.hookData);

    // ... REPAY LOGIC GOES HERE ... //

    // This is the post-call hook
    if (address(_hook) != address(0))
      _hook.afterRepay(msg.sender, pos, asset, address(this), amount, data.hookData);
  }

Here we can see that before and after the repay logic is executed, the beforeRepay and afterRepay hooks are called, executing any custom logic that the hook has been coded with.

Last updated