Factor DAO Vaults

Smart Contract Audit Report

Audit Summary

Factor DAO Vaults Audit Report Factor DAO Vaults is a new platform that allows its owner to create various Vaults, each with associated Strategies.

For this audit, we reviewed the project team's FactorVault, FactorVaultMulti, FactorVaultManager, and FactorVaultMultiManager contracts at commit 00405f1d56f0f1a8b0c4d55df2ba3cae97944502 on the team's private GitHub repository.

Audit Findings

No findings were identified, though some centralized aspects are present.
Date: May 9th, 2023.
Updated: July 18th, 2023 to reflect changes from commit 2caf30e2c2daee605ebea930a69c8d6f891a5f5b to commit 00405f1d56f0f1a8b0c4d55df2ba3cae97944502.

Contracts Overview

  • ReentrancyGuard is utilized to protect against reentrancy attacks in applicable functions.
  • As the contracts are implemented with Solidity v0.8.x, they are safe from any possible overflows/underflows.
FactorVault Contract:
  • This contract allows users to deposit a specified asset in exchange for minted vault shares.
  • Upon depositing, the asset is transferred from the user to this contract. Any assets in the contract are then deposited into the associated Strategy contract.
  • A user can specify any address to receive the minted shares upon depositing.
  • When withdrawing, shares are burned from the user and funds are subsequently withdrawn from the Strategy contract.
  • A user can redeem another user's shares to any address if they have been granted an allowance.
  • The owner can propose a new Strategy at any time.
  • Once the contract's "upgrade time lock" has passed, the owner can upgrade the strategy, which invokes the Strategy contract to upgrade itself to the newly proposed implementation.
  • As the Strategy contract was not included within the scope of this audit, we are unable to provide an assessment with regards to its security or functionality.
  • The owner can upgrade this contract at any time, as long as the new implementation is registered in the FactorVaultManager contract.
FactorVaultMulti Contract:
  • This contract allows users to deposit a denominating asset in exchange for vault shares.
  • Upon deposit, the asset is split into portions of various sizes determined by the Strategy contract and deposited into the Strategy.
  • These portions are intended to be swapped into various underlying assets once received by the Strategy contract.
  • A user can specify any address to receive the minted shares upon depositing.
  • Upon withdrawing, the user's share of each of the assets in the Strategy are intended to be swapped back to the denominating asset in the Strategy contract and subsequently withdrawn.
  • A user can redeem another user's shares to any address if they have been granted an allowance.
  • As the Strategy contract was not included within the scope of this audit, we are unable to provide an assessment with regards to its security or functionality.
  • The owner can propose a new Strategy at any time.
  • Once the contract's "upgrade time lock" has passed, the owner can upgrade the strategy, which invokes the Strategy contract to upgrade itself to the newly proposed implementation.
  • As the Strategy contract was not included within the scope of this audit, we are unable to provide an assessment with regards to its security or functionality.
  • The owner can upgrade this contract at any time, as long as the new implementation is registered in the FactorVaultManager contract.
  • The project team should ensure that a price oracle is used in the Strategy contract in order to prevent frontrunning attacks on deposits or withdrawal swaps.
FactorVaultManager & FactorVaultMultiManager Contracts:
  • These contracts allow the owner to deploy Vaults with specified Strategys.
  • The FactorVaultManager contract is used to deploy new FactorVault and Strategy contracts; the FactorVaultMultiManager contract is used to deploy new FactorVaultMulti and StrategyMulti contracts.
  • New Strategy and Vault contracts are deployed and initialized using the contract's current Vault implementation and the owner's specified Strategy implementation.
  • A new Vault's upgrade time lock is set using this contract's value upon the Vault's deployment.
  • The owner can update the upgrade time lock period used for future Vaults at any time.
  • Ownership of both the Vault and Strategy are subsequently transferred to the deploying user.
  • The owner can register or deregister a Vault implementation at any time, allowing any Vault to be upgraded to it at any time.
  • The owner can update the Vault implementation used for new Vault deployments at any time.

Audit Results

