Deploy and Finalize Flash Loan Arbitrage Smart Contract on BSC Mainnet

Job ID: 39304021

Budget: $30 – $250 SGD

We are hiring an experienced Solidity/DeFi smart contract developer to review, correct, deploy, and verify a custom arbitrage smart contract on Binance Smart Chain (BSC Mainnet).
The contract uses an AAVE flash loan to perform multi-step arbitrage across PancakeSwap V3, THENA Fusion, and OpenOcean.



Key Objectives:
1. Check the provided code for errors, incomplete logic (e.g., path not declared), and token approval issues.
2. Fix and finalize the logic to ensure the arbitrage flow works unconditionally (swaps should not revert if unprofitable).
3. Deploy and verify the smart contract on BSC Mainnet using correct router addresses.
4. Ensure functionality, test execution using a flash loan of 500 USDT.
5. If current logic fails, adapt the contract to execute as intended.



Smart Contract Code (To Review and Finalize):

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@aave/core-v3/contracts/interfaces/IPool.sol";
import "@aave/core-v3/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

interface IDEXRouter {
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);

function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
}

contract ArbitrageBot is IFlashLoanSimpleReceiver, Ownable {
address public immutable AAVE_POOL;
address public immutable USDT;
address public immutable WBNB;
address public immutable PANCAKE_ROUTER;
address public immutable THENA_ROUTER;
address public immutable OPENOCEAN_ROUTER;

uint constant USDT_DECIMALS = 1e6;
uint public slippageTolerance = 50; // 0.5%

constructor(address _aavePool, address _usdt, address _wbnb) {
AAVE_POOL = _aavePool;
USDT = _usdt;
WBNB = _wbnb;

PANCAKE_ROUTER = 0x3AfD8fDe64e9E246f9AC7b97a19c9d43F4a31Ff4;
THENA_ROUTER = 0x9e7d9d4c2EFe7111e6C9A8D0AeE03B26f1A0b35D;
OPENOCEAN_ROUTER = 0x17C83E2B96ACfb5190d63F5E46d93c107eC0b514;

IERC20(_usdt).approve(PANCAKE_ROUTER, type(uint).max);
IERC20(_wbnb).approve(THENA_ROUTER, type(uint).max);
IERC20(_usdt).approve(THENA_ROUTER, type(uint).max);
IERC20(_wbnb).approve(OPENOCEAN_ROUTER, type(uint).max);
IERC20(_usdt).approve(AAVE_POOL, type(uint).max);
}

function executeArbitrage() external onlyOwner {
uint amount = 500 * USDT_DECIMALS;
IPool(AAVE_POOL).flashLoanSimple(
address(this),
USDT,
amount,
bytes(""),
0
);
}

function executeOperation(
address asset,
uint256 amount,
uint256 premium,
address initiator,
bytes calldata params
) external override returns (bool) {
require(msg.sender == AAVE_POOL, "Caller not AAVE");

_swapUSDTtoWBNB_Pancake(amount);
uint wbnbBalance = IERC20(WBNB).balanceOf(address(this));

_swapWBNBtoUSDT_THENA(wbnbBalance);
uint usdtBalance = IERC20(USDT).balanceOf(address(this));

_swapUSDTtoWBNB_THENA(usdtBalance);
wbnbBalance = IERC20(WBNB).balanceOf(address(this));

_swapWBNBtoUSDT_OpenOcean(wbnbBalance);

uint totalOwed = amount + premium;
uint finalUSDTBalance = IERC20(USDT).balanceOf(address(this));
IERC20(USDT).transfer(AAVE_POOL, finalUSDTBalance >= totalOwed ? totalOwed : finalUSDTBalance);

return true;
}

function _getMinAmountOut(address router, uint amountIn, address[] memory path) internal view returns (uint) {
uint[] memory amounts = IDEXRouter(router).getAmountsOut(amountIn, path);
return amounts[1] * (10000 - slippageTolerance) / 10000;
}

function _swapUSDTtoWBNB_Pancake(uint amountIn) internal {
address ;
path[0] = USDT;
path[1] = WBNB;
uint minOut = _getMinAmountOut(PANCAKE_ROUTER, amountIn, path);
IDEXRouter(PANCAKE_ROUTER).swapExactTokensForTokens(amountIn, minOut, path, address(this), block.timestamp);
}

function _swapWBNBtoUSDT_THENA(uint amountIn) internal {
address ;
path[0] = WBNB;
path[1] = USDT;
uint minOut = _getMinAmountOut(THENA_ROUTER, amountIn, path);
IDEXRouter(THENA_ROUTER).swapExactTokensForTokens(amountIn, minOut, path, address(this), block.timestamp);
}

function _swapUSDTtoWBNB_THENA(uint amountIn) internal {
address ;
path[0] = USDT;
path[1] = WBNB;
uint minOut = _getMinAmountOut(THENA_ROUTER, amountIn, path);
IDEXRouter(THENA_ROUTER).swapExactTokensForTokens(amountIn, minOut, path, address(this), block.timestamp);
}

function _swapWBNBtoUSDT_OpenOcean(uint amountIn) internal {
address ;
path[0] = WBNB;
path[1] = USDT;
uint minOut = _getMinAmountOut(OPENOCEAN_ROUTER, amountIn, path);
IDEXRouter(OPENOCEAN_ROUTER).swapExactTokensForTokens(amountIn, minOut, path, address(this), block.timestamp);
}

function withdraw(address token) external onlyOwner {
uint balance = IERC20(token).balanceOf(address(this));
IERC20(token).transfer(msg.sender, balance);
}

function updateSlippageTolerance(uint newToleranceBps) external onlyOwner {
require(newToleranceBps <= 1000, "Max 10%");
slippageTolerance = newToleranceBps;
}

receive() external payable {}
}





Deliverables:
• Final and corrected smart contract (if issues found)
• Verified deployment on BSC Mainnet
• Instructions or simple script to execute executeArbitrage()
• Confirmation of working trade via flash loan with no revert condition even if no profit
• Source code and deployment address



Requirements:
• Solidity and DeFi integration experience
• Experience with AAVE, PancakeSwap, OpenOcean, THENA
• Familiarity with BSC deployment
• Strong debugging and gas optimization skills