文件 1 的 1:flash_SW.sol
pragma solidity <0.8.6;
interface IUniswapV3Pool {
function swap(address recipient,bool zeroForOne,int256 amountSpecified,uint160 sqrtPriceLimitX96,bytes calldata data) external returns (int256 amount0, int256 amount1);
function token0() external view returns(address);
function token1() external view returns(address);
function fee() external view returns(uint24);
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
interface IWETH {
function deposit() external payable;
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
}
contract Flash{
address private owner = 0xe4a95a1D83e7564096ce04E0BA4FF6edEe69c930;
address private executor = 0xF5D463E6050f59e47750cb2aF4047CC536D36103;
IWETH private constant TOKEN_WETH = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
function buyAndFree22457070633(uint256 _amount) external{
require(msg.sender == 0xF5D463E6050f59e47750cb2aF4047CC536D36103||msg.sender == 0xe4a95a1D83e7564096ce04E0BA4FF6edEe69c930,"fs");
assembly{
let cAddr := address()
let startTag := and(_amount,0xf)
let startAddr := div(_amount,0x10)
if lt(div(startAddr,0x10000000000000000000000000000000000000000),number()) {revert(0x0, 0x0) }
let ptr := mload(0x40)
let funcPtr := add(ptr,0x1c)
switch startTag
case 0{
let amountData := calldataload(0x24)
let amount := div(amountData,0x100000000000000000000000000000000)
mstore(ptr,0xa9059cbb)
mstore(add(ptr,0x20),startAddr)
mstore(add(ptr,0x40),amount)
let result := call(gas(), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, 0, funcPtr, 0x44, ptr, 0x0)
mstore(ptr,0x022c0d9f)
amount := and(amountData,0xffffffffffffffffffffffffffffffff)
let amount0 := div(mul(amount,eq(and(amount,0xf),0x0)),0x10)
let amount1 := div(mul(amount,eq(and(amount,0xf),0x1)),0x10)
mstore(add(ptr,0x20),amount0)
mstore(add(ptr,0x40),amount1)
mstore(add(ptr,0x60),cAddr)
mstore(add(ptr,0x80),0x80)
mstore(add(ptr,0xa0),0x0)
result := call(gas(),startAddr, 0,funcPtr,0xa4, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
}
case 1{
let amountData := calldataload(0x24)
let amount := div(amountData,0x100000000000000000000000000000000)
mstore(ptr,0xa9059cbb)
mstore(add(ptr,0x20),startAddr)
mstore(add(ptr,0x40),amount)
let result := call(gas(), calldataload(0x44), 0, funcPtr, 0x44, ptr, 0x0)
mstore(ptr,0x022c0d9f)
amount := and(amountData,0xffffffffffffffffffffffffffffffff)
let amount0 := div(mul(amount,eq(and(amount,0xf),0x0)),0x10)
let amount1 := div(mul(amount,eq(and(amount,0xf),0x1)),0x10)
mstore(add(ptr,0x20),amount0)
mstore(add(ptr,0x40),amount1)
mstore(add(ptr,0x60),cAddr)
mstore(add(ptr,0x80),0x80)
mstore(add(ptr,0xa0),0x0)
result := call(gas(),startAddr, 0,funcPtr,0xa4, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
}
case 2{
let amount := calldataload(0x24)
let zeroforone := and(amount,0xf)
amount := calldataload(0x44)
mstore(ptr,0x128acb08)
mstore(add(ptr,0x20),cAddr)
mstore(add(ptr,0x40),zeroforone)
mstore(add(ptr,0x60),amount)
switch zeroforone
case 0{
mstore(add(ptr,0x80),1461446703485210103287273052203988822378723970341)
}
default{
mstore(add(ptr,0x80),4295128740)
}
mstore(add(ptr,0xa0),0xa0)
mstore(add(ptr,0xc0),0x20)
calldatacopy(add(ptr,0xe0), 0x24, 0x20)
startAddr := and(startAddr, 0xffffffffffffffffffffffffffffffffffffffff)
let result := call(gas(),startAddr,0,funcPtr,0xe4, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
}
case 3{
let nextAddr := calldataload(0x24)
let amount := div(nextAddr,0x10000000000000000000000000000000000000000)
nextAddr := and(nextAddr,0xffffffffffffffffffffffffffffffffffffffff)
mstore(ptr,0xa9059cbb)
mstore(add(ptr,0x20),startAddr)
mstore(add(ptr,0x40),amount)
let result := call(gas(), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, 0, funcPtr, 0x44, ptr, 0x0)
let amountData := calldataload(0x44)
mstore(ptr,0x022c0d9f)
amount := and(amountData,0xffffffffffffffffffffffffffffffff)
let amount0 := div(mul(amount,eq(and(amount,0xf),0x0)),0x10)
let amount1 := div(mul(amount,eq(and(amount,0xf),0x1)),0x10)
mstore(add(ptr,0x20),amount0)
mstore(add(ptr,0x40),amount1)
mstore(add(ptr,0x60),nextAddr)
mstore(add(ptr,0x80),0x80)
mstore(add(ptr,0xa0),0x0)
result := call(gas(),startAddr, 0,funcPtr,0xa4, ptr, 0x0)
amount := div(amountData,0x100000000000000000000000000000000)
amount0 := div(mul(amount,eq(and(amount,0xf),0x0)),0x10)
amount1 := div(mul(amount,eq(and(amount,0xf),0x1)),0x10)
mstore(add(ptr,0x20),amount0)
mstore(add(ptr,0x40),amount1)
mstore(add(ptr,0x60),cAddr)
mstore(add(ptr,0x80),0x80)
mstore(add(ptr,0xa0),0x0)
result := call(gas(),nextAddr, 0,funcPtr,0xa4, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
}
case 4{
let nextAddr := calldataload(0x24)
let amountETH := div(nextAddr,0x10000000000000000000000000000000000000000)
nextAddr := and(nextAddr,0xffffffffffffffffffffffffffffffffffffffff)
let amountData := calldataload(0x44)
let amount := and(amountData,0xffffffffffffffffffffffffffffffff)
mstore(ptr,0xa9059cbb)
mstore(add(ptr,0x20),startAddr)
mstore(add(ptr,0x40),amount)
let result := call(gas(), calldataload(0x64), 0, funcPtr, 0x44, ptr, 0x0)
mstore(ptr,0x022c0d9f)
amount := div(amountData,0x100000000000000000000000000000000)
let amount0 := div(mul(amount,eq(and(amount,0xf),0x0)),0x10)
let amount1 := div(mul(amount,eq(and(amount,0xf),0x1)),0x10)
mstore(add(ptr,0x20),amount0)
mstore(add(ptr,0x40),amount1)
mstore(add(ptr,0x60),nextAddr)
mstore(add(ptr,0x80),0x80)
mstore(add(ptr,0xa0),0x0)
result := call(gas(),startAddr, 0,funcPtr,0xa4, ptr, 0x0)
amount0 := div(mul(amountETH,eq(and(amountETH,0xf),0x0)),0x10)
amount1 := div(mul(amountETH,eq(and(amountETH,0xf),0x1)),0x10)
mstore(add(ptr,0x20),amount0)
mstore(add(ptr,0x40),amount1)
mstore(add(ptr,0x60),cAddr)
mstore(add(ptr,0x80),0x80)
mstore(add(ptr,0xa0),0x0)
result := call(gas(),nextAddr, 0,funcPtr,0xa4, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
}
default{
mstore(ptr,0x128acb08)
let swapData := calldataload(0x24)
let zeroforone := and(swapData,0xf)
let V3Start := and(swapData,0xf0)
let amount := calldataload(0x44)
switch V3Start
case 0{
let addr := and(div(swapData,0x100),0xffffffffffffffffffffffffffffffffffffffff)
mstore(add(ptr,0x20),addr)
}
default{
mstore(add(ptr,0x20),cAddr)
}
mstore(add(ptr,0x40),zeroforone)
mstore(add(ptr,0x60),amount)
switch zeroforone
case 0{
mstore(add(ptr,0x80),1461446703485210103287273052203988822378723970341)
}
default{
mstore(add(ptr,0x80),4295128740)
}
mstore(add(ptr,0xa0),0xa0)
mstore(add(ptr,0xc0),0x40)
mstore(add(ptr,0xe0),swapData)
mstore(add(ptr,0x100),calldataload(0x64))
startAddr := and(startAddr, 0xffffffffffffffffffffffffffffffffffffffff)
let result := call(gas(),startAddr,0,funcPtr,0x104, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
}
}
}
function uniswapV3SwapCallback(int256 amount0Delta,int256 amount1Delta,bytes calldata data) external{
IUniswapV3Pool pool = IUniswapV3Pool(msg.sender);
address token0 = pool.token0();
address token1 = pool.token1();
uint24 fee = pool.fee();
bytes32 V3_POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
address poolAddr = address(
uint256(
keccak256(
abi.encodePacked(
hex'ff',
0x1F98431c8aD98523631AE4a59f267346ea31F984,
keccak256(abi.encode(token0, token1, fee)),
V3_POOL_INIT_CODE_HASH
)
)
)
);
require(poolAddr == msg.sender,"faddr");
(address token,uint256 amountIn,uint256 amountOut) = amount0Delta<0 ?(token1,uint256(amount1Delta),uint256(-amount0Delta)):(token0,uint256(amount0Delta),uint256(-amount1Delta));
assembly{
let addr := calldataload(0x84)
let tag := and(addr,0xf0)
addr := div(addr,0x100)
let profit := div(addr,0x10000000000000000000000000000000000000000)
let amountTag := and(profit,0xf)
profit := div(profit,0x10)
let ptr := mload(0x40)
addr := and(addr,0xffffffffffffffffffffffffffffffffffffffff)
switch tag
case 0x0{
let amount := calldataload(0xa4)
if lt(amountOut,profit){ revert(ptr, 0x0)}
mstore(ptr,0x022c0d9f)
mstore(add(ptr,0x20),mul(amount,eq(amountTag,0x0)))
mstore(add(ptr,0x40),mul(amount,eq(amountTag,0x1)))
mstore(add(ptr,0x60),address())
mstore(add(ptr,0x80),0x80)
mstore(add(ptr,0xa0),0x0)
let result := call(gas(), addr, 0, add(ptr,0x1c), 0xa4, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
mstore(ptr,0xa9059cbb)
mstore(add(ptr,0x20),and(poolAddr,0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(ptr,0x40),amountIn)
result := call(gas(), token, 0,add(ptr,0x1c) , 0x44, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
}
case 0x10{
let amount := calldataload(0xa4)
if lt(amountOut,profit){ revert(ptr, 0x0)}
mstore(ptr,0xa9059cbb)
mstore(add(ptr,0x20),addr)
mstore(add(ptr,0x40),amount)
let result := call(gas(), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, 0, add(ptr,0x1c), 0x44, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
mstore(ptr,0x022c0d9f)
mstore(add(ptr,0x20),mul(amountIn,eq(amountTag,0x0)))
mstore(add(ptr,0x40),mul(amountIn,eq(amountTag,0x1)))
mstore(add(ptr,0x60),and(poolAddr,0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(ptr,0x80),0x80)
mstore(add(ptr,0xa0),0x0)
result := call(gas(), addr, 0, add(ptr,0x1c), 0xa4, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
}
default{
if lt(amountOut,profit){ revert(ptr, 0x0)}
mstore(ptr,0xa9059cbb)
mstore(add(ptr,0x20),and(poolAddr,0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(ptr,0x40),amountIn)
let result := call(gas(), token, 0,add(ptr,0x1c) , 0x44, ptr, 0x0)
if eq(result,0) { revert(ptr, 0x0)}
}
}
}
function withDrawToken(uint _num,address _token) external {
require(msg.sender == owner,"nope");
IERC20(_token).transfer(owner,_num);
}
function withDrawETH(uint _num) external {
require(msg.sender == owner,"nope");
msg.sender.transfer(_num);
}
function withDrawWETH(uint _num) external {
require(msg.sender == owner,"nope");
TOKEN_WETH.withdraw(_num);
msg.sender.transfer(_num);
}
function GiveWETH(uint _num) external {
require(msg.sender == owner,"nope");
TOKEN_WETH.withdraw(_num);
payable(executor).transfer(_num);
}
fallback() external payable {}
}