@yak-spirit/yak-swap-ui
Version:
A reusable React component for swapping with Yield Yak Router. The YY Router can be found [here](https://github.com/yieldyak/yak-aggregator).
146 lines (145 loc) • 6.69 kB
JavaScript
import Web3 from 'web3';
import PairABI from '../abis/PairABI.json';
import YakRouterABI from '../abis/YakRouter.json';
import { ADDRESSES } from '../utils/constants.js';
import { BigNumber } from 'bignumber.js';
import { userState } from '../state/index.js';
import { tokenList } from './tokenList.js';
import { toast } from 'react-toastify';
import { signERC2612Permit } from 'eth-permit';
const MaxUint256 = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';
const yakRouterAddress = ADDRESSES.helpers.yakRouter;
const fee = 0;
export const swap = async (payload) => {
const provider = window.ethereum;
const web3 = new Web3(provider);
const userAddress = userState.userAddress;
if (userAddress) {
const { trade, fromAVAX, toAVAX } = payload;
const yakRouterContract = new web3.eth.Contract(YakRouterABI, yakRouterAddress, {
from: userAddress,
});
try {
if (fromAVAX) {
const tx = await yakRouterContract.methods
.swapNoSplitFromAVAX({
amountIn: trade.amounts[0],
amountOut: trade.amounts[trade.amounts.length - 1],
path: trade.path,
adapters: trade.adapters,
}, userAddress, fee)
.send({ from: userAddress, value: trade.amounts[0] });
if (tx.status) {
toast.success('Swap success');
}
else {
toast.error('Swap failed');
}
return tx;
}
else {
// handle approval
const fromTokenAddress = trade.path[0];
const permitSupported = tokenList.find((token) => token.address.toLowerCase() === fromTokenAddress.toLowerCase())?.permitSupported;
const tokenContract = new web3.eth.Contract(PairABI, fromTokenAddress, {
from: userAddress,
});
const approvedBalance = await tokenContract.methods.allowance(userAddress, yakRouterAddress).call();
try {
if (!permitSupported) {
throw new Error('Permit not supported');
}
if (new BigNumber(approvedBalance).gte(trade.amounts[0])) {
throw new Error('Permit not needed');
}
const signature = await signERC2612Permit(provider, trade.path[0], userAddress, yakRouterAddress, trade.amounts[0]);
if (toAVAX) {
const tx = await yakRouterContract.methods
.swapNoSplitToAvaxWithPermit({
amountIn: trade.amounts[0],
amountOut: trade.amounts[trade.amounts.length - 1],
path: trade.path,
adapters: trade.adapters,
}, userAddress, fee, signature.deadline, signature.v, signature.r, signature.s)
.send({ from: userAddress });
if (tx.status) {
toast.success('Swap success');
}
else {
toast.error('Swap failed');
}
return tx;
}
else {
const tx = await yakRouterContract.methods
.swapNoSplitWithPermit({
amountIn: trade.amounts[0],
amountOut: trade.amounts[trade.amounts.length - 1],
path: trade.path,
adapters: trade.adapters,
}, userAddress, fee, signature.deadline, signature.v, signature.r, signature.s)
.send({ from: userAddress });
if (tx.status) {
toast.success('Swap success');
}
else {
toast.error('Swap failed');
}
return tx;
}
}
catch {
try {
if (new BigNumber(approvedBalance).lt(trade.amounts[0])) {
await tokenContract.methods.approve(yakRouterAddress, MaxUint256).send({ from: userAddress });
}
if (toAVAX) {
const tx = await yakRouterContract.methods
.swapNoSplitToAVAX({
amountIn: trade.amounts[0],
amountOut: trade.amounts[trade.amounts.length - 1],
path: trade.path,
adapters: trade.adapters,
}, userAddress, fee)
.send({ from: userAddress });
if (tx.status) {
toast.success('Swap success');
}
else {
toast.error('Swap failed');
}
return tx;
}
else {
const tx = await yakRouterContract.methods
.swapNoSplit({
amountIn: trade.amounts[0],
amountOut: trade.amounts[trade.amounts.length - 1],
path: trade.path,
adapters: trade.adapters,
}, userAddress, fee)
.send({ from: userAddress });
if (tx.status) {
toast.success('Swap success');
}
else {
toast.error('Swap failed');
}
return tx;
}
}
catch (err) {
console.error('swap', err);
toast.error('Swap error');
return false;
}
}
}
}
catch (err) {
console.error('swap', err);
toast.error('Swap error');
return false;
}
}
};