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
callerControl: None.
Constraints: None.
Impact: Caller performing the withdrawal.
receiverControl: Arbitrary.
Constraints: None.
Impact: Receiver of the withdrawal.
ownerControl: None.
Constraints: If not the sender,
callermust have allowance.Impact: Owner of the shares to withdraw.
assetsControl: Arbitrary (when coming from
withdraw).Constraints: None (directly, owner share balance must be sufficient).
Impact: Amount of assets to unwrap.
sharesControl: 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?
ownerandshares.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?
ownerandshares.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 (
vaultis 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 (
assetis considered trusted).
rootFunction -> IERC20Upgradeable(asset()).safeTransfer(receiver, assets)What is controllable?
receiverandassets.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 (
assetis considered trusted).