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
amountControl: Fully controllable by the caller (
smartVaultManager).Constraints: Amount is not zero and is within the deposit cap.
Impact: Amount of token.
depositorControl: Fully controllable by the caller (
smartVaultManager).Constraints: Should be whitelisted when whitelist mode is enabled.
Impact: Address of the depositor.
receiverControl: Fully controllable by the caller (
smartVaultManager).Constraints: None.
Impact: Address of the share receiver.
Branches and code coverage
Intended branches
Invoke the
_beforeDepositfunction.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
_depositERC20function.Call the
transferCallbackfunction ofsmartVaultManagerto get the underlying asset amount.Update the total deposited underlying asset amount.
Update the shares for the receiver.
Emit the
Depositevent.Invoke the
_manageDebtAndStakefunction.Calculate the underlying token value using the manager's
fetchPricefunction.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?
depositorandamount.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?
stakingVaultis set bysmartVaultManagerandamountbut 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?
stakingVaultset bysmartVaultManagerandamountbut 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.