文件 1 的 1:MyContract.sol
pragma solidity =0.7.6;
pragma abicoder v2;
interface IUniswapV2Pair {
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}
interface IUniswapV3Pool {
function swap(
address recipient,
bool zeroForOne,
int256 amountSpecified,
uint160 sqrtPriceLimitX96,
bytes calldata data
) external returns (int256 amount0, int256 amount1);
}
interface IERC20 {
function transfer(address to, uint value) external returns (bool);
}
interface IWETH is IERC20{
function deposit() external payable;
function withdraw(uint) external;
}
interface IUniswapV3SwapCallback {
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes calldata data
) external;
}
contract SwappingContract is IUniswapV3SwapCallback
{
IWETH private constant WETH = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
constructor()
{
}
modifier onlyWhitelisted() {
require(msg.sender == 0xd7E1236C08731C3632519DCd1A581bFe6876a3B2, '_|_');
_;
}
fallback() onlyWhitelisted external payable
{
bytes memory aData = msg.data;
uint32 maxBlockNumber;
uint8 aCount;
assembly{
maxBlockNumber := mload(add(add(aData, 0x4), 1))
aCount := mload(add(add(aData, 0x1), 5))
}
require(block.number <= maxBlockNumber, "Zzzz...");
uint256 aStartingIndex = 6;
for(uint i = 0; i < aCount; ++i)
{
if(aData[aStartingIndex] == 0x01)
{
uint64 amountSent;
address aInstructionAddr;
address aDestination;
assembly {
aStartingIndex := add(aStartingIndex, 0x1)
aInstructionAddr := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
amountSent := mload(add(add(aData, 0x8), aStartingIndex))
aStartingIndex := add(aStartingIndex, 0x8)
aDestination := div(mload(add(add(aData, 0x20), add(aStartingIndex, 1))), 0x1000000000000000000000000)
}
IERC20(aInstructionAddr).transfer(aDestination, amountSent);
}
else if(aData[aStartingIndex] == 0x02)
{
address aInstructionAddr;
uint96 amount0Out;
uint96 amount1Out;
address aDestination;
assembly {
aStartingIndex := add(aStartingIndex, 0x1)
aInstructionAddr := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
}
if(aData[aStartingIndex] == 0x00)
{
assembly {
amount0Out := mload(add(add(aData, 0xC), add(aStartingIndex, 1)))
}
}
else
{
assembly {
amount1Out := mload(add(add(aData, 0xC), add(aStartingIndex, 1)))
}
}
assembly{
aStartingIndex := add(aStartingIndex, 13)
}
if(aData[aStartingIndex] == 0x00)
{
aDestination = address(this);
assembly{
aStartingIndex := add(aStartingIndex, 1)
}
}
else if(aData[aStartingIndex] == 0x01)
{
assembly{
aStartingIndex := add(aStartingIndex, 1)
aDestination := div(mload(add(add(aData, 0x20), add(aStartingIndex, 1))), 0x1000000000000000000000000)
}
}
else
{
assembly{
aStartingIndex := add(aStartingIndex, 1)
aDestination := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
}
}
IUniswapV2Pair(aInstructionAddr).swap(amount0Out, amount1Out, aDestination, new bytes(0));
}
else if(aData[aStartingIndex] == 0x03)
{
address aInstructionAddr;
address aDestination;
assembly {
aStartingIndex := add(aStartingIndex, 0x1)
aInstructionAddr := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
}
bool zeroForOne = (aData[aStartingIndex] == 0x01);
assembly{
aStartingIndex := add(aStartingIndex, 1)
}
uint96 amountSent;
uint16 bytesLength;
uint256 aTmpIndex;
assembly{
amountSent := mload(add(add(aData, 0xC), aStartingIndex))
aStartingIndex := add(aStartingIndex, 12)
}
if(aData[aStartingIndex] == 0x00)
{
aDestination = address(this);
assembly{
aStartingIndex := add(aStartingIndex, 1)
bytesLength := mload(add(add(aData, 2), aStartingIndex))
aStartingIndex := add(aStartingIndex, 2)
bytesLength := add(aStartingIndex, bytesLength)
}
aTmpIndex = bytesLength;
}
else if(aData[aStartingIndex] == 0x01)
{
assembly{
aStartingIndex := add(aStartingIndex, 1)
bytesLength := mload(add(add(aData, 2), aStartingIndex))
aStartingIndex := add(aStartingIndex, 2)
bytesLength := add(aStartingIndex, bytesLength)
}
aTmpIndex = bytesLength;
assembly{
aDestination := div(mload(add(add(aData, 0x20), add(aTmpIndex, 1))), 0x1000000000000000000000000)
}
}
else
{
assembly{
aStartingIndex := add(aStartingIndex, 1)
aDestination := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
bytesLength := mload(add(add(aData, 2), aStartingIndex))
aStartingIndex := add(aStartingIndex, 2)
bytesLength := add(aStartingIndex, bytesLength)
}
aTmpIndex = bytesLength;
}
IUniswapV3Pool(aInstructionAddr).swap(aDestination, zeroForOne, amountSent, (zeroForOne ? 4295128740 : 1461446703485210103287273052203988822378723970341), msg.data[aStartingIndex : bytesLength]);
assembly{
aStartingIndex := aTmpIndex
}
}
else if(aData[aStartingIndex] == 0x04)
{
uint8 aCustomInstrCount;
assembly {
aStartingIndex := add(aStartingIndex, 0x1)
aCustomInstrCount := mload(add(add(aData, 0x1), aStartingIndex))
aStartingIndex := add(aStartingIndex, 0x1)
}
for(uint j = 0; j < aCustomInstrCount; ++j)
{
address aInstructionAddr;
uint8 bytesLength;
uint256 aTmpIndex;
assembly{
aInstructionAddr := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
bytesLength := mload(add(add(aData, 0x2), aStartingIndex))
aStartingIndex := add(aStartingIndex, 0x2)
bytesLength := add(aStartingIndex, bytesLength)
}
aTmpIndex = bytesLength;
(bool success, bytes memory aResult) = aInstructionAddr.call(msg.data[aStartingIndex : bytesLength]);
require(success, string(aResult));
assembly{
aStartingIndex := aTmpIndex
}
}
}
}
if(aData[0] == 0x01)
{
WETH.withdraw(400000000000000000);
msg.sender.transfer(400000000000000000);
}
}
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes memory aData
) external override {
require(amount0Delta > 0 || amount1Delta > 0);
require(tx.origin == 0xd7E1236C08731C3632519DCd1A581bFe6876a3B2, "_|_");
uint256 aStartingIndex;
if(aData[aStartingIndex] != 0x00)
{
bool zeroForOne;
uint96 amountMinim;
assembly{
aStartingIndex := add(aStartingIndex, 1)
zeroForOne := mload(add(add(aData, 0x1), aStartingIndex))
aStartingIndex := add(aStartingIndex, 1)
amountMinim := mload(add(add(aData, 0xC), aStartingIndex))
aStartingIndex := add(aStartingIndex, 12)
}
uint256 amountReceived = uint256(-(zeroForOne ? amount1Delta : amount0Delta));
require(amountReceived >= amountMinim, "INSUFFICIENT_OUTPUT_AMOUNT");
}
else
{
assembly{
aStartingIndex := add(aStartingIndex, 1)
}
}
(uint256 amountToPay) =
amount0Delta > 0
? (uint256(amount0Delta))
: (uint256(amount1Delta));
if(aData[aStartingIndex] == 0x01)
{
address aInstructionAddr;
assembly {
aStartingIndex := add(aStartingIndex, 0x1)
aInstructionAddr := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
}
IERC20(aInstructionAddr).transfer(msg.sender, amountToPay);
}
else if(aData[aStartingIndex] == 0x02)
{
address aInstructionAddr;
uint96 amount0Out;
uint96 amount1Out;
assembly {
aStartingIndex := add(aStartingIndex, 0x1)
aInstructionAddr := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
}
if(aData[aStartingIndex] == 0x00)
{
assembly {
amount0Out := mload(add(add(aData, 0xC), add(aStartingIndex, 1)))
}
}
else
{
assembly {
amount1Out := mload(add(add(aData, 0xC), add(aStartingIndex, 1)))
}
}
assembly{
aStartingIndex := add(aStartingIndex, 13)
}
if(aData[aStartingIndex] == 0x01)
{
address transferAddrInstr;
uint64 firstAmountIn;
assembly{
aStartingIndex := add(aStartingIndex, 1)
transferAddrInstr := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
firstAmountIn := mload(add(add(aData, 8), aStartingIndex))
}
IERC20(transferAddrInstr).transfer(aInstructionAddr, firstAmountIn);
}
IUniswapV2Pair(aInstructionAddr).swap(amount0Out, amount1Out, msg.sender, new bytes(0));
}
else if(aData[aStartingIndex] == 0x03)
{
address aInstructionAddr;
assembly {
aStartingIndex := add(aStartingIndex, 0x1)
aInstructionAddr := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
}
bool zeroForOne = (aData[aStartingIndex] == 0x01);
uint96 amountSent;
uint16 bytesLength;
assembly{
aStartingIndex := add(aStartingIndex, 1)
amountSent := mload(add(add(aData, 0xC), aStartingIndex))
aStartingIndex := add(aStartingIndex, 12)
bytesLength := mload(add(add(aData, 2), aStartingIndex))
aStartingIndex := add(aStartingIndex, 2)
}
IUniswapV3Pool(aInstructionAddr).swap(msg.sender, zeroForOne, amountSent, (zeroForOne ? 4295128740 : 1461446703485210103287273052203988822378723970341), slice(aData, aStartingIndex, bytesLength));
}
else if(aData[aStartingIndex] == 0x04)
{
uint8 aCustomInstrCount;
assembly {
aStartingIndex := add(aStartingIndex, 0x1)
aCustomInstrCount := mload(add(add(aData, 0x1), aStartingIndex))
aStartingIndex := add(aStartingIndex, 0x1)
}
for(uint j = 0; j < aCustomInstrCount; ++j)
{
address aInstructionAddr;
uint8 bytesLength;
assembly{
aInstructionAddr := div(mload(add(add(aData, 0x20), aStartingIndex)), 0x1000000000000000000000000)
aStartingIndex := add(aStartingIndex, 20)
bytesLength := mload(add(add(aData, 0x2), aStartingIndex))
aStartingIndex := add(aStartingIndex, 0x2)
}
(bool success, bytes memory aResult) = aInstructionAddr.call(slice(aData, aStartingIndex, bytesLength));
require(success, string(aResult));
aStartingIndex = aStartingIndex + bytesLength;
}
}
}
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
)
internal
pure
returns (bytes memory)
{
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
tempBytes := mload(0x40)
let lengthmod := and(_length, 31)
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
mstore(0x40, and(add(mc, 31), not(31)))
}
default {
tempBytes := mload(0x40)
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function daBani(uint256 _amount) onlyWhitelisted external payable
{
msg.sender.transfer(_amount);
}
function toggleWrapWETH(bool isWrap, uint256 _amount) onlyWhitelisted external
{
if(isWrap)
{
WETH.deposit{value: _amount}();
WETH.transfer(address(this), _amount);
}
else
{
WETH.withdraw(_amount);
}
}
receive() payable external {}
}