BaseVault

Inherits: IBaseVault, Pausable, CallbackHandler, ReentrancyGuardTransient, Auth2Step, IERC721Receiver

This contract embeds core Aera platform functionality: the ability to enlist off-chain guardians to take guarded actions on a vault. It is meant to either be extended with deposit/withdraw capabilities for users or used directly. When used directly, a depositor can simply transfer assets to the vault and a guardian can transfer them out when needed Registered guardians call the submit function and trigger vault operations. The vault may run before and after submit hooks and revert if a guardian is using an unauthorized operation. Authorized operations are configured in an off-chain merkle tree and guardians need to provide a merkle proof for each operation. In addition to validating operation targets (the contract and function being called), the merkle tree can maintain custom per-operation hooks that extract specific parts of the calldata for validation or even perform (possibly stateful) validation during the submit call

State Variables

HOOK_CALL_TYPE_SLOT

ERC7201-compliant transient storage slot for the current hook call type flag

Equal to keccak256(abi.encode(uint256(keccak256("aera.basevault.hookCallType")) - 1)) & ~bytes32(uint256(0xff));

bytes32 internal constant HOOK_CALL_TYPE_SLOT = 0xb8706f504833578f7e830b12e31c3cfba31669a85b02596177f00c6a7faf6e00;

WHITELIST

The whitelist contract that controls vault permissions

IWhitelist public immutable WHITELIST;

submitHooks

Address of the submit hooks contract for vault-level operations

ISubmitHooks public submitHooks;

guardianRoots

Enumerable map of each guardian address to their merkle root

Functions

onlyAuthOrGuardian

Ensures caller either has auth authorization requiresAuth (owner or authorized role) or is a guardian

constructor

receive

Receive function to allow the vault to receive native tokens

submit

Submit a series of operations to the vault

Parameters

Name
Type

data

bytes

setGuardianRoot

Set the merkle root for a guardian Used to add guardians and update their permissions

Parameters

Name
Type
Description

guardian

address

Address of the guardian

root

bytes32

Merkle root

removeGuardian

Removes a guardian from the vault

Parameters

Name
Type
Description

guardian

address

Address of the guardian

checkGuardianWhitelist

Check if the guardian is whitelisted and set the root to zero if not Used to disable guardians who were removed from the whitelist after being selected as guardians

Parameters

Name
Type
Description

guardian

address

The guardian address

Returns

Name
Type
Description

isRemoved

bool

Whether the guardian was removed from the whitelist

setSubmitHooks

Set the submit hooks address

Parameters

Name
Type
Description

newSubmitHooks

ISubmitHooks

Address of the new submit hooks contract

pause

Pause the vault, halting the ability for guardians to submit

unpause

Unpause the vault, allowing guardians to submit operations

getActiveGuardians

Get all active guardians

Returns

Name
Type
Description

<none>

address[]

Array of active guardian addresses

getGuardianRoot

Get the guardian root for a guardian

Parameters

Name
Type
Description

guardian

address

The guardian address

Returns

Name
Type
Description

<none>

bytes32

The guardian root

getCurrentHookCallType

Get the current hook call type

Returns

Name
Type
Description

<none>

HookCallType

The current hook call type

onERC721Received

Whenever an {IERC721} tokenId token is transferred to this contract via {IERC721-safeTransferFrom} by operator from from, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with IERC721Receiver.onERC721Received.selector.

_handleCallbackOperations

Parameters

Name
Type
Description

root

bytes32

The merkle root of the callback

cursor

uint256

The cursor to the callback data

Returns

Name
Type
Description

returnValue

bytes

The return value of the callback

_processExpectedCallback

Prepare for a callback if the guardian expects one

Writes to transient storage to encode callback expectations

Parameters

Name
Type
Description

reader

CalldataReader

Current position in the calldata

root

bytes32

The merkle root of the active guardian that triggered the callback

Returns

Name
Type
Description

<none>

CalldataReader

Updated cursor position

<none>

uint208

Packed callback data

_beforeSubmitHooks

Call the before submit hooks if defined

Submit hooks passed as an argument to reduce storage loading

Parameters

Name
Type
Description

hooks

address

Address of the submit hooks contract

data

bytes

Calldata to pass to the before submit hooks

_afterSubmitHooks

Call the after submit hooks if defined

Submit hooks passed as an argument to reduce storage loading

Parameters

Name
Type
Description

hooks

address

Address of the submit hooks contract

data

bytes

Calldata to pass to the after submit hooks

_beforeOperationHooks

