Receiving Callbacks
What are Callback Handlers?
The hooks system is very flexible and allows guardians to invoke arbitrary operations, however, some interactions may trigger callbacks into the Aera Vault. A common instance is flash loans which need to be paid back atomically and therefore only provide access to funds through a callback.
Callback handlers provide a way for guardians to prepare for a callback by “queueing up” additional operations that would be executed during the callback. These operations are protected by the same Merkle tree (see Merkle Trees) and hooks (see Using Configurable Hooks) as general Aera vault operations (see Operations and submit()).
Why They Matter
Aera Vaults can inherit from BaseVault
and add functions to respond to callbacks. However, this approach defeats the purpose of the Aera system which is to allow guardians to take flexible operations that are informed by off chain computation with onchain protections.
Callback handlers provide significantly more flexibility and together with input/output chaining allow guardians to implement complex multi-step operations that were previously only available to MEV bots.
How to use Callback Handlers
To invoke a callback handler, you need to do the following:
Decide which operation will trigger a callback into the Aera vault
Call submit and for that operation:
Set
hasCallback
to 1,Provide
selector
, the function selector for the callback function that the vault will be called with,Provide
calldataOffset
the specific byte in the calldata that Aera Vault should extract the operations for,Provide
caller
, the contract that will call the Aera Vault.
Whenever the callback occurs, the Aera Vault will check if the callback is expected with the given selector and caller. If so, it will decode the series of operations starting at the calldata offset and execute them while complying to the guardian's Merkle tree.
Consider Morpho flash loans as an example. The following would happen:
The guardian creates a submit transaction with the operation
morpho.flashLoan
;flashLoan
accepts 3 arguments:token
,amount
anddata
. The guardian encodes all the operations which should trigger on the callback in thedata
argument;The guardian also adds a callback to the operation using the selector of
onMorphoFlashLoan(amount, data)
(0x31f57072
) usingmorpho
as the caller (0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb
) and specifying the calldata index ofdata
variable inonMorphoFlashLoan
(100). Note that 100 is chosen because we need to skip the pointer and the length variable asCalldataReader
uses a more compact length encoding;Now
submit
executes and calls themorpho
contract;Morpho executes the
onMorphoFlashLoan
callback which is handled by Aera. Morpho forwards alldata
provided to flashLoan in thedata
argument. In the handler, the vault decodes operations and runs them from the handler.
Caveats
Callback handlers only exist during a given submit
call by a guardian. It means that they cannot be used for asynchronous interactions (such as receiving a settlement order in response to an RFQ) and that the same callback function can trigger different operations in different submit
calls. To add new functions to an Aera vault, an extension to BaseVault
is recommended.
Only “pull”-based flash loans are currently supported because push-based flash loans require a transfer operation to dynamically allow repayment based on how much was borrowed. Push-based flash loans can still be supported by creating a dedicated handler contract.
Last updated