Vulnerability Category Notes Result
Arbitrary Jump/Storage Write N/A PASS
Centralization of Control
  • The owner has the permissions described above.
  • The owner can upgrade the FactorVault and FactorVaultMulti contracts at any time as long as the new implementation is registered in the Manager contract.
  • The owner can update a Vault's Strategy at any time after waiting for its upgrade time lock period to pass.
  • WARNING
    Compiler Issues N/A PASS
    Delegate Call to Untrusted Contract N/A PASS
    Dependence on Predictable Variables N/A PASS
    Ether/Token Theft N/A PASS
    Flash Loans N/A PASS
    Front Running N/A PASS
    Improper Events N/A PASS
    Improper Authorization Scheme N/A PASS
    Integer Over/Underflow N/A PASS
    Logical Issues N/A PASS
    Oracle Issues N/A PASS
    Outdated Compiler Version N/A PASS
    Race Conditions N/A PASS
    Reentrancy N/A PASS
    Signature Issues N/A PASS
    Sybil Attack N/A PASS
    Unbounded Loops N/A PASS
    Unused Code N/A PASS
    Overall Contract Safety   PASS

    FactorVault Contract

    Smart Contract Audit - Inheritance

    Smart Contract Audit - Graph

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
     
     + [Int] IERC20Upgradeable 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     + [Int] IERC20MetadataUpgradeable (IERC20Upgradeable)
        - [Ext] name
        - [Ext] symbol
        - [Ext] decimals
    
     + [Lib] AddressUpgradeable 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] verifyCallResultFromTarget
        - [Int] verifyCallResult
        - [Prv] _revert
    
     +  Initializable 
        - [Int] _disableInitializers #
        - [Int] _getInitializedVersion
        - [Int] _isInitializing
    
     +  ContextUpgradeable (Initializable)
        - [Int] __Context_init #
           - modifiers: onlyInitializing
        - [Int] __Context_init_unchained #
           - modifiers: onlyInitializing
        - [Int] _msgSender
        - [Int] _msgData
    
     +  ERC20Upgradeable (Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable)
        - [Int] __ERC20_init #
           - modifiers: onlyInitializing
        - [Int] __ERC20_init_unchained #
           - modifiers: onlyInitializing
        - [Pub] name
        - [Pub] symbol
        - [Pub] decimals
        - [Pub] totalSupply
        - [Pub] balanceOf
        - [Pub] transfer #
        - [Pub] allowance
        - [Pub] approve #
        - [Pub] transferFrom #
        - [Pub] increaseAllowance #
        - [Pub] decreaseAllowance #
        - [Int] _transfer #
        - [Int] _mint #
        - [Int] _burn #
        - [Int] _approve #
        - [Int] _spendAllowance #
        - [Int] _beforeTokenTransfer #
        - [Int] _afterTokenTransfer #
    
     +  OwnableUpgradeable (Initializable, ContextUpgradeable)
        - [Int] __Ownable_init #
           - modifiers: onlyInitializing
        - [Int] __Ownable_init_unchained #
           - modifiers: onlyInitializing
        - [Pub] owner
        - [Int] _checkOwner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
        - [Int] _transferOwnership #
    
     +  ReentrancyGuardUpgradeable (Initializable)
        - [Int] __ReentrancyGuard_init #
           - modifiers: onlyInitializing
        - [Int] __ReentrancyGuard_init_unchained #
           - modifiers: onlyInitializing
        - [Prv] _nonReentrantBefore #
        - [Prv] _nonReentrantAfter #
    
     + [Int] IERC1822ProxiableUpgradeable 
        - [Ext] proxiableUUID
    
     + [Int] IBeaconUpgradeable 
        - [Ext] implementation
    
     + [Lib] StorageSlotUpgradeable 
        - [Int] getAddressSlot
        - [Int] getBooleanSlot
        - [Int] getBytes32Slot
        - [Int] getUint256Slot
    
     +  ERC1967UpgradeUpgradeable (Initializable)
        - [Int] __ERC1967Upgrade_init #
           - modifiers: onlyInitializing
        - [Int] __ERC1967Upgrade_init_unchained #
           - modifiers: onlyInitializing
        - [Int] _getImplementation
        - [Prv] _setImplementation #
        - [Int] _upgradeTo #
        - [Int] _upgradeToAndCall #
        - [Int] _upgradeToAndCallUUPS #
        - [Int] _getAdmin
        - [Prv] _setAdmin #
        - [Int] _changeAdmin #
        - [Int] _getBeacon
        - [Prv] _setBeacon #
        - [Int] _upgradeBeaconToAndCall #
        - [Prv] _functionDelegateCall #
    
     +  UUPSUpgradeable (Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable)
        - [Int] __UUPSUpgradeable_init #
           - modifiers: onlyInitializing
        - [Int] __UUPSUpgradeable_init_unchained #
           - modifiers: onlyInitializing
        - [Ext] proxiableUUID
           - modifiers: notDelegated
        - [Ext] upgradeTo #
           - modifiers: onlyProxy
        - [Ext] upgradeToAndCall ($)
           - modifiers: onlyProxy
        - [Int] _authorizeUpgrade #
    
     + [Lib] MathUpgradeable 
        - [Int] max
        - [Int] min
        - [Int] average
        - [Int] ceilDiv
        - [Int] mulDiv
        - [Int] mulDiv
        - [Int] sqrt
        - [Int] sqrt
        - [Int] log2
        - [Int] log2
        - [Int] log10
        - [Int] log10
        - [Int] log256
        - [Int] log256
    
     + [Int] IERC20 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     + [Int] IERC20Permit 
        - [Ext] permit #
        - [Ext] nonces
        - [Ext] DOMAIN_SEPARATOR
    
     + [Lib] Address 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] functionDelegateCall #
        - [Int] functionDelegateCall #
        - [Int] verifyCallResultFromTarget
        - [Int] verifyCallResult
        - [Prv] _revert
    
     + [Lib] SafeERC20 
        - [Int] safeTransfer #
        - [Int] safeTransferFrom #
        - [Int] safeApprove #
        - [Int] safeIncreaseAllowance #
        - [Int] safeDecreaseAllowance #
        - [Int] safePermit #
        - [Prv] _callOptionalReturn #
    
     + [Int] IStrategy 
        - [Ext] asset
        - [Ext] vault
        - [Ext] beforeDeposit #
        - [Ext] deposited #
        - [Ext] withdraw #
        - [Ext] balanceOf
        - [Ext] harvest #
        - [Ext] exit #
        - [Ext] panic #
        - [Ext] pause #
        - [Ext] unpause #
        - [Ext] paused
    
     + [Int] IStrategyUpgradeTo 
        - [Ext] upgradeTo #
    
     + [Int] IFactorVaultManager 
        - [Ext] isRegisteredUpgrade
    
     +  FactorVault (Initializable, ERC20Upgradeable, OwnableUpgradeable, ReentrancyGuardUpgradeable, UUPSUpgradeable)
        - [Pub]  #
        - [Pub] initialize #
           - modifiers: initializer
        - [Pub] asset
        - [Pub] assetBalance
        - [Pub] availableBalance
        - [Pub] getPricePerShare
        - [Pub] deposit #
           - modifiers: nonReentrant
        - [Int] _deposit #
        - [Int] earn #
        - [Pub] withdraw #
           - modifiers: nonReentrant
        - [Int] _withdraw #
        - [Pub] proposeStrategy #
           - modifiers: onlyOwner
        - [Pub] upgradeStrategy #
           - modifiers: onlyOwner
        - [Int] _authorizeUpgrade
           - modifiers: onlyOwner
    
    
    

    FactorVaultMulti Contract

    Smart Contract Audit - Inheritance

    Smart Contract Audit - Graph

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
     
     + [Int] IERC20Upgradeable 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     + [Int] IERC20MetadataUpgradeable (IERC20Upgradeable)
        - [Ext] name
        - [Ext] symbol
        - [Ext] decimals
    
     + [Lib] AddressUpgradeable 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] verifyCallResultFromTarget
        - [Int] verifyCallResult
        - [Prv] _revert
    
     +  Initializable 
        - [Int] _disableInitializers #
        - [Int] _getInitializedVersion
        - [Int] _isInitializing
    
     +  ContextUpgradeable (Initializable)
        - [Int] __Context_init #
           - modifiers: onlyInitializing
        - [Int] __Context_init_unchained #
           - modifiers: onlyInitializing
        - [Int] _msgSender
        - [Int] _msgData
    
     +  ERC20Upgradeable (Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable)
        - [Int] __ERC20_init #
           - modifiers: onlyInitializing
        - [Int] __ERC20_init_unchained #
           - modifiers: onlyInitializing
        - [Pub] name
        - [Pub] symbol
        - [Pub] decimals
        - [Pub] totalSupply
        - [Pub] balanceOf
        - [Pub] transfer #
        - [Pub] allowance
        - [Pub] approve #
        - [Pub] transferFrom #
        - [Pub] increaseAllowance #
        - [Pub] decreaseAllowance #
        - [Int] _transfer #
        - [Int] _mint #
        - [Int] _burn #
        - [Int] _approve #
        - [Int] _spendAllowance #
        - [Int] _beforeTokenTransfer #
        - [Int] _afterTokenTransfer #
    
     +  OwnableUpgradeable (Initializable, ContextUpgradeable)
        - [Int] __Ownable_init #
           - modifiers: onlyInitializing
        - [Int] __Ownable_init_unchained #
           - modifiers: onlyInitializing
        - [Pub] owner
        - [Int] _checkOwner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
        - [Int] _transferOwnership #
    
     +  ReentrancyGuardUpgradeable (Initializable)
        - [Int] __ReentrancyGuard_init #
           - modifiers: onlyInitializing
        - [Int] __ReentrancyGuard_init_unchained #
           - modifiers: onlyInitializing
        - [Prv] _nonReentrantBefore #
        - [Prv] _nonReentrantAfter #
    
     + [Int] IERC1822ProxiableUpgradeable 
        - [Ext] proxiableUUID
    
     + [Int] IBeaconUpgradeable 
        - [Ext] implementation
    
     + [Lib] StorageSlotUpgradeable 
        - [Int] getAddressSlot
        - [Int] getBooleanSlot
        - [Int] getBytes32Slot
        - [Int] getUint256Slot
    
     +  ERC1967UpgradeUpgradeable (Initializable)
        - [Int] __ERC1967Upgrade_init #
           - modifiers: onlyInitializing
        - [Int] __ERC1967Upgrade_init_unchained #
           - modifiers: onlyInitializing
        - [Int] _getImplementation
        - [Prv] _setImplementation #
        - [Int] _upgradeTo #
        - [Int] _upgradeToAndCall #
        - [Int] _upgradeToAndCallUUPS #
        - [Int] _getAdmin
        - [Prv] _setAdmin #
        - [Int] _changeAdmin #
        - [Int] _getBeacon
        - [Prv] _setBeacon #
        - [Int] _upgradeBeaconToAndCall #
        - [Prv] _functionDelegateCall #
    
     +  UUPSUpgradeable (Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable)
        - [Int] __UUPSUpgradeable_init #
           - modifiers: onlyInitializing
        - [Int] __UUPSUpgradeable_init_unchained #
           - modifiers: onlyInitializing
        - [Ext] proxiableUUID
           - modifiers: notDelegated
        - [Ext] upgradeTo #
           - modifiers: onlyProxy
        - [Ext] upgradeToAndCall ($)
           - modifiers: onlyProxy
        - [Int] _authorizeUpgrade #
    
     + [Lib] MathUpgradeable 
        - [Int] max
        - [Int] min
        - [Int] average
        - [Int] ceilDiv
        - [Int] mulDiv
        - [Int] mulDiv
        - [Int] sqrt
        - [Int] sqrt
        - [Int] log2
        - [Int] log2
        - [Int] log10
        - [Int] log10
        - [Int] log256
        - [Int] log256
    
     + [Int] IERC20 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     + [Int] IERC20Permit 
        - [Ext] permit #
        - [Ext] nonces
        - [Ext] DOMAIN_SEPARATOR
    
     + [Lib] Address 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] functionDelegateCall #
        - [Int] functionDelegateCall #
        - [Int] verifyCallResultFromTarget
        - [Int] verifyCallResult
        - [Prv] _revert
    
     + [Lib] SafeERC20 
        - [Int] safeTransfer #
        - [Int] safeTransferFrom #
        - [Int] safeApprove #
        - [Int] safeIncreaseAllowance #
        - [Int] safeDecreaseAllowance #
        - [Int] safePermit #
        - [Prv] _callOptionalReturn #
    
     + [Int] IStrategyMulti 
        - [Ext] denominator
        - [Ext] underlyingAssets
        - [Ext] underlyingAssetsCount
        - [Ext] underlyingAssetsBalance
        - [Ext] vault
        - [Ext] deposit #
        - [Ext] withdraw #
        - [Ext] harvest #
        - [Ext] exit #
        - [Ext] panic #
        - [Ext] pause #
        - [Ext] unpause #
        - [Ext] paused
    
     + [Int] IStrategyUpgradeTo 
        - [Ext] upgradeTo #
    
     + [Int] IFactorVaultManager 
        - [Ext] isRegisteredUpgrade
    
     + [Int] IERC20Decimals 
        - [Ext] decimals
    
     +  FactorVaultMulti (Initializable, ERC20Upgradeable, OwnableUpgradeable, ReentrancyGuardUpgradeable, UUPSUpgradeable)
        - [Pub]  #
        - [Pub] initialize #
           - modifiers: initializer
        - [Pub] denominator
        - [Pub] underlyingAssets
        - [Pub] underlyingAssetsCount
        - [Pub] underlyingAssetsBalance
        - [Pub] deposit #
           - modifiers: nonReentrant
        - [Int] _deposit #
        - [Pub] withdraw #
           - modifiers: nonReentrant
        - [Int] _withdraw #
        - [Pub] proposeStrategy #
           - modifiers: onlyOwner
        - [Pub] upgradeStrategy #
           - modifiers: onlyOwner
        - [Int] _authorizeUpgrade
           - modifiers: onlyOwner
    
     
    

    FactorVaultManager Contract

    Smart Contract Audit - Inheritance

    Smart Contract Audit - Graph

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
     
     + [Lib] AddressUpgradeable 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] verifyCallResultFromTarget
        - [Int] verifyCallResult
        - [Prv] _revert
    
     +  Initializable 
        - [Int] _disableInitializers #
        - [Int] _getInitializedVersion
        - [Int] _isInitializing
    
     +  ContextUpgradeable (Initializable)
        - [Int] __Context_init #
           - modifiers: onlyInitializing
        - [Int] __Context_init_unchained #
           - modifiers: onlyInitializing
        - [Int] _msgSender
        - [Int] _msgData
    
     +  OwnableUpgradeable (Initializable, ContextUpgradeable)
        - [Int] __Ownable_init #
           - modifiers: onlyInitializing
        - [Int] __Ownable_init_unchained #
           - modifiers: onlyInitializing
        - [Pub] owner
        - [Int] _checkOwner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
        - [Int] _transferOwnership #
    
     +  Proxy 
        - [Int] _delegate #
        - [Int] _implementation
        - [Int] _fallback #
        - [Ext]  ($)
        - [Ext]  ($)
        - [Int] _beforeFallback #
    
     + [Int] IBeacon 
        - [Ext] implementation
    
     + [Int] IERC1822Proxiable 
        - [Ext] proxiableUUID
    
     + [Lib] Address 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] functionDelegateCall #
        - [Int] functionDelegateCall #
        - [Int] verifyCallResultFromTarget
        - [Int] verifyCallResult
        - [Prv] _revert
    
     + [Lib] StorageSlot 
        - [Int] getAddressSlot
        - [Int] getBooleanSlot
        - [Int] getBytes32Slot
        - [Int] getUint256Slot
    
     +  ERC1967Upgrade 
        - [Int] _getImplementation
        - [Prv] _setImplementation #
        - [Int] _upgradeTo #
        - [Int] _upgradeToAndCall #
        - [Int] _upgradeToAndCallUUPS #
        - [Int] _getAdmin
        - [Prv] _setAdmin #
        - [Int] _changeAdmin #
        - [Int] _getBeacon
        - [Prv] _setBeacon #
        - [Int] _upgradeBeaconToAndCall #
    
     +  ERC1967Proxy (Proxy, ERC1967Upgrade)
        - [Pub]  ($)
        - [Int] _implementation
    
     +  TransparentUpgradeableProxy (ERC1967Proxy)
        - [Pub]  ($)
           - modifiers: ERC1967Proxy
        - [Ext] admin #
           - modifiers: ifAdmin
        - [Ext] implementation #
           - modifiers: ifAdmin
        - [Ext] changeAdmin #
           - modifiers: ifAdmin
        - [Ext] upgradeTo #
           - modifiers: ifAdmin
        - [Ext] upgradeToAndCall ($)
           - modifiers: ifAdmin
        - [Int] _admin
        - [Int] _beforeFallback #
    
     +  Context 
        - [Int] _msgSender
        - [Int] _msgData
    
     +  Ownable (Context)
        - [Pub]  #
        - [Pub] owner
        - [Int] _checkOwner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
        - [Int] _transferOwnership #
    
     +  ProxyAdmin (Ownable)
        - [Pub] getProxyImplementation
        - [Pub] getProxyAdmin
        - [Pub] changeProxyAdmin #
           - modifiers: onlyOwner
        - [Pub] upgrade #
           - modifiers: onlyOwner
        - [Pub] upgradeAndCall ($)
           - modifiers: onlyOwner
    
     + [Int] IStrategy 
        - [Ext] asset
        - [Ext] vault
        - [Ext] beforeDeposit #
        - [Ext] deposited #
        - [Ext] withdraw #
        - [Ext] balanceOf
        - [Ext] harvest #
        - [Ext] exit #
        - [Ext] panic #
        - [Ext] pause #
        - [Ext] unpause #
        - [Ext] paused
    
     + [Int] IERC20 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     + [Int] IERC20Permit 
        - [Ext] permit #
        - [Ext] nonces
        - [Ext] DOMAIN_SEPARATOR
    
     + [Lib] SafeERC20 
        - [Int] safeTransfer #
        - [Int] safeTransferFrom #
        - [Int] safeApprove #
        - [Int] safeIncreaseAllowance #
        - [Int] safeDecreaseAllowance #
        - [Int] safePermit #
        - [Prv] _callOptionalReturn #
    
     + [Int] IFactorVault 
        - [Ext] initialize #
        - [Ext] asset
        - [Ext] deposit #
    
     + [Int] IOwnable 
        - [Ext] transferOwnership #
    
     +  FactorVaultManager (OwnableUpgradeable)
        - [Pub]  #
        - [Pub] initialize #
           - modifiers: initializer
        - [Ext] deployVault #
           - modifiers: onlyOwner
        - [Ext] setUpgradeTimelock #
           - modifiers: onlyOwner
        - [Pub] getNextVaultAddress
        - [Ext] isRegisteredUpgrade
        - [Ext] registerUpgrade #
           - modifiers: onlyOwner
        - [Ext] removeUpgrade #
           - modifiers: onlyOwner
        - [Ext] updateImplementation #
           - modifiers: onlyOwner
    
     
    

    FactorVaultMultiManager Contract

    Smart Contract Audit - Inheritance

    Smart Contract Audit - Graph

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
     
     + [Lib] AddressUpgradeable 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] verifyCallResultFromTarget
        - [Int] verifyCallResult
        - [Prv] _revert
    
     +  Initializable 
        - [Int] _disableInitializers #
        - [Int] _getInitializedVersion
        - [Int] _isInitializing
    
     +  ContextUpgradeable (Initializable)
        - [Int] __Context_init #
           - modifiers: onlyInitializing
        - [Int] __Context_init_unchained #
           - modifiers: onlyInitializing
        - [Int] _msgSender
        - [Int] _msgData
    
     +  OwnableUpgradeable (Initializable, ContextUpgradeable)
        - [Int] __Ownable_init #
           - modifiers: onlyInitializing
        - [Int] __Ownable_init_unchained #
           - modifiers: onlyInitializing
        - [Pub] owner
        - [Int] _checkOwner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
        - [Int] _transferOwnership #
    
     +  Proxy 
        - [Int] _delegate #
        - [Int] _implementation
        - [Int] _fallback #
        - [Ext]  ($)
        - [Ext]  ($)
        - [Int] _beforeFallback #
    
     + [Int] IBeacon 
        - [Ext] implementation
    
     + [Int] IERC1822Proxiable 
        - [Ext] proxiableUUID
    
     + [Lib] Address 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] functionDelegateCall #
        - [Int] functionDelegateCall #
        - [Int] verifyCallResultFromTarget
        - [Int] verifyCallResult
        - [Prv] _revert
    
     + [Lib] StorageSlot 
        - [Int] getAddressSlot
        - [Int] getBooleanSlot
        - [Int] getBytes32Slot
        - [Int] getUint256Slot
    
     +  ERC1967Upgrade 
        - [Int] _getImplementation
        - [Prv] _setImplementation #
        - [Int] _upgradeTo #
        - [Int] _upgradeToAndCall #
        - [Int] _upgradeToAndCallUUPS #
        - [Int] _getAdmin
        - [Prv] _setAdmin #
        - [Int] _changeAdmin #
        - [Int] _getBeacon
        - [Prv] _setBeacon #
        - [Int] _upgradeBeaconToAndCall #
    
     +  ERC1967Proxy (Proxy, ERC1967Upgrade)
        - [Pub]  ($)
        - [Int] _implementation
    
     +  TransparentUpgradeableProxy (ERC1967Proxy)
        - [Pub]  ($)
           - modifiers: ERC1967Proxy
        - [Ext] admin #
           - modifiers: ifAdmin
        - [Ext] implementation #
           - modifiers: ifAdmin
        - [Ext] changeAdmin #
           - modifiers: ifAdmin
        - [Ext] upgradeTo #
           - modifiers: ifAdmin
        - [Ext] upgradeToAndCall ($)
           - modifiers: ifAdmin
        - [Int] _admin
        - [Int] _beforeFallback #
    
     +  Context 
        - [Int] _msgSender
        - [Int] _msgData
    
     +  Ownable (Context)
        - [Pub]  #
        - [Pub] owner
        - [Int] _checkOwner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
        - [Int] _transferOwnership #
    
     +  ProxyAdmin (Ownable)
        - [Pub] getProxyImplementation
        - [Pub] getProxyAdmin
        - [Pub] changeProxyAdmin #
           - modifiers: onlyOwner
        - [Pub] upgrade #
           - modifiers: onlyOwner
        - [Pub] upgradeAndCall ($)
           - modifiers: onlyOwner
    
     + [Int] IStrategyMulti 
        - [Ext] denominator
        - [Ext] underlyingAssets
        - [Ext] underlyingAssetsCount
        - [Ext] underlyingAssetsBalance
        - [Ext] vault
        - [Ext] deposit #
        - [Ext] withdraw #
        - [Ext] harvest #
        - [Ext] exit #
        - [Ext] panic #
        - [Ext] pause #
        - [Ext] unpause #
        - [Ext] paused
    
     + [Int] IERC20 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     + [Int] IERC20Permit 
        - [Ext] permit #
        - [Ext] nonces
        - [Ext] DOMAIN_SEPARATOR
    
     + [Lib] SafeERC20 
        - [Int] safeTransfer #
        - [Int] safeTransferFrom #
        - [Int] safeApprove #
        - [Int] safeIncreaseAllowance #
        - [Int] safeDecreaseAllowance #
        - [Int] safePermit #
        - [Prv] _callOptionalReturn #
    
     + [Int] IFactorVaultMulti 
        - [Ext] initialize #
        - [Ext] denominator
        - [Ext] deposit #
    
     + [Int] IOwnable 
        - [Ext] transferOwnership #
    
     +  FactorVaultMultiManager (OwnableUpgradeable)
        - [Pub]  #
        - [Pub] initialize #
           - modifiers: initializer
        - [Ext] deployVault #
           - modifiers: onlyOwner
        - [Ext] setUpgradeTimelock #
           - modifiers: onlyOwner
        - [Pub] getNextVaultAddress
        - [Ext] isRegisteredUpgrade
        - [Ext] registerUpgrade #
           - modifiers: onlyOwner
        - [Ext] removeUpgrade #
           - modifiers: onlyOwner
        - [Ext] updateImplementation #
           - modifiers: onlyOwner
    
     
    

    About SourceHat

    SourceHat has quickly grown to have one of the most experienced and well-equipped smart contract auditing teams in the industry. Our team has conducted 1800+ solidity smart contract audits covering all major project types and protocols, securing a total of over $50 billion U.S. dollars in on-chain value!
    Our firm is well-reputed in the community and is trusted as a top smart contract auditing company for the review of solidity code, no matter how complex. Our team of experienced solidity smart contract auditors performs audits for tokens, NFTs, crowdsales, marketplaces, gambling games, financial protocols, and more!

    Contact us today to get a free quote for a smart contract audit of your project!

    What is a SourceHat Audit?

    Typically, a smart contract audit is a comprehensive review process designed to discover logical errors, security vulnerabilities, and optimization opportunities within code. A SourceHat Audit takes this a step further by verifying economic logic to ensure the stability of smart contracts and highlighting privileged functionality to create a report that is easy to understand for developers and community members alike.

    How Do I Interpret the Findings?

    Each of our Findings will be labeled with a Severity level. We always recommend the team resolve High, Medium, and Low severity findings prior to deploying the code to the mainnet. Here is a breakdown on what each Severity level means for the project:

    • High severity indicates that the issue puts a large number of users' funds at risk and has a high probability of exploitation, or the smart contract contains serious logical issues which can prevent the code from operating as intended.
    • Medium severity issues are those which place at least some users' funds at risk and has a medium to high probability of exploitation.
    • Low severity issues have a relatively minor risk association; these issues have a low probability of occurring or may have a minimal impact.
    • Informational issues pose no immediate risk, but inform the project team of opportunities for gas optimizations and following smart contract security best practices.