//SPDX-License-Identifier: Unlicensed pragma solidity 0.8.10; import "./interfaces/IPancakeFactory.sol"; import "./lib/PancakeLib.sol"; import "./interfaces/IPancakePair.sol"; import "./interfaces/IPancakeERC20.sol"; import "./interfaces/IWETH.sol"; //solhint-disable contract PancakeRouter { address public immutable factory; //solhint-disable-next-line address public immutable WETH; //solhint-disable-next-line constructor(address _factory, address _WETH) { factory = _factory; WETH = _WETH; } // **** SWAP **** // requires the initial amount to have already been sent to the first pair function _swap( uint256[] memory amounts, address[] memory path, address _to ) internal virtual { for (uint256 i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0, ) = PancakeLib.sortTokens(input, output); uint256 amountOut = amounts[i + 1]; (uint256 amount0Out, uint256 amount1Out) = input == token0 ? (uint256(0), amountOut) : (amountOut, uint256(0)); address to = i < path.length - 2 ? PancakeLib.pairFor(factory, output, path[i + 2]) : _to; IPancakePair(PancakeLib.pairFor(factory, input, output)).swap( amount0Out, amount1Out, to, new bytes(0) ); } } function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 ) external virtual returns (uint256[] memory amounts) { amounts = PancakeLib.getAmountsOut(factory, amountIn, path); require( amounts[amounts.length - 1] >= amountOutMin, "INSUFFICIENT_OUTPUT_AMOUNT" ); IPancakeERC20(path[0]).transferFrom( msg.sender, PancakeLib.pairFor(factory, path[0], path[1]), amounts[0] ); _swap(amounts, path, to); } function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 ) public virtual returns (uint256 amountA, uint256 amountB) { address pair = PancakeLib.pairFor(factory, tokenA, tokenB); IPancakeERC20(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair (uint256 amount0, uint256 amount1) = IPancakePair(pair).burn(to); (address token0, ) = PancakeLib.sortTokens(tokenA, tokenB); (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); require(amountA >= amountAMin, "PancakeRouter: INSUFFICIENT_A_AMOUNT"); require(amountB >= amountBMin, "PancakeRouter: INSUFFICIENT_B_AMOUNT"); } }