This commit is contained in:
Georges KABBOUCHI 2021-08-16 22:22:40 +03:00
parent 1179aeb007
commit f64226d001
4 changed files with 209 additions and 13 deletions

View File

@ -362,6 +362,7 @@ import ButtonCTA from '~/components/common/input/ButtonCTA.vue'
import { useFormatting } from '~/composables/useFormatting'
import { useBalances } from '~/composables/useBalances'
import { useBigNumber } from '~/composables/useBigNumber'
import { use1InchSwap } from '~/composables/swap/use1InchSwap'
export default defineComponent({
components: { List, Menu, IconCurrency, Button, Dropdown, DropdownMenu, ToggleButton, InputPercent, ButtonCTA },

View File

@ -1,7 +1,60 @@
import { useBigNumber } from "../useBigNumber";
import { useDSA } from "../useDSA";
import { useFormatting } from "../useFormatting";
import { useMath } from "../useMath";
import { Network, useNetwork } from "../useNetwork";
export const use1InchSwap = () => {
const swap = ({ buyAddress, sellAddress, sellAmount, unitAmount }) => {};
const { divWithDec } = useMath();
const { activeNetworkId } = useNetwork();
const { dsa, activeAccount } = useDSA();
const { isZero, ensureValue, gt, minus, times, plus, toBN } = useBigNumber();
const { formatPercent, getFractionDigits } = useFormatting();
/**
* @dev Get different sell spell, based on simulation mode on/offand account network .
* Shared params:
* @param {string} params.buyAddr - buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
* @param {string} params.sellAddr - selling token amount.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
* @param {number} params.sellAmt - selling token amount.
* @param {number} params.unitAmt - unit amount of buyAmt/sellAmt with slippage.
* @param {number} params.setId - set token amount at this ID in `InstaMemory` Contract.
*
* 1Inch related params:
* @param {string} params.calldata - data from 1inch API.
*
* 1Split related params(using in simulation mode):
* @param {number[]} params.distribution - distribution of swap across different dex.
* @param {number} params.disableDexes - disable a dex. (To disable none: 0)
* @param {number} params.getId - get token amount at this ID from `InstaMemory` Contract.
*/
function getSellSpell({
buyAddr,
sellAddr,
sellAmt,
unitAmt,
calldata,
setId
}) {
if (
activeNetworkId.value === Network.Polygon ||
activeAccount.value.version == 2
) {
return {
connector: "1INCH-A",
method: "sell",
args: [buyAddr, sellAddr, sellAmt, unitAmt, calldata, setId]
};
}
return {
connector: "oneInch",
method: "sellThree",
args: [buyAddr, sellAddr, sellAmt, unitAmt, calldata, setId]
};
}
return {
swap
getSellSpell
};
};

66
composables/useMath.ts Normal file
View File

@ -0,0 +1,66 @@
import { useBigNumber } from './useBigNumber'
const { pow, div, toBN, lt, isZero } = useBigNumber()
export function useMath() {
// Convert bigNumber in string (use to save us from big number error on web3)
// TODO - start using big number library for it?
function bigNumInString(x) {
if (Math.abs(x) < 1.0) {
const e = parseInt(x.toString().split('e-')[1])
if (e) {
x *= Math.pow(10, e - 1)
x = '0.' + new Array(e).join('0') + x.toString().substring(2)
}
} else {
let e = parseInt(x.toString().split('+')[1])
if (e > 20) {
e -= 20
x /= Math.pow(10, e)
x += new Array(e + 1).join('0')
}
}
return x
}
// Use to convert large decimal into small. Eg:- number 321.242312 with power 3 = 321.242
function cleanDecimal(num, power) {
let MUL_DIV = 100
if (power || power === 0) {
MUL_DIV = 10 ** power
} else {
if (num < 0.01) MUL_DIV = 10 ** 6
if (num < 1) MUL_DIV = 10 ** 4
}
return Math.floor(Number(num) * MUL_DIV) / MUL_DIV
}
function roundDecimals(value) {
if (isZero(value)) return 0.0
if (lt(value, '0.001')) return cleanDecimal(toBN(value).toNumber(), 6)
if (lt(value, '0.01')) return cleanDecimal(toBN(value).toNumber(), 5)
if (lt(value, '0.1')) return cleanDecimal(toBN(value).toNumber(), 4)
if (lt(value, '1')) return cleanDecimal(toBN(value).toNumber(), 3)
return cleanDecimal(toBN(value).toNumber(), 3)
}
function divWithDec(num, power) {
power = typeof power !== 'undefined' ? power : 0
const divider = pow('10', power)
return div(num, divider).toFixed()
}
/**
* Checks divisor for 0. Returns 0 instead of NaN.
*
* @param {number} divident Divident.
* @param {number} divisor Divisor.
*/
function safeDivide(divident, divisor) {
if (!divisor) return 0
return divident / divisor
}
return { bigNumInString, divWithDec, cleanDecimal, safeDivide, roundDecimals }
}

View File

@ -31,7 +31,7 @@
:on-swap="swap"
@token0="sellToken = $event"
@token1="buyToken = $event"
@slippage="fee = $event"
@slippage="slippage = $event"
:token1Amount="buyToken ? buyToken.amount : '0'"
/>
</div>
@ -54,6 +54,10 @@ import axios from "axios";
import { useToken } from "~/composables/useToken";
import { useBigNumber } from "~/composables/useBigNumber";
import { useNetwork } from "~/composables/useNetwork";
import { useDSA } from "~/composables/useDSA";
import { use1InchSwap } from "~/composables/swap/use1InchSwap";
import { useWeb3 } from "~/composables/useWeb3";
import { useNotification } from "~/composables/useNotification";
export default defineComponent({
components: {
@ -64,17 +68,65 @@ export default defineComponent({
setup() {
const { toBN, pow, div } = useBigNumber();
const { activeNetwork } = useNetwork();
const { dsa } = useDSA();
const { getSellSpell } = use1InchSwap();
const { account } = useWeb3();
const { showPendingTransaction, showWarning } = useNotification();
const { valInt } = useToken();
const sellToken = ref();
const buyToken = ref();
const fee = ref("3.0");
const slippage = ref("3.0");
const swap = async (token0, token1, slippage) => {
await wait(3000);
function caculateUnitAmt() {
let unitAmt: any = toBN(buyToken.value.amount).dividedBy(
toBN(sellToken.value.amount)
);
unitAmt = unitAmt.multipliedBy((100 - 0.3) / 100);
unitAmt = unitAmt.multipliedBy(1e18).toFixed(0);
return unitAmt;
}
const swap = async () => {
const result = await fetchSwapData();
const spells = dsa.value.Spell();
console.log(
getSellSpell({
buyAddr: buyToken.value.address,
sellAddr: sellToken.value.address,
sellAmt: sellToken.value.balance,
unitAmt: caculateUnitAmt(),
calldata: result.tx.data,
setId: 0
})
);
spells.add(
getSellSpell({
buyAddr: buyToken.value.address,
sellAddr: sellToken.value.address,
sellAmt: valInt(sellToken.value.amount, sellToken.value.decimals),
unitAmt: caculateUnitAmt(),
calldata: result.tx.data,
setId: 0
})
);
try {
const txHash = await dsa.value.cast({
spells,
from: account.value
});
showPendingTransaction(txHash);
} catch (error) {
showWarning(error.message);
}
};
const fetchSwapInfo = async () => {
const fetchSwapQuote = async () => {
if (!sellToken.value || !buyToken.value) return;
if (!sellToken.value.amount || sellToken.value.amount === "0") {
@ -88,8 +140,7 @@ export default defineComponent({
params: {
fromTokenAddress: sellToken.value.address,
toTokenAddress: buyToken.value.address,
amount: valInt(sellToken.value.amount, sellToken.value.decimals),
fee: fee.value
amount: valInt(sellToken.value.amount, sellToken.value.decimals)
}
}
);
@ -100,11 +151,36 @@ export default defineComponent({
buyToken.value.amount = div(num, multiplier).toFixed(7);
};
watch([sellToken, buyToken, fee], fetchSwapInfo);
const fetchSwapData = async () => {
if (!sellToken.value || !buyToken.value) return;
if (!sellToken.value.amount || sellToken.value.amount === "0") {
buyToken.value.amount = "0";
return;
}
const { data } = await axios.get(
`https://api.1inch.exchange/v3.0/${activeNetwork.value.chainId}/swap`,
{
params: {
fromTokenAddress: sellToken.value.address.toLowerCase(),
toTokenAddress: buyToken.value.address.toLowerCase(),
amount: valInt(sellToken.value.amount, sellToken.value.decimals),
fromAddress: dsa.value.instance.address.toLowerCase(),
slippage: slippage.value,
disableEstimate: true
}
}
);
return data;
};
watch([sellToken, buyToken, slippage], fetchSwapQuote);
let interval;
onMounted(() => {
interval = setInterval(fetchSwapInfo, 10000);
interval = setInterval(fetchSwapQuote, 10000);
});
onBeforeUnmount(() => {
@ -115,7 +191,7 @@ export default defineComponent({
return {
swap,
fee,
slippage,
sellToken,
buyToken
};