Description:
Decentralized Finance (DeFi) protocol contract providing Mintable, Burnable, Swap, Liquidity, Factory functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"contracts/swapv3agg.sol": {
"content": "
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
pragma abicoder v2;
library SafeCast {
function toUint160(uint256 y) internal pure returns (uint160 z) {
require((z = uint160(y)) == y);
}
function toInt128(int256 y) internal pure returns (int128 z) {
require((z = int128(y)) == y);
}
function toInt256(uint256 y) internal pure returns (int256 z) {
require(y < 2**255);
z = int256(y);
}
}
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
interface IPancakePair {
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event Transfer(address indexed from, address indexed to, uint256 value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint256);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
event Mint(address indexed sender, uint256 amount0, uint256 amount1);
event Burn(
address indexed sender,
uint256 amount0,
uint256 amount1,
address indexed to
);
event Swap(
address indexed sender,
uint256 amount0In,
uint256 amount1In,
uint256 amount0Out,
uint256 amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint256);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
function price0CumulativeLast() external view returns (uint256);
function price1CumulativeLast() external view returns (uint256);
function kLast() external view returns (uint256);
function mint(address to) external returns (uint256 liquidity);
function burn(address to)
external
returns (uint256 amount0, uint256 amount1);
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
function skim(address to) external;
function sync() external;
function initialize(address, address) external;
}
interface IPancakeRouter02 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
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);
}
library TransferHelper {
function safeApprove(
address token,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('approve(address,uint256)')));
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x095ea7b3, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper: APPROVE_FAILED"
);
}
function safeTransfer(
address token,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0xa9059cbb, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper: TRANSFER_FAILED"
);
}
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x23b872dd, from, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper: TRANSFER_FROM_FAILED"
);
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, "TransferHelper: ETH_TRANSFER_FAILED");
}
}
interface ISwapRouterQuick {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 limitSqrtPrice;
}
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
}
interface IERC20 {
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event Transfer(address indexed from, address indexed to, uint256 value);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
}
library SafeMath {
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x, "ds-math-add-overflow");
}
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x, "ds-math-sub-underflow");
}
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
}
}
interface IWETH {
function deposit() external payable;
function transfer(address to, uint256 value) external returns (bool);
function withdraw(uint256) external;
}
interface IUniswapV3Pool {
function token0() external returns (address);
function token1() external returns (address);
function swap(
address recipient,
bool zeroForOne,
int256 amountSpecified,
uint160 sqrtPriceLimitX96,
bytes calldata data
) external returns (int256 amount0, int256 amount1);
}
interface ISwapUniRouter {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
function exactInputSingle(ExactInputSingleParams calldata params)
external
payable
returns (uint256 amountOut);
struct ExactInputParams {
bytes path;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
}
function exactInput(ExactInputParams calldata params)
external
payable
returns (uint256 amountOut);
function factory() external view returns (address);
}
interface ISwapRouter {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
function exactInputSingle(ExactInputSingleParams calldata params)
external
payable
returns (uint256 amountOut);
struct ExactInputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
}
function exactInput(ExactInputParams calldata params)
external
payable
returns (uint256 amountOut);
function factory() external view returns (address);
}
interface IUniswapV3Factory {
function getPool(
address tokenA,
address tokenB,
uint24 fee
) external view returns (address);
function createPool(
address tokenA,
address tokenB,
uint24 fee
) external returns (address pool);
function owner() external view returns (address);
function feeAmountTickSpacing(uint24 fee) external view returns (int24);
function setOwner(address _owner) external;
function enableFeeAmount(uint24 fee, int24 tickSpacing) external;
}
contract dexaggregator is ReentrancyGuard {
using SafeMath for uint256;
using SafeCast for uint256;
address public WETH;
address public owneraddress;
uint256 public Fee;
address public operator;
address Zero = 0x0000000000000000000000000000000000000000;
uint256 hundred = 100000000000000000000;
uint256 impact = 500000000000000000;
address public constant coinAddressApi = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
struct userdetails {
address userAddress;
address sellToken;
address buyToken;
uint256 amount;
uint256 timeStamp;
bool status;
}
struct _stableFee{
uint256 fee;
}
struct ExactInputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
}
struct _Pair {
address[] pairAddress ;
uint256 command;
address token0;
address token1;
uint256 amountIn;
uint256 amountOut;
uint256 to;
uint24[] fee;
uint256 deadline;
uint256 types;
address router;
}
struct call_v2{
uint256[] amounts;
address[] path;
address[] pair;
uint24[] fee;
}
struct _handleFinalTransfer{
address user;
address tk0;
address finalToken;
uint256 amount;
bool coinStatus;
}
struct call_v3{
address[] pairAddress;
address tokenIn;
address tokenOut;
uint24[] poolFee;
uint256 amountIn;
uint256 amountOut;
address router;
uint256 types;
}
modifier onlyContractOwner() {
require(msg.sender == owneraddress, "onlyOwner");
_;
}
modifier controlOrder() {
require(
msg.sender == owneraddress || msg.sender == operator,
"onlyOwner or operator"
);
_;
}
modifier ensure(uint256 deadline) {
require(deadline >= block.timestamp, "AggregateRouter: EXPIRED");
_;
}
receive() external payable {
assert(msg.sender == WETH);
}
constructor(
address _WETH,
address _Owner,
uint256 _fee,
address _operator
) {
WETH = _WETH;
owneraddress = _Owner;
Fee = _fee;
operator = _operator;
}
mapping(address =>mapping(address =>_stableFee)) private stableFee;
mapping(address => mapping(uint256 => userdetails)) private _userdetails;
userdetails[] internal _users;
event EstRecive(uint256 estimateRecive, uint256 estimateFee);
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut,
uint256 fee
) internal pure returns (uint256 amountOut) {
require(amountIn > 0, "PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT");
require(
reserveIn > 0 && reserveOut > 0,
"PancakeLibrary: INSUFFICIENT_LIQUIDITY"
);
uint256 amountInWithFee = amountIn * (10000 - fee);
uint256 numerator = amountInWithFee * reserveOut;
uint256 denominator = reserveIn * 10000 + amountInWithFee;
amountOut = numerator / denominator;
}
function sortTokens(address tokenA, address tokenB)
internal
pure
returns (address token0, address token1)
{
require(tokenA != tokenB, "PancakeLibrary: IDENTICAL_ADDRESSES");
(token0, token1) = tokenA < tokenB
? (tokenA, tokenB)
: (tokenB, tokenA);
require(token0 != address(0), "PancakeLibrary: ZERO_ADDRESS");
}
function getStableFee(address[2] memory _address) public view returns (uint256){
uint256 showFee = stableFee[_address[0]][_address[1]].fee > 0?stableFee[_address[0]][_address[1]].fee:
stableFee[_address[1]][_address[0]].fee > 0?stableFee[_address[1]][_address[0]].fee:Fee;
return showFee;
}
function changeStablefee(address[2] memory _address, uint256 setFee) public controlOrder{
stableFee[_address[0]][_address[1]].fee = setFee;
}
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) internal pure returns (uint256 amountOut) {
require(amountIn > 0, "PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT");
require(
reserveIn > 0 && reserveOut > 0,
"PancakeLibrary: INSUFFICIENT_LIQUIDITY"
);
uint256 amountInWithFee = amountIn.mul(9975);
uint256 numerator = amountInWithFee.mul(reserveOut);
uint256 denominator = reserveIn.mul(10000).add(amountInWithFee);
amountOut = numerator / denominator;
}
function addLimitOrder(
address buy,
address sell,
uint256 amount,
uint256 _timeStamp
) external payable virtual ensure(_timeStamp) {
require(amount > 0, "It's not valied");
userdetails storage details = _userdetails[msg.sender][_timeStamp];
require(details.userAddress == address(0), "Order already exists for this user");
if (sell == WETH) {
require(msg.value >= amount, "insufficient amount");
} else {
TransferHelper.safeTransferFrom(
sell,
msg.sender,
address(this),
amount
);
}
details.userAddress = msg.sender;
details.buyToken = buy;
details.sellToken = sell;
details.amount = amount;
details.timeStamp = _timeStamp;
details.status = true;
_users.push(details);
}
function _cancelledOrder(
address buy,
address sell,
uint256 _timeStamp,
address _userAddress
) external controlOrder {
userdetails storage details = _userdetails[_userAddress][_timeStamp];
require(
details.buyToken == buy && details.sellToken == sell,
"this not correct way"
);
// require(msg.sender == details.userAddress);
if (sell == WETH) {
TransferHelper.safeTransferETH(details.userAddress, details.amount);
} else {
TransferHelper.safeTransfer(
details.sellToken,
details.userAddress,
details.amount
);
}
details.status = false;
delete _userdetails[_userAddress][_timeStamp];
}
event _cancelOrder(address buy , address sell ,address userAddress ,uint256 _timeStamp );
function LimitOrderCancelled(
address buy,
address sell,
uint256 _timeStamp
) external {
userdetails storage details = _userdetails[msg.sender][_timeStamp];
require(
details.buyToken == buy && details.sellToken == sell,
"this not correct way"
);
require(msg.sender == details.userAddress);
if (sell == WETH) {
TransferHelper.safeTransferETH(details.userAddress, details.amount);
} else {
TransferHelper.safeTransfer(
details.sellToken,
details.userAddress,
details.amount
);
}
emit _cancelOrder(details.buyToken, details.sellToken, details.userAddress, _timeStamp);
details.status = false;
delete _userdetails[msg.sender][_timeStamp];
}
function getUser(address userAddress) external view returns (userdetails[] memory) {
uint256 count;
for (uint256 i = 0; i < _users.length; i++) {
if (
_users[i].userAddress == userAddress &&
_users[i].status == true
) {
userdetails storage details = _userdetails[_users[i].userAddress][_users[i].timeStamp];
if (details.userAddress != address(0)) {
count++;
}
}
}
userdetails[] memory userArr = new userdetails[](count);
uint256 index = 0;
for (uint256 i = 0; i < _users.length; i++) {
if (
_users[i].userAddress == userAddress &&
_users[i].status == true
) {
userdetails storage details = _userdetails[_users[i].userAddress][_users[i].timeStamp];
if (details.userAddress != address(0)) {
userArr[index] = _users[i];
index++;
}
}
}
return userArr;
}
function getFeeAndTransferUser(address userAddress,address tokenA,address tokenB,uint256 amountsOut,uint256 status)internal{
uint256 exeFee = stableFee[tokenA][tokenB].fee > 0?stableFee[tokenA][tokenB].fee:
stableFee[tokenB][tokenA].fee > 0?stableFee[tokenB][tokenA].fee:Fee;
uint256 _fee = (exeFee * amountsOut) / hundred;
uint256 amountToSendToUser = amountsOut > _fee? amountsOut - _fee: _fee - amountsOut;
if(tokenB == WETH && status == 1){
TransferHelper.safeTransferETH(
userAddress,
amountToSendToUser
);
if(_fee > 0){
TransferHelper.safeTransferETH(
owneraddress,
_fee
);
}
emit EstRecive(amountToSendToUser, _fee);
}else{
TransferHelper.safeTransfer(
tokenB,
userAddress,
amountToSendToUser
);
if(_fee > 0){
TransferHelper.safeTransfer(
tokenB,
owneraddress,
_fee
);
}
emit EstRecive(amountToSendToUser, _fee);
}
}
function multiSwap(
_Pair[] memory pairs,
uint256 _amountIn,
uint256 minOut,
bool coinStatus
) external payable virtual ensure(pairs[0].deadline) {
address tk0 = pairs[0].token0;
if (tk0 == WETH || tk0 == address(uint160(coinAddressApi))) {
if (msg.value > 0) {
require(msg.value == _amountIn, "ETH amount mismatch");
IWETH(WETH).deposit{value: msg.value}();
} else {
TransferHelper.safeTransferFrom(tk0, msg.sender, address(this), _amountIn);
}
} else {
TransferHelper.safeTransferFrom(tk0, msg.sender, address(this), _amountIn);
}
for (uint256 i = 0; i < pairs.length; i++) {
require(pairs[i].pairAddress[pairs[i].pairAddress.length -1] != address(0) || pairs[i].command == 1, "INVALID_PATH");
uint256 inputAmount = i == 0 ? pairs[i].amountIn :
pairs[i].amountIn < IERC20(pairs[i].token0).balanceOf(address(this))? pairs[i].amountIn:IERC20(pairs[i].token0).balanceOf(address(this));
if (pairs[i].command == 0) {
// V2 Swap
uint256[] memory amounts = new uint256[](2);
address[] memory _tokens = new address[](2);
_tokens[0] = pairs[i].token0;
_tokens[1] = pairs[i].token1;
amounts[0] = inputAmount;
amounts[1] = pairs[i].amountOut;
call_v2 memory call_v2Params = call_v2({
amounts:amounts,
path: _tokens,
pair:pairs[i].pairAddress,
fee:pairs[i].fee});
swapv2(call_v2Params);
} else {
// V3 Swap
require(pairs[i].amountIn > 0, "Invalid swap amount");
swapv3(call_v3({
pairAddress: pairs[i].pairAddress,
tokenIn: pairs[i].token0,
tokenOut: pairs[i].token1,
poolFee: pairs[i].fee,
amountIn: inputAmount,
amountOut: pairs[i].amountOut,
router: pairs[i].router,
types : pairs[i].types
}));
}
if (i == pairs.length - 1) {
_handleFinalTransfer memory transferData = _handleFinalTransfer({
user: msg.sender,
tk0: tk0,
finalToken: pairs[i].token1,
amount: minOut,
coinStatus: coinStatus
});
handleFinalTransfer(transferData);
}
}
}
function handleFinalTransfer(
_handleFinalTransfer memory _datas
) internal {
if (_datas.finalToken == WETH || _datas.finalToken == address(uint160(coinAddressApi))) {
if (_datas.coinStatus) {
uint256 wethBalance = IERC20(WETH).balanceOf(address(this));
require(wethBalance >= _datas.amount, "Insufficient WETH balance");
IWETH(WETH).withdraw(wethBalance);
getFeeAndTransferUser(_datas.user, _datas.tk0, WETH, wethBalance, 1);
} else {
require(IERC20(_datas.finalToken).balanceOf(address(this)) >= _datas.amount, "Insufficient User receive balance");
getFeeAndTransferUser(_datas.user, _datas.tk0, _datas.finalToken, IERC20(_datas.finalToken).balanceOf(address(this)), 0);
}
} else {
require(IERC20(_datas.finalToken).balanceOf(address(this)) >= _datas.amount, "Insufficient User receive balance");
getFeeAndTransferUser(_datas.user, _datas.tk0, _datas.finalToken, IERC20(_datas.finalToken).balanceOf(address(this)), 0);
}
}
function swapv2(
call_v2 memory datas
) internal {
require(datas.amounts.length > 0 && datas.path.length > 0, "Invalid input arrays v2");
require(datas.amounts[0] > 0, "Invalid input amount v2");
if (datas.path[0] == WETH || datas.path[0] == address(uint160(coinAddressApi))) {
require(IERC20(WETH).balanceOf(address(this)) >= datas.amounts[0], "Insufficient WETH balance v2");
IWETH(WETH).transfer(datas.pair[0], datas.amounts[0]);
} else {
require(IERC20(datas.path[0]).balanceOf(address(this)) >= datas.amounts[0], "Insufficient token balance v2");
TransferHelper.safeTransfer(datas.path[0], datas.pair[0], datas.amounts[0]);
}
address middleToken;
uint256 amountOut;
for (uint256 i; i < datas.pair.length; i++)
{
address _token0 = IPancakePair(datas.pair[i]).token0();
address _token1 = IPancakePair(datas.pair[i]).token1();
(uint reserve0, uint reserve1, ) = IPancakePair(datas.pair[i]).getReserves();
uint256 reserveIn = i == 0 ?datas.path[i] == _token0 ? reserve0 : reserve1:middleToken == _token0 ? reserve0 : reserve1;
uint256 reserveOut = i == 0 ?datas.path[i] == _token0 ? reserve1 : reserve0:middleToken == _token0 ? reserve1 : reserve0;
amountOut = getAmountOut(i == 0 ? datas.amounts[0] : amountOut, reserveIn, reserveOut,datas.fee[i]);
address to = i < datas.pair.length - 1 ? datas.pair[i+1] : address(this);
(uint amount0Out, uint amount1Out) = i == 0? datas.path[i] == _token0 ? (uint(0), amountOut)
: (amountOut, uint(0)): middleToken == _token0 ? (uint(0), amountOut)
: (amountOut, uint(0));
middleToken = datas.path[i] == _token0 ? _token1: _token0;
IPancakePair(datas.pair[i]).swap(amount0Out, amount1Out, to, new bytes(0));
}
}
//uinswapV3 swap code
function swapv3(call_v3 memory swapData) internal {
require(swapData.router != address(0), "Zero router address");
require(swapData.tokenIn != address(0), "Zero tokenIn address");
require(swapData.tokenOut != address(0), "Zero tokenOut address");
require(swapData.amountIn > 0, "Zero amountIn");
require(swapData.poolFee.length > 0, "No pool fee provided");
if (swapData.pairAddress.length == 1) {
if (swapData.types == 0) {
_executeSwapV3(swapData);
}else if(swapData.types == 2){
_executeUniswapV3Swap(swapData);
} else {
_executeQuickSwapV3(swapData);
}
} else {
if (swapData.types == 2) {
_executeUniswapMultiHopSwap(swapData);
}else if(swapData.types == 1){
_executeMultiHopQuickSwap(swapData);
}else{
_executeMultiHopSwap(swapData);
}
}
if (swapData.tokenOut == address(uint160(coinAddressApi))) {
require(address(this).balance >= swapData.amountOut, "Insufficient ETH for deposit");
IWETH(WETH).deposit{value: swapData.amountOut}();
}
}
function _executeMultiHopQuickSwap(call_v3 memory swapData) private {
require(swapData.poolFee.length >= 2, "Insufficient pool fees MultiHop");
ISwapRouter router = ISwapRouter(swapData.router);
if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance swapv3");
IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
}
address intermediateToken = swapData.tokenIn == IPancakePair(swapData.pairAddress[0]).token0() ?
IPancakePair(swapData.pairAddress[0]).token1() :
IPancakePair(swapData.pairAddress[0]).token0();
bytes memory path = abi.encodePacked(
swapData.tokenIn,
intermediateToken,
swapData.tokenOut
);
ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
path: path,
recipient: address(this),
deadline: block.timestamp + 300,
amountIn: swapData.amountIn,
amountOutMinimum: 0
});
if (swapData.tokenIn == WETH || swapData.tokenIn == address(uint160(coinAddressApi))) {
require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance v3");
IWETH(WETH).withdraw(swapData.amountIn);
require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance v3");
router.exactInput{value: swapData.amountIn}(params);
} else {
router.exactInput(params);
}
}
function _executeMultiHopSwap(call_v3 memory swapData) private {
require(swapData.poolFee.length >= 2, "Insufficient pool fees MultiHop");
ISwapRouter router = ISwapRouter(swapData.router);
if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance swapv3");
IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
}
address intermediateToken = swapData.tokenIn == IPancakePair(swapData.pairAddress[0]).token0() ?
IPancakePair(swapData.pairAddress[0]).token1() :
IPancakePair(swapData.pairAddress[0]).token0();
bytes memory path = abi.encodePacked(
swapData.tokenIn,
swapData.poolFee[0],
intermediateToken,
swapData.poolFee[swapData.poolFee.length - 1],
swapData.tokenOut
);
ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
path: path,
recipient: address(this),
deadline: block.timestamp + 300,
amountIn: swapData.amountIn,
amountOutMinimum: 0
});
if (swapData.tokenIn == WETH || swapData.tokenIn == address(uint160(coinAddressApi))) {
require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance v3");
IWETH(WETH).withdraw(swapData.amountIn);
require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance v3");
router.exactInput{value: swapData.amountIn}(params);
} else {
router.exactInput(params);
}
}
// Helper function for Uniswap V3 single swaps
function _executeUniswapV3Swap(call_v3 memory swapData) private {
ISwapUniRouter router = ISwapUniRouter(swapData.router);
if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance uni");
IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
}
ISwapUniRouter.ExactInputSingleParams memory params = ISwapUniRouter.ExactInputSingleParams({
tokenIn: swapData.tokenIn,
tokenOut: swapData.tokenOut,
fee: swapData.poolFee[0],
recipient: address(this),
amountIn: swapData.amountIn,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});
if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
router.exactInputSingle(params);
} else {
require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance uni");
IWETH(WETH).withdraw(swapData.amountIn);
require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance uni");
router.exactInputSingle{value: swapData.amountIn}(params);
}
}
function _executeSwapV3(call_v3 memory swapData) private {
ISwapRouter router = ISwapRouter(swapData.router);
if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance swapv3");
IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
}
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
tokenIn: swapData.tokenIn,
tokenOut: swapData.tokenOut,
fee: swapData.poolFee[0],
recipient: address(this),
deadline: block.timestamp +300,
amountIn: swapData.amountIn,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});
if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
router.exactInputSingle(params);
} else {
require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance swapv3");
IWETH(WETH).withdraw(swapData.amountIn);
require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance swapv3");
router.exactInputSingle{value: swapData.amountIn}(params);
}
}
function _executeQuickSwapV3(call_v3 memory swapData) private {
ISwapRouterQuick router = ISwapRouterQuick(swapData.router);
if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
uint256 balance = IERC20(swapData.tokenIn).balanceOf(address(this));
require(balance >= swapData.amountIn, "Insufficient tokenIn balance quick");
TransferHelper.safeApprove(swapData.tokenIn, address(router), swapData.amountIn);
}
ISwapRouterQuick.ExactInputSingleParams memory params = ISwapRouterQuick.ExactInputSingleParams({
tokenIn: swapData.tokenIn,
tokenOut: swapData.tokenOut,
recipient: address(this),
deadline: block.timestamp + 300,
amountIn: swapData.amountIn,
amountOutMinimum: 0,
limitSqrtPrice: 0
});
if (swapData.tokenIn == WETH || swapData.tokenIn == address(uint160(coinAddressApi))) {
require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance quick");
IWETH(WETH).withdraw(swapData.amountIn);
require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance quick");
router.exactInputSingle{value: swapData.amountIn}(params);
} else {
router.exactInputSingle(params);
}
}
function _executeUniswapMultiHopSwap(call_v3 memory swapData) private {
require(swapData.poolFee.length >= 2, "Insufficient pool fees MultiHop");
require(swapData.poolFee[0] > 0 && swapData.poolFee[swapData.poolFee.length - 1] > 0, "Invalid pool fees");
ISwapUniRouter router = ISwapUniRouter(swapData.router);
if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance swapv3");
IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
}
address intermediateToken = swapData.tokenIn == IPancakePair(swapData.pairAddress[0]).token0() ?
IPancakePair(swapData.pairAddress[0]).token1() :
IPancakePair(swapData.pairAddress[0]).token0();
bytes memory path = abi.encodePacked(
swapData.tokenIn,
swapData.poolFee[0],
intermediateToken,
swapData.poolFee[swapData.poolFee.length - 1],
swapData.tokenOut
);
ISwapUniRouter.ExactInputParams memory params = ISwapUniRouter.ExactInputParams({
path: path,
recipient: address(this),
amountIn: swapData.amountIn,
amountOutMinimum: 0
});
if (swapData.tokenIn == WETH || swapData.tokenIn == address(uint160(coinAddressApi))) {
require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance MultiHop");
IWETH(WETH).withdraw(swapData.amountIn);
require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance MultiHop");
router.exactInput{value: swapData.amountIn}(params);
} else {
router.exactInput(params);
}
}
function withdrawETH(address payable _to, uint256 _amount)
public
onlyContractOwner
returns (uint256)
{
_to.transfer(_amount);
return _amount;
}
function withdrawTokens(address _tokenAddress, uint256 _amount)
public
onlyContractOwner
{
require(IERC20(_tokenAddress).balanceOf(address(this)) >= _amount, "Insufficient balance");
bool success = IERC20(_tokenAddress).transfer(msg.sender, _amount);
require(success, "Token transfer failed");
}
function changeOperator(address _operator)public controlOrder{
operator =_operator;
}
function changeFee(uint256 _Fee)public controlOrder{
Fee = _Fee;
}
function changeOwner(address _Owneraddress)public onlyContractOwner{
owneraddress = _Owneraddress;
}
}"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}
}}
Submitted on: 2025-09-19 12:29:42
Comments
Log in to comment.
No comments yet.