Account Status Checks
Account status checks are implemented by vaults to enforce account solvency. Vaults must expose an external checkAccountStatus
function that will receive an account's address and this account's list of enabled collateral vaults. If the account has not borrowed anything from this vault then the function should return a special magic success value (the function selector for the checkAccountStatus
method). Otherwise, the vault should evaluate application-specific logic to determine whether or not the account is in an acceptable state. If so, it should return the special magic success value, otherwise throw an exception.
When performing the account status checks, vaults have the freedom to price all the assets according to their preference (both liability and accepted collaterals), without depending on potentially untrustworthy oracles.
Execution Flow
Although the vaults themselves implement checkAccountStatus
, there is no need for them to invoke this function directly. It will be called by the EVC when necessary. Instead, after performing any operation that could affect an account's liquidity, a vault should invoke requireAccountStatusCheck
on the EVC to schedule a future callback. Additionally, operations that can affect the liquidity of a separate account will need their own requireAccountStatusCheck
calls.
Upon a requireAccountStatusCheck
call, the EVC will determine whether the current execution context is in a checks-deferrable call and if so, it will defer checking the status for this account until the end of the execution context. Otherwise, the account status check will be performed immediately.
There is a subtle complication that vault implementations should consider if they use re-entrancy guards (which is recommended). When a vault is invoked without account status checks being deferred (i.e. directly, not via the EVC), if it calls requireAccountStatusCheck
on the EVC, the EVC will immediately call back into the vault's checkAccountStatus
function. A normal re-entrancy guard would fail upon re-entering at this point. To avoid this, vaults may wish to use the call
EVC function.
Single Controller
At the time of the account status check, an account can have at most one controller. This is how single-liability-per-account is enforced. Multiple controllers are disallowed because it is unlikely two independent controllers would be able to behave consistently in the presence of "shared" accounts. If this is ever required, a multi-controller controller could be created with the desired sharing logic.
Although having more than one controller is disallowed when the account status check is performed, multiple controllers can be transiently attached while these checks are deferred. As long as all or all but one controllers release themselves during the execution of the checks-deferrable call, the account status check will succeed.
Last Account Status Check Timestamp
A successful checkAccountStatus
call to the enabled controller vault will record the timestamp of the last successful account status check for a given account in the EVC's storage. This timestamp can be later retrieved using the getLastAccountStatusCheckTimestamp
function on the EVC.