buyCollateral() does not work properly
The `BBLeverage.buyCollateral()` function does not work as expected.\\nThe implementation of `BBLeverage.buyCollateral()` is as follows:\\n```\\n    function buyCollateral(address from, uint256 borrowAmount, uint256 supplyAmount, bytes calldata data)\\n        external\\n        optionNotPaused(PauseType.LeverageBuy)\\n        solvent(from, false)\\n        notSelf(from)\\n        returns (uint256 amountOut)\\n    {\\n        if (address(leverageExecutor) == address(0)) {\\n            revert LeverageExecutorNotValid();\\n        }\\n\\n        // Stack too deep fix\\n        _BuyCollateralCalldata memory calldata_;\\n        _BuyCollateralMemoryData memory memoryData;\\n        {\\n            calldata_.from = from;\\n            calldata_.borrowAmount = borrowAmount;\\n            calldata_.supplyAmount = supplyAmount;\\n            calldata_.data = data;\\n        }\\n\\n        {\\n            uint256 supplyShare = yieldBox.toShare(assetId, calldata_.supplyAmount, true);\\n            if (supplyShare > 0) {\\n                (memoryData.supplyShareToAmount,) =\\n                    yieldBox.withdraw(assetId, calldata_.from, address(leverageExecutor), 0, supplyShare);\\n            }\\n        }\\n\\n        {\\n            (, uint256 borrowShare) = _borrow(\\n                calldata_.from,\\n                address(this),\\n                calldata_.borrowAmount,\\n                _computeVariableOpeningFee(calldata_.borrowAmount)\\n            );\\n            (memoryData.borrowShareToAmount,) =\\n                yieldBox.withdraw(assetId, address(this), address(leverageExecutor), 0, borrowShare);\\n        }\\n        {\\n            amountOut = leverageExecutor.getCollateral(\\n                collateralId,\\n                address(asset),\\n                address(collateral),\\n                memoryData.supplyShareToAmount + memoryData.borrowShareToAmount,\\n              calldata_.from,\\n                calldata_.data\\n            );\\n        }\\n        uint256 collateralShare = yieldBox.toShare(collateralId, amountOut, false);\\n      address(asset).safeApprove(address(yieldBox), type(uint256).max);\\n      yieldBox.depositAsset(collateralId, address(this), address(this), 0, collateralShare); // TODO Check for rounding attack?\\n      address(asset).safeApprove(address(yieldBox), 0);\\n\\n        if (collateralShare == 0) revert CollateralShareNotValid();\\n        _allowedBorrow(calldata_.from, collateralShare);\\n        _addCollateral(calldata_.from, calldata_.from, false, 0, collateralShare);\\n    }\\n```\\n\\nThe code above has several issues:\\n`leverageExecutor.getCollateral()` receiver should be `address(this)`. ---> for 2th step deposit to YB\\n`address(asset).safeApprove()` should use `address(collateral).safeApprove()`.\\n`yieldBox.depositAsset()` receiver should be `calldata_.from`. ----> for next execute addCollateral(calldata.from)\\nNote: SGLLeverage.sol have same issue
```\\n    function buyCollateral(address from, uint256 borrowAmount, uint256 supplyAmount, bytes calldata data)\\n        external\\n        optionNotPaused(PauseType.LeverageBuy)\\n        solvent(from, false)\\n        notSelf(from)\\n        returns (uint256 amountOut)\\n    {\\n// rest of code.\\n\\n        {\\n            (, uint256 borrowShare) = _borrow(\\n                calldata_.from,\\n                address(this),\\n                calldata_.borrowAmount,\\n                _computeVariableOpeningFee(calldata_.borrowAmount)\\n            );\\n            (memoryData.borrowShareToAmount,) =\\n                yieldBox.withdraw(assetId, address(this), address(leverageExecutor), 0, borrowShare);\\n        }\\n        {\\n            amountOut = leverageExecutor.getCollateral(\\n                collateralId,\\n                address(asset),\\n                address(collateral),\\n                memoryData.supplyShareToAmount // Add the line below\\n memoryData.borrowShareToAmount,\\n// Remove the line below\\n               calldata_.from,\\n// Add the line below\\n               address(this),\\n                calldata_.data\\n            );\\n        }\\n        uint256 collateralShare = yieldBox.toShare(collateralId, amountOut, false);\\n// Remove the line below\\n       address(asset).safeApprove(address(yieldBox), type(uint256).max);\\n// Remove the line below\\n       yieldBox.depositAsset(collateralId, address(this), address(this), 0, collateralShare); // TODO Check for rounding attack?\\n// Remove the line below\\n       address(asset).safeApprove(address(yieldBox), 0);\\n// Add the line below\\n       address(collateral).safeApprove(address(yieldBox), type(uint256).max);\\n// Add the line below\\n       yieldBox.depositAsset(collateralId, address(this), calldata_.from, 0, collateralShare);\\n// Add the line below\\n       address(collateral).safeApprove(address(yieldBox), 0);\\n\\n        if (collateralShare == 0) revert CollateralShareNotValid();\\n        _allowedBorrow(calldata_.from, collateralShare);\\n        _addCollateral(calldata_.from, calldata_.from, false, 0, collateralShare);\\n    }\\n```\\n
`buyCollateral()` does not work properly.
```\\n    function buyCollateral(address from, uint256 borrowAmount, uint256 supplyAmount, bytes calldata data)\\n        external\\n        optionNotPaused(PauseType.LeverageBuy)\\n        solvent(from, false)\\n        notSelf(from)\\n        returns (uint256 amountOut)\\n    {\\n        if (address(leverageExecutor) == address(0)) {\\n            revert LeverageExecutorNotValid();\\n        }\\n\\n        // Stack too deep fix\\n        _BuyCollateralCalldata memory calldata_;\\n        _BuyCollateralMemoryData memory memoryData;\\n        {\\n            calldata_.from = from;\\n            calldata_.borrowAmount = borrowAmount;\\n            calldata_.supplyAmount = supplyAmount;\\n            calldata_.data = data;\\n        }\\n\\n        {\\n            uint256 supplyShare = yieldBox.toShare(assetId, calldata_.supplyAmount, true);\\n            if (supplyShare > 0) {\\n                (memoryData.supplyShareToAmount,) =\\n                    yieldBox.withdraw(assetId, calldata_.from, address(leverageExecutor), 0, supplyShare);\\n            }\\n        }\\n\\n        {\\n            (, uint256 borrowShare) = _borrow(\\n                calldata_.from,\\n                address(this),\\n                calldata_.borrowAmount,\\n                _computeVariableOpeningFee(calldata_.borrowAmount)\\n            );\\n            (memoryData.borrowShareToAmount,) =\\n                yieldBox.withdraw(assetId, address(this), address(leverageExecutor), 0, borrowShare);\\n        }\\n        {\\n            amountOut = leverageExecutor.getCollateral(\\n                collateralId,\\n                address(asset),\\n                address(collateral),\\n                memoryData.supplyShareToAmount + memoryData.borrowShareToAmount,\\n              calldata_.from,\\n                calldata_.data\\n            );\\n        }\\n        uint256 collateralShare = yieldBox.toShare(collateralId, amountOut, false);\\n      address(asset).safeApprove(address(yieldBox), type(uint256).max);\\n      yieldBox.depositAsset(collateralId, address(this), address(this), 0, collateralShare); // TODO Check for rounding attack?\\n      address(asset).safeApprove(address(yieldBox), 0);\\n\\n        if (collateralShare == 0) revert CollateralShareNotValid();\\n        _allowedBorrow(calldata_.from, collateralShare);\\n        _addCollateral(calldata_.from, calldata_.from, false, 0, collateralShare);\\n    }\\n```\\n