From dad9fd4fe6a8e70f7b947fd0082454236c8d95d9 Mon Sep 17 00:00:00 2001 From: butterscotch Date: Mon, 16 Oct 2023 22:02:22 +0300 Subject: [PATCH 1/4] ConnectWallet: use variable instead of static value. --- src/components/ConnectWallet.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ConnectWallet.vue b/src/components/ConnectWallet.vue index abffc51..401ac48 100644 --- a/src/components/ConnectWallet.vue +++ b/src/components/ConnectWallet.vue @@ -113,7 +113,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 { From 2d35457076b67974562e6a90b3c32afd3fca43ce Mon Sep 17 00:00:00 2001 From: butterscotch Date: Mon, 16 Oct 2023 22:03:22 +0300 Subject: [PATCH 2/4] memeburner: use minETH and minBLOOD params in sacrifice functions. --- src/stores/memeburner.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/stores/memeburner.js b/src/stores/memeburner.js index 2f98a39..27a4df3 100644 --- a/src/stores/memeburner.js +++ b/src/stores/memeburner.js @@ -48,7 +48,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); @@ -70,7 +70,7 @@ export const useMemeburnerStore = defineStore("memeburner", { }); return data; }, - async sacrificeMeme(amount) { + async sacrificeMeme(amount, minETH) { const tokenStore = useTokenStore(); try { if (!amount || amount == 0) { @@ -79,11 +79,12 @@ export const useMemeburnerStore = defineStore("memeburner", { return; } this.loading = true; - const amountDecimal = BigInt(amount * Math.pow(10, tokenStore.activeToken.decimals)); + // 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, amountDecimal.toString(), - 0 + minETH.toString() ]); return hash; } catch (error) { @@ -93,14 +94,14 @@ export const useMemeburnerStore = defineStore("memeburner", { this.loading = false; } }, - async sacrificeMemeAndBuyBLOOD(amount) { + async sacrificeMemeAndBuyBLOOD(amount, minBLOOD) { const tokenStore = useTokenStore(); - const amountDecimal = BigInt(amount * Math.pow(10, tokenStore.activeToken.decimals)); + const amountDecimal = BigInt(amount) * 10n ** BigInt(tokenStore.activeToken.decimals); var hash = await this.contract.write.sacrificeMemeAndBuyBLOOD([ tokenStore.activeToken.contractAddress, amountDecimal.toString(), - 0, + minBLOOD.toString() ]); return hash; }, @@ -111,7 +112,7 @@ export const useMemeburnerStore = defineStore("memeburner", { console.log("getAmountETHBase"); const tokenStore = useTokenStore(); return await this.contract.read.getAmountETHBase([tokenStore.activeToken.contract.address, amount, true]); - + } }, From 320cbb5c63ab53b494ee32f135f1a9a6418e8422 Mon Sep 17 00:00:00 2001 From: butterscotch Date: Mon, 16 Oct 2023 22:04:16 +0300 Subject: [PATCH 3/4] Quoter: define tokenIn and tokenOut, use ethBase as a param. --- src/stores/uniswap.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/stores/uniswap.js b/src/stores/uniswap.js index eb4fd9b..1b76597 100644 --- a/src/stores/uniswap.js +++ b/src/stores/uniswap.js @@ -2,6 +2,7 @@ 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 { getContract, multicall } from "@wagmi/core"; @@ -38,28 +39,32 @@ 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); + // TODO: change it in your style + const tokenOut = BloodlineJson.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 ]); return {result: true, amount: quotedAmountOut}; } catch (error) { + return { result: false, amount: null }; } }, From fe44a619d44263cc65a56ae0cec061f2c67a69cf Mon Sep 17 00:00:00 2001 From: butterscotch Date: Mon, 16 Oct 2023 22:05:00 +0300 Subject: [PATCH 4/4] sacrifice: refactoring. --- src/stores/sacrifice.js | 78 +++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/src/stores/sacrifice.js b/src/stores/sacrifice.js index b8be191..b607968 100644 --- a/src/stores/sacrifice.js +++ b/src/stores/sacrifice.js @@ -13,7 +13,7 @@ import { formatNumber } from "@/helper/helper.js"; export const useSacrificeStore = defineStore("sacrifice", { state: () => ({ - sacrificeNumber: null, + sacrificeNumber: 0n, sacrificeState: 0, }), getters: {}, @@ -24,7 +24,7 @@ export const useSacrificeStore = defineStore("sacrifice", { const walletStore = useWalletStoreV2(); const tokenStore = useTokenStore(); const cycleStore = useCycleStore(); - + try { this.sacrificeState = 2; @@ -33,11 +33,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); } @@ -53,7 +53,7 @@ export const useSacrificeStore = defineStore("sacrifice", { // (topic) => topic === "0x5e60ccd3c81486143d815dce24867a494d7fee585a0a44282cf479b19a5186ee" // ); // }); - + var rewardData = data.logs.filter((logObject) => { return logObject.topics.filter( (topic) => topic === "0x5e60ccd3c81486143d815dce24867a494d7fee585a0a44282cf479b19a5186ee" @@ -89,34 +89,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; + 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( - BigInt(value * Math.pow(10, token.decimals)) - ); - const rewardsForResultNumber = rewardsForResult.reduce((x, y) => { - return x + Number(y) / Math.pow(10, token.decimals); - }, 0); - var quoteRewards = await uniswapStore.quoteExactInputSingle(value * Math.pow(10, token.decimals)); + + 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 = Number(quoteRewards.amount) / Math.pow(10, token.decimals); - if (quoteRewardsNumber * 0.995 > 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 { @@ -125,24 +132,27 @@ export const useSacrificeStore = defineStore("sacrifice", { * quoter threw an error */ // - output = rewardsForResultNumber; + output = rewardsForResultSum; } console.log("variant", variant); - const amountDecimal = BigInt(value * Math.pow(10, token.decimals)); 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 @@ -153,7 +163,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, }); @@ -161,32 +171,30 @@ 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 = Number(amountBuy) / Math.pow(10, token.decimals); - const amountSacrificeNumber = Number(amountSacrifice) / Math.pow(10, token.decimals); - 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"); } } //potential staking rewards let stakingRewardsNumber = 0; - if (output > 0) { + if (output > 0n && walletStore.connected) { const stakingReward = await rewardLockerStore.getStakeRewardForSacrificeReward( token.contractAddress, - output * Math.pow(10, token.decimals) + output ); - stakingRewardsNumber = (Number(stakingReward) / Math.pow(10, token.decimals)).toFixed(2); + stakingRewardsNumber = (Number(stakingReward / 10n ** BigInt(token.decimals))).toFixed(2); } - return { output: output, variant: variant, staking: stakingRewardsNumber }; + return { output: output, variant: variant, minETH: minETH, minBLOOD: minBLOOD, staking: stakingRewardsNumber }; } catch (error) { console.error("getRewardsFor", error); }