Smart Vault

The Smart Vault contract is a crucial component of the Mimic protocol, providing a central repository for users to store and manage their assets. It is also responsible for enabling connectors and defining different tasks workflows.

The contract code of the Smart Vault can be found here.

Functionality

The Smart Vault contract provides the following key functions:

Collect

This function allows the Smart Vault to fetch tokens from an external source following the ERC20 transfer-from functionality.

/**
 * @dev Collect tokens from an external account to the Smart Vault
 * @param token Address of the token to be collected
 * @param source Address where the tokens will be transferred from
 * @param amount Amount of tokens to be transferred
 */
function collect(address token, address source, uint256 amount) external;

Withdraw

This function allows the Smart Vault to send tokens to an account following the ERC20 transfer functionality.

/**
 * @dev Withdraw tokens to an external account
 * @param token Address of the token to be withdrawn
 * @param recipient Address where the tokens will be transferred to
 * @param amount Amount of tokens to withdraw
 */
function withdraw(address token, address recipient, uint256 amount) external;

Wrap

This function allows the Smart Vault to wrap native tokens following the WETH standard.

/**
 * @dev Wrap an amount of native tokens to the wrapped ERC20 version of it
 * @param amount Amount of native tokens to be wrapped
 */
function wrap(uint256 amount) external;

Unwrap

This function allows the Smart Vault to unwrap wrapped native tokens following the WETH standard.

/**
 * @dev Unwrap an amount of wrapped native tokens
 * @param amount Amount of wrapped native tokens to unwrapped
 */
function unwrap(uint256 amount) external;

Call

This function allows the Smart Vault to execute arbitrary calls in case the user needs to perform a custom contract call.

/**
 * @dev Executes an arbitrary call from the Smart Vault
 * @param target Address where the call will be sent
 * @param data Call data to be used for the call
 * @param value Value in wei that will be attached to the call
 * @return result Call response if it was successful, otherwise it reverts
 */
function call(address target, bytes memory data, uint256 value) external returns (bytes memory result);

Execute

This function allows the Smart Vault to execute a connector. Be careful that executing connectors means a delegate call to a library. The main purpose here is to allow the Smart Vault executing custom code in order to interact with external DeFi protocols. By default the Smart Vault won't allow executing any other connector unless it is registered in the list of curated connectors by Mimic. However, this functionality can be overridden by the user in case they deside to allow a custom connector.

/**
 * @dev Executes a connector inside of the Smart Vault context
 * @param connector Address of the connector that will be executed
 * @param data Call data to be used for the delegate-call
 * @return result Call response if it was successful, otherwise it reverts
 */
function execute(address connector, bytes memory data) external returns (bytes memory result);

Configuration

It also provides the following configuration:

Pause

This function allows the Smart Vault to be paused. Pausing the Smart Vault basically blocks all it's non-view functions until it is unpaused again.

/**
 * @dev Pauses a smart vault
 */
function pause() external;

/**
 * @dev Unpauses a smart vault
 */
function unpause() external;

Price oracle

The Smart Vault only keeps one single Price Oracle reference for all its tasks. The reference can be set here. Mimic provides a standard implementation for the Price Oracle. However, users can plug whatever Price Oracle they want to use.

/**
 * @dev Sets the price oracle
 * @param newPriceOracle Address of the new price oracle to be set
 */
function setPriceOracle(address newPriceOracle) external;

Connector checks

When the Smart Vault is requested to execute a connector, it will validate against the Mimic Registry if the requested connector is registered and it's not deprecated. However, users can decide to override this check in order to execute custom connectors if desired.

/**
 * @dev Overrides connector checks
 * @param connector Address of the connector to override its check
 * @param ignored Whether the connector check should be ignored
 */
function overrideConnectorCheck(address connector, bool ignored) external;

Balance connector

This functionality allows the Smart Vault to define different workflows for different set of tasks. Usually this function is called by tasks automatically. Different tasks may use different balance connectors to make sure they don't collude with the assets they are supposed to operate.

/**
 * @dev Updates a balance connector
 * @param id Balance connector identifier to be updated
 * @param token Address of the token to update the balance connector for
 * @param amount Amount to be updated to the balance connector
 * @param add Whether the balance connector should be increased or decreased
 */
function updateBalanceConnector(bytes32 id, address token, uint256 amount, bool add) external;

Security Considerations

Authentication

The Smart Vault, like other components in the architecture, operates under the governance of the Authorizer. The Authorizer acts as a central authority where users define the permissions and access rights for various actions. In the implementation of the Smart Vault, you'll notice that all non-view functions are marked with auth modifiers to restrict access.

It's essential to highlight that Mimic does not impose specific permission settings for every Smart Vault. Instead, users have the autonomy to configure and determine the permissions according to their specific requirements and preferences. This flexibility empowers users to tailor the access control system to align with their desired security and governance models.

Reentrancy

Reentrancy is a vulnerability in smart contracts that occurs when a contract's function can be called multiple times before the previous invocation has completed. This can potentially lead to unexpected and malicious behavior, allowing an attacker to exploit the contract's state and manipulate its execution flow.

In the implementation of the Smart Vault, all non-view functions are also tagged with the nonReentrant modifier, which is provided by OpenZeppelin's ReentrancyGuard module. This precautionary measure is taken to prevent potential reentrancy attacks, ensuring the security and integrity of the contract.

By applying the nonReentrant modifier to non-view functions, the Smart Vault contract mitigates the risk of reentrancy attacks. This modifier, provided by the ReentrancyGuard module, enforces a lock mechanism that restricts the reentrant execution of functions. It ensures that a function cannot be called again until the current invocation completes, preventing any potential interference or manipulation by malicious actors.

Pausing

The Smart Vault incorporates a pausing mechanism designed to enhance control and security within the protocol. This mechanism allows for the temporary suspension of certain operations by blocking all non-view functions when the Smart Vault is in a paused state. This ensures that critical actions cannot be executed during the paused period until the Smart Vault is unpaused.

When the Smart Vault is paused, all non-view functions are effectively disabled. This includes functions that involve asset transfers, deposits, withdrawals, authorizations, and other sensitive operations. By preventing these functions from being invoked, the pausing mechanism adds an extra layer of protection and mitigates potential risks during specific scenarios.

It is important to note that in the Mimic protocol, the ability to pause Smart Vaults is not enforced by the protocol itself. Instead, the decision and capability to pause Smart Vaults lie within the permissions layout configured by the users.

Last updated