I'm attempting to swap ERC20 tokens for ETH with the Uniswap Unviersal Router.
When doing an ETH -> ERC20 swap everything works fine, but with the code below (Function where it is going wrong) where I'm attempting to do ERC20 -> ETH it doesn't work. The code is the exact same only difference are the fields within the trade constant. The transaction is going through but it fails, any ideas on what I'm doing wrong? There is also no error being thrown in the console, it just reads it as a success and prints the receipt.
Here is the transaction on Goerli Etherscan: https://goerli.etherscan.io/tx/0xdcce95957af99edb4b69e42f8a72768286a2c89ab64908842d3cabb07c624332
ERC20 -> ETH (Not working)
async function createTrade(): Promise<
| RouterTrade<Currency, Currency, TradeType>
| TransactionState.PoolPairFail
| TransactionState.CreateTradeFail
> {
try {
const amount = ethers.utils.parseEther('0.0001').toString();
// Retrieve data, this returns either a Pair, Pool or a TransactionState.
const poolPairRetrieval = await getUniswapPools(CurrentConfig.tokens.erc20Token, CurrentConfig.tokens.wethToken, CurrentConfig.tokens.poolFee);
// If its a V2 Pair build a V2 ERC20 -> ETH trade.
if (poolPairRetrieval instanceof Pair) {
const trade = new TradeV2(
new RouteV2([poolPairRetrieval as Pair], CurrentConfig.tokens.erc20Token, CurrentConfig.tokens.ethToken),
CurrencyAmount.fromRawAmount(CurrentConfig.tokens.ethToken, amount),
TradeType.EXACT_OUTPUT
);
const routerTrade = buildTrade([trade]);
return routerTrade;
// If its a V3 Pool build a V3 ERC20 -> ETH trade.
} else if (poolPairRetrieval instanceof Pool) {
const trade = await TradeV3.fromRoute(
new RouteV3([poolPairRetrieval as Pool], CurrentConfig.tokens.erc20Token, CurrentConfig.tokens.ethToken),
CurrencyAmount.fromRawAmount(CurrentConfig.tokens.ethToken, amount),
TradeType.EXACT_OUTPUT
);
const routerTrade = buildTrade([trade]);
return routerTrade;
} else {
return TransactionState.PoolPairFail;
};
} catch (e) {
console.error("createTrade:", e)
return TransactionState.CreateTradeFail;
};
};
ETH -> ERC20 (Working)
async function createTrade(): Promise<
| RouterTrade<Currency, Currency, TradeType>
| TransactionState.PoolPairFail
| TransactionState.CreateTradeFail
> {
try {
const amount = ethers.utils.parseEther('0.0001').toString();
// Retrieve data, this returns either a Pair, Pool or a TransactionState.
const poolPairRetrieval = await getUniswapPools(CurrentConfig.tokens.wethToken, CurrentConfig.tokens.erc20Token, CurrentConfig.tokens.poolFee);
// If its a V2 Pair build a V2 ETH -> ERC20 trade.
if (poolPairRetrieval instanceof Pair) {
const trade = new TradeV2(
new RouteV2([poolPairRetrieval as Pair], CurrentConfig.tokens.ethToken, CurrentConfig.tokens.erc20Token),
CurrencyAmount.fromRawAmount(CurrentConfig.tokens.ethToken, amount),
TradeType.EXACT_INPUT
);
const routerTrade = buildTrade([trade]);
return routerTrade;
// If its a V3 Pool build a V3 ETH -> ERC20 trade.
} else if (poolPairRetrieval instanceof Pool) {
const trade = await TradeV3.fromRoute(
new RouteV3([poolPairRetrieval as Pool], CurrentConfig.tokens.ethToken, CurrentConfig.tokens.erc20Token),
CurrencyAmount.fromRawAmount(CurrentConfig.tokens.ethToken, amount),
TradeType.EXACT_INPUT
);
const routerTrade = buildTrade([trade]);
return routerTrade;
} else {
return TransactionState.PoolPairFail;
};
} catch (e) {
console.error("createTrade:", e)
return TransactionState.CreateTradeFail;
};
};
CurrentConfig.tokens.wethToken
Token {
chainId: 5,
decimals: 18,
symbol: 'WETH',
name: 'Wrapped Ether',
isNative: false,
isToken: true,
address: '0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6',
buyFeeBps: undefined,
sellFeeBps: undefined
}
CurrentConfig.tokens.erc20Token
Token {
chainId: 5,
decimals: 18,
symbol: 'RSRV',
name: 'Reserve',
isNative: false,
isToken: true,
address: '0xaE1E99d4AD9BB6Fb52a8B5B148d2876C5488bC72',
buyFeeBps: undefined,
sellFeeBps: undefined
}
CurrentConfig.tokens.ethToken
Ether {
chainId: 5,
decimals: 18,
symbol: 'ETH',
name: 'Ether',
isNative: true,
isToken: false
}