diff --git a/src/components/ConnectWallet.vue b/src/components/ConnectWallet.vue index 91ca403..0fa2c24 100644 --- a/src/components/ConnectWallet.vue +++ b/src/components/ConnectWallet.vue @@ -120,7 +120,7 @@ function badgeClick(token) { if (tokenStore.memeToken.contractAddress === token.contractAddress) { //buy window.open( - "https://app.uniswap.org/swap?inputCurrency=ETH&outputCurrency=0x00E5DAd5dA0FC4Da0baB7f0D99E28C07d8A88ee4&chain=goerli", + `https://app.uniswap.org/swap?inputCurrency=ETH&outputCurrency=${token.contractAddress}&chain=goerli`, "_blank" ); } else { diff --git a/src/stores/memeburner.js b/src/stores/memeburner.js index db1ccc5..59a27e9 100644 --- a/src/stores/memeburner.js +++ b/src/stores/memeburner.js @@ -49,7 +49,7 @@ export const useMemeburnerStore = defineStore("memeburner", { return await this.contract.read.getSacrificedMeme([cycleNumber, tokenAddress]); }, async getAmountToReachGoal(tokenAddress) { - return await this.contract.read.getAmountToReachGoal([tokenAddress, 0]); + return await this.contract.read.getAmountToReachGoal([tokenAddress]); }, async getSacrificedCycle(cycleNumber) { console.log("getSacrificedCycle", cycleNumber); @@ -71,7 +71,7 @@ export const useMemeburnerStore = defineStore("memeburner", { }); return data; }, - async sacrificeMeme(amount) { + async sacrificeMeme(amount, minETH) { const tokenStore = useTokenStore(); try { if (!amount || amount == 0) { @@ -80,10 +80,13 @@ export const useMemeburnerStore = defineStore("memeburner", { return; } this.loading = true; + + // TODO: store all integer values as one type: BigInt + const amountDecimal = BigInt(amount) * 10n ** BigInt(tokenStore.activeToken.decimals); var hash = await this.contract.write.sacrificeMeme([ tokenStore.activeToken.contractAddress, - amount, - 0, + amountDecimal.toString(), + minETH.toString() ]); return hash; } catch (error) { @@ -93,13 +96,14 @@ export const useMemeburnerStore = defineStore("memeburner", { this.loading = false; } }, - async sacrificeMemeAndBuyBLOOD(amount) { + async sacrificeMemeAndBuyBLOOD(amount, minBLOOD) { const tokenStore = useTokenStore(); + const amountDecimal = BigInt(amount) * 10n ** BigInt(tokenStore.activeToken.decimals); var hash = await this.contract.write.sacrificeMemeAndBuyBLOOD([ tokenStore.activeToken.contractAddress, - amount, - 0, + amountDecimal.toString(), + minBLOOD.toString() ]); return hash; }, @@ -110,7 +114,7 @@ export const useMemeburnerStore = defineStore("memeburner", { console.log("getAmountETHBase"); const tokenStore = useTokenStore(); return await this.contract.read.getAmountETHBase([tokenStore.activeToken.contract.address, amount, true]); - + } }, diff --git a/src/stores/sacrifice.js b/src/stores/sacrifice.js index 7667bcd..0647f85 100644 --- a/src/stores/sacrifice.js +++ b/src/stores/sacrifice.js @@ -25,7 +25,7 @@ export const useSacrificeStore = defineStore("sacrifice", { const walletStore = useWalletStoreV2(); const tokenStore = useTokenStore(); const cycleStore = useCycleStore(); - + try { this.sacrificeState = 2; @@ -34,11 +34,11 @@ export const useSacrificeStore = defineStore("sacrifice", { let hash = null; if (getRewards.variant === "sacrifice") { console.log("sacrifice"); - hash = await memeburnerStore.sacrificeMeme(amount); + hash = await memeburnerStore.sacrificeMeme(amount, getRewards.minETH); console.log("hash", hash); } else { console.log("buy"); - hash = await memeburnerStore.sacrificeMemeAndBuyBLOOD(amount); + hash = await memeburnerStore.sacrificeMemeAndBuyBLOOD(amount, getRewards.minBLOOD); console.log("hash", hash); } @@ -54,7 +54,7 @@ export const useSacrificeStore = defineStore("sacrifice", { // (topic) => topic === "0x5e60ccd3c81486143d815dce24867a494d7fee585a0a44282cf479b19a5186ee" // ); // }); - + var rewardData = data.logs.filter((logObject) => { return logObject.topics.find( (topic) => topic === "0x5e60ccd3c81486143d815dce24867a494d7fee585a0a44282cf479b19a5186ee" @@ -92,34 +92,41 @@ export const useSacrificeStore = defineStore("sacrifice", { const uniswapStore = useUniswapStore(); const walletStore = useWalletStoreV2(); const rewardLockerStore = useRewardLockerStore(); - - + // what is value here? i thought amount and value are same + const amountDecimal = BigInt(value) * 10n ** BigInt(token.decimals == undefined ? 18n : token.decimals); let output = 0; - try { - if (!value) { + const amountETHBase = await memeburnerStore.getAmountETHBase(amountDecimal); + // take 99.5% of amount ETH got for selling meme, 0.5% allowed slippage + const minETH = amountETHBase[1] * 995n / 1000n; + + let minBLOOD; + + try { + if (!value || isNaN(value)) { this.sacrificeState = 0; return output; } - const rewardsForResult = await memeburnerStore.getRewardFor(value); - console.log("rewardsForResult", rewardsForResult); - const rewardsForResultNumber = rewardsForResult.reduce((x, y) => { - return x + y - }, 0n); - var quoteRewards = await uniswapStore.quoteExactInputSingle(value); - - let variant = "sacrifice"; + + const rewardsForResult = await memeburnerStore.getRewardFor(amountDecimal); + const rewardsForResultSum = rewardsForResult[0] + rewardsForResult[1]; + // quote blood amount against ETH base amount + var quoteRewards = await uniswapStore.quoteExactInputSingle(amountDecimal, amountETHBase[0]); + + let variant = "sacrifice"; if (quoteRewards.result) { - const quoteRewardsNumber = quoteRewards.amount; - if ((quoteRewardsNumber * 995n) / 1000n > rewardsForResultNumber) { + // take 99.5% of quoted amount, 0.5% allowed slippage + minBLOOD = quoteRewards.amount * 995n / 1000n; + + if (quoteRewards.amount * 95n / 100n > rewardsForResultSum) { variant = "buy"; console.log("use Buy-function", { - quoteRewardsNumber: quoteRewardsNumber, - rewardsForResultNumber, + quoteRewardsNumber: quoteRewards.amount, + rewardsForResultSum, }); } else { console.log("use sacrifice-function", { - quoteRewardsNumber: quoteRewardsNumber, - rewardsForResultNumber, + quoteRewardsNumber: quoteRewards.amount, + rewardsForResultSum, }); } } else { @@ -128,22 +135,27 @@ export const useSacrificeStore = defineStore("sacrifice", { * quoter threw an error */ // - output = rewardsForResultNumber; + output = rewardsForResultSum; } console.log("variant", variant); + console.log("amountDecimal", amountDecimal); + // TODO: when token.allowance become BigInt with decimals, value must be amountDecimal if (!walletStore.connected || (walletStore.connected && token.allowance < value)) { /** * case 1 * user is not logged in or Allowance is less than Input, then I show getRewardsForSacrifice Value * variante not relevant */ - output = rewardsForResultNumber; + output = rewardsForResultSum; + if (variant === "buy") { + output = quoteRewards.amount + } } else if (walletStore.connected && variant === "sacrifice") { /** * case 2 * user is logged in and allowance is greater or equal input and variant is sacrifice */ - output = rewardsForResultNumber; + output = rewardsForResultSum; } else if (walletStore.connected && variant === "buy") { /** * case 3 @@ -154,7 +166,7 @@ export const useSacrificeStore = defineStore("sacrifice", { address: memeburnerStore.contract.address, abi: memeburnerStore.contract.abi, functionName: "sacrificeMeme", - args: [token.contractAddress, amountDecimal.toString(), 0], + args: [token.contractAddress, amountDecimal.toString(), minETH.toString()], account: walletStore.address, }); @@ -162,19 +174,17 @@ export const useSacrificeStore = defineStore("sacrifice", { address: memeburnerStore.contract.address, abi: memeburnerStore.contract.abi, functionName: "sacrificeMemeAndBuyBLOOD", - args: [token.contractAddress, amountDecimal.toString(), 0], + args: [token.contractAddress, amountDecimal.toString(), minBLOOD.toString()], account: walletStore.address, }); - const amountBuyNumber = amountBuy - const amountSacrificeNumber = amountSacrifice - if (amountBuyNumber * 0.995 > amountSacrificeNumber) { + if (amountBuy * 95n / 100n > amountSacrifice) { variant = "buy"; - output = amountBuyNumber; + output = amountBuy; console.log("use buy after comparison sacrificeMemeAndBuyBLOOD and sacrificeMeme"); } else { variant = "sacrifice"; - output = amountSacrificeNumber; + output = amountSacrifice; console.log("use sacrifice after comparison sacrificeMemeAndBuyBLOOD and sacrificeMeme"); } } @@ -188,7 +198,7 @@ export const useSacrificeStore = defineStore("sacrifice", { stakingRewardsNumber = stakingReward / 10n ** token.decimals } const outputNumber = output / 10n ** BigInt(token.decimals); - return { output: outputNumber, variant: variant, staking: stakingRewardsNumber }; + return { output: outputNumber, variant: variant, minETH: minETH, minBLOOD: minBLOOD, staking: stakingRewardsNumber }; } catch (error) { console.error("getRewardsFor", error); } diff --git a/src/stores/uniswap.js b/src/stores/uniswap.js index 76e4c76..9f5a690 100644 --- a/src/stores/uniswap.js +++ b/src/stores/uniswap.js @@ -2,7 +2,9 @@ import { defineStore } from "pinia"; import { useWalletStoreV2 } from "@/stores/walletV2"; import QuoterJson from "@/assets/contracts/Quoter.json"; import UniswapPoolJson from "@/assets/contracts/UniswapPool.json"; +import BloodlineJson from "@/assets/contracts/Bloodline.json"; import { useMemeburnerStore } from "@/stores/memeburner"; +import { useTokenStore } from "@/stores/tokens"; import { getContract, multicall } from "@wagmi/core"; @@ -38,29 +40,34 @@ export const useUniswapStore = defineStore("uniswap", { this.getPoolData(); }, - async quoteExactInputSingle(amount) { + async quoteExactInputSingle(amount, ethBase) { try { console.log("quoteExactInputSingle"); - const memeBurnerStore = useMemeburnerStore(); - var amountEthBase = await memeBurnerStore.getAmountETHBase(amount); - console.log("amountEthBase", amountEthBase); + const memeBurnerStore = useMemeburnerStore(); + const tokenStore = useTokenStore(); + + const tokenOut = tokenStore.memeToken.contractAddress; + // tokenIn - WETH + const tokenIn = BigInt(this.poolData.token0) == BigInt(tokenOut) ? this.poolData.token1 : this.poolData.token0; console.log("quoteExactInputSingle-parameter", { - token0: this.poolData.token0, - token1: this.poolData.token1, + tokenIn: tokenIn, // WETH + tokenOut: tokenOut, // BLOOD fee: this.poolData.fee, - amountEthBase: amountEthBase[0], + amountEthBase: ethBase, pricelimit: 0, //sqrtPriceLimitX96 }); + const quotedAmountOut = await this.quoateV3Contract.read.quoteExactInputSingle([ - this.poolData.token0, //bloodline - this.poolData.token1, //weth + tokenIn, //weth + tokenOut, //bloodline this.poolData.fee, - amountEthBase[0], + ethBase, 0, //sqrtPriceLimitX96 ]); console.log("quotedAmountOut", quotedAmountOut); return {result: true, amount: quotedAmountOut}; } catch (error) { + return { result: false, amount: null }; } },