Skip to content
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
137 changes: 137 additions & 0 deletions abi/external/uniswapFactory.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
[
{
"name": "NewExchange",
"inputs": [
{
"type": "address",
"name": "token",
"indexed": true
},
{
"type": "address",
"name": "exchange",
"indexed": true
}
],
"anonymous": false,
"type": "event"
},
{
"name": "initializeFactory",
"outputs": [],
"inputs": [
{
"type": "address",
"name": "template"
}
],
"constant": false,
"payable": false,
"type": "function",
"gas": 35725
},
{
"name": "createExchange",
"outputs": [
{
"type": "address",
"name": "out"
}
],
"inputs": [
{
"type": "address",
"name": "token"
}
],
"constant": false,
"payable": false,
"type": "function",
"gas": 187911
},
{
"name": "getExchange",
"outputs": [
{
"type": "address",
"name": "out"
}
],
"inputs": [
{
"type": "address",
"name": "token"
}
],
"constant": true,
"payable": false,
"type": "function",
"gas": 715
},
{
"name": "getToken",
"outputs": [
{
"type": "address",
"name": "out"
}
],
"inputs": [
{
"type": "address",
"name": "exchange"
}
],
"constant": true,
"payable": false,
"type": "function",
"gas": 745
},
{
"name": "getTokenWithId",
"outputs": [
{
"type": "address",
"name": "out"
}
],
"inputs": [
{
"type": "uint256",
"name": "token_id"
}
],
"constant": true,
"payable": false,
"type": "function",
"gas": 736
},
{
"name": "exchangeTemplate",
"outputs": [
{
"type": "address",
"name": "out"
}
],
"inputs": [],
"constant": true,
"payable": false,
"type": "function",
"gas": 633
},
{
"name": "tokenCount",
"outputs": [
{
"type": "uint256",
"name": "out"
}
],
"inputs": [],
"constant": true,
"payable": false,
"type": "function",
"gas": 663
}
]
10 changes: 4 additions & 6 deletions examples/two.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ const rpcURL = 'https://kovan.infura.io';
const detherJs = new DetherJS(false);

const destAddress = '0xB06c40B9c72231502949B33bC8b2543701C863Ef';
const sellToken = 'ETH'
const buyToken = 'DAI'
const value = '1.32111';
const sellToken = 'DAI'
const buyToken = 'ETH'
const value = '3.32111';

let buyAmount;

let wallet;
let encryptedWallet;
let user;

Expand All @@ -27,7 +26,7 @@ const checkApproved = () => detherJs.hasApproval(address, buyToken, '44444444');

