From 25be1272ae289c260804eea5bffd7920aee61a63 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 16 Sep 2020 13:35:05 +0800 Subject: [PATCH] update to pancake --- README.md | 11 +- contracts/Migrations.sol | 19 +++ ...swapV2Migrator.sol => PancakeMigrator.sol} | 10 +- ...niswapV2Router02.sol => PancakeRouter.sol} | 140 +++++++++--------- ...swapV2Router01.sol => PancakeRouter01.sol} | 112 +++++++------- contracts/examples/ExampleFlashSwap.sol | 22 +-- contracts/examples/ExampleOracleSimple.sol | 14 +- .../examples/ExampleSlidingWindowOracle.sol | 18 +-- contracts/examples/ExampleSwapToPrice.sol | 12 +- ...wapV2Migrator.sol => IPancakeMigrator.sol} | 2 +- ...wapV2Router01.sol => IPancakeRouter01.sol} | 2 +- ...wapV2Router02.sol => IPancakeRouter02.sol} | 4 +- ...niswapV2Library.sol => PancakeLibrary.sol} | 33 +++-- ...leLibrary.sol => PancakeOracleLibrary.sol} | 10 +- contracts/test/RouterEventEmitter.sol | 14 +- package.json | 12 +- 16 files changed, 225 insertions(+), 210 deletions(-) create mode 100644 contracts/Migrations.sol rename contracts/{UniswapV2Migrator.sol => PancakeMigrator.sol} (89%) rename contracts/{UniswapV2Router02.sol => PancakeRouter.sol} (69%) rename contracts/{UniswapV2Router01.sol => PancakeRouter01.sol} (63%) rename contracts/interfaces/{IUniswapV2Migrator.sol => IPancakeMigrator.sol} (81%) rename contracts/interfaces/{IUniswapV2Router01.sol => IPancakeRouter01.sol} (99%) rename contracts/interfaces/{IUniswapV2Router02.sol => IPancakeRouter02.sol} (93%) rename contracts/libraries/{UniswapV2Library.sol => PancakeLibrary.sol} (72%) rename contracts/libraries/{UniswapV2OracleLibrary.sol => PancakeOracleLibrary.sol} (82%) diff --git a/README.md b/README.md index f60505c..5f3caf0 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,6 @@ -# Uniswap V2 +# Pancake Router -[![Actions Status](https://github.com/Uniswap/uniswap-v2-periphery/workflows/CI/badge.svg)](https://github.com/Uniswap/uniswap-v2-periphery/actions) -[![npm](https://img.shields.io/npm/v/@uniswap/v2-periphery?style=flat-square)](https://npmjs.com/package/@uniswap/v2-periphery) - -In-depth documentation on Uniswap V2 is available at [uniswap.org](https://uniswap.org/docs). - -The built contract artifacts can be browsed via [unpkg.com](https://unpkg.com/browse/@uniswap/v2-periphery@latest/). - -# Local Development +### Bsc-Test The following assumes the use of `node@>=10`. diff --git a/contracts/Migrations.sol b/contracts/Migrations.sol new file mode 100644 index 0000000..6b7bf35 --- /dev/null +++ b/contracts/Migrations.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.25 <0.7.0; + +contract Migrations { + address public owner; + uint public last_completed_migration; + + modifier restricted() { + if (msg.sender == owner) _; + } + + constructor() public { + owner = msg.sender; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } +} diff --git a/contracts/UniswapV2Migrator.sol b/contracts/PancakeMigrator.sol similarity index 89% rename from contracts/UniswapV2Migrator.sol rename to contracts/PancakeMigrator.sol index fcd6354..b05f78e 100644 --- a/contracts/UniswapV2Migrator.sol +++ b/contracts/PancakeMigrator.sol @@ -2,19 +2,19 @@ pragma solidity =0.6.6; import '@uniswap/lib/contracts/libraries/TransferHelper.sol'; -import './interfaces/IUniswapV2Migrator.sol'; +import './interfaces/IPancakeMigrator.sol'; import './interfaces/V1/IUniswapV1Factory.sol'; import './interfaces/V1/IUniswapV1Exchange.sol'; -import './interfaces/IUniswapV2Router01.sol'; +import './interfaces/IPancakeRouter01.sol'; import './interfaces/IERC20.sol'; -contract UniswapV2Migrator is IUniswapV2Migrator { +contract PancakeMigrator is IPancakeMigrator { IUniswapV1Factory immutable factoryV1; - IUniswapV2Router01 immutable router; + IPancakeRouter01 immutable router; constructor(address _factoryV1, address _router) public { factoryV1 = IUniswapV1Factory(_factoryV1); - router = IUniswapV2Router01(_router); + router = IPancakeRouter01(_router); } // needs to accept ETH from any v1 exchange and the router. ideally this could be enforced, as in the router, diff --git a/contracts/UniswapV2Router02.sol b/contracts/PancakeRouter.sol similarity index 69% rename from contracts/UniswapV2Router02.sol rename to contracts/PancakeRouter.sol index c57d4e6..6cdf9c0 100644 --- a/contracts/UniswapV2Router02.sol +++ b/contracts/PancakeRouter.sol @@ -1,22 +1,22 @@ pragma solidity =0.6.6; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakeFactory.sol'; import '@uniswap/lib/contracts/libraries/TransferHelper.sol'; -import './interfaces/IUniswapV2Router02.sol'; -import './libraries/UniswapV2Library.sol'; +import './interfaces/IPancakeRouter02.sol'; +import './libraries/PancakeLibrary.sol'; import './libraries/SafeMath.sol'; import './interfaces/IERC20.sol'; import './interfaces/IWETH.sol'; -contract UniswapV2Router02 is IUniswapV2Router02 { +contract PancakeRouter is IPancakeRouter02 { using SafeMath for uint; address public immutable override factory; address public immutable override WETH; modifier ensure(uint deadline) { - require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED'); + require(deadline >= block.timestamp, 'PancakeRouter: EXPIRED'); _; } @@ -39,21 +39,21 @@ contract UniswapV2Router02 is IUniswapV2Router02 { uint amountBMin ) internal virtual returns (uint amountA, uint amountB) { // create the pair if it doesn't exist yet - if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) { - IUniswapV2Factory(factory).createPair(tokenA, tokenB); + if (IPancakeFactory(factory).getPair(tokenA, tokenB) == address(0)) { + IPancakeFactory(factory).createPair(tokenA, tokenB); } - (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB); + (uint reserveA, uint reserveB) = PancakeLibrary.getReserves(factory, tokenA, tokenB); if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); } else { - uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB); + uint amountBOptimal = PancakeLibrary.quote(amountADesired, reserveA, reserveB); if (amountBOptimal <= amountBDesired) { - require(amountBOptimal >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); + require(amountBOptimal >= amountBMin, 'PancakeRouter: INSUFFICIENT_B_AMOUNT'); (amountA, amountB) = (amountADesired, amountBOptimal); } else { - uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA); + uint amountAOptimal = PancakeLibrary.quote(amountBDesired, reserveB, reserveA); assert(amountAOptimal <= amountADesired); - require(amountAOptimal >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); + require(amountAOptimal >= amountAMin, 'PancakeRouter: INSUFFICIENT_A_AMOUNT'); (amountA, amountB) = (amountAOptimal, amountBDesired); } } @@ -69,10 +69,10 @@ contract UniswapV2Router02 is IUniswapV2Router02 { uint deadline ) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) { (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin); - address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB); TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA); TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB); - liquidity = IUniswapV2Pair(pair).mint(to); + liquidity = IPancakePair(pair).mint(to); } function addLiquidityETH( address token, @@ -90,11 +90,11 @@ contract UniswapV2Router02 is IUniswapV2Router02 { amountTokenMin, amountETHMin ); - address pair = UniswapV2Library.pairFor(factory, token, WETH); + address pair = PancakeLibrary.pairFor(factory, token, WETH); TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken); IWETH(WETH).deposit{value: amountETH}(); assert(IWETH(WETH).transfer(pair, amountETH)); - liquidity = IUniswapV2Pair(pair).mint(to); + liquidity = IPancakePair(pair).mint(to); // refund dust eth, if any if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH); } @@ -109,13 +109,13 @@ contract UniswapV2Router02 is IUniswapV2Router02 { address to, uint deadline ) public virtual override ensure(deadline) returns (uint amountA, uint amountB) { - address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); - IUniswapV2Pair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair - (uint amount0, uint amount1) = IUniswapV2Pair(pair).burn(to); - (address token0,) = UniswapV2Library.sortTokens(tokenA, tokenB); + address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB); + IPancakePair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair + (uint amount0, uint amount1) = IPancakePair(pair).burn(to); + (address token0,) = PancakeLibrary.sortTokens(tokenA, tokenB); (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); - require(amountA >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); - require(amountB >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); + require(amountA >= amountAMin, 'PancakeRouter: INSUFFICIENT_A_AMOUNT'); + require(amountB >= amountBMin, 'PancakeRouter: INSUFFICIENT_B_AMOUNT'); } function removeLiquidityETH( address token, @@ -148,9 +148,9 @@ contract UniswapV2Router02 is IUniswapV2Router02 { uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external virtual override returns (uint amountA, uint amountB) { - address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB); uint value = approveMax ? uint(-1) : liquidity; - IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + IPancakePair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); (amountA, amountB) = removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, to, deadline); } function removeLiquidityETHWithPermit( @@ -162,9 +162,9 @@ contract UniswapV2Router02 is IUniswapV2Router02 { uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external virtual override returns (uint amountToken, uint amountETH) { - address pair = UniswapV2Library.pairFor(factory, token, WETH); + address pair = PancakeLibrary.pairFor(factory, token, WETH); uint value = approveMax ? uint(-1) : liquidity; - IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + IPancakePair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); (amountToken, amountETH) = removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline); } @@ -199,9 +199,9 @@ contract UniswapV2Router02 is IUniswapV2Router02 { uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external virtual override returns (uint amountETH) { - address pair = UniswapV2Library.pairFor(factory, token, WETH); + address pair = PancakeLibrary.pairFor(factory, token, WETH); uint value = approveMax ? uint(-1) : liquidity; - IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + IPancakePair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); amountETH = removeLiquidityETHSupportingFeeOnTransferTokens( token, liquidity, amountTokenMin, amountETHMin, to, deadline ); @@ -212,11 +212,11 @@ contract UniswapV2Router02 is IUniswapV2Router02 { function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual { for (uint i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); - (address token0,) = UniswapV2Library.sortTokens(input, output); + (address token0,) = PancakeLibrary.sortTokens(input, output); uint amountOut = amounts[i + 1]; (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0)); - address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to; - IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)).swap( + address to = i < path.length - 2 ? PancakeLibrary.pairFor(factory, output, path[i + 2]) : _to; + IPancakePair(PancakeLibrary.pairFor(factory, input, output)).swap( amount0Out, amount1Out, to, new bytes(0) ); } @@ -228,10 +228,10 @@ contract UniswapV2Router02 is IUniswapV2Router02 { address to, uint deadline ) external virtual override ensure(deadline) returns (uint[] memory amounts) { - amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); - require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + amounts = PancakeLibrary.getAmountsOut(factory, amountIn, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT'); TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0] ); _swap(amounts, path, to); } @@ -242,10 +242,10 @@ contract UniswapV2Router02 is IUniswapV2Router02 { address to, uint deadline ) external virtual override ensure(deadline) returns (uint[] memory amounts) { - amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); - require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + amounts = PancakeLibrary.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= amountInMax, 'PancakeRouter: EXCESSIVE_INPUT_AMOUNT'); TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0] ); _swap(amounts, path, to); } @@ -257,11 +257,11 @@ contract UniswapV2Router02 is IUniswapV2Router02 { ensure(deadline) returns (uint[] memory amounts) { - require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsOut(factory, msg.value, path); - require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + require(path[0] == WETH, 'PancakeRouter: INVALID_PATH'); + amounts = PancakeLibrary.getAmountsOut(factory, msg.value, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT'); IWETH(WETH).deposit{value: amounts[0]}(); - assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); + assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0])); _swap(amounts, path, to); } function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) @@ -271,11 +271,11 @@ contract UniswapV2Router02 is IUniswapV2Router02 { ensure(deadline) returns (uint[] memory amounts) { - require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); - require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + require(path[path.length - 1] == WETH, 'PancakeRouter: INVALID_PATH'); + amounts = PancakeLibrary.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= amountInMax, 'PancakeRouter: EXCESSIVE_INPUT_AMOUNT'); TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0] ); _swap(amounts, path, address(this)); IWETH(WETH).withdraw(amounts[amounts.length - 1]); @@ -288,11 +288,11 @@ contract UniswapV2Router02 is IUniswapV2Router02 { ensure(deadline) returns (uint[] memory amounts) { - require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); - require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + require(path[path.length - 1] == WETH, 'PancakeRouter: INVALID_PATH'); + amounts = PancakeLibrary.getAmountsOut(factory, amountIn, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT'); TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0] ); _swap(amounts, path, address(this)); IWETH(WETH).withdraw(amounts[amounts.length - 1]); @@ -306,11 +306,11 @@ contract UniswapV2Router02 is IUniswapV2Router02 { ensure(deadline) returns (uint[] memory amounts) { - require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); - require(amounts[0] <= msg.value, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + require(path[0] == WETH, 'PancakeRouter: INVALID_PATH'); + amounts = PancakeLibrary.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= msg.value, 'PancakeRouter: EXCESSIVE_INPUT_AMOUNT'); IWETH(WETH).deposit{value: amounts[0]}(); - assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); + assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0])); _swap(amounts, path, to); // refund dust eth, if any if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]); @@ -321,18 +321,18 @@ contract UniswapV2Router02 is IUniswapV2Router02 { function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to) internal virtual { for (uint i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); - (address token0,) = UniswapV2Library.sortTokens(input, output); - IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)); + (address token0,) = PancakeLibrary.sortTokens(input, output); + IPancakePair pair = IPancakePair(PancakeLibrary.pairFor(factory, input, output)); uint amountInput; uint amountOutput; { // scope to avoid stack too deep errors (uint reserve0, uint reserve1,) = pair.getReserves(); (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountInput = IERC20(input).balanceOf(address(pair)).sub(reserveInput); - amountOutput = UniswapV2Library.getAmountOut(amountInput, reserveInput, reserveOutput); + amountOutput = PancakeLibrary.getAmountOut(amountInput, reserveInput, reserveOutput); } (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); - address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to; + address to = i < path.length - 2 ? PancakeLibrary.pairFor(factory, output, path[i + 2]) : _to; pair.swap(amount0Out, amount1Out, to, new bytes(0)); } } @@ -344,13 +344,13 @@ contract UniswapV2Router02 is IUniswapV2Router02 { uint deadline ) external virtual override ensure(deadline) { TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn + path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amountIn ); uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); _swapSupportingFeeOnTransferTokens(path, to); require( IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin, - 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT' + 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT' ); } function swapExactETHForTokensSupportingFeeOnTransferTokens( @@ -365,15 +365,15 @@ contract UniswapV2Router02 is IUniswapV2Router02 { payable ensure(deadline) { - require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); + require(path[0] == WETH, 'PancakeRouter: INVALID_PATH'); uint amountIn = msg.value; IWETH(WETH).deposit{value: amountIn}(); - assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn)); + assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amountIn)); uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); _swapSupportingFeeOnTransferTokens(path, to); require( IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin, - 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT' + 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT' ); } function swapExactTokensForETHSupportingFeeOnTransferTokens( @@ -388,20 +388,20 @@ contract UniswapV2Router02 is IUniswapV2Router02 { override ensure(deadline) { - require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); + require(path[path.length - 1] == WETH, 'PancakeRouter: INVALID_PATH'); TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn + path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amountIn ); _swapSupportingFeeOnTransferTokens(path, address(this)); uint amountOut = IERC20(WETH).balanceOf(address(this)); - require(amountOut >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + require(amountOut >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT'); IWETH(WETH).withdraw(amountOut); TransferHelper.safeTransferETH(to, amountOut); } // **** LIBRARY FUNCTIONS **** function quote(uint amountA, uint reserveA, uint reserveB) public pure virtual override returns (uint amountB) { - return UniswapV2Library.quote(amountA, reserveA, reserveB); + return PancakeLibrary.quote(amountA, reserveA, reserveB); } function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) @@ -411,7 +411,7 @@ contract UniswapV2Router02 is IUniswapV2Router02 { override returns (uint amountOut) { - return UniswapV2Library.getAmountOut(amountIn, reserveIn, reserveOut); + return PancakeLibrary.getAmountOut(amountIn, reserveIn, reserveOut); } function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) @@ -421,7 +421,7 @@ contract UniswapV2Router02 is IUniswapV2Router02 { override returns (uint amountIn) { - return UniswapV2Library.getAmountIn(amountOut, reserveIn, reserveOut); + return PancakeLibrary.getAmountIn(amountOut, reserveIn, reserveOut); } function getAmountsOut(uint amountIn, address[] memory path) @@ -431,7 +431,7 @@ contract UniswapV2Router02 is IUniswapV2Router02 { override returns (uint[] memory amounts) { - return UniswapV2Library.getAmountsOut(factory, amountIn, path); + return PancakeLibrary.getAmountsOut(factory, amountIn, path); } function getAmountsIn(uint amountOut, address[] memory path) @@ -441,6 +441,6 @@ contract UniswapV2Router02 is IUniswapV2Router02 { override returns (uint[] memory amounts) { - return UniswapV2Library.getAmountsIn(factory, amountOut, path); + return PancakeLibrary.getAmountsIn(factory, amountOut, path); } } diff --git a/contracts/UniswapV2Router01.sol b/contracts/PancakeRouter01.sol similarity index 63% rename from contracts/UniswapV2Router01.sol rename to contracts/PancakeRouter01.sol index 74a4035..2e35f86 100644 --- a/contracts/UniswapV2Router01.sol +++ b/contracts/PancakeRouter01.sol @@ -1,19 +1,19 @@ pragma solidity =0.6.6; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakeFactory.sol'; import '@uniswap/lib/contracts/libraries/TransferHelper.sol'; -import './libraries/UniswapV2Library.sol'; -import './interfaces/IUniswapV2Router01.sol'; +import './libraries/PancakeLibrary.sol'; +import './interfaces/IPancakeRouter01.sol'; import './interfaces/IERC20.sol'; import './interfaces/IWETH.sol'; -contract UniswapV2Router01 is IUniswapV2Router01 { +contract PancakeRouter01 is IPancakeRouter01 { address public immutable override factory; address public immutable override WETH; modifier ensure(uint deadline) { - require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED'); + require(deadline >= block.timestamp, 'PancakeRouter: EXPIRED'); _; } @@ -36,21 +36,21 @@ contract UniswapV2Router01 is IUniswapV2Router01 { uint amountBMin ) private returns (uint amountA, uint amountB) { // create the pair if it doesn't exist yet - if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) { - IUniswapV2Factory(factory).createPair(tokenA, tokenB); + if (IPancakeFactory(factory).getPair(tokenA, tokenB) == address(0)) { + IPancakeFactory(factory).createPair(tokenA, tokenB); } - (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB); + (uint reserveA, uint reserveB) = PancakeLibrary.getReserves(factory, tokenA, tokenB); if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); } else { - uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB); + uint amountBOptimal = PancakeLibrary.quote(amountADesired, reserveA, reserveB); if (amountBOptimal <= amountBDesired) { - require(amountBOptimal >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); + require(amountBOptimal >= amountBMin, 'PancakeRouter: INSUFFICIENT_B_AMOUNT'); (amountA, amountB) = (amountADesired, amountBOptimal); } else { - uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA); + uint amountAOptimal = PancakeLibrary.quote(amountBDesired, reserveB, reserveA); assert(amountAOptimal <= amountADesired); - require(amountAOptimal >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); + require(amountAOptimal >= amountAMin, 'PancakeRouter: INSUFFICIENT_A_AMOUNT'); (amountA, amountB) = (amountAOptimal, amountBDesired); } } @@ -66,10 +66,10 @@ contract UniswapV2Router01 is IUniswapV2Router01 { uint deadline ) external override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) { (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin); - address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB); TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA); TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB); - liquidity = IUniswapV2Pair(pair).mint(to); + liquidity = IPancakePair(pair).mint(to); } function addLiquidityETH( address token, @@ -87,11 +87,11 @@ contract UniswapV2Router01 is IUniswapV2Router01 { amountTokenMin, amountETHMin ); - address pair = UniswapV2Library.pairFor(factory, token, WETH); + address pair = PancakeLibrary.pairFor(factory, token, WETH); TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken); IWETH(WETH).deposit{value: amountETH}(); assert(IWETH(WETH).transfer(pair, amountETH)); - liquidity = IUniswapV2Pair(pair).mint(to); + liquidity = IPancakePair(pair).mint(to); if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH); // refund dust eth, if any } @@ -105,13 +105,13 @@ contract UniswapV2Router01 is IUniswapV2Router01 { address to, uint deadline ) public override ensure(deadline) returns (uint amountA, uint amountB) { - address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); - IUniswapV2Pair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair - (uint amount0, uint amount1) = IUniswapV2Pair(pair).burn(to); - (address token0,) = UniswapV2Library.sortTokens(tokenA, tokenB); + address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB); + IPancakePair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair + (uint amount0, uint amount1) = IPancakePair(pair).burn(to); + (address token0,) = PancakeLibrary.sortTokens(tokenA, tokenB); (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); - require(amountA >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); - require(amountB >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); + require(amountA >= amountAMin, 'PancakeRouter: INSUFFICIENT_A_AMOUNT'); + require(amountB >= amountBMin, 'PancakeRouter: INSUFFICIENT_B_AMOUNT'); } function removeLiquidityETH( address token, @@ -144,9 +144,9 @@ contract UniswapV2Router01 is IUniswapV2Router01 { uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external override returns (uint amountA, uint amountB) { - address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB); uint value = approveMax ? uint(-1) : liquidity; - IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + IPancakePair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); (amountA, amountB) = removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, to, deadline); } function removeLiquidityETHWithPermit( @@ -158,9 +158,9 @@ contract UniswapV2Router01 is IUniswapV2Router01 { uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external override returns (uint amountToken, uint amountETH) { - address pair = UniswapV2Library.pairFor(factory, token, WETH); + address pair = PancakeLibrary.pairFor(factory, token, WETH); uint value = approveMax ? uint(-1) : liquidity; - IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + IPancakePair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); (amountToken, amountETH) = removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline); } @@ -169,11 +169,11 @@ contract UniswapV2Router01 is IUniswapV2Router01 { function _swap(uint[] memory amounts, address[] memory path, address _to) private { for (uint i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); - (address token0,) = UniswapV2Library.sortTokens(input, output); + (address token0,) = PancakeLibrary.sortTokens(input, output); uint amountOut = amounts[i + 1]; (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0)); - address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to; - IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)).swap(amount0Out, amount1Out, to, new bytes(0)); + address to = i < path.length - 2 ? PancakeLibrary.pairFor(factory, output, path[i + 2]) : _to; + IPancakePair(PancakeLibrary.pairFor(factory, input, output)).swap(amount0Out, amount1Out, to, new bytes(0)); } } function swapExactTokensForTokens( @@ -183,9 +183,9 @@ contract UniswapV2Router01 is IUniswapV2Router01 { address to, uint deadline ) external override ensure(deadline) returns (uint[] memory amounts) { - amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); - require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); - TransferHelper.safeTransferFrom(path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]); + amounts = PancakeLibrary.getAmountsOut(factory, amountIn, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT'); + TransferHelper.safeTransferFrom(path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]); _swap(amounts, path, to); } function swapTokensForExactTokens( @@ -195,9 +195,9 @@ contract UniswapV2Router01 is IUniswapV2Router01 { address to, uint deadline ) external override ensure(deadline) returns (uint[] memory amounts) { - amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); - require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); - TransferHelper.safeTransferFrom(path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]); + amounts = PancakeLibrary.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= amountInMax, 'PancakeRouter: EXCESSIVE_INPUT_AMOUNT'); + TransferHelper.safeTransferFrom(path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]); _swap(amounts, path, to); } function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) @@ -207,11 +207,11 @@ contract UniswapV2Router01 is IUniswapV2Router01 { ensure(deadline) returns (uint[] memory amounts) { - require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsOut(factory, msg.value, path); - require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + require(path[0] == WETH, 'PancakeRouter: INVALID_PATH'); + amounts = PancakeLibrary.getAmountsOut(factory, msg.value, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT'); IWETH(WETH).deposit{value: amounts[0]}(); - assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); + assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0])); _swap(amounts, path, to); } function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) @@ -220,10 +220,10 @@ contract UniswapV2Router01 is IUniswapV2Router01 { ensure(deadline) returns (uint[] memory amounts) { - require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); - require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); - TransferHelper.safeTransferFrom(path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]); + require(path[path.length - 1] == WETH, 'PancakeRouter: INVALID_PATH'); + amounts = PancakeLibrary.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= amountInMax, 'PancakeRouter: EXCESSIVE_INPUT_AMOUNT'); + TransferHelper.safeTransferFrom(path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]); _swap(amounts, path, address(this)); IWETH(WETH).withdraw(amounts[amounts.length - 1]); TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); @@ -234,10 +234,10 @@ contract UniswapV2Router01 is IUniswapV2Router01 { ensure(deadline) returns (uint[] memory amounts) { - require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); - require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); - TransferHelper.safeTransferFrom(path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]); + require(path[path.length - 1] == WETH, 'PancakeRouter: INVALID_PATH'); + amounts = PancakeLibrary.getAmountsOut(factory, amountIn, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT'); + TransferHelper.safeTransferFrom(path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]); _swap(amounts, path, address(this)); IWETH(WETH).withdraw(amounts[amounts.length - 1]); TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); @@ -249,32 +249,32 @@ contract UniswapV2Router01 is IUniswapV2Router01 { ensure(deadline) returns (uint[] memory amounts) { - require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); - require(amounts[0] <= msg.value, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + require(path[0] == WETH, 'PancakeRouter: INVALID_PATH'); + amounts = PancakeLibrary.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= msg.value, 'PancakeRouter: EXCESSIVE_INPUT_AMOUNT'); IWETH(WETH).deposit{value: amounts[0]}(); - assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); + assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0])); _swap(amounts, path, to); if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]); // refund dust eth, if any } function quote(uint amountA, uint reserveA, uint reserveB) public pure override returns (uint amountB) { - return UniswapV2Library.quote(amountA, reserveA, reserveB); + return PancakeLibrary.quote(amountA, reserveA, reserveB); } function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) public pure override returns (uint amountOut) { - return UniswapV2Library.getAmountOut(amountIn, reserveIn, reserveOut); + return PancakeLibrary.getAmountOut(amountIn, reserveIn, reserveOut); } function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public pure override returns (uint amountIn) { - return UniswapV2Library.getAmountOut(amountOut, reserveIn, reserveOut); + return PancakeLibrary.getAmountOut(amountOut, reserveIn, reserveOut); } function getAmountsOut(uint amountIn, address[] memory path) public view override returns (uint[] memory amounts) { - return UniswapV2Library.getAmountsOut(factory, amountIn, path); + return PancakeLibrary.getAmountsOut(factory, amountIn, path); } function getAmountsIn(uint amountOut, address[] memory path) public view override returns (uint[] memory amounts) { - return UniswapV2Library.getAmountsIn(factory, amountOut, path); + return PancakeLibrary.getAmountsIn(factory, amountOut, path); } } diff --git a/contracts/examples/ExampleFlashSwap.sol b/contracts/examples/ExampleFlashSwap.sol index 17b2781..f09d54e 100644 --- a/contracts/examples/ExampleFlashSwap.sol +++ b/contracts/examples/ExampleFlashSwap.sol @@ -1,15 +1,15 @@ pragma solidity =0.6.6; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Callee.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakeCallee.sol'; -import '../libraries/UniswapV2Library.sol'; +import '../libraries/PancakeLibrary.sol'; import '../interfaces/V1/IUniswapV1Factory.sol'; import '../interfaces/V1/IUniswapV1Exchange.sol'; -import '../interfaces/IUniswapV2Router01.sol'; +import '../interfaces/IPancakeRouter01.sol'; import '../interfaces/IERC20.sol'; import '../interfaces/IWETH.sol'; -contract ExampleFlashSwap is IUniswapV2Callee { +contract ExampleFlashSwap is IPancakeCallee { IUniswapV1Factory immutable factoryV1; address immutable factory; IWETH immutable WETH; @@ -17,7 +17,7 @@ contract ExampleFlashSwap is IUniswapV2Callee { constructor(address _factory, address _factoryV1, address router) public { factoryV1 = IUniswapV1Factory(_factoryV1); factory = _factory; - WETH = IWETH(IUniswapV2Router01(router).WETH()); + WETH = IWETH(IPancakeRouter01(router).WETH()); } // needs to accept ETH from any V1 exchange and WETH. ideally this could be enforced, as in the router, @@ -25,14 +25,14 @@ contract ExampleFlashSwap is IUniswapV2Callee { receive() external payable {} // gets tokens/WETH via a V2 flash swap, swaps for the ETH/tokens on V1, repays V2, and keeps the rest! - function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external override { + function pancakeCall(address sender, uint amount0, uint amount1, bytes calldata data) external override { address[] memory path = new address[](2); uint amountToken; uint amountETH; { // scope for token{0,1}, avoids stack too deep errors - address token0 = IUniswapV2Pair(msg.sender).token0(); - address token1 = IUniswapV2Pair(msg.sender).token1(); - assert(msg.sender == UniswapV2Library.pairFor(factory, token0, token1)); // ensure that msg.sender is actually a V2 pair + address token0 = IPancakePair(msg.sender).token0(); + address token1 = IPancakePair(msg.sender).token1(); + assert(msg.sender == PancakeLibrary.pairFor(factory, token0, token1)); // ensure that msg.sender is actually a V2 pair assert(amount0 == 0 || amount1 == 0); // this strategy is unidirectional path[0] = amount0 == 0 ? token0 : token1; path[1] = amount0 == 0 ? token1 : token0; @@ -48,7 +48,7 @@ contract ExampleFlashSwap is IUniswapV2Callee { (uint minETH) = abi.decode(data, (uint)); // slippage parameter for V1, passed in by caller token.approve(address(exchangeV1), amountToken); uint amountReceived = exchangeV1.tokenToEthSwapInput(amountToken, minETH, uint(-1)); - uint amountRequired = UniswapV2Library.getAmountsIn(factory, amountToken, path)[0]; + uint amountRequired = PancakeLibrary.getAmountsIn(factory, amountToken, path)[0]; assert(amountReceived > amountRequired); // fail if we didn't get enough ETH back to repay our flash loan WETH.deposit{value: amountRequired}(); assert(WETH.transfer(msg.sender, amountRequired)); // return WETH to V2 pair @@ -58,7 +58,7 @@ contract ExampleFlashSwap is IUniswapV2Callee { (uint minTokens) = abi.decode(data, (uint)); // slippage parameter for V1, passed in by caller WETH.withdraw(amountETH); uint amountReceived = exchangeV1.ethToTokenSwapInput{value: amountETH}(minTokens, uint(-1)); - uint amountRequired = UniswapV2Library.getAmountsIn(factory, amountETH, path)[0]; + uint amountRequired = PancakeLibrary.getAmountsIn(factory, amountETH, path)[0]; assert(amountReceived > amountRequired); // fail if we didn't get enough tokens back to repay our flash loan assert(token.transfer(msg.sender, amountRequired)); // return tokens to V2 pair assert(token.transfer(sender, amountReceived - amountRequired)); // keep the rest! (tokens) diff --git a/contracts/examples/ExampleOracleSimple.sol b/contracts/examples/ExampleOracleSimple.sol index 6ab916f..b8f806b 100644 --- a/contracts/examples/ExampleOracleSimple.sol +++ b/contracts/examples/ExampleOracleSimple.sol @@ -1,11 +1,11 @@ pragma solidity =0.6.6; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol'; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakeFactory.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakePair.sol'; import '@uniswap/lib/contracts/libraries/FixedPoint.sol'; -import '../libraries/UniswapV2OracleLibrary.sol'; -import '../libraries/UniswapV2Library.sol'; +import '../libraries/PancakeOracleLibrary.sol'; +import '../libraries/PancakeLibrary.sol'; // fixed window oracle that recomputes the average price for the entire period once every period // note that the price average is only guaranteed to be over at least 1 period, but may be over a longer period @@ -14,7 +14,7 @@ contract ExampleOracleSimple { uint public constant PERIOD = 24 hours; - IUniswapV2Pair immutable pair; + IPancakePair immutable pair; address public immutable token0; address public immutable token1; @@ -25,7 +25,7 @@ contract ExampleOracleSimple { FixedPoint.uq112x112 public price1Average; constructor(address factory, address tokenA, address tokenB) public { - IUniswapV2Pair _pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, tokenA, tokenB)); + IPancakePair _pair = IPancakePair(PancakeLibrary.pairFor(factory, tokenA, tokenB)); pair = _pair; token0 = _pair.token0(); token1 = _pair.token1(); @@ -39,7 +39,7 @@ contract ExampleOracleSimple { function update() external { (uint price0Cumulative, uint price1Cumulative, uint32 blockTimestamp) = - UniswapV2OracleLibrary.currentCumulativePrices(address(pair)); + PancakeOracleLibrary.currentCumulativePrices(address(pair)); uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired // ensure that at least one full period has passed since the last update diff --git a/contracts/examples/ExampleSlidingWindowOracle.sol b/contracts/examples/ExampleSlidingWindowOracle.sol index 1b8af30..cc73109 100644 --- a/contracts/examples/ExampleSlidingWindowOracle.sol +++ b/contracts/examples/ExampleSlidingWindowOracle.sol @@ -1,12 +1,12 @@ pragma solidity =0.6.6; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol'; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakeFactory.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakePair.sol'; import '@uniswap/lib/contracts/libraries/FixedPoint.sol'; import '../libraries/SafeMath.sol'; -import '../libraries/UniswapV2Library.sol'; -import '../libraries/UniswapV2OracleLibrary.sol'; +import '../libraries/PancakeLibrary.sol'; +import '../libraries/PancakeOracleLibrary.sol'; // sliding window oracle that uses observations collected over a window to provide moving price averages in the past // `windowSize` with a precision of `windowSize / granularity` @@ -67,7 +67,7 @@ contract ExampleSlidingWindowOracle { // update the cumulative price for the observation at the current timestamp. each observation is updated at most // once per epoch period. function update(address tokenA, address tokenB) external { - address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB); // populate the array with empty observations (first call only) for (uint i = pairObservations[pair].length; i < granularity; i++) { @@ -81,7 +81,7 @@ contract ExampleSlidingWindowOracle { // we only want to commit updates once per period (i.e. windowSize / granularity) uint timeElapsed = block.timestamp - observation.timestamp; if (timeElapsed > periodSize) { - (uint price0Cumulative, uint price1Cumulative,) = UniswapV2OracleLibrary.currentCumulativePrices(pair); + (uint price0Cumulative, uint price1Cumulative,) = PancakeOracleLibrary.currentCumulativePrices(pair); observation.timestamp = block.timestamp; observation.price0Cumulative = price0Cumulative; observation.price1Cumulative = price1Cumulative; @@ -105,7 +105,7 @@ contract ExampleSlidingWindowOracle { // range [now - [windowSize, windowSize - periodSize * 2], now] // update must have been called for the bucket corresponding to timestamp `now - windowSize` function consult(address tokenIn, uint amountIn, address tokenOut) external view returns (uint amountOut) { - address pair = UniswapV2Library.pairFor(factory, tokenIn, tokenOut); + address pair = PancakeLibrary.pairFor(factory, tokenIn, tokenOut); Observation storage firstObservation = getFirstObservationInWindow(pair); uint timeElapsed = block.timestamp - firstObservation.timestamp; @@ -113,8 +113,8 @@ contract ExampleSlidingWindowOracle { // should never happen. require(timeElapsed >= windowSize - periodSize * 2, 'SlidingWindowOracle: UNEXPECTED_TIME_ELAPSED'); - (uint price0Cumulative, uint price1Cumulative,) = UniswapV2OracleLibrary.currentCumulativePrices(pair); - (address token0,) = UniswapV2Library.sortTokens(tokenIn, tokenOut); + (uint price0Cumulative, uint price1Cumulative,) = PancakeOracleLibrary.currentCumulativePrices(pair); + (address token0,) = PancakeLibrary.sortTokens(tokenIn, tokenOut); if (token0 == tokenIn) { return computeAmountOut(firstObservation.price0Cumulative, price0Cumulative, timeElapsed, amountIn); diff --git a/contracts/examples/ExampleSwapToPrice.sol b/contracts/examples/ExampleSwapToPrice.sol index e169bce..f370659 100644 --- a/contracts/examples/ExampleSwapToPrice.sol +++ b/contracts/examples/ExampleSwapToPrice.sol @@ -1,21 +1,21 @@ pragma solidity =0.6.6; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakePair.sol'; import '@uniswap/lib/contracts/libraries/Babylonian.sol'; import '@uniswap/lib/contracts/libraries/TransferHelper.sol'; import '../interfaces/IERC20.sol'; -import '../interfaces/IUniswapV2Router01.sol'; +import '../interfaces/IPancakeRouter01.sol'; import '../libraries/SafeMath.sol'; -import '../libraries/UniswapV2Library.sol'; +import '../libraries/PancakeLibrary.sol'; contract ExampleSwapToPrice { using SafeMath for uint256; - IUniswapV2Router01 public immutable router; + IPancakeRouter01 public immutable router; address public immutable factory; - constructor(address factory_, IUniswapV2Router01 router_) public { + constructor(address factory_, IPancakeRouter01 router_) public { factory = factory_; router = router_; } @@ -62,7 +62,7 @@ contract ExampleSwapToPrice { bool aToB; uint256 amountIn; { - (uint256 reserveA, uint256 reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB); + (uint256 reserveA, uint256 reserveB) = PancakeLibrary.getReserves(factory, tokenA, tokenB); (aToB, amountIn) = computeProfitMaximizingTrade( truePriceTokenA, truePriceTokenB, reserveA, reserveB diff --git a/contracts/interfaces/IUniswapV2Migrator.sol b/contracts/interfaces/IPancakeMigrator.sol similarity index 81% rename from contracts/interfaces/IUniswapV2Migrator.sol rename to contracts/interfaces/IPancakeMigrator.sol index 723e348..868b644 100644 --- a/contracts/interfaces/IUniswapV2Migrator.sol +++ b/contracts/interfaces/IPancakeMigrator.sol @@ -1,5 +1,5 @@ pragma solidity >=0.5.0; -interface IUniswapV2Migrator { +interface IPancakeMigrator { function migrate(address token, uint amountTokenMin, uint amountETHMin, address to, uint deadline) external; } diff --git a/contracts/interfaces/IUniswapV2Router01.sol b/contracts/interfaces/IPancakeRouter01.sol similarity index 99% rename from contracts/interfaces/IUniswapV2Router01.sol rename to contracts/interfaces/IPancakeRouter01.sol index 4619967..032a2c4 100644 --- a/contracts/interfaces/IUniswapV2Router01.sol +++ b/contracts/interfaces/IPancakeRouter01.sol @@ -1,6 +1,6 @@ pragma solidity >=0.6.2; -interface IUniswapV2Router01 { +interface IPancakeRouter01 { function factory() external pure returns (address); function WETH() external pure returns (address); diff --git a/contracts/interfaces/IUniswapV2Router02.sol b/contracts/interfaces/IPancakeRouter02.sol similarity index 93% rename from contracts/interfaces/IUniswapV2Router02.sol rename to contracts/interfaces/IPancakeRouter02.sol index 1fc7b0a..a5a1a8b 100644 --- a/contracts/interfaces/IUniswapV2Router02.sol +++ b/contracts/interfaces/IPancakeRouter02.sol @@ -1,8 +1,8 @@ pragma solidity >=0.6.2; -import './IUniswapV2Router01.sol'; +import './IPancakeRouter01.sol'; -interface IUniswapV2Router02 is IUniswapV2Router01 { +interface IPancakeRouter02 is IPancakeRouter01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, diff --git a/contracts/libraries/UniswapV2Library.sol b/contracts/libraries/PancakeLibrary.sol similarity index 72% rename from contracts/libraries/UniswapV2Library.sol rename to contracts/libraries/PancakeLibrary.sol index 107fb2e..24e87e7 100644 --- a/contracts/libraries/UniswapV2Library.sol +++ b/contracts/libraries/PancakeLibrary.sol @@ -1,17 +1,17 @@ pragma solidity >=0.5.0; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakePair.sol'; import "./SafeMath.sol"; -library UniswapV2Library { +library PancakeLibrary { using SafeMath for uint; // returns sorted token addresses, used to handle return values from pairs sorted in this order function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { - require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES'); + require(tokenA != tokenB, 'PancakeLibrary: IDENTICAL_ADDRESSES'); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); - require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS'); + require(token0 != address(0), 'PancakeLibrary: ZERO_ADDRESS'); } // calculates the CREATE2 address for a pair without making any external calls @@ -21,29 +21,30 @@ library UniswapV2Library { hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), - hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash + hex'b01f877cddbaa1bbfb44c31b8b90c4829b8cb72549c5b90f8fef5437ebab0d2e' // init code hash )))); } // fetches and sorts the reserves for a pair function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) { (address token0,) = sortTokens(tokenA, tokenB); - (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves(); + pairFor(factory, tokenA, tokenB); + (uint reserve0, uint reserve1,) = IPancakePair(pairFor(factory, tokenA, tokenB)).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { - require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT'); - require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); + require(amountA > 0, 'PancakeLibrary: INSUFFICIENT_AMOUNT'); + require(reserveA > 0 && reserveB > 0, 'PancakeLibrary: INSUFFICIENT_LIQUIDITY'); amountB = amountA.mul(reserveB) / reserveA; } // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { - require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT'); - require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); - uint amountInWithFee = amountIn.mul(997); + require(amountIn > 0, 'PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT'); + require(reserveIn > 0 && reserveOut > 0, 'PancakeLibrary: INSUFFICIENT_LIQUIDITY'); + uint amountInWithFee = amountIn.mul(998); uint numerator = amountInWithFee.mul(reserveOut); uint denominator = reserveIn.mul(1000).add(amountInWithFee); amountOut = numerator / denominator; @@ -51,16 +52,16 @@ library UniswapV2Library { // given an output amount of an asset and pair reserves, returns a required input amount of the other asset function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) { - require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT'); - require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); + require(amountOut > 0, 'PancakeLibrary: INSUFFICIENT_OUTPUT_AMOUNT'); + require(reserveIn > 0 && reserveOut > 0, 'PancakeLibrary: INSUFFICIENT_LIQUIDITY'); uint numerator = reserveIn.mul(amountOut).mul(1000); - uint denominator = reserveOut.sub(amountOut).mul(997); + uint denominator = reserveOut.sub(amountOut).mul(998); amountIn = (numerator / denominator).add(1); } // performs chained getAmountOut calculations on any number of pairs function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) { - require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); + require(path.length >= 2, 'PancakeLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[0] = amountIn; for (uint i; i < path.length - 1; i++) { @@ -71,7 +72,7 @@ library UniswapV2Library { // performs chained getAmountIn calculations on any number of pairs function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) { - require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); + require(path.length >= 2, 'PancakeLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[amounts.length - 1] = amountOut; for (uint i = path.length - 1; i > 0; i--) { diff --git a/contracts/libraries/UniswapV2OracleLibrary.sol b/contracts/libraries/PancakeOracleLibrary.sol similarity index 82% rename from contracts/libraries/UniswapV2OracleLibrary.sol rename to contracts/libraries/PancakeOracleLibrary.sol index 4cff017..318c242 100644 --- a/contracts/libraries/UniswapV2OracleLibrary.sol +++ b/contracts/libraries/PancakeOracleLibrary.sol @@ -1,10 +1,10 @@ pragma solidity >=0.5.0; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; +import '@uniswap/v2-core/contracts/interfaces/IPancakePair.sol'; import '@uniswap/lib/contracts/libraries/FixedPoint.sol'; // library with helper methods for oracles that are concerned with computing average prices -library UniswapV2OracleLibrary { +library PancakeOracleLibrary { using FixedPoint for *; // helper function that returns the current block timestamp within the range of uint32, i.e. [0, 2**32 - 1] @@ -17,11 +17,11 @@ library UniswapV2OracleLibrary { address pair ) internal view returns (uint price0Cumulative, uint price1Cumulative, uint32 blockTimestamp) { blockTimestamp = currentBlockTimestamp(); - price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast(); - price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast(); + price0Cumulative = IPancakePair(pair).price0CumulativeLast(); + price1Cumulative = IPancakePair(pair).price1CumulativeLast(); // if time has elapsed since the last update on the pair, mock the accumulated price values - (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IUniswapV2Pair(pair).getReserves(); + (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IPancakePair(pair).getReserves(); if (blockTimestampLast != blockTimestamp) { // subtraction overflow is desired uint32 timeElapsed = blockTimestamp - blockTimestampLast; diff --git a/contracts/test/RouterEventEmitter.sol b/contracts/test/RouterEventEmitter.sol index 319af12..a534fff 100644 --- a/contracts/test/RouterEventEmitter.sol +++ b/contracts/test/RouterEventEmitter.sol @@ -1,6 +1,6 @@ pragma solidity =0.6.6; -import '../interfaces/IUniswapV2Router01.sol'; +import '../interfaces/IPancakeRouter01.sol'; contract RouterEventEmitter { event Amounts(uint[] amounts); @@ -16,7 +16,7 @@ contract RouterEventEmitter { uint deadline ) external { (bool success, bytes memory returnData) = router.delegatecall(abi.encodeWithSelector( - IUniswapV2Router01(router).swapExactTokensForTokens.selector, amountIn, amountOutMin, path, to, deadline + IPancakeRouter01(router).swapExactTokensForTokens.selector, amountIn, amountOutMin, path, to, deadline )); assert(success); emit Amounts(abi.decode(returnData, (uint[]))); @@ -31,7 +31,7 @@ contract RouterEventEmitter { uint deadline ) external { (bool success, bytes memory returnData) = router.delegatecall(abi.encodeWithSelector( - IUniswapV2Router01(router).swapTokensForExactTokens.selector, amountOut, amountInMax, path, to, deadline + IPancakeRouter01(router).swapTokensForExactTokens.selector, amountOut, amountInMax, path, to, deadline )); assert(success); emit Amounts(abi.decode(returnData, (uint[]))); @@ -45,7 +45,7 @@ contract RouterEventEmitter { uint deadline ) external payable { (bool success, bytes memory returnData) = router.delegatecall(abi.encodeWithSelector( - IUniswapV2Router01(router).swapExactETHForTokens.selector, amountOutMin, path, to, deadline + IPancakeRouter01(router).swapExactETHForTokens.selector, amountOutMin, path, to, deadline )); assert(success); emit Amounts(abi.decode(returnData, (uint[]))); @@ -60,7 +60,7 @@ contract RouterEventEmitter { uint deadline ) external { (bool success, bytes memory returnData) = router.delegatecall(abi.encodeWithSelector( - IUniswapV2Router01(router).swapTokensForExactETH.selector, amountOut, amountInMax, path, to, deadline + IPancakeRouter01(router).swapTokensForExactETH.selector, amountOut, amountInMax, path, to, deadline )); assert(success); emit Amounts(abi.decode(returnData, (uint[]))); @@ -75,7 +75,7 @@ contract RouterEventEmitter { uint deadline ) external { (bool success, bytes memory returnData) = router.delegatecall(abi.encodeWithSelector( - IUniswapV2Router01(router).swapExactTokensForETH.selector, amountIn, amountOutMin, path, to, deadline + IPancakeRouter01(router).swapExactTokensForETH.selector, amountIn, amountOutMin, path, to, deadline )); assert(success); emit Amounts(abi.decode(returnData, (uint[]))); @@ -89,7 +89,7 @@ contract RouterEventEmitter { uint deadline ) external payable { (bool success, bytes memory returnData) = router.delegatecall(abi.encodeWithSelector( - IUniswapV2Router01(router).swapETHForExactTokens.selector, amountOut, path, to, deadline + IPancakeRouter01(router).swapETHForExactTokens.selector, amountOut, path, to, deadline )); assert(success); emit Amounts(abi.decode(returnData, (uint[]))); diff --git a/package.json b/package.json index 5b8bb78..2cdd6dc 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,14 @@ { - "name": "@uniswap/v2-periphery", + "name": "pancake/periphery", "version": "1.1.0-beta.0", - "description": "🎚 Peripheral smart contracts for interacting with Uniswap V2", + "description": "🎚 Peripheral smart contracts for interacting with pancake", "engines": { "node": ">=10" }, - "homepage": "https://uniswap.org", + "homepage": "https://pancakeswap.finance", "repository": { "type": "git", - "url": "https://github.com/Uniswap/uniswap-v2-periphery" + "url": "https://github.com/pancakeswap/pancake-swap-periphery.git" }, "files": [ "build", @@ -16,7 +16,9 @@ ], "dependencies": { "@uniswap/lib": "1.1.1", - "@uniswap/v2-core": "1.0.0" + "@uniswap/v2-core": "^1.0.1", + "truffle-hdwallet-provider": "^1.0.17", + "truffle-plugin-verify": "^0.4.0" }, "devDependencies": { "@types/chai": "^4.2.6",