Assessment reports>Beefy Wrapper>Threat Model>_withdraw

Function: _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares)

This internal function overrides the default ERC-4626 implementation and is invoked by the public, inherited functions withdraw and redeem.

Inputs

  • caller

    • Control: None.

    • Constraints: None.

    • Impact: Caller performing the withdrawal.

  • receiver

    • Control: Arbitrary.

    • Constraints: None.

    • Impact: Receiver of the withdrawal.

  • owner

    • Control: None.

    • Constraints: If not the sender, caller must have allowance.

    • Impact: Owner of the shares to withdraw.

  • assets

    • Control: Arbitrary (when coming from withdraw).

    • Constraints: None (directly, owner share balance must be sufficient).

    • Impact: Amount of assets to unwrap.

  • shares

    • Control: Arbitrary (when coming from redeem).

    • Constraints: None (directly, owner share balance must be sufficient).

    • Impact: Amount of shares to unwrap.

Branches and code coverage (including function calls)

Intended branches

  • Spends allowance if caller is not owner.

  • Burns owner shares, withdraws shares from the vault, transfers min(assets, balance) to the receiver.

Negative behavior

  • Reverts if the caller does not have sufficient allowance.

  • Reverts if owner balance is insufficient.

  • Reverts if vault withdrawal fails.

  • Reverts if asset transfer fails (should be impossible).

Function call analysis

  • rootFunction -> _spendAllowance(owner, caller, shares)

    • What is controllable? owner and shares.

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

    • What happens if it reverts, reenters, or does other unusual control flow? Reverts bubble up; reentrancy is not possible.

  • rootFunction -> _burn(owner, shares)

    • What is controllable? owner and shares.

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

    • What happens if it reverts, reenters, or does other unusual control flow? Reverts bubble up; reentrancy is not possible.

  • rootFunction -> IVault(vault).withdraw(shares)

    • What is controllable? shares.

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

    • What happens if it reverts, reenters, or does other unusual control flow? Reverts bubble up; reentrancy is not possible (vault is considered trusted).

  • rootFunction -> IERC20Upgradeable(asset()).balanceOf(address(this))

    • What is controllable? Nothing.

    • If return value controllable, how is it used and how can it go wrong? Used to limit the maximum withdrawal.

    • What happens if it reverts, reenters, or does other unusual control flow? Reverts bubble up; reentrancy is not possible (asset is considered trusted).

  • rootFunction -> IERC20Upgradeable(asset()).safeTransfer(receiver, assets)

    • What is controllable? receiver and assets.

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

    • What happens if it reverts, reenters, or does other unusual control flow? Reverts bubble up; reentrancy is not possible (asset is considered trusted).

Zellic © 2024Back to top ↑