Skip to content
This repository was archived by the owner on Feb 25, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 32 additions & 32 deletions src/routes/uniswap.route.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import BigNumber from 'bignumber.js';
import { ethers } from 'ethers';
import express from 'express';

Expand All @@ -11,7 +10,6 @@ const debug = require('debug')('router')
const router = express.Router()
const uniswap = new Uniswap(process.env.ETHEREUM_CHAIN)

const denomMultiplier = 1e18
const swapMoreThanMaxPriceError = 'Price too high'
const swapLessThanMaxPriceError = 'Price too low'

Expand Down Expand Up @@ -53,25 +51,27 @@ router.post('/sell-price', async (req, res) => {
const paramData = getParamData(req.body)
const baseTokenAddress = paramData.base
const quoteTokenAddress = paramData.quote
const amount = paramData.amount

try {
// fetch the optimal pool mix from uniswap
const route = await uniswap.fetch_route(
const { trade, expectedOut} = await uniswap.priceSwapIn(
baseTokenAddress, // tokenIn is base asset
quoteTokenAddress, // tokenOut is quote asset
amount
)

if (route != null) {
if (trade !== null && expectedOut !== null) {
res.status(200).json({
network: uniswap.network,
timestamp: initTime,
latency: latency(initTime, Date.now()),
base: baseTokenAddress,
quote: quoteTokenAddress,
amount: parseFloat(paramData.amount),
expectedOut: parseFloat(paramData.amount * route.midPrice.toSignificant(8)),
price: route.midPrice.toSignificant(8),
swaps: route.path,
amount: amount,
expectedOut: expectedOut.toSignificant(8),
price: trade.executionPrice.toSignificant(8),
trade: trade,
})
} else { // no pool available
res.status(200).json({
Expand All @@ -80,6 +80,7 @@ router.post('/sell-price', async (req, res) => {
})
}
} catch (err) {
debug(err)
let reason
err.reason ? reason = err.reason : reason = statusMessages.operation_error
res.status(500).json({
Expand All @@ -103,24 +104,26 @@ router.post('/buy-price', async (req, res) => {
const paramData = getParamData(req.body)
const baseTokenAddress = paramData.base
const quoteTokenAddress = paramData.quote
const amount = paramData.amount

try {
// fetch the optimal pool mix from uniswap
const route = await uniswap.fetch_route(
const { trade, expectedIn } = await uniswap.priceSwapOut(
quoteTokenAddress, // tokenIn is quote asset
baseTokenAddress, // tokenOut is base asset
amount
)
if (route != null) {
if (trade !== null && expectedIn !== null) {
res.status(200).json({
network: uniswap.network,
timestamp: initTime,
latency: latency(initTime, Date.now()),
base: baseTokenAddress,
quote: quoteTokenAddress,
amount: parseFloat(paramData.amount),
expectedIn: parseFloat(paramData.amount * route.midPrice.invert().toSignificant(8)),
price: route.midPrice.invert().toSignificant(8),
swaps: route.path,
amount: amount,
expectedIn: expectedIn.toSignificant(8),
price: trade.executionPrice.invert().toSignificant(8),
trade: trade,
})
} else { // no pool available
res.status(200).json({
Expand All @@ -129,6 +132,7 @@ router.post('/buy-price', async (req, res) => {
})
}
} catch (err) {
debug(err)
let reason
err.reason ? reason = err.reason : reason = statusMessages.operation_error
res.status(500).json({
Expand Down Expand Up @@ -157,7 +161,7 @@ router.post('/sell', async (req, res) => {
const wallet = new ethers.Wallet(privateKey, uniswap.provider)
const baseTokenAddress = paramData.base
const quoteTokenAddress = paramData.quote
const amount = new BigNumber(parseInt(paramData.amount * denomMultiplier))
const amount = paramData.amount

let maxPrice
if (paramData.maxPrice) {
Expand All @@ -168,25 +172,22 @@ router.post('/sell', async (req, res) => {
gasPrice = parseFloat(paramData.gasPrice)
}

const minAmountOut = maxPrice / amount
debug('minAmountOut', minAmountOut)

try {
// fetch the optimal pool mix from uniswap
const route = await uniswap.fetch_route(
const { trade, expectedOut} = await uniswap.priceSwapIn(
baseTokenAddress, // tokenIn is base asset
quoteTokenAddress, // tokenOut is quote asset
amount
)

const price = route.midPrice.toSignificant(8)
const price = trade.executionPrice.toSignificant(8)
debug(`Price: ${price.toString()}`)
if (!maxPrice || price >= maxPrice) {
// pass swaps to exchange-proxy to complete trade
const txObj = await uniswap.swapExactIn(
wallet,
route,
trade,
baseTokenAddress,
amount,
gasPrice,
)

Expand All @@ -197,8 +198,8 @@ router.post('/sell', async (req, res) => {
latency: latency(initTime, Date.now()),
base: baseTokenAddress,
quote: quoteTokenAddress,
amount: parseFloat(paramData.amount),
expectedOut: parseFloat(paramData.amount * route.midPrice.toSignificant(8)),
amount: amount,
expectedOut: expectedOut.toSignificant(8),
price: price,
gasUsed: parseInt(txObj.gasUsed),
txHash: txObj.transactionHash,
Expand Down Expand Up @@ -240,7 +241,7 @@ router.post('/buy', async (req, res) => {
const wallet = new ethers.Wallet(privateKey, uniswap.provider)
const baseTokenAddress = paramData.base
const quoteTokenAddress = paramData.quote
const amount = new BigNumber(parseInt(paramData.amount * denomMultiplier))
const amount = paramData.amount

let maxPrice
if (paramData.maxPrice) {
Expand All @@ -253,21 +254,20 @@ router.post('/buy', async (req, res) => {

try {
// fetch the optimal pool mix from uniswap
const route = await uniswap.fetch_route(
const { trade, expectedIn} = await uniswap.priceSwapOut(
quoteTokenAddress, // tokenIn is quote asset
baseTokenAddress, // tokenOut is base asset
// amount,
amount,
)

const price = route.midPrice.invert().toSignificant(8)
const price = trade.executionPrice.invert().toSignificant(8)
debug(`Price: ${price.toString()}`)
if (!maxPrice || price <= maxPrice) {
// pass swaps to exchange-proxy to complete trade
const txObj = await uniswap.swapExactOut(
wallet,
route,
trade,
baseTokenAddress,
amount,
gasPrice,
)

Expand All @@ -278,8 +278,8 @@ router.post('/buy', async (req, res) => {
latency: latency(initTime, Date.now()),
base: baseTokenAddress,
quote: quoteTokenAddress,
amount: parseFloat(paramData.amount),
expectedIn: parseFloat(paramData.amount * route.midPrice.invert().toSignificant(8)),
amount: amount,
expectedIn: expectedIn.toSignificant(8),
price: price,
gasUsed: parseInt(txObj.gasUsed),
txHash: txObj.transactionHash,
Expand Down
42 changes: 28 additions & 14 deletions src/services/uniswap.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const debug = require('debug')('router')

// constants
const ROUTER = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
const GAS_LIMIT = 1200000;
const GAS_LIMIT = 150688;
const TTL = 60;

export default class Uniswap {
Expand Down Expand Up @@ -46,12 +46,28 @@ export default class Uniswap {
return route
}

async swapExactIn (wallet, route, tokenAddress, amountIn, gasPrice) {
const tIn = await uni.Fetcher.fetchTokenData(this.chainID, tokenAddress)
const tokenAmountIn = new uni.TokenAmount(tIn, amountIn)
async priceSwapIn (tokenIn, tokenOut, tokenInAmount) {
const tIn = await uni.Fetcher.fetchTokenData(this.chainID, tokenIn)
const tokenAmountIn = new uni.TokenAmount(tIn, ethers.utils.parseUnits(tokenInAmount, tIn.decimals))
const route = await this.fetch_route(tokenIn, tokenOut)
const trade = uni.Trade.exactIn(route, tokenAmountIn)
const expectedOut = trade.minimumAmountOut(this.allowedSlippage)
return { trade, expectedOut }
}

async priceSwapOut (tokenIn, tokenOut, tokenOutAmount) {
const tOut = await uni.Fetcher.fetchTokenData(this.chainID, tokenOut)
const tokenAmountOut = new uni.TokenAmount(tOut, ethers.utils.parseUnits(tokenOutAmount, tOut.decimals))
const route = await this.fetch_route(tokenIn, tokenOut)
const trade = uni.Trade.exactOut(route, tokenAmountOut)
const expectedIn = trade.maximumAmountIn(this.allowedSlippage)
return { trade, expectedIn }
}

async swapExactIn (wallet, trade, tokenAddress, gasPrice) {
const result = uni.Router.swapCallParameters(
uni.Trade.exactIn(route, tokenAmountIn),
{
trade,
{
ttl: TTL,
recipient: wallet.address,
allowedSlippage: this.allowedSlippage
Expand All @@ -73,15 +89,13 @@ export default class Uniswap {
return txObj
}

async swapExactOut (wallet, route, tokenAddress, amountOut, gasPrice) {
const tOut = await uni.Fetcher.fetchTokenData(this.chainID, tokenAddress)
const tokenAmountOut = new uni.TokenAmount(tOut, amountOut)
async swapExactOut (wallet, trade, tokenAddress, gasPrice) {
const result = uni.Router.swapCallParameters(
uni.Trade.exactOut(route, tokenAmountOut),
{
ttl: TTL,
recipient: wallet.address,
allowedSlippage: this.allowedSlippage
trade,
{
ttl: TTL,
recipient: wallet.address,
allowedSlippage: this.allowedSlippage
}
)

Expand Down