const sendDelayedExchangeRawTx = async buyAmount => {
const txCount = await detherJs.provider.getTransactionCount(address)
const nonce = txCount + 1
const nonce = txCount
const rawTx = await detherJs.execExchange_delayed(USER_PASSWORD, sellToken, buyToken, ethers.utils.parseEther(value).toString(), buyAmount, nonce)
console.log('Raw tx: ', rawTx)
const txResponse = await detherJs.provider.sendTransaction(rawTx)
Expand All @@ -48,7 +47,6 @@ const testUniswap = async () => {
const wallet = new ethers.Wallet(USER_PRIV_KEY, rpcURL)
const encryptedWallet = await wallet.encrypt(USER_PASSWORD);
await detherJs.loadUser(encryptedWallet)
// const result = await detherJs.execExchange(USER_PASSWORD, sellToken, buyToken, ethers.utils.parseEther(value).toString(), buyAmount)
// const result = await sendDelayedExchangeRawTx(buyAmount)
const result = await execExchange(buyAmount)
console.log('exec exchange result: ', result)
Expand Down
16 changes: 6 additions & 10 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const CONTRACT_ADDRESSES: any = {
// Mkr/Oasis is not on ropsten
// AirSwap is not on ropsten
kyberNetworkProxy: '0x818E6FECD516Ecc3849DAf6845e3EC868087B755',
uniswapExchange: '',
},
kovan: {
// dether
Expand All @@ -96,10 +97,8 @@ export const CONTRACT_ADDRESSES: any = {
// Mkr/Oasis is not on ropsten
// AirSwap is not on ropsten
kyberNetworkProxy: '0x7e6b8b9510D71BF8EF0f893902EbB9C865eEF4Df',
uniswapExchange: {
DAI: '0x8779C708e2C3b1067de9Cd63698E4334866c691C',
MKR: '0xc64F00B099649D578Bf289894d3A51ee7d0b04e5',
}
uniswapFactory: '0xD3E51Ef092B2845f10401a0159B2B96e8B6c3D30',
uniswapExchange: '',
},
rinkeby: {
// dether
Expand All @@ -115,6 +114,7 @@ export const CONTRACT_ADDRESSES: any = {
// external
// Mkr/Oasis is not on rinkeby
airswapExchange: '0x07fc7c43d8168a2730344e5cf958aaecc3b42b41',
uniswapExchange: '',
},
homestead: {
// dether
Expand All @@ -129,12 +129,7 @@ export const CONTRACT_ADDRESSES: any = {
Shops: '',
// external
kyberNetworkProxy: '0x818E6FECD516Ecc3849DAf6845e3EC868087B755',
uniswapExchange: {
DAI: '0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14',
ZRX: '0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF',
KNC: '0x49c4f9bc14884f6210F28342ceD592A633801a8b',
MKR: '0x2C4Bd064b998838076fa341A83d007FC2FA50957',
}
uniswapExchange: '',
},
custom: {
// dether
Expand All @@ -149,6 +144,7 @@ export const CONTRACT_ADDRESSES: any = {
Shops: '',
// external
kyberNetworkProxy: '',
uniswapExchange: '',
},
};

Expand Down
13 changes: 5 additions & 8 deletions src/core/exchanges/uniswap.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ExchangeBase from './base';
import { ethers } from 'ethers'
import * as contract from '../../helpers/contracts';
import { CONTRACT_ADDRESSES } from '../../constants';

import {
Token, Exchange, ExternalContract, ITxOptions
Expand All @@ -15,9 +14,9 @@ export default class ExchangeUniswap extends ExchangeBase {

async estimate(sellAmount: string, provider: ethers.providers.Provider): Promise<string> {
const erc20Token = this.sellToken === 'ETH' ? this.buyToken : this.sellToken
let { name: networkName } = await provider.getNetwork();
const exchangeAddress = CONTRACT_ADDRESSES[networkName][ExternalContract.uniswapExchange][erc20Token]
const exchangeAddress = await contract.getUniswapExchangeAddress(provider, erc20Token)
const uniswapContract = await contract.get(provider, ExternalContract.uniswapExchange, exchangeAddress);

const network = await provider.getNetwork();
const buyAmountWei = this.sellToken === 'ETH'
? (await uniswapContract.getEthToTokenInputPrice(sellAmount))
Expand All @@ -31,9 +30,9 @@ export default class ExchangeUniswap extends ExchangeBase {
}

async trade(sellAmount: string, buyAmount: string, wallet: ethers.Wallet, txOptions: ITxOptions): Promise<ethers.ContractTransaction> {

const erc20Token = this.sellToken === 'ETH' ? this.buyToken : this.sellToken
let { name: networkName } = await wallet.provider.getNetwork();
const exchangeAddress = CONTRACT_ADDRESSES[networkName][ExternalContract.uniswapExchange][erc20Token]
const exchangeAddress = await contract.getUniswapExchangeAddress(wallet.provider, erc20Token)
const uniswapContract = await contract.get(wallet.provider, ExternalContract.uniswapExchange, exchangeAddress);

if (this.sellToken === Token.ETH) {
Expand All @@ -58,11 +57,9 @@ export default class ExchangeUniswap extends ExchangeBase {
// https://docs.ethers.io/ethers.js/html/api-advanced.html?highlight=encode
const uniswapInterfaceAbi = await contract.getAbi(ExternalContract.uniswapExchange)
const iUniswap = new ethers.utils.Interface(uniswapInterfaceAbi);
let { name: networkName } = await wallet.provider.getNetwork();
const erc20Token = this.sellToken === 'ETH' ? this.buyToken : this.sellToken

const exchangeAddress = CONTRACT_ADDRESSES[networkName][ExternalContract.uniswapExchange][erc20Token]

const exchangeAddress = await contract.getUniswapExchangeAddress(wallet.provider, erc20Token)
const uniswapContract = await contract.get(wallet.provider, ExternalContract.uniswapExchange, exchangeAddress);

const deadline = Math.floor(Date.now() / 1000) + 600 // 600 seconds from now
Expand Down
6 changes: 2 additions & 4 deletions src/core/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ export const getAvailableToken = async (provider: ethers.providers.Provider, for

export const hasApproval = async (owner: string, sellToken: Token, amount: string, provider: ethers.providers.Provider): Promise<boolean> => {
const erc20instance = await contract.getErc20(provider, sellToken);
let { name: networkName } = await provider.getNetwork();
const exchangeAddress = constants.CONTRACT_ADDRESSES[networkName][ExternalContract.uniswapExchange][sellToken]
const exchangeAddress = await contract.getUniswapExchangeAddress(provider, sellToken)
const approve = await erc20instance.allowance(owner, exchangeAddress);

if (Number(approve) > Number(amount)) {
Expand Down Expand Up @@ -106,8 +105,7 @@ export const sendCrypto = async (amount: string, toAddress: string, token: Token
};

export const approveToken = async (token: Token, wallet: ethers.Wallet, txOptions: ITxOptions): Promise<ethers.ContractTransaction> => {
const network = await wallet.provider.getNetwork();
const exchangeAddress = constants.CONTRACT_ADDRESSES[network.name][ExternalContract.uniswapExchange][token]
const exchangeAddress = await contract.getUniswapExchangeAddress(wallet.provider, token)
const erc20instance = await contract.getErc20(wallet.provider, token);
return erc20instance.connect(wallet).approve(exchangeAddress, ethers.utils.bigNumberify(2).pow(256).sub(1), txOptions);
};
10 changes: 10 additions & 0 deletions src/helpers/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const ABI: any = {
[ExternalContract.erc20]: require('../../abi/external/erc20.json'),
[ExternalContract.kyberNetworkProxy]: require('../../abi/external/kyberNetworkProxy.json'),
[ExternalContract.uniswapExchange]: require('../../abi/external/uniswapExchange.json'),
[ExternalContract.uniswapFactory]: require('../../abi/external/uniswapFactory.json'),
};

export const getAbi = async (contractName: DetherContract | ExternalContract): Promise<any> => {
Expand All @@ -27,6 +28,15 @@ export const getContractAddress = async (contractName: DetherContract | External
return CONTRACT_ADDRESSES[networkName][contractName];
}

export const getUniswapExchangeAddress = async (provider: ethers.providers.Provider, token: string): Promise<any> => {
const contractName = ExternalContract.uniswapFactory
let { name: networkName } = await provider.getNetwork();
const tokenAddress = TICKER[networkName][token];
const uniswapFactoryInstance = await get(provider, contractName);

return uniswapFactoryInstance.getExchange(tokenAddress)
}

export const get = async (provider: ethers.providers.Provider, contractName: DetherContract | ExternalContract, address?: string, overwriteAbi?: any): Promise<any> => {
if (!provider) throw new Error('missing provider arg');
if (!contractName) throw new Error('missing contract name');
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export enum ExternalContract {
airswapExchange = 'airswapExchange',
kyberNetworkProxy = 'kyberNetworkProxy',
uniswapExchange = 'uniswapExchange',
uniswapFactory = 'uniswapFactory',
appealableArbitrator = 'appealableArbitrator',
}

Expand Down