pragma solidity ^0.8.19;
interface ierc {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
using Math for uint256;
contract UBahn4Rev {
uint a0Out;
uint a1Out;
address Pair1;
address Pair2;
uint DEXA;
uint DEXB;
address LP;
address Token;
address t0;
address t1;
uint In;
uint160 MIN_SQRT_RATIO = 4295128739;
uint160 MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;
address BOR;
address OTH;
address owner;
bool secondo = false;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
bytes16 HEX_DIGITS = "0123456789abcdef";
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
bytes16 HEX_DIGITS = "0123456789abcdef";
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
return string(buffer);
}
function divRoundingUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
assembly {
z := add(div(x, y), gt(mod(x, y), 0))
}
}
function mulDivRoundingUp(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
result = Math.mulDiv(a, b, denominator);
if (mulmod(a, b, denominator) > 0) {
require(result < type(uint256).max);
result++;
}
}
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
require(amountIn > 0, 'getAmountOut: INSUFFICIENT_INPUT_AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'getAmountOut: INSUFFICIENT_LIQUIDITY');
uint amountInWithFee = amountIn*997;
uint numerator = amountInWithFee*reserveOut;
uint denominator = reserveIn*1000 + amountInWithFee;
amountOut = numerator / denominator;
}
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes memory data
) external {
// Pay back the Pool
(uint ze, address to, address pai, uint Inn) = abi.decode(data,(uint,address,address,uint));
// IUniswapV3Pool(Pair1).swap(address(this),true,In,0,"");
uint F3 = uint(IUniswapV3Pool(pai).fee()/10**6);
if (Inn==2222222) { revert(toString(Inn)); }
if (Inn==2222223) { revert(toString(ierc(to).balanceOf(pai)));}
if (ze==0) {
ierc(to).approve(pai,uint(amount0Delta*(1+int(F3))));
ierc(to).transfer(pai,uint(amount0Delta*(1+int(F3))));
if (Inn==2222224) { revert(toString(ierc(to).balanceOf(pai)));}
}
if (ze==1) {
ierc(to).approve(pai,uint(amount1Delta*(1+int(F3))));
ierc(to).transfer(pai,uint(amount1Delta*(1+int(F3))));
if (Inn==2222225) { revert(toString(ierc(to).balanceOf(pai)));}
}
}
function pancakeV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes memory data
) external {
// Pay back the Pool
(uint ze, address to, address pai, uint Inn) = abi.decode(data,(uint,address,address,uint));
// IUniswapV3Pool(Pair1).swap(address(this),true,In,0,"");
uint F3 = uint(IUniswapV3Pool(pai).fee()/10**6);
if (ze==0) {
ierc(to).approve(pai,uint(amount0Delta*(1+int(F3))));
ierc(to).transfer(pai,uint(amount0Delta*(1+int(F3))));
}
if (ze==1) {
ierc(to).approve(pai,uint(amount1Delta*(1+int(F3))));
ierc(to).transfer(pai,uint(amount1Delta*(1+int(F3))));
}
}
function Pairswap(address loanPair, address token, uint amount, uint dexa, uint dexb, address pair1, address pair2) external payable
{
BOR = token;
uint pos = IUniswapV2Pair(loanPair).token0() == token ? 0 : 1;
a0Out = pos==1 ? 0 : amount;
a1Out = pos==1 ? amount : 0;
owner = msg.sender;
bytes memory by = abi.encode(dexa,dexb,pair1,pair2,loanPair,token);
IUniswapV2Pair(loanPair).swap(a0Out,a1Out,address(this),by);
}
function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external {
(DEXA, DEXB, Pair1, Pair2, LP, Token) = abi.decode(data, (uint,uint,address,address,address,address));
In = ierc(Token).balanceOf(address(this));
if (In==1500001) { revert(toString(In)); }
if (DEXA==2) {
t0 = IUniswapV2Pair(Pair1).token0();
t1 = IUniswapV2Pair(Pair1).token1();
(uint112 r0,uint112 r1,) = IUniswapV2Pair(Pair1).getReserves();
if (In==1500003) { revert(toString(ierc(BOR).balanceOf(address(this)))); }
if (In==500001) { revert(toString(r1)); }
ierc(BOR).approve(address(this),ierc(BOR).balanceOf(address(this)));
ierc(BOR).transferFrom(address(this),Pair1,ierc(BOR).balanceOf(address(this)));
(uint112 r2,uint112 r3,) = IUniswapV2Pair(Pair1).getReserves();
if (In==500002) { revert(toString(r3)); }
if (In==1500004) { revert(toString(ierc(BOR).balanceOf(address(this)))); }
uint Q = BOR==t0 ? getAmountOut(In,r0,r1) : getAmountOut(In,r1,r0);
if (In==1550004) { revert(toString(Q));}
if (BOR==t0) {
IUniswapV2Pair(Pair1).swap(0,Q,address(this),"");
} else {
if (In==1550005) { revert(toString(Q)); }
IUniswapV2Pair(Pair1).swap(Q,0,address(this),""); }
if (In==1500005) { revert("PRIMO SWAP V2 OK"); }
} else {
t0 = IUniswapV3Pool(Pair1).token0();
t1 = IUniswapV3Pool(Pair1).token1();
(uint160 SQ,,,,,,) = IUniswapV3Pool(Pair1).slot0();
uint128 liq = IUniswapV3Pool(Pair1).liquidity();
if (In==1500006) { revert(toString(SQ)); }
if (BOR==t0) {
uint z = 0;
IUniswapV3Pool(Pair1).swap(address(this),true,int(In),MIN_SQRT_RATIO+1,abi.encode(z,BOR,Pair1,In));
if (In==1500009) { revert("PRIMO SWAP V3 BOR T0 OK"); }
} else {
if (In==1500007) { revert(toString(ierc(BOR).balanceOf(address(this)))); }
uint z = 1;
IUniswapV3Pool(Pair1).swap(address(this),false,int(In),MAX_SQRT_RATIO-1,abi.encode(z,BOR,Pair1,In));
if (In==1500010) { revert("PRIMO SWAP V3 BOR T1 OK"); }
}}
secondo = true;
if (In==1500011) { revert("SECONDO TRUE"); }
uint am2;
if (BOR==t0) {
am2 = ierc(t1).balanceOf(address(this));
OTH = t1;
} else {
am2 = ierc(t0).balanceOf(address(this));
OTH = t0;
}
if (DEXB==2) {
address t2 = IUniswapV2Pair(Pair2).token0();
address t3 = IUniswapV2Pair(Pair2).token1();
(uint112 r2,uint112 r3,) = IUniswapV2Pair(Pair2).getReserves();
if (t2!=OTH && t3!=OTH) {
revert("Stesso token ma con indirizzi diversi");
}
uint Q2;
if (In==1555555) { revert(toString(am2)); }
Q2 = BOR==t3 ? getAmountOut(am2,r2,r3) : getAmountOut(am2,r3,r2);
if (In==1500014) { revert(toString(Q2)); }
ierc(OTH).approve(address(this),ierc(OTH).balanceOf(address(this)));
ierc(OTH).transferFrom(address(this),Pair2,ierc(OTH).balanceOf(address(this)));
if (BOR==t3) {
IUniswapV2Pair(Pair2).swap(0,Q2,address(this),"");
if (In==1500016) { revert("SECONDO SWAP V2 BOR T3 OK"); }
} else {
IUniswapV2Pair(Pair2).swap(Q2,0,address(this),"");
if (In==1500017) { revert("SECONDO SWAP V2 BOR T2 OK"); } }
} else {
uint In2 = ierc(OTH).balanceOf(address(this));
if (In==1500018) { revert(toString(In2)); }
address t2 = IUniswapV3Pool(Pair2).token0();
address t3 = IUniswapV3Pool(Pair2).token1();
(uint160 SQ2,,,,,,) = IUniswapV3Pool(Pair2).slot0();
uint128 liq2 = IUniswapV3Pool(Pair2).liquidity();
if (BOR==t3) {
uint z = 0;
IUniswapV3Pool(Pair2).swap(address(this),true,int(In2),MIN_SQRT_RATIO+1,abi.encode(z,OTH,Pair2,In));
if (In==1500022) { revert("SECONDO SWAP V3 BOR T3 OK"); }
} else {
uint z = 1;
IUniswapV3Pool(Pair2).swap(address(this),false,int(In2),MAX_SQRT_RATIO-1,abi.encode(z,OTH,Pair2,In));
if (In==1500024) { revert("SECONDO SWAP V3 BOR T2 OK"); }
}}
uint Out = ierc(BOR).balanceOf(address(this));
if (In==1500025) { revert(toString(Out)); }
if (Out<In) {
revert("T");
} else {
uint256 loanFee = Math.mulDiv(In,3,997)+1;
ierc(BOR).approve(LP,In+loanFee);
if (In==1500026) { revert(toString(In+loanFee)); }
ierc(BOR).transferFrom(address(this),LP,In+loanFee);
if (In==1500027) { revert(toString(ierc(BOR).balanceOf(address(this)))); }
ierc(BOR).approve(owner,ierc(BOR).balanceOf(address(this)));
if (In==1500028) { revert(toString(ierc(BOR).balanceOf(address(this)))); }
ierc(BOR).transferFrom(address(this),owner,ierc(BOR).balanceOf(address(this)));
if (In==1500029) { revert("FINE"); } // }
}
}}