_onWithdraw
returns scaledCollateral
which is already scaled, while _withdraw
scales it againThe amount returned by ICDPVault#withdraw()
is scaled at _onWithdraw()
implementations. Then it gets scaled again at PositionAction.sol#L627-628.
function _withdraw(
address vault,
address position,
CollateralParams calldata collateralParams
) internal returns (uint256) {
uint256 collateral = _onWithdraw(vault, position, collateralParams.targetToken, collateralParams.amount, collateralParams.minAmountOut);
uint256 scaledCollateral = wmul(collateral, ICDPVault(vault).tokenScale());
// perform swap from collateral to arbitrary token
if (collateralParams.auxSwap.assetIn != address(0)) {
SwapParams memory auxSwap = collateralParams.auxSwap;
if (auxSwap.swapType == SwapType.EXACT_IN) {
auxSwap.amount = scaledCollateral;
}
_delegateCall(
address(swapAction),
abi.encodeWithSelector(swapAction.swap.selector, auxSwap)
);
} else {
// otherwise just send the collateral to `collateralizer`
IERC20(collateralParams.targetToken).safeTransfer(collateralParams.collateralizer, scaledCollateral);
}
return scaledCollateral;
}
/// @notice Hook to withdraw collateral from CDPVault, handles any CDP specific actions
/// @param vault The CDP Vault
/// @param position The CDP Vault position
/// @param dst Token the caller expects to receive
/// @param amount The amount of collateral to deposit [wad]
/// @param minAmountOut The minimum amount out for the aux swap
/// @return Amount of collateral (or dst) withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 minAmountOut
) internal virtual returns (uint256);
@@ 52,55 @@
/// @notice Withdraw collateral from the vault
/// @param vault Address of the vault
/// @param position Address of the position
/// @param amount Amount of collateral to withdraw [wad]
/// @return Amount of collateral withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address /*dst*/,
uint256 amount,
uint256 /*minAmountOut*/
) internal override returns (uint256) {
// Convert from wad to tokenScale using wdiv
uint256 withdrawAmount = ICDPVault(vault).withdraw(position, amount);
uint256 scaledAmount = wmul(withdrawAmount, ICDPVault(vault).tokenScale());
return scaledAmount;
}
function _withdraw(
address vault,
address position,
CollateralParams calldata collateralParams
) internal returns (uint256) {
uint256 collateral = _onWithdraw(vault, position, collateralParams.targetToken, collateralParams.amount, collateralParams.minAmountOut);
uint256 scaledCollateral = wmul(collateral, ICDPVault(vault).tokenScale());
// perform swap from collateral to arbitrary token
if (collateralParams.auxSwap.assetIn != address(0)) {
SwapParams memory auxSwap = collateralParams.auxSwap;
if (auxSwap.swapType == SwapType.EXACT_IN) {
auxSwap.amount = scaledCollateral;
}
_delegateCall(
address(swapAction),
abi.encodeWithSelector(swapAction.swap.selector, auxSwap)
);
} else {
// otherwise just send the collateral to `collateralizer`
IERC20(collateralParams.targetToken).safeTransfer(collateralParams.collateralizer, scaledCollateral);
}
return scaledCollateral;
}
/// @notice Hook to withdraw collateral from CDPVault, handles any CDP specific actions
/// @param vault The CDP Vault
/// @param position The CDP Vault position
/// @param dst Token the caller expects to receive
/// @param amount The amount of collateral to deposit [wad]
/// @param minAmountOut The minimum amount out for the aux swap
/// @return Amount of collateral (or dst) withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 minAmountOut
) internal virtual returns (uint256);
@@ 52,55 @@
/// @notice Withdraw collateral from the vault
/// @param vault Address of the vault
/// @param position Address of the position
/// @param amount Amount of collateral to withdraw [wad]
/// @return Amount of collateral withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address /*dst*/,
uint256 amount,
uint256 /*minAmountOut*/
) internal override returns (uint256) {
// Convert from wad to tokenScale using wdiv
uint256 withdrawAmount = ICDPVault(vault).withdraw(position, amount);
uint256 scaledAmount = wmul(withdrawAmount, ICDPVault(vault).tokenScale());
return scaledAmount;
}
PositionAction4626.sol#L50 already represents the face value of ERC4626's shares (returned by IERC4626(collateral).deposit(amount, address(this))
), which is then multiplied by
This calculation leads to incorrect amount
(PositionAction4626.sol#L54-55) values when tokenScale
is not equal to 1e18.
/// @notice Deposit collateral into the vault
/// @param vault Address of the vault
/// @param src Token passed in by the caller
/// @param amount Amount of collateral to deposit [CDPVault.tokenScale()]
/// @return Amount of collateral deposited [wad]
function _onDeposit(address vault, address position, address src, uint256 amount) internal override returns (uint256) {
address collateral = address(ICDPVault(vault).token());
// if the src is not the collateralToken, we need to deposit the underlying into the ERC4626 vault
if (src != collateral) {
address underlying = IERC4626(collateral).asset();
IERC20(underlying).forceApprove(collateral, amount);
uint256 depositAmount = IERC4626(collateral).deposit(amount, address(this));
amount = wmul(depositAmount, ICDPVault(vault).tokenScale());
}
IERC20(collateral).forceApprove(vault, amount);
return ICDPVault(vault).deposit(position, amount);
}
/// @notice Deposit collateral into the vault
/// @param vault Address of the vault
/// @param src Token passed in by the caller
/// @param amount Amount of collateral to deposit [CDPVault.tokenScale()]
/// @return Amount of collateral deposited [wad]
function _onDeposit(address vault, address position, address src, uint256 amount) internal override returns (uint256) {
address collateral = address(ICDPVault(vault).token());
// if the src is not the collateralToken, we need to deposit the underlying into the ERC4626 vault
if (src != collateral) {
address underlying = IERC4626(collateral).asset();
IERC20(underlying).forceApprove(collateral, amount);
uint256 depositAmount = IERC4626(collateral).deposit(amount, address(this));
amount = wmul(depositAmount, ICDPVault(vault).tokenScale());
}
IERC20(collateral).forceApprove(vault, amount);
return ICDPVault(vault).deposit(position, amount);
}
PositionAction4626._onWithdraw()
should return the amount of IERC4626(collateral).asset()
tokens when dst == IERC4626(collateral).asset()
.This allows the _onWithdraw()
consumer to process the correct available IERC4626(collateral).asset()
token amount.
Note: In the previous version, L81 was return collateralWithdrawn;
/// @notice Hook to withdraw collateral from CDPVault, handles any CDP specific actions
/// @param vault The CDP Vault
/// @param position The CDP Vault position
/// @param dst Token the caller expects to receive
/// @param amount The amount of collateral to deposit [wad]
/// @param minAmountOut The minimum amount out for the aux swap
/// @return Amount of collateral (or dst) withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 minAmountOut
) internal virtual returns (uint256);
/// @notice Withdraw collateral from the vault
/// @param vault Address of the vault
/// @param position Address of the position
/// @param dst Token the caller expects to receive
/// @param amount Amount of collateral to withdraw [wad]
/// @param /*minAmountOut*/ The minimum amount out for the aux swap
/// @return Amount of collateral withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 /*minAmountOut*/
) internal override returns (uint256) {
uint256 collateralWithdrawn = ICDPVault(vault).withdraw(position, amount);
uint256 scaledAmount = wmul(collateralWithdrawn, ICDPVault(vault).tokenScale());
// if collateral is not the dst token, we need to withdraw the underlying from the ERC4626 vault
address collateral = address(ICDPVault(vault).token());
if (dst != collateral) {
collateralWithdrawn = IERC4626(collateral).redeem(scaledAmount, address(this), address(this));
}
return scaledAmount;
}
/// @notice Withdraws collateral from CDPVault (optionally swaps collateral to an arbitrary token)
/// @param vault The CDP Vault
/// @param collateralParams The collateral parameters
/// @return The amount of collateral withdrawn [token.decimals()]
function _withdraw(
address vault,
address position,
CollateralParams calldata collateralParams
) internal returns (uint256) {
uint256 collateral = _onWithdraw(vault, position, collateralParams.targetToken, collateralParams.amount, collateralParams.minAmountOut);
uint256 scaledCollateral = wmul(collateral, ICDPVault(vault).tokenScale());
// perform swap from collateral to arbitrary token
if (collateralParams.auxSwap.assetIn != address(0)) {
SwapParams memory auxSwap = collateralParams.auxSwap;
if (auxSwap.swapType == SwapType.EXACT_IN) {
auxSwap.amount = scaledCollateral;
}
_delegateCall(
address(swapAction),
abi.encodeWithSelector(swapAction.swap.selector, auxSwap)
);
} else {
// otherwise just send the collateral to `collateralizer`
IERC20(collateralParams.targetToken).safeTransfer(collateralParams.collateralizer, scaledCollateral);
}
return scaledCollateral;
}
Consider changing to:
/// @notice Withdraw collateral from the vault
/// @param vault Address of the vault
/// @param position Address of the position
/// @param dst Token the caller expects to receive
/// @param amount Amount of collateral to withdraw [wad]
/// @param /*minAmountOut*/ The minimum amount out for the aux swap
/// @return Amount of dst token withdrawn [10 ** dst.decimals()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 /*minAmountOut*/
) internal override returns (uint256) {
uint256 collateralWithdrawn = ICDPVault(vault).withdraw(position, amount);
uint256 scaledAmount = wmul(collateralWithdrawn, ICDPVault(vault).tokenScale());
// if collateral is not the dst token, we need to withdraw the underlying from the ERC4626 vault
address collateral = address(ICDPVault(vault).token());
if (dst == collateral) {
return scaledAmount;
} else {
return IERC4626(collateral).redeem(scaledAmount, address(this), address(this));
}
}
/// @notice Hook to withdraw collateral from CDPVault, handles any CDP specific actions
/// @param vault The CDP Vault
/// @param position The CDP Vault position
/// @param dst Token the caller expects to receive
/// @param amount The amount of collateral to deposit [wad]
/// @param minAmountOut The minimum amount out for the aux swap
/// @return Amount of dst token withdrawn [10 ** dst.decimals()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 minAmountOut
) internal virtual returns (uint256);
And update the @return
NatSpec documentation for other _onWithdraw()
implementations.
For consistency and to avoid confusion, it is recommended to rename all instances of "scaled" to follow the convention where scaled*Amount
refers to the normalized amount in [wad]
units, rather than calling the raw token amount (in [token ** token.decimals()]
base) as scaled*Amount
.
/// @notice Hook to withdraw collateral from CDPVault, handles any CDP specific actions
/// @param vault The CDP Vault
/// @param position The CDP Vault position
/// @param dst Token the caller expects to receive
/// @param amount The amount of collateral to deposit [wad]
/// @param minAmountOut The minimum amount out for the aux swap
/// @return Amount of collateral (or dst) withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 minAmountOut
) internal virtual returns (uint256);
/// @notice Withdraw collateral from the vault
/// @param vault Address of the vault
/// @param position Address of the position
/// @param dst Token the caller expects to receive
/// @param amount Amount of collateral to withdraw [wad]
/// @param /*minAmountOut*/ The minimum amount out for the aux swap
/// @return Amount of collateral withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 /*minAmountOut*/
) internal override returns (uint256) {
uint256 collateralWithdrawn = ICDPVault(vault).withdraw(position, amount);
uint256 scaledAmount = wmul(collateralWithdrawn, ICDPVault(vault).tokenScale());
// if collateral is not the dst token, we need to withdraw the underlying from the ERC4626 vault
address collateral = address(ICDPVault(vault).token());
if (dst != collateral) {
collateralWithdrawn = IERC4626(collateral).redeem(scaledAmount, address(this), address(this));
}
return scaledAmount;
}
/// @notice Withdraws collateral from CDPVault (optionally swaps collateral to an arbitrary token)
/// @param vault The CDP Vault
/// @param collateralParams The collateral parameters
/// @return The amount of collateral withdrawn [token.decimals()]
function _withdraw(
address vault,
address position,
CollateralParams calldata collateralParams
) internal returns (uint256) {
uint256 collateral = _onWithdraw(vault, position, collateralParams.targetToken, collateralParams.amount, collateralParams.minAmountOut);
uint256 scaledCollateral = wmul(collateral, ICDPVault(vault).tokenScale());
// perform swap from collateral to arbitrary token
if (collateralParams.auxSwap.assetIn != address(0)) {
SwapParams memory auxSwap = collateralParams.auxSwap;
if (auxSwap.swapType == SwapType.EXACT_IN) {
auxSwap.amount = scaledCollateral;
}
_delegateCall(
address(swapAction),
abi.encodeWithSelector(swapAction.swap.selector, auxSwap)
);
} else {
// otherwise just send the collateral to `collateralizer`
IERC20(collateralParams.targetToken).safeTransfer(collateralParams.collateralizer, scaledCollateral);
}
return scaledCollateral;
}
PositionActionPendle._onWithdraw()
when dst == collateralToken || dst == address(0)
, it unexpectedly returns the amount in [wad]
base instead of the expected [10 ** dst.decimals()]
base.We recommend changing the return value to the amount of dst token withdrawn in [10 ** dst.decimals()]
base.
/// @notice Withdraw collateral from the vault
/// @param vault Address of the vault
/// @param amount Amount of collateral to withdraw [wad]
/// @param minAmountOut The minimum amount out for the aux swap
/// @return Amount of collateral withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 minAmountOut
) internal override returns (uint256) {
uint256 collateralWithdrawn = ICDPVault(vault).withdraw(address(position), amount);
uint256 scaledAmount = wmul(collateralWithdrawn, ICDPVault(vault).tokenScale());
address collateralToken = address(ICDPVault(vault).token());
if (dst != collateralToken && dst != address(0)) {
@@ 70,86 @@
PoolActionParams memory poolActionParams = PoolActionParams({
protocol: Protocol.PENDLE,
minOut: minAmountOut,
recipient: address(this),
args: abi.encode(
collateralToken,
scaledAmount,
dst
)
});
bytes memory exitData = _delegateCall(
address(poolAction),
abi.encodeWithSelector(poolAction.exit.selector, poolActionParams)
);
collateralWithdrawn = abi.decode(exitData, (uint256));
}
return collateralWithdrawn;
}
/// @notice Withdraw collateral from the vault
/// @param vault Address of the vault
/// @param amount Amount of collateral to withdraw [wad]
/// @param minAmountOut The minimum amount out for the aux swap
/// @return Amount of collateral withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address dst,
uint256 amount,
uint256 minAmountOut
) internal override returns (uint256) {
uint256 collateralWithdrawn = ICDPVault(vault).withdraw(address(position), amount);
uint256 scaledAmount = wmul(collateralWithdrawn, ICDPVault(vault).tokenScale());
address collateralToken = address(ICDPVault(vault).token());
if (dst != collateralToken && dst != address(0)) {
@@ 70,86 @@
PoolActionParams memory poolActionParams = PoolActionParams({
protocol: Protocol.PENDLE,
minOut: minAmountOut,
recipient: address(this),
args: abi.encode(
collateralToken,
scaledAmount,
dst
)
});
bytes memory exitData = _delegateCall(
address(poolAction),
abi.encodeWithSelector(poolAction.exit.selector, poolActionParams)
);
collateralWithdrawn = abi.decode(exitData, (uint256));
}
return collateralWithdrawn;
}
PositionAction20._onDeposit()
, PositionActionPendle._onDeposit()
, PositionActionTranchess._onDeposit()
is inconsistent with NatSpec documentation and PositionAction4626._onDeposit()
PositionAction4626._onDeposit()
return value unit: [wad]
PositionAction20._onDeposit()
, PositionActionPendle._onDeposit()
, PositionActionTranchess._onDeposit()
return value unit: [CDPVault.tokenScale()]
/// @notice Deposit collateral into the vault
/// @param vault Address of the vault
/// @param amount Amount of collateral to deposit [CDPVault.tokenScale()]
/// @return Amount of collateral deposited [wad]
function _onDeposit(
address vault,
address position,
address /*src*/,
uint256 amount
) internal override returns (uint256) {
address collateralToken = address(ICDPVault(vault).token());
IERC20(collateralToken).forceApprove(vault, amount);
uint256 depositAmount = ICDPVault(vault).deposit(position, amount);
uint256 scaledAmount = wmul(depositAmount, ICDPVault(vault).tokenScale());
return scaledAmount;
}
/// @notice Deposit collateral into the vault
/// @param vault Address of the vault
/// @param amount Amount of collateral to deposit [CDPVault.tokenScale()]
/// @return Amount of collateral deposited [wad]
function _onDeposit(
address vault,
address position,
address /*src*/,
uint256 amount
) internal override returns (uint256) {
address collateralToken = address(ICDPVault(vault).token());
IERC20(collateralToken).forceApprove(vault, amount);
uint256 depositAmount = ICDPVault(vault).deposit(position, amount);
uint256 scaledAmount = wmul(depositAmount, ICDPVault(vault).tokenScale());
return scaledAmount;
}
/// @notice Deposit collateral into the vault
/// @param vault Address of the vault
/// @param amount Amount of collateral to deposit [CDPVault.tokenScale()]
/// @return Amount of collateral deposited [wad]
function _onDeposit(
address vault,
address position,
address /*src*/,
uint256 amount
) internal override returns (uint256) {
address collateralToken = address(ICDPVault(vault).token());
IERC20(collateralToken).forceApprove(vault, amount);
uint256 depositAmount = ICDPVault(vault).deposit(position, amount);
uint256 scaledAmount = wmul(depositAmount, ICDPVault(vault).tokenScale());
return scaledAmount;
}
/// @notice Deposit collateral into the vault
/// @param vault Address of the vault
/// @param amount Amount of collateral to deposit [CDPVault.tokenScale()]
/// @return Amount of collateral deposited [wad]
function _onDeposit(
address vault,
address position,
address /*src*/,
uint256 amount
) internal override returns (uint256) {
address collateralToken = address(ICDPVault(vault).token());
IERC20(collateralToken).forceApprove(vault, amount);
uint256 depositAmount = ICDPVault(vault).deposit(position, amount);
uint256 scaledAmount = wmul(depositAmount, ICDPVault(vault).tokenScale());
return scaledAmount;
}
/// @notice Deposit collateral into the vault
/// @param vault Address of the vault
/// @param amount Amount of collateral to deposit [CDPVault.tokenScale()]
/// @return Amount of collateral deposited [wad]
function _onDeposit(
address vault,
address position,
address /*src*/,
uint256 amount
) internal override returns (uint256) {
address collateralToken = address(ICDPVault(vault).token());
IERC20(collateralToken).forceApprove(vault, amount);
uint256 depositAmount = ICDPVault(vault).deposit(position, amount);
uint256 scaledAmount = wmul(depositAmount, ICDPVault(vault).tokenScale());
return scaledAmount;
}
/// @notice Deposit collateral into the vault
/// @param vault Address of the vault
/// @param amount Amount of collateral to deposit [CDPVault.tokenScale()]
/// @return Amount of collateral deposited [wad]
function _onDeposit(
address vault,
address position,
address /*src*/,
uint256 amount
) internal override returns (uint256) {
address collateralToken = address(ICDPVault(vault).token());
IERC20(collateralToken).forceApprove(vault, amount);
uint256 depositAmount = ICDPVault(vault).deposit(position, amount);
uint256 scaledAmount = wmul(depositAmount, ICDPVault(vault).tokenScale());
return scaledAmount;
}
wmul
instead of wdiv
/// @notice Withdraw collateral from the vault
/// @param vault Address of the vault
/// @param position Address of the position
/// @param amount Amount of collateral to withdraw [wad]
/// @return Amount of collateral withdrawn [CDPVault.tokenScale()]
function _onWithdraw(
address vault,
address position,
address /*dst*/,
uint256 amount,
uint256 /*minAmountOut*/
) internal override returns (uint256) {
// Convert from wad to tokenScale using wdiv
uint256 withdrawAmount = ICDPVault(vault).withdraw(position, amount);
uint256 scaledAmount = wmul(withdrawAmount, ICDPVault(vault).tokenScale());
return scaledAmount;
}
PositionAction4626._onDecreaseLever()
@return /// @notice Hook to decrease lever by withdrawing collateral from the CDPVault and the ERC4626 Vault
/// @param leverParams LeverParams struct
/// @param subCollateral Amount of collateral to withdraw in CDPVault decimals [wad]
/// @return tokenOut Amount of underlying token withdrawn from the ERC4626 vault [CDPVault.tokenScale()]
function _onDecreaseLever(
LeverParams memory leverParams,
uint256 subCollateral
) internal override returns (uint256 tokenOut) {
// withdraw collateral from vault
uint256 withdrawnCollateral = ICDPVault(leverParams.vault).withdraw(leverParams.position, subCollateral);
withdrawnCollateral = wmul(withdrawnCollateral, ICDPVault(leverParams.vault).tokenScale());
// withdraw collateral from the ERC4626 vault and return underlying assets
tokenOut = IERC4626(leverParams.collateralToken).redeem(withdrawnCollateral, address(this), address(this));
if (leverParams.auxAction.args.length != 0) {
_delegateCall(
address(poolAction),
abi.encodeWithSelector(poolAction.exit.selector, leverParams.auxAction)
);
tokenOut = IERC20(IERC4626(leverParams.collateralToken).asset()).balanceOf(address(this));
}
}
Consider changing to:
/// @notice Hook to decrease lever by withdrawing collateral from the CDPVault and the ERC4626 Vault
/// @param leverParams LeverParams struct
/// @param subCollateral Amount of collateral to withdraw in CDPVault decimals [wad]
/// @return tokenOut Amount of underlying token withdrawn from the ERC4626 vault [10 ** IERC4626(collateralToken).asset().decimals()]
function _onDecreaseLever(
LeverParams memory leverParams,
uint256 subCollateral
) internal override returns (uint256 tokenOut) {
// withdraw collateral from vault
uint256 withdrawnCollateral = ICDPVault(leverParams.vault).withdraw(leverParams.position, subCollateral);
withdrawnCollateral = wmul(withdrawnCollateral, ICDPVault(leverParams.vault).tokenScale());
// withdraw collateral from the ERC4626 vault and return underlying assets
tokenOut = IERC4626(leverParams.collateralToken).redeem(withdrawnCollateral, address(this), address(this));
if (leverParams.auxAction.args.length != 0) {
_delegateCall(
address(poolAction),
abi.encodeWithSelector(poolAction.exit.selector, leverParams.auxAction)
);
tokenOut = IERC20(IERC4626(leverParams.collateralToken).asset()).balanceOf(address(this));
}
}
/// @notice Hook to decrease lever by withdrawing collateral from the CDPVault and the ERC4626 Vault
/// @param leverParams LeverParams struct
/// @param subCollateral Amount of collateral to withdraw in CDPVault decimals [wad]
/// @return tokenOut Amount of underlying token withdrawn from the ERC4626 vault [CDPVault.tokenScale()]
function _onDecreaseLever(
LeverParams memory leverParams,
uint256 subCollateral
) internal override returns (uint256 tokenOut) {
// withdraw collateral from vault
uint256 withdrawnCollateral = ICDPVault(leverParams.vault).withdraw(leverParams.position, subCollateral);
withdrawnCollateral = wmul(withdrawnCollateral, ICDPVault(leverParams.vault).tokenScale());
// withdraw collateral from the ERC4626 vault and return underlying assets
tokenOut = IERC4626(leverParams.collateralToken).redeem(withdrawnCollateral, address(this), address(this));
if (leverParams.auxAction.args.length != 0) {
_delegateCall(
address(poolAction),
abi.encodeWithSelector(poolAction.exit.selector, leverParams.auxAction)
);
tokenOut = IERC20(IERC4626(leverParams.collateralToken).asset()).balanceOf(address(this));
}
}