Skip to content

Commit

Permalink
uniswap v3 pair
Browse files Browse the repository at this point in the history
  • Loading branch information
diwu1989 committed May 8, 2022
1 parent b912498 commit 2068ac3
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 60 deletions.
24 changes: 12 additions & 12 deletions contracts/interfaces/uniswap/Quoter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ library Quoter {
Slot0 memory slot0Start;
(
slot0Start.sqrtPriceX96,
slot0Start.tick, // uint16 observationIndex, // uint16 observationCardinality, // uint16 observationCardinalityNext,
,
,
,
slot0Start.tick,
, // uint16 observationIndex
, // uint16 observationCardinality
, // uint16 observationCardinalityNext
slot0Start.feeProtocol,
// bool unlocked

Expand Down Expand Up @@ -186,14 +186,14 @@ library Quoter {
(
,
// uint128 liquidityGross,
int128 liquidityNet, // uint256 feeGrowthOutside0X128, // uint256 feeGrowthOutside1X128, // int56 tickCumulativeOutside, // uint160 secondsPerLiquidityOutsideX128, // uint32 secondsOutside,
,
,
,
,
,

) = // bool initialized
int128 liquidityNet,
, // uint256 feeGrowthOutside0X128
, // uint256 feeGrowthOutside1X128
, // int56 tickCumulativeOutside
, // uint160 secondsPerLiquidityOutsideX128
, // uint32 secondsOutside
// bool initialized
) =
pool.ticks(step.tickNext);

// if we're moving leftward, we interpret liquidityNet as the opposite sign
Expand Down
94 changes: 46 additions & 48 deletions contracts/swappa/PairUniswapV3.sol
Original file line number Diff line number Diff line change
@@ -1,63 +1,61 @@
// SPDX-License-Identifier: MIT
pragma solidity ~0.6.8;
pragma solidity >=0.4.0 <0.8.0;

import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "../interfaces/uniswap/IUniswapV2Pair.sol";
import "../interfaces/uniswap/IUniswapV3Pool.sol";
import "../interfaces/uniswap/Quoter.sol";
import "../interfaces/uniswap/SafeCast.sol";
import "../interfaces/uniswap/TickMath.sol";
import "./ISwappaPairV1.sol";

contract PairUniswapV3 is ISwappaPairV1 {
using SafeMath for uint;
using SafeCast for uint;

function swap(
address input,
address output,
address to,
bytes calldata data
) external override {
(address pairAddr, uint feeK) = parseData(data);
uint inputAmount = ERC20(input).balanceOf(address(this));
require(
ERC20(input).transfer(pairAddr, inputAmount),
"PairUniswapV2: transfer failed!");
IUniswapV2Pair pair = IUniswapV2Pair(pairAddr);
(uint reserve0, uint reserve1,) = pair.getReserves();
if (pair.token0() == input) {
uint outputAmount = getAmountOut(inputAmount, reserve0, reserve1, feeK);
pair.swap(0, outputAmount, to, new bytes(0));
} else {
uint outputAmount = getAmountOut(inputAmount, reserve1, reserve0, feeK);
pair.swap(outputAmount, 0, to, new bytes(0));
}
}

function parseData(bytes memory data) private pure returns (address pairAddr, uint fee) {
require(data.length == 21, "PairUniswapV2: invalid data!");
fee = uint(1000).sub(uint8(data[20]));
assembly {
pairAddr := mload(add(data, 20))
function swap(
address input,
address output,
address to,
bytes calldata data
) external override {
address pairAddr = parseData(data);
uint inputAmount = ERC20(input).balanceOf(address(this));
require(
ERC20(input).transfer(pairAddr, inputAmount),
"PairUniswapV3: transfer failed!");
IUniswapV3Pool pair = IUniswapV3Pool(pairAddr);
bool zeroForOne = pair.token0() == input;
pair.swap(
to,
zeroForOne,
inputAmount.toInt256(),
zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1,
new bytes(0));
}
}

function getOutputAmount(
address input,
address output,
uint amountIn,
bytes calldata data
) external view override returns (uint amountOut) {
(address pairAddr, uint feeK) = parseData(data);
IUniswapV2Pair pair = IUniswapV2Pair(pairAddr);
(uint reserve0, uint reserve1,) = pair.getReserves();
(uint reserveIn, uint reserveOut) = pair.token0() == input ? (reserve0, reserve1) : (reserve1, reserve0);
return getAmountOut(amountIn, reserveIn, reserveOut, feeK);
}
function parseData(bytes memory data) private pure returns (address pairAddr) {
require(data.length == 20, "PairUniswapV3: invalid data!");
assembly {
pairAddr := mload(add(data, 20))
}
}

function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut, uint feeK) internal pure returns (uint amountOut) {
uint amountInWithFee = amountIn.mul(feeK);
uint numerator = amountInWithFee.mul(reserveOut);
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
function getOutputAmount(
address input,
address output,
uint amountIn,
bytes calldata data
) external view override returns (uint amountOut) {
address pairAddr = parseData(data);
IUniswapV3Pool pair = IUniswapV3Pool(pairAddr);
bool zeroForOne = pair.token0() == input;
// amount0, amount1 are delta of the pair reserves
(int256 amount0, int256 amount1) = Quoter.quote(
pair,
zeroForOne,
amountIn.toInt256(),
zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1);
return zeroForOne ? uint256(-amount1) : uint256(-amount0);
}
}

0 comments on commit 2068ac3

Please sign in to comment.