Assessment reports>Smart Vault>Threat Model>depositERC20

Function: depositERC20(uint256 amount, address depositor, address receiver)

This function is used to deposit ERC-20 tokens to the smart vault. It is expected to be called from the smart vault manager.

Inputs

  • amount

    • Control: Fully controllable by the caller (smartVaultManager).

    • Constraints: Amount is not zero and is within the deposit cap.

    • Impact: Amount of token.

  • depositor

    • Control: Fully controllable by the caller (smartVaultManager).

    • Constraints: Should be whitelisted when whitelist mode is enabled.

    • Impact: Address of the depositor.

  • receiver

    • Control: Fully controllable by the caller (smartVaultManager).

    • Constraints: None.

    • Impact: Address of the share receiver.

Branches and code coverage

Intended branches

  • Invoke the _beforeDeposit function.

  • Check if the current timestamp is within the deposit time range.

  • Check if the depositor is whitelisted when whitelist mode is enabled.

  • Check if the amount is within the deposit cap.

  • Check if the amount is within the deposit cap per user.

  • Update the reward for the receiver.

  • Invoke the _depositERC20 function.

  • Call the transferCallback function of smartVaultManager to get the underlying asset amount.

  • Update the total deposited underlying asset amount.

  • Update the shares for the receiver.

  • Emit the Deposit event.

  • Invoke the _manageDebtAndStake function.

  • Calculate the underlying token value using the manager's fetchPrice function.

  • Calculate the target staking amount using the staking factor.

    • If the target is greater than the minted, mint the debt token and adjust the staking amount.

    • If the target is less than the minted, burn the debt token and adjust the staking amount.

Negative behavior

  • Revert if the caller is not the manager.

  • Revert if the contract is paused.

  • Revert if the amount is zero.

  • Revert if the depositor is not whitelisted when whitelist mode is enabled.

  • Revert if the amount is within the deposit cap.

  • Revert if the amount is within the deposit cap per user.

  • Revert if minting/burning debt token fails.

Function call analysis

  • this._depositERC20(amount, depositor, receiver) -> smartVaultManager.transferCallback(underlyingAsset, depositor, amount)

    • What is controllable? depositor and amount.

    • If the return value is controllable, how is it used and how can it go wrong? The return value is not used.

    • What happens if it reverts, reenters or does other unusual control flow? A revert indicates the transfer failed.

  • this._manageDebtAndStake() -> this._calculateUnderlyingTokenValue() -> this._getAssetPrice() -> this.smartVaultManager.fetchPrice(this.underlyingAsset)

    • What is controllable? Nothing.

    • If the return value is controllable, how is it used and how can it go wrong? If the price feed fails to return the correct current market price, it would be critical to the vault's collateral calculation.

    • What happens if it reverts, reenters or does other unusual control flow? A revert indicates a failure in the oracle system, which prevents the vault from calculating the collateral asset value and thus causes it to malfunction.

  • this._manageDebtAndStake() -> this._mintDebtToken(mintAmount) -> this.smartVaultManager.vaultMintDebtTokenCallback(amount)

    • What is controllable? amount.

    • If the return value is controllable, how is it used and how can it go wrong? The return value is not used.

    • What happens if it reverts, reenters or does other unusual control flow? A revert indicates the debt-token minting failed.

  • this._manageDebtAndStake() -> this._mintDebtToken(mintAmount) -> this.smartVaultManager.debtToken().balanceOf(address(this))

    • What is controllable? Nothing.

    • If the return value is controllable, how is it used and how can it go wrong? Even without an actual token minting, the callback can still succeed.

    • What happens if it reverts, reenters or does other unusual control flow? A revert indicates the debt token is not a valid ERC-20 token.

  • this._manageDebtAndStake() -> this._burnDebtToken(mintAmount) -> this.smartVaultManager.vaultBurnDebtTokenCallback(amount)

    • What is controllable? amount.

    • If the return value is controllable, how is it used and how can it go wrong? The return value is not used.

    • What happens if it reverts, reenters or does other unusual control flow? A revert indicates the debt-token burning failed.

  • this._manageDebtAndStake() -> this._burnDebtToken(mintAmount) -> this.smartVaultManager.debtToken().balanceOf(address(this))

    • What is controllable? Nothing.

    • If the return value is controllable, how is it used and how can it go wrong? Even without an actual token burning, the callback can still succeed.

    • What happens if it reverts, reenters or does other unusual control flow? A revert indicates the debt token is not a valid ERC-20 token.

  • this._manageDebtAndStake() -> this._adjustStaking(target) -> this._stakeDebtToken(stakeAmount) -> IStakingVault(stakingVault).deposit(amount, address(this))

    • What is controllable? stakingVault is set by smartVaultManager and amount but calculated by staking factor and the price of underlying asset.

    • If the return value is controllable, how is it used and how can it go wrong? The return value is not used.

    • What happens if it reverts, reenters or does other unusual control flow? A revert indicates the staking failed.

  • this._manageDebtAndStake() -> this._adjustStaking(target) -> this._stakeDebtToken(stakeAmount) -> IStakingVault(smartVaultManager.stakingVault().withdraw(amount, address(this), address(this))

    • What is controllable? stakingVault set by smartVaultManager and amount but calculated by staking factor and the price of underlying asset.

    • If the return value is controllable, how is it used and how can it go wrong? The return value is not used.

    • What happens if it reverts, reenters or does other unusual control flow? A revert indicates the unstaking failed.

Zellic © 2025Back to top ↑