Call the before operation hooks if defined

Parameters

Name
Type
Description

operationHooks

address

Address of the operation-specific hooks

data

bytes

Operation calldata

i

uint256

Operation index

Returns

Name
Type
Description

result

bytes

Result of the hooks call

_afterOperationHooks

Call the after operation hooks if defined

Parameters

Name
Type
Description

operationHooks

address

Address of the operation-specific hooks

data

bytes

Operation calldata

i

uint256

Operation index

_executeSubmit

Executes a series of operations

Approvals are tracked so we can verify if they have been zeroed out at the end of submit

Parameters

Name
Type
Description

root

bytes32

The merkle root of the active guardian that triggered the callback

reader

CalldataReader

Current position in the calldata

isCalledFromCallback

bool

Whether the submit is called from a callback

Returns

Name
Type
Description

approvals

Approval[]

Array of outgoing approvals created during execution

approvalsLength

uint256

Length of approvals array

results

bytes[]

Array of results from the operations

newReader

CalldataReader

Updated cursor position

_processBeforeOperationHooks

Processes all hooks for operation

Returns extracted data if configurable or contract before operation hooks is defined

Custom hooks (with contracts) can run before and after each operation but a configurable hooks can only run before an operation. This function processes all of the possible configurations of hooks which doesn't allow using both a custom before hook and a configurable before hook

Parameters

Name
Type
Description

reader

CalldataReader

Current position in the calldata

callData

bytes

Operation calldata

i

uint256

Operation index

Returns

Name
Type
Description

<none>

CalldataReader

reader Updated reader position

<none>

bytes

extractedData Extracted chunks of calldata

<none>

uint256

hooksConfigBytes hooks configuration bytes

<none>

address

operationHooks Operation hooks address

_setSubmitHooks

Set the submit hooks address

Parameters

Name
Type
Description

submitHooks_

ISubmitHooks

Address of the submit hooks contract

_setGuardianRoot

Set the guardian root

Parameters

Name
Type
Description

guardian

address

Address of the guardian

root

bytes32

Merkle root

_setHookCallType

Set the hook call type

Parameters

Name
Type
Description

hookCallType

HookCallType

The hook call type

_noPendingApprovalsInvariant

Verify no pending approvals remain at the end of a submit

We iterate backwards to avoid extra i variable

While loop is preferred over for(;approvalsLength != 0;)

Iterator variable is not used because it's not needed and decrement needs to be unchecked

Parameters

Name
Type
Description

approvals

Approval[]

Array of approvals to check

approvalsLength

uint256

Length of approvals array

_getReturnValue

Get the return value from the operations

Parameters

Name
Type
Description

reader

CalldataReader

Current position in the calldata

results

bytes[]

Array of results from the operations

Returns

Name
Type
Description

newReader

CalldataReader

Updated reader position

returnValue

bytes

Return value from the operations

_verifyOperation

Verify an operation by validating the merkle proof

Parameters

Name
Type
Description

proof

bytes32[]

The merkle proof

root

bytes32

The merkle root

leaf

bytes32

The merkle leaf to verify

_createMerkleLeaf

Create a merkle leaf

Parameters

Name
Type
Description

ctx

OperationContext

The operation context

extractedData

bytes

The extracted data

Returns

Name
Type
Description

<none>

bytes32

leaf The merkle leaf

_extractApprovalSpender

Extract spender address from approval data

Extract spender address from approval data

Parameters

Name
Type
Description

data

bytes

Approval calldata

Returns

Name
Type
Description

spender

address

Address of the spender

_hasBeforeHooks

Check if hooks needs to be called before the submit/operation

Check if hooks needs to be called before the submit/operation

Parameters

Name
Type
Description

hooks

address

Hooks address to check

Returns

Name
Type
Description

<none>

bool

True if hooks needs to be called before the submit/operation

_hasAfterHooks

least significant bit is 1 indicating it's a before hooks

Check if submit hooks needs to be called after the submit/operation

Check if submit hooks needs to be called after the submit/operation

Parameters

Name
Type
Description

hooks

address

Submit hooks address to check

Returns

Name
Type
Description

<none>

bool

True if submit hooks needs to be called after the submit/operation

_isAllowanceSelector

second least significant bit is 1 indicating it's a after hooks

Check if the selector is an allowance handling selector

Check if the selector is an allowance handling selector

Parameters

Name
Type
Description

selector

bytes4

Selector to check

Returns

Name
Type
Description

<none>

bool

True if the selector is an allowance handling selector

Last updated