37 Commits
Author SHA1 Message Date
EmberSpirit 7d1e7dcbf5 contract update 2023-10-24 06:31:01 +02:00
EmberSpirit cc3fb88d1e replace static 18n 2023-10-23 22:09:42 +02:00
EmberSpirit fcf6133a47 contract update 2023-10-23 22:00:09 +02:00
EmberSpirit 32db2d291c update bloodchart compact number 2023-10-23 21:58:54 +02:00
EmberSpirit 1b799b8825 Merge branch 'fix/simplifyUniswap' into development 2023-10-23 21:40:07 +02:00
EmberSpirit 99ff2cb166 merge pull request 2023-10-23 21:39:39 +02:00
EmberSpirit 6e58bc6319 update m issues + e frontend improvements 2023-10-23 21:35:38 +02:00
butterscotch 74dd5b7e0a sacrifice.js getRewards fixes 2023-10-23 20:45:24 +03:00
butterscotch bc3b7eac67 simplified uniswap.js 2023-10-23 01:01:34 +03:00
EmberSpirit 44df04cc23 fix issues e + new contracts 2023-10-22 21:37:15 +02:00
EmberSpirit bf76e55fb5 update m issues + digit change numbers 2023-10-22 17:14:00 +02:00
EmberSpirit fa4fa54033 bloodchart crown fix 2023-10-19 20:47:32 +02:00
EmberSpirit 167ad941bc update m issues + e issues 2023-10-19 20:30:27 +02:00
EmberSpirit cfaf527b95 bloodchart resize 2023-10-19 11:46:43 +02:00
EmberSpirit f45128ceb9 update visual fixes 2023-10-18 23:26:29 +02:00
EmberSpirit 32ababbb39 update bigint + smaller style issues fixes 2023-10-17 22:19:52 +02:00
EmberSpirit fedcd0314d Merge branch 'feat/sacrificeChoice' into development 2023-10-17 18:18:03 +02:00
EmberSpirit 9eabba9c11 merged pull request 2023-10-17 18:17:18 +02:00
EmberSpirit d25ef5ad63 bigint umpdate 2023-10-17 18:06:25 +02:00
butterscotch fe44a619d4 sacrifice: refactoring. 2023-10-16 22:05:00 +03:00
butterscotch 320cbb5c63 Quoter: define tokenIn and tokenOut, use ethBase as a param. 2023-10-16 22:04:16 +03:00
butterscotch 2d35457076 memeburner: use minETH and minBLOOD params in sacrifice functions. 2023-10-16 22:03:22 +03:00
butterscotch dad9fd4fe6 ConnectWallet: use variable instead of static value. 2023-10-16 22:02:22 +03:00
EmberSpirit d761adef18 fix user not logged in getrewardsFor & badget +/- fix 2023-10-16 17:31:44 +02:00
EmberSpirit 1fb59225e3 bloodsplash component fix 2023-10-16 13:54:24 +02:00
EmberSpirit b3191f493b blood splash 2023-10-16 13:52:19 +02:00
EmberSpirit 35f2f0782f stepper badge update + injected wallet + smaller fixes 2023-10-16 12:07:07 +02:00
EmberSpirit 301c569edc footer gap improve 2023-10-16 09:36:24 +02:00
EmberSpirit a34de54d60 update loading cycle + potential staking rewards 2023-10-12 23:04:35 +02:00
EmberSpirit 2b4405579e comments + contract update +
smaller design issues fix2
2023-10-12 20:05:22 +02:00
EmberSpirit b5c6f8af33 comments + contract update +
smaller design issues
2023-10-12 20:01:11 +02:00
EmberSpirit 68cd720c59 fill round update + notification update + visual fixes 2023-10-08 22:44:14 +02:00
EmberSpirit 5c7e176457 token-result 2023-10-08 12:17:57 +02:00
EmberSpirit 18d14f1478 updated contracts + install metamask if not installed 2023-10-08 11:22:17 +02:00
EmberSpirit 8d8423b1cb padding sacrifice-token 2023-10-08 10:00:52 +02:00
EmberSpirit 2965cbe065 Merge branch 'development' of http://gitea.loseyourip.com:4000/cindylouwho/ImmortalClanVue into development 2023-10-07 23:58:48 +02:00
EmberSpirit e33c59d621 update new images + update smaller fixes 2023-10-07 23:58:36 +02:00
71 changed files with 3241 additions and 2394 deletions
-12
View File
@@ -1,15 +1,3 @@
# vue-ethereum2
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
+212 -4
View File
@@ -20,10 +20,12 @@
"sass": "^1.62.1",
"swiper": "^9.4.1",
"viem": "^1.4.1",
"vite-svg-loader": "^4.0.0",
"vue": "^3.3.2",
"vue-collapsed": "^1.2.8",
"vue-router": "^4.2.0",
"vue-toastification": "^2.0.0-rc.5"
"vue-toastification": "^2.0.0-rc.5",
"vue3-lottie": "^3.2.0"
},
"devDependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
@@ -1533,6 +1535,14 @@
"@stablelib/wipe": "^1.0.1"
}
},
"node_modules/@trysound/sax": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@@ -2471,8 +2481,7 @@
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
"node_modules/borsh": {
"version": "0.7.0",
@@ -2711,6 +2720,44 @@
"node": ">= 8"
}
},
"node_modules/css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-tree": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
"dependencies": {
"mdn-data": "2.0.30",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
"node_modules/css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -2723,6 +2770,36 @@
"node": ">=4"
}
},
"node_modules/csso": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
"integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
"dependencies": {
"css-tree": "~2.2.0"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/csso/node_modules/css-tree": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
"integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
"dependencies": {
"mdn-data": "2.0.28",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/csso/node_modules/mdn-data": {
"version": "2.0.28",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
"integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="
},
"node_modules/csstype": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
@@ -2799,6 +2876,57 @@
"node": ">=6.0.0"
}
},
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
},
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/duplexify": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz",
@@ -2847,6 +2975,17 @@
"once": "^1.4.0"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
@@ -3941,6 +4080,11 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
},
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
@@ -3964,6 +4108,11 @@
"loose-envify": "cli.js"
}
},
"node_modules/lottie-web": {
"version": "5.12.2",
"resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz",
"integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg=="
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -3984,6 +4133,11 @@
"sourcemap-codec": "^1.4.8"
}
},
"node_modules/mdn-data": {
"version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="
},
"node_modules/micro-ftch": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz",
@@ -4103,7 +4257,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dev": true,
"dependencies": {
"boolbase": "^1.0.0"
},
@@ -4993,6 +5146,37 @@
"node": ">=8"
}
},
"node_modules/svgo": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz",
"integrity": "sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==",
"dependencies": {
"@trysound/sax": "0.2.0",
"commander": "^7.2.0",
"css-select": "^5.1.0",
"css-tree": "^2.2.1",
"csso": "^5.0.5",
"picocolors": "^1.0.0"
},
"bin": {
"svgo": "bin/svgo"
},
"engines": {
"node": ">=14.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/svgo"
}
},
"node_modules/svgo/node_modules/commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"engines": {
"node": ">= 10"
}
},
"node_modules/swiper": {
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-9.4.1.tgz",
@@ -5370,6 +5554,15 @@
}
}
},
"node_modules/vite-svg-loader": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/vite-svg-loader/-/vite-svg-loader-4.0.0.tgz",
"integrity": "sha512-0MMf1yzzSYlV4MGePsLVAOqXsbF5IVxbn4EEzqRnWxTQl8BJg/cfwIzfQNmNQxZp5XXwd4kyRKF1LytuHZTnqA==",
"dependencies": {
"@vue/compiler-sfc": "^3.2.20",
"svgo": "^3.0.2"
}
},
"node_modules/vite/node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
@@ -5822,6 +6015,21 @@
"vue": "^3.0.2"
}
},
"node_modules/vue3-lottie": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/vue3-lottie/-/vue3-lottie-3.2.0.tgz",
"integrity": "sha512-PtNXbv7iD4XGmK8CXd71aLWmILIR6P6VzLMDw6ZzmDAeuJZuJ0MdOVnn50LOARgq+cOFJsn/2z+7tZh0F9T9qw==",
"dependencies": {
"lodash-es": "^4.17.21",
"lottie-web": "5.12.2"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"vue": "^3.2"
}
},
"node_modules/web3-eth-abi": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.1.tgz",
+3 -1
View File
@@ -21,10 +21,12 @@
"sass": "^1.62.1",
"swiper": "^9.4.1",
"viem": "^1.4.1",
"vite-svg-loader": "^4.0.0",
"vue": "^3.3.2",
"vue-collapsed": "^1.2.8",
"vue-router": "^4.2.0",
"vue-toastification": "^2.0.0-rc.5"
"vue-toastification": "^2.0.0-rc.5",
"vue3-lottie": "^3.2.0"
},
"devDependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

+71 -81
View File
@@ -6,63 +6,45 @@ import { useRoute, useRouter } from "vue-router";
import Navbar from "./components/Navbar.vue";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import { useContractStore } from "@/stores/contracts";
import { useSacrificeStore } from "@/stores/sacrifice";
import { useMemeburnerStore } from "@/stores/memeburner";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useRoundsStore } from "@/stores/rounds";
import { useCycleStore } from "@/stores/cycles";
import SlideoutPanel from "./components/SlideoutPanel.vue";
import ConnectWallet from "./components/ConnectWallet.vue";
import CardComponent from "@/components/CardComponent.vue";
import BloodSplash from "./components/BloodSplash.vue";
import { getNetwork, fetchTransaction } from "@wagmi/core";
import {
watchAccount,
watchNetwork,
watchContractEvent,
watchWalletClient,
watchPublicClient,
getAccount,
getNetwork,
getPublicClient,
getWalletClient,
} from "@wagmi/core";
import profileIcon from "@/assets/img/profile-icon.svg?component";
import cycleIcon from "@/assets/img/cycle-icon.svg?component";
import homeIcon from "@/assets/img/home-icon.svg?component";
const tokenStore = useTokenStore();
const contractStore = useContractStore();
const memeBurnerStore = useMemeburnerStore();
const rewardLockerStore = useRewardLockerStore();
const roundsStore = useRoundsStore();
const walletStore = useWalletStoreV2();
const { memeBurner, token } = storeToRefs(tokenStore);
const { list } = storeToRefs(contractStore);
const isMobile = ref(false);
const showPanel = ref(false);
const eventWatch = ref(null);
const netWorkEvent = ref(null);
const memeSacrificedEvent = ref(null);
const clientClientEvent = ref(null);
const splashBlood = ref(0);
const router = useRouter();
const route = useRoute();
isMobile.value = isMobileFunc();
onUnmounted(() => {
window.removeEventListener("resize", handleWindowSizeChange);
eventWatch.value();
netWorkEvent.value();
memeSacrificedEvent.value();
clientClientEvent.value();
console.log("unsubscribe");
});
watch(showPanel, (newValue, oldValue) => {
console.log("document.body", document.body);
console.log("newValue", newValue);
if (newValue) {
document.body.classList.add("sideoutpanel-open");
if (isMobile) {
document.body.classList.add("mobile");
}
} else {
document.body.classList.remove("sideoutpanel-open");
if (isMobile) {
document.body.classList.remove("mobile");
}
}
});
@@ -71,10 +53,7 @@ const handleWindowSizeChange = () => {
// your code
};
function showPanelTest(bla) {
console.log("bla", bla);
}
//to have mobile breakpoint not only on sass side
function isMobileFunc() {
if (screen.width <= 760) {
return true;
@@ -84,56 +63,33 @@ function isMobileFunc() {
}
function changeRoute(name) {
console.log("route", route);
console.log("router", router);
router.push({
name: name,
});
}
provide("isMobile", isMobile);
provide("showPanel", showPanel);
provide("splashBlood", splashBlood);
onMounted(async () => {
console.log("onmounted");
window.addEventListener("resize", handleWindowSizeChange);
handleWindowSizeChange();
const showPanel = ref(false);
const eventWatch = ref(null);
const netWorkEvent = ref(null);
const memeSacrificedEvent = ref(null);
const clientClientEvent = ref(null);
console.log("beforeEach");
const tokenStore = useTokenStore();
const memeBurnerStore = useMemeburnerStore();
const rewardLockerStore = useRewardLockerStore();
const roundsStore = useRoundsStore();
const cycleStore = useCycleStore();
const walletStore = useWalletStoreV2();
console.log("walletStore.initialized", walletStore.initialized);
walletStore.initialized = true;
console.log("hier");
// await walletStore.init();
// await tokenStore.initV2();
// await memeBurnerStore.init();
// await rewardLockerStore.init();
// await memeBurnerStore.init();
console.log("init router");
console.log("roundsStore.currentRound", roundsStore.currentRound);
if (!roundsStore.currentRound) {
roundsStore.currentRound = parseInt(await memeBurnerStore.getCurrentRound());
console.log("roundsStore.currentRound", roundsStore.currentRound);
roundsStore.activeRound = roundsStore.currentRound;
//check if it is necessary
if (!cycleStore.currentCycle) {
cycleStore.currentCycle = parseInt(await memeBurnerStore.getCurrentCycle());
console.log("cycleStore.currentCycle", cycleStore.currentCycle);
cycleStore.activeCycle = cycleStore.currentCycle;
}
const { chain, chains } = getNetwork();
console.log("chain", chain?.id);
console.log("chains", chains);
await roundsStore.fillRound(roundsStore.activeRound);
// await walletStore.loadWalletData();
// initContracts
//Memeburner Contract
console.log("cycleStore.activeCycle", cycleStore.activeCycle);
await cycleStore.fillCycle(cycleStore.activeCycle);
});
</script>
@@ -145,9 +101,12 @@ onMounted(async () => {
<div class="main" :class="{ 'no-scroll': showPanel, mobile: isMobile }">
<RouterView />
</div>
<blood-splash :key="splashBlood"></blood-splash>
<div class="footer">
<div class="footer-inner">
<div class="footer-headline">Join Bloodline</div>
<div class="footer-headline" v-if="!isMobile">Join Bloodline</div>
<div class="footer-social-links">
<div class="social-bloodline-badge">
<div class="social-bloodline-badge-icon">
@@ -164,18 +123,29 @@ onMounted(async () => {
<font-awesome-icon icon="fa-brands fa-twitter" />
</div>
</div>
<div class="social-bloodline-badge">
<div class="social-bloodline-badge-icon">
<font-awesome-icon icon="fa-solid fa-blog" />
</div>
</div>
</div>
</div>
</div>
<div class="mobile-navigation-bar" v-if="isMobile">
<div @click="changeRoute('home')" :class="{ active: route.name === 'home' }">
<font-awesome-icon icon="fa-droplet" />
<!-- <font-awesome-icon icon="fa-droplet" /> -->
<!-- <img src="/assets/img/sacrifice-icon.png" alt="sacrifice-icon" /> -->
<homeIcon />
</div>
<div @click="changeRoute('cycle')" :class="{ active: route.name === 'cycle' }">
<font-awesome-icon icon="fa-moon" />
<!-- <font-awesome-icon icon="fa-moon" /> -->
<!-- <img src="/assets/img/cycle-icon.png" alt="cycle-icon" /> -->
<cycleIcon />
</div>
<div @click="changeRoute('profile')" :class="{ active: route.name === 'profile' }">
<font-awesome-icon icon="fa-person" />
<!-- <img src="/assets/img/profile-icon.svg " alt="profile-icon" /> -->
<profileIcon />
<!-- <font-awesome-icon icon="fa-person" /> -->
</div>
</div>
</template>
@@ -184,22 +154,30 @@ onMounted(async () => {
.footer
height: auto
background-color: var(--midnight-black)
background-color: #2D2D2D
padding-bottom: 72px
@media (min-width: 992px)
background-color: var(--midnight-black)
height: 150px
min-height: 150px
display: flex
flex-direction: column
justify-content: center
padding-bottom: unset
margin-top: auto
.footer-inner
padding: 16px 0 24px 0
padding: 24px 0
font-size: 24px
display: flex
flex-direction: column
gap: 8px
gap: 16px
align-items: center
border-top: 1px solid #000
@media (min-width: 992px)
padding: 16px 0 24px 0
justify-content: center
border-top: unset
background-color: transparent
.footer-headline
font-size: 16px
.footer-social-links
@@ -209,7 +187,7 @@ onMounted(async () => {
border-radius: 14px
background: var(--grey, #858585)
display: flex
padding: 0px 16px
padding: 6px 20px
align-items: center
flex: 0 1 0
color: black
@@ -223,7 +201,7 @@ onMounted(async () => {
margin-top: 82px
padding: 24px 0
@media (min-width: 992px)
margin-top: 96px
margin-top: 80px
padding: 80px 0
&.mobile
&.no-scroll
@@ -246,8 +224,14 @@ onMounted(async () => {
div
font-size: 40px
cursor: pointer
-webkit-tap-highlight-color: transparent
&.active
color: var(--purple)
svg
path
color: var(--purple)
fill: var(--purple)
.modal-overlay
background-color: rgb(15, 15, 15, 0.7)
@@ -273,7 +257,7 @@ onMounted(async () => {
z-index: 100
gap: 16px
@media (min-width: 992px)
top: 142px
top: 10%
right: 24px
left: unset
transform: unset
@@ -297,7 +281,7 @@ body::-webkit-scrollbar-track
background: #202020
body::-webkit-scrollbar-thumb
background: #202020
background: grey
body:hover::-webkit-scrollbar-thumb
background: grey
@@ -305,4 +289,10 @@ body:hover::-webkit-scrollbar-thumb
.toast-header, .toast-body
font-size: 16px
.Vue-Toastification__container
&.bloodline-toast-container
&.top-right
@media (min-width: 992px)
top: 100px
</style>
+1 -1
View File
@@ -1,6 +1,6 @@
{
"contractName": "Bloodline",
"contractAddress": "0x00E5DAd5dA0FC4Da0baB7f0D99E28C07d8A88ee4",
"contractAddress": "0x16351Cd1f3F1eb010758ff9FCf7013f48B0f5495",
"abi": [
{
"inputs": [
+236 -306
View File
@@ -1,6 +1,6 @@
{
"contractName": "LiquidityOwner",
"contractAddress": "0x947f05D74ac7dA0Eb0CA88eF9b579D196B178BaE",
"contractAddress": "0x460f41499B6dA662ce289b57ba62A75FBd753b5c",
"abi": [
{
"inputs": [
@@ -19,24 +19,94 @@
"name": "_weth",
"type": "address"
},
{
"internalType": "address",
"name": "_nfPositionManager",
"type": "address"
},
{
"internalType": "address",
"name": "_memeAltar",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "CallbackCanBeCalledOnlyByPool",
"type": "error"
},
{
"inputs": [],
"name": "CurrentPriceDisallowsToProvide",
"type": "error"
},
{
"inputs": [],
"name": "NothingToProvide",
"type": "error"
},
{
"inputs": [],
"name": "OnlyMemeAltar",
"type": "error"
},
{
"inputs": [],
"name": "ProjectAlive",
"type": "error"
},
{
"inputs": [],
"name": "WrongSideOfPrice",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"indexed": true,
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"indexed": true,
"internalType": "uint256",
"name": "_chunk",
"name": "amountWETH",
"type": "uint256"
}
],
"stateMutability": "payable",
"type": "constructor"
"name": "LiquidityProvided",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"indexed": true,
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amountWETH",
"type": "uint256"
}
],
"name": "LiquidityShouldBeProvidedLater",
"type": "event"
},
{
"inputs": [
@@ -62,85 +132,56 @@
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"internalType": "uint128",
"name": "liquidity",
"type": "uint128"
},
{
"internalType": "uint80",
"name": "tokenId",
"type": "uint80"
}
],
"internalType": "struct LiquidityOwner.Position",
"name": "position",
"type": "tuple"
}
],
"name": "addETHPositionToLinkedList",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "int24",
"name": "_tickLower",
"name": "tick",
"type": "int24"
},
{
"internalType": "int24",
"name": "_tickUpper",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "uint256",
"name": "amountBloodline",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountWETH",
"type": "uint256"
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"name": "addNewPosition",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "int48",
"name": "",
"type": "int48"
}
],
"name": "allRangesLinkedList",
"name": "_liquidityCanBeProvided",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "int48",
"name": "",
"type": "int48"
}
],
"name": "_positions",
"outputs": [
{
"internalType": "uint112",
"name": "providedETH",
"type": "uint112"
},
{
"internalType": "uint112",
"name": "unprovidedETH",
"type": "uint112"
}
],
"stateMutability": "view",
"type": "function"
},
@@ -158,44 +199,77 @@
"type": "function"
},
{
"inputs": [],
"name": "burn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "chunk",
"outputs": [
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
"internalType": "int24",
"name": "tickCycle",
"type": "int24"
}
],
"stateMutability": "view",
"name": "calculateTicksForRange1",
"outputs": [
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256[]",
"name": "liquidityTokenIds",
"type": "uint256[]"
"internalType": "int24",
"name": "tickCycle",
"type": "int24"
}
],
"name": "collectDeveloperFees",
"name": "calculateTicksForRange2",
"outputs": [
{
"internalType": "uint256",
"name": "amount0",
"type": "uint256"
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "uint256",
"name": "amount1",
"type": "uint256"
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"name": "collectPositionFees",
"outputs": [
{
"internalType": "uint128",
"name": "wethAmount",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "bloodlineAmount",
"type": "uint128"
}
],
"stateMutability": "nonpayable",
@@ -206,22 +280,9 @@
"name": "collectedEthTotal",
"outputs": [
{
"internalType": "uint256",
"internalType": "uint112",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "currentTokenIdToFill",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
"type": "uint112"
}
],
"stateMutability": "view",
@@ -231,52 +292,19 @@
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"name": "",
"type": "uint256"
},
{
"internalType": "uint128",
"name": "liquidity",
"type": "uint128"
}
],
"name": "decreasePositionLiquidity",
"name": "cycleTicks",
"outputs": [
{
"internalType": "uint256",
"name": "amount0",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount1",
"type": "uint256"
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountWETH",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountBloodline",
"type": "uint256"
}
],
"name": "increasePositionLiquidity",
"outputs": [],
"stateMutability": "nonpayable",
"stateMutability": "view",
"type": "function"
},
{
@@ -292,96 +320,15 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256[]",
"name": "positionsToCancel",
"type": "uint256[]"
},
{
"internalType": "uint256",
"name": "amountOfWETHToUse",
"type": "uint256"
}
],
"name": "movePriceUP",
"outputs": [
{
"internalType": "uint256",
"name": "amount0Collected",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount1Collected",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "nfPositionManager",
"outputs": [
{
"internalType": "contract INonfungiblePositionManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "onERC721Received",
"outputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "developerFee",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountOfETHToPaySender",
"type": "uint256"
}
],
"name": "payDeveloperFeeAndForGas",
"name": "payDeveloperFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
@@ -405,34 +352,13 @@
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "positions",
"inputs": [],
"name": "pool",
"outputs": [
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"internalType": "uint128",
"name": "liquidity",
"type": "uint128"
},
{
"internalType": "uint80",
"name": "tokenId",
"type": "uint80"
"internalType": "contract IUniswapV3Pool",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
@@ -440,31 +366,12 @@
},
{
"inputs": [],
"name": "rebalance",
"name": "previousBDLTotalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"internalType": "uint128",
"name": "",
"type": "uint256"
}
],
"name": "tokenIds",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
"type": "uint128"
}
],
"stateMutability": "view",
@@ -473,12 +380,12 @@
{
"inputs": [
{
"internalType": "uint256",
"name": "collectedEthInRound",
"type": "uint256"
"internalType": "uint112",
"name": "collectedEthInCycle",
"type": "uint112"
}
],
"name": "triggerRoundCompleted",
"name": "provideLiquidity",
"outputs": [
{
"internalType": "uint256",
@@ -490,37 +397,71 @@
"type": "function"
},
{
"inputs": [],
"name": "uniV3Pool",
"outputs": [
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"stateMutability": "view",
"name": "provideUnprovidedLiquidity",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "int256",
"name": "amount0Delta",
"type": "int256"
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int256",
"name": "amount1Delta",
"type": "int256"
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"name": "rageQuit",
"outputs": [
{
"internalType": "uint128",
"name": "wethAmount",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "bloodlineAmount",
"type": "uint128"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount0Owed",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount1Owed",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_data",
"name": "",
"type": "bytes"
}
],
"name": "uniswapV3SwapCallback",
"name": "uniswapV3MintCallback",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
@@ -537,17 +478,6 @@
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "withdrawETH",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]
}
+162 -192
View File
@@ -1,6 +1,6 @@
{
"contractName": "MemeAltar",
"contractAddress": "0x9842954639aF0c1d7A692222955868806287aeEA",
"contractAddress": "0xAa72C9dB8332c28b4ebcC36D927e967EFC98D78C",
"abi": [
{
"inputs": [
@@ -48,6 +48,16 @@
"name": "ArraysHaveDifferentLength",
"type": "error"
},
{
"inputs": [],
"name": "CycleCompletedRegistrationFailed",
"type": "error"
},
{
"inputs": [],
"name": "GoalCannotBeZero",
"type": "error"
},
{
"inputs": [],
"name": "InsufficientOutputAmount",
@@ -65,7 +75,17 @@
},
{
"inputs": [],
"name": "NextRoundRegistrationFailed",
"name": "NextCycleRegistrationFailed",
"type": "error"
},
{
"inputs": [],
"name": "NotAdmin",
"type": "error"
},
{
"inputs": [],
"name": "NotExactInput",
"type": "error"
},
{
@@ -80,7 +100,12 @@
},
{
"inputs": [],
"name": "RoundCompletedRegistrationFailed",
"name": "SwapCallbackCanBeCalledOnlyByPool",
"type": "error"
},
{
"inputs": [],
"name": "SwapWithinZeroLiquidity",
"type": "error"
},
{
@@ -93,6 +118,11 @@
"name": "TokenIsNotInSacrificableList",
"type": "error"
},
{
"inputs": [],
"name": "TooLittleReceived",
"type": "error"
},
{
"inputs": [
{
@@ -110,7 +140,7 @@
{
"indexed": true,
"internalType": "uint256",
"name": "roundNumber",
"name": "cycleNumber",
"type": "uint256"
},
{
@@ -135,7 +165,7 @@
{
"indexed": true,
"internalType": "uint256",
"name": "roundNumber",
"name": "cycleNumber",
"type": "uint256"
},
{
@@ -190,60 +220,21 @@
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "uint40",
"name": "b1",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m1",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b3",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m4",
"type": "uint40"
}
],
"indexed": false,
"internalType": "struct MemeAltar.BM",
"name": "_bm",
"type": "tuple"
"indexed": true,
"internalType": "uint64",
"name": "b",
"type": "uint64"
},
{
"indexed": true,
"internalType": "uint64",
"name": "m",
"type": "uint64"
}
],
"name": "NewBM",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "newDefaultGoal",
"type": "uint256"
}
],
"name": "NewDefaultRoundGoal",
"type": "event"
},
{
"anonymous": false,
"inputs": [
@@ -254,7 +245,20 @@
"type": "uint256"
}
],
"name": "NewRoundDurationLimit",
"name": "NewCycleDurationLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "newDefaultGoal",
"type": "uint256"
}
],
"name": "NewDefaultCycleGoal",
"type": "event"
},
{
@@ -284,41 +288,14 @@
{
"inputs": [
{
"components": [
{
"internalType": "uint40",
"name": "b1",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m1",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b3",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m4",
"type": "uint40"
}
],
"internalType": "struct MemeAltar.BM",
"name": "newBM",
"type": "tuple"
"internalType": "uint64",
"name": "newB",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "newM",
"type": "uint64"
}
],
"name": "adjustBM",
@@ -332,6 +309,25 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "newDurationLimit",
"type": "uint32"
}
],
"name": "adjustCycleDurationLimit",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
@@ -351,25 +347,6 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "newDurationLimit",
"type": "uint32"
}
],
"name": "adjustRoundDurationLimit",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "admin",
@@ -383,6 +360,19 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "b",
"outputs": [
{
"internalType": "uint64",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "bloodline",
@@ -398,37 +388,12 @@
},
{
"inputs": [],
"name": "bm",
"name": "currentCycle",
"outputs": [
{
"internalType": "uint40",
"name": "b1",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m1",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b3",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m4",
"type": "uint40"
"internalType": "uint112",
"name": "",
"type": "uint112"
}
],
"stateMutability": "view",
@@ -436,14 +401,43 @@
},
{
"inputs": [],
"name": "currentRound",
"name": "cycleDurationLimit",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint112",
"name": "",
"type": "uint112"
}
],
"name": "cycles",
"outputs": [
{
"internalType": "uint112",
"name": "goal",
"type": "uint112"
},
{
"internalType": "uint112",
"name": "ethUsedToBuy",
"type": "uint112"
},
{
"internalType": "uint32",
"name": "expirationTimestamp",
"type": "uint32"
}
],
"stateMutability": "view",
"type": "function"
},
@@ -474,7 +468,7 @@
},
{
"internalType": "bool",
"name": "roundParticipant",
"name": "cycleParticipant",
"type": "bool"
}
],
@@ -484,6 +478,11 @@
"internalType": "uint256",
"name": "amountETHBase",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountETHForSelling",
"type": "uint256"
}
],
"stateMutability": "view",
@@ -495,11 +494,6 @@
"internalType": "address",
"name": "memeToSacrifice",
"type": "address"
},
{
"internalType": "bool",
"name": "buyFunc",
"type": "bool"
}
],
"name": "getAmountToReachGoal",
@@ -517,7 +511,7 @@
"inputs": [
{
"internalType": "uint112",
"name": "roundNumber",
"name": "cycleNumber",
"type": "uint112"
}
],
@@ -549,7 +543,12 @@
"outputs": [
{
"internalType": "uint256",
"name": "",
"name": "rewardCurrentCycle",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rewardNextCycle",
"type": "uint256"
}
],
@@ -560,7 +559,7 @@
"inputs": [
{
"internalType": "uint112",
"name": "roundNumber",
"name": "cycleNumber",
"type": "uint112"
},
{
@@ -590,9 +589,9 @@
"name": "issuancePrice",
"outputs": [
{
"internalType": "uint256",
"internalType": "uint128",
"name": "",
"type": "uint256"
"type": "uint128"
}
],
"stateMutability": "view",
@@ -611,6 +610,19 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "m",
"outputs": [
{
"internalType": "uint64",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
@@ -681,48 +693,6 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "roundDurationLimit",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint112",
"name": "",
"type": "uint112"
}
],
"name": "rounds",
"outputs": [
{
"internalType": "uint112",
"name": "goal",
"type": "uint112"
},
{
"internalType": "uint112",
"name": "ethUsedToBuy",
"type": "uint112"
},
{
"internalType": "uint32",
"name": "expirationTimestamp",
"type": "uint32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
+151 -112
View File
@@ -1,6 +1,6 @@
{
"contractName": "RewardLocker",
"contractAddress": "0xc9f5F78320D0f75099eEA8f8F6FD35BF246f0916",
"contractAddress": "0x8b15b2CB5b019472C31aEf487BF700037c321F85",
"abi": [
{
"inputs": [
@@ -20,7 +20,17 @@
},
{
"inputs": [],
"name": "RoundIsNotCompletedYet",
"name": "CycleIsNotCompletedYet",
"type": "error"
},
{
"inputs": [],
"name": "NotMemeAltar",
"type": "error"
},
{
"inputs": [],
"name": "StakePartMoreThan100Percent",
"type": "error"
},
{
@@ -52,6 +62,44 @@
"name": "ClaimedReward",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "index",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "winnerToken",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "totalCycleRewards",
"type": "uint256"
}
],
"name": "CycleCompleted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "CycleStarted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
@@ -64,7 +112,7 @@
{
"indexed": true,
"internalType": "uint256",
"name": "stakedRound",
"name": "stakedCycle",
"type": "uint256"
},
{
@@ -89,7 +137,7 @@
{
"indexed": true,
"internalType": "uint256",
"name": "unstakeRound",
"name": "unstakeCycle",
"type": "uint256"
},
{
@@ -114,7 +162,7 @@
{
"indexed": true,
"internalType": "uint256",
"name": "roundNumber",
"name": "cycleNumber",
"type": "uint256"
},
{
@@ -133,44 +181,6 @@
"name": "Rewarded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "index",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "winnerToken",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "totalRoundRewards",
"type": "uint256"
}
],
"name": "RoundCompleted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "RoundStarted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
@@ -183,7 +193,7 @@
{
"indexed": true,
"internalType": "uint256",
"name": "unstakeRound",
"name": "unstakeCycle",
"type": "uint256"
},
{
@@ -213,7 +223,7 @@
"inputs": [
{
"internalType": "uint256[]",
"name": "_rounds",
"name": "_cycles",
"type": "uint256[]"
},
{
@@ -237,7 +247,7 @@
"inputs": [
{
"internalType": "uint256[]",
"name": "_rounds",
"name": "_cycles",
"type": "uint256[]"
}
],
@@ -256,7 +266,7 @@
"inputs": [
{
"internalType": "uint256[]",
"name": "_rounds",
"name": "_cycles",
"type": "uint256[]"
},
{
@@ -276,6 +286,35 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "cycles",
"outputs": [
{
"internalType": "uint32",
"name": "cycleCompletedTimestamp",
"type": "uint32"
},
{
"internalType": "uint224",
"name": "totalSacrificeCompetitionRewards",
"type": "uint224"
},
{
"internalType": "uint256",
"name": "totalStakeRewards",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
@@ -285,7 +324,7 @@
},
{
"internalType": "uint256",
"name": "roundNumber",
"name": "cycleNumber",
"type": "uint256"
},
{
@@ -314,7 +353,7 @@
"inputs": [
{
"internalType": "uint256",
"name": "roundNumber",
"name": "cycleNumber",
"type": "uint256"
}
],
@@ -333,7 +372,7 @@
"inputs": [
{
"internalType": "uint256",
"name": "roundNumber",
"name": "cycleNumber",
"type": "uint256"
},
{
@@ -353,6 +392,35 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "user",
"type": "address"
},
{
"internalType": "address",
"name": "sacrificedToken",
"type": "address"
},
{
"internalType": "uint256",
"name": "reward",
"type": "uint256"
}
],
"name": "getStakeRewardForSacrificeReward",
"outputs": [
{
"internalType": "uint256",
"name": "stakeReward",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
@@ -362,7 +430,7 @@
},
{
"internalType": "uint256[]",
"name": "roundNumbers",
"name": "cycleNumbers",
"type": "uint256[]"
}
],
@@ -386,7 +454,7 @@
"inputs": [
{
"internalType": "uint256",
"name": "roundNumber",
"name": "cycleNumber",
"type": "uint256"
},
{
@@ -426,7 +494,7 @@
},
{
"inputs": [],
"name": "lastCompletedRound",
"name": "lastCompletedCycle",
"outputs": [
{
"internalType": "uint256",
@@ -456,7 +524,7 @@
"outputs": [
{
"internalType": "uint256",
"name": "unstakeRound",
"name": "unstakeCycle",
"type": "uint256"
}
],
@@ -467,7 +535,31 @@
"inputs": [
{
"internalType": "uint256",
"name": "roundIndex",
"name": "cycleIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "winnerToken",
"type": "address"
}
],
"name": "registerCycleCompleted",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "cycleIndex",
"type": "uint256"
},
{
@@ -476,7 +568,7 @@
"type": "address[]"
}
],
"name": "registerNextRound",
"name": "registerNextCycle",
"outputs": [
{
"internalType": "bool",
@@ -516,59 +608,6 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "roundIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "winnerToken",
"type": "address"
}
],
"name": "registerRoundCompleted",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "rounds",
"outputs": [
{
"internalType": "uint256",
"name": "roundCompletedTimestamp",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalSacrificeCompetitionRewards",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalStakeRewards",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
@@ -578,7 +617,7 @@
},
{
"internalType": "uint256[]",
"name": "_rounds",
"name": "_cycles",
"type": "uint256[]"
},
{
@@ -646,7 +685,7 @@
"inputs": [
{
"internalType": "uint256[]",
"name": "_rounds",
"name": "_cycles",
"type": "uint256[]"
},
{
@@ -708,7 +747,7 @@
"inputs": [
{
"internalType": "uint256",
"name": "unstakeRound",
"name": "unstakeCycle",
"type": "uint256"
}
],
File diff suppressed because one or more lines are too long
+5
View File
@@ -0,0 +1,5 @@
{
"contractName": "WETH",
"contractAddress": "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6",
"contractAddressMainnet": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
}
+1 -1
View File
@@ -1 +1 @@
[{"inputs":[{"internalType":"address","name":"meme","type":"address"},{"internalType":"address","name":"uniV2Pool","type":"address"}],"name":"addMemeToList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"b1","type":"uint8"},{"internalType":"uint8","name":"m1","type":"uint8"},{"internalType":"uint8","name":"b2","type":"uint8"},{"internalType":"uint8","name":"m2","type":"uint8"},{"internalType":"uint8","name":"b3","type":"uint8"},{"internalType":"uint8","name":"m4","type":"uint8"}],"internalType":"struct MemeAltar.BM","name":"newBM","type":"tuple"}],"name":"adjustBM","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDefaultGoal","type":"uint256"}],"name":"adjustDefaultGoal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDurationLimit","type":"uint256"}],"name":"adjustRoundDurationLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"meme","type":"address"}],"name":"removeMemeFromList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"switchAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFixedPrice","type":"uint256"}],"name":"adjustFixedPrice","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
[{"inputs":[{"internalType":"address","name":"meme","type":"address"},{"internalType":"address","name":"uniV2Pool","type":"address"}],"name":"addMemeToList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint40","name":"b1","type":"uint40"},{"internalType":"uint40","name":"m1","type":"uint40"},{"internalType":"uint40","name":"b2","type":"uint40"},{"internalType":"uint40","name":"m2","type":"uint40"},{"internalType":"uint40","name":"b3","type":"uint40"},{"internalType":"uint40","name":"m4","type":"uint40"}],"internalType":"struct MemeAltar.BM","name":"newBM","type":"tuple"}],"name":"adjustBM","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint112","name":"newDefaultGoal","type":"uint112"}],"name":"adjustDefaultGoal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"newDurationLimit","type":"uint32"}],"name":"adjustRoundDurationLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"switchAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"meme","type":"address"},{"internalType":"address","name":"newUniV2Pool","type":"address"}],"name":"switchUniV2Pool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"meme","type":"address"}],"name":"removeMemeFromList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
+3
View File
@@ -0,0 +1,3 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5332 0.223612C14.5688 -0.68935 16.3324 1.37298 15.6956 3.16362C13.5347 9.2395 14.8624 16.1404 19.3476 20.6276C23.8556 25.1377 30.7963 26.4633 36.8868 24.2619C38.659 23.6213 40.6637 25.369 39.7876 27.3579C39.7616 27.4167 39.7355 27.4752 39.7091 27.534C38.1498 30.9948 35.6553 34.2494 32.4281 36.4315C28.9883 38.7574 24.9319 40 20.7803 40H20.7783C15.9506 39.9948 11.2749 38.3095 7.5529 35.2332C3.83085 32.1569 1.2942 27.8809 0.377993 23.1382C-0.538209 18.3955 0.22314 13.4818 2.53147 9.23928C4.71976 5.21736 8.39949 2.09189 12.4733 0.250546L12.5332 0.223612Z" fill="#F9F9FA"/>
</svg>

After

Width:  |  Height:  |  Size: 731 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.4808 0.762253C16.1401 0.28454 15.5867 0 14.9994 0C14.4107 0 13.8586 0.283234 13.5153 0.762253C9.85024 5.87744 0.667969 19.3317 0.667969 25.6686C0.667969 33.5835 7.08316 40 14.9981 40C22.9143 40 29.3308 33.5835 29.3308 25.6686C29.3321 19.3317 20.1459 5.87744 16.4808 0.762253Z" fill="#F9F9FA"/>
</svg>

After

Width:  |  Height:  |  Size: 410 B

+12
View File
@@ -0,0 +1,12 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1478_31440)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.8333 12C11.8333 7.58797 15.498 7.6 19.9997 7.6C24.5035 7.6 28.1661 7.58797 28.1661 12C28.1661 16.412 24.5035 20 19.9997 20C15.498 20 11.8333 16.412 11.8333 12ZM39.9114 35.2719C38.4271 28.5539 33.7845 23.5959 27.674 21.3459C30.912 18.7919 32.8005 14.6619 32.1063 10.1399C31.302 4.89386 26.8472 0.695954 21.4697 0.0839537C14.0464 -0.762046 7.75014 4.89797 7.75014 12C7.75014 15.78 9.53858 19.1479 12.3274 21.3459C6.21487 23.5959 1.57433 28.5539 0.088048 35.2719C-0.450933 37.7139 1.558 40 4.10795 40H35.8915C38.4434 40 40.4524 37.7139 39.9114 35.2719Z" fill="#F9F9FA"/>
<path d="M17.2809 18.8008L16.4813 16.4008L15.2025 15.2008L19.3594 15.2008L18.0813 16.4008L17.2809 18.8008Z" fill="#F9F9FA"/>
<path d="M23.359 18.8008L22.5594 16.4008L21.2806 15.2008L25.4375 15.2008L24.1594 16.4008L23.359 18.8008Z" fill="#F9F9FA"/>
</g>
<defs>
<clipPath id="clip0_1478_31440">
<rect width="40" height="40" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long
+1
View File
@@ -20,5 +20,6 @@
&[disabled], &.btn--disabled
background-color: darken($purple, 10%)
cursor: not-allowed
color: var(--white-dark)
&:hover,&:focus,&:active
background-color: darken($purple, 10%),
+1 -3
View File
@@ -34,8 +34,6 @@ body
display: flex
flex-direction: column
height: 100vh
.footer
margin-top: auto
.container
margin-right: auto
@@ -47,7 +45,7 @@ body
// max-width: 800px
// padding: 24px 64px
@media (min-width: 992px)
max-width: 640px
max-width: 670px
h1
font-weight: 700
+12 -2
View File
@@ -9,6 +9,7 @@ $tertiary-dark: darken($tertiary, 20%)
$tertiary-light: lighten($tertiary, 20%)
$white: #F9F9FA
$white-dark: darken($white, 20%)
$black: #0F0F0F
$grey: #858585
$grey-light: lighten($grey, 20%)
@@ -31,7 +32,8 @@ $button-background-color: $black
--tertiary: #{$tertiary}
--tertiary-light: #{$tertiary-light}
--tertiary-dark: #{$tertiary-dark}
--white: #{#F9F9FA}
--white: #{$white}
--white-dark: #{$white-dark}
--grey: #{$grey}
--grey-light: #{$grey-light}
--grey2: #{$grey2}
@@ -97,8 +99,16 @@ $button-background-color: $black
font-style: normal
font-weight: 400
line-height: normal
// @media (min-width: 992px)
// font-size: 30px
.sub-header-2
font-family: Inter
font-style: normal
font-weight: 400
line-height: normal
font-size: 24px
@media (min-width: 992px)
font-size: 30px
font-size: 32px
// :root
// --font-size-text: 16px
+73 -124
View File
@@ -1,99 +1,35 @@
<template>
<div class="blood-chart-wrapper" v-if="isMobile">
<div class="blood-chart-wrapper">
<div class="blood-arrow left">
<img
class="swiper-arrow"
src="/assets/img/blood-arrow-left.png"
alt="left-arrow"
@click="swiperInstance.slidePrev()"
v-if="token.length > 3"
v-if="token?.length > 3"
/>
</div>
<swiper
v-if="isMobile"
class="blood-chart"
:slidesPerView="3"
:centeredSlides="false"
:initial-slide="0"
:spaceBetween="35"
:spaceBetween="0"
@swiper="onSwiper"
>
<swiper-slide class="blood-chart-element" v-for="coin in token" :key="coin.name">
<div class="blood-chart-element-header">
<div class="blood-chart-coin">
<img :src="getImageUrl(coin.vamplogo)" alt="logo" />
<template v-if="cycleStore.getCycleWinner.contractAddress === coin.contractAddress">
<img class="logo" :src="coin.vamplogo" alt="logo" />
<img class="crown" src="/assets/img/winnerCrown.png" alt="" />
</template>
<template v-else>
<img :src="coin.vamplogo" alt="logo" />
</template>
</div>
<div class="blood-chart-coin-title low-mid-text">{{ coin.name }}</div>
</div>
<div class="blood-chart-element-body">
<div class="blood-chart-bar-wrapper">
<svg
class="waves"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 24 150 28"
preserveAspectRatio="none"
shape-rendering="auto"
>
<defs>
<path
id="gentle-wave"
d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"
/>
</defs>
<g class="parallax">
<use xlink:href="#gentle-wave" x="48" y="0" fill="rgba(139, 0, 0,0.7)" />
<use xlink:href="#gentle-wave" x="48" y="3" fill="rgba(139, 0, 0,0.5)" />
<use xlink:href="#gentle-wave" x="48" y="5" fill="rgba(139, 0, 0,0.3)" />
<use xlink:href="#gentle-wave" x="48" y="7" fill="#8B0000" />
</g>
</svg>
<div class="blood-chart-bar" :style="`height: ${getPercentage(coin.amount, props.data.goal)}%`">
<div class="wrapper">
<div><span class="dot"></span></div>
<div><span class="dot"></span></div>
<div><span class="dot"></span></div>
<div><span class="dot"></span></div>
<div><span class="dot"></span></div>
<div><span class="dot"></span></div>
</div>
<div class="blood-chart-bar-percentage">
{{ getPercentage(coin.amount, props.data.goal) }}%
</div>
</div>
</div>
</div>
<div class="blood-chart-element-footer">
<div class="blood-chart-amount">
<!-- {{ compactNumber(coin.amount) }} -->
{{ coin.amount.toFixed(2) }}
</div>
<div>$BLOOD</div>
</div>
</swiper-slide>
<!-- <button @click="swiperInstance.slidePrev()">left</button>
<button @click="swiperInstance.slideNext()">left</button> -->
</swiper>
<div class="blood-arrow right">
<img
class="swiper-arrow"
src="/assets/img/blood-arrow-right.png"
alt="left-arrow"
@click="swiperInstance.slideNext()"
v-if="token.length > 3"
/>
</div>
</div>
<div class="blood-chart-wrapper" v-else>
<div class="blood-chart">
<div class="blood-chart-element" v-for="coin in token" :key="coin.name">
<div class="blood-chart-element-header">
<div class="blood-chart-coin">
<img :src="getImageUrl(coin.vamplogo)" alt="logo" />
</div>
<div class="blood-chart-coin-title">{{ coin.name }}</div>
</div>
<div class="blood-chart-element-body">
<div class="blood-chart-bar-wrapper">
<svg
@@ -136,21 +72,41 @@
</div>
</div>
<div class="blood-chart-element-footer">
<div class="blood-chart-amount">
<!-- {{ compactNumber(coin.amount) }} -->
{{ coin.amount.toFixed(2) }}
<div
class="blood-chart-amount"
:title="formatBigIntDivision(coin.amountInBLD, 10n ** tokenStore.memeToken.decimals)"
>
{{
compactNumber(formatBigIntDivision(coin.amountInBLD, 10n ** tokenStore.memeToken.decimals))
}}
</div>
<div class="blood-chart-coin">$BLOOD</div>
<div>$BLOOD</div>
</div>
</div>
</swiper-slide>
<!-- <button @click="swiperInstance.slidePrev()">left</button>
<button @click="swiperInstance.slideNext()">left</button> -->
</swiper>
<div class="blood-arrow right">
<img
class="swiper-arrow"
src="/assets/img/blood-arrow-right.png"
alt="left-arrow"
@click="swiperInstance.slideNext()"
v-if="token?.length > 3"
/>
</div>
</div>
</template>
<script setup>
import { computed, ref, inject } from "vue";
import { getPercentage, compactNumber } from "@/helper/helper.js";
import { computed, ref, inject, onMounted } from "vue";
import { getPercentage, formatNumber, compactNumber, formatBigIntDivision } from "@/helper/helper.js";
import { useCycleStore } from "@/stores/cycles";
import { useMemeburnerStore } from "@/stores/memeburner";
import { useTokenStore } from "@/stores/tokens";
import { Swiper, SwiperSlide } from "swiper/vue";
// Import Swiper styles
@@ -158,15 +114,18 @@ import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
// import required modules
const memeBurnerStore = useMemeburnerStore();
const cycleStore = useCycleStore();
const tokenStore = useTokenStore();
const isMobile = inject("isMobile");
const props = defineProps({
data: Object,
});
const isMobile = inject("isMobile");
console.log(props.data);
onMounted(() => {
console.log("bloodchart-data", props.data);
});
const swiperInstance = ref();
@@ -174,34 +133,15 @@ function onSwiper(swiper) {
swiperInstance.value = swiper;
}
function getImageUrl(url) {
return new URL(url, import.meta.url).href;
}
const token = computed(() => props.data?.token);
// const dataPoints = [
// {
// name: "$PEPE",
// percentage: 62.2,
// icon: "/assets/img/token/pepevamp.png",
// },
// {
// name: "$SHIB",
// percentage: 31.2,
// icon: "/assets/img/token/shibvamp.png",
// },
// {
// name: "$ELON",
// percentage: 54.5,
// icon: "/assets/img/token/elonvamp.png",
// },
// ];
const token = computed(() => {
return props.data?.token.sort((a, b) => (a.amount > b.amount ? -1 : b.amount > a.amount ? 1 : 0));
});
//start with visual 8% of the filled bar, because otherwise the percentage number is not visible
function getPercentageBloodChart(amount, goal) {
let returnNumber = 5;
if ((Number(amount) / Number(goal)) * 100 < 5) {
returnNumber = 5;
let returnNumber = 8;
if ((Number(amount) / Number(goal)) * 100 < 8) {
returnNumber = 8;
} else {
returnNumber = (Number(amount) / Number(goal)) * 100;
}
@@ -216,11 +156,13 @@ function getPercentageBloodChart(amount, goal) {
justify-content: center
// margin-bottom: 80px
position: relative
margin-top: 24px
.blood-chart
height: 750px
height: 560px
width: 100%
justify-content: space-around
display: inline-flex
overflow: unset
@media (min-width: 992px)
gap: 32px
width: unset
@@ -229,34 +171,45 @@ function getPercentageBloodChart(amount, goal) {
.blood-chart-element
height: 100%
width: 80px
align-items: center
@media (min-width: 992px)
width: 60px
width: 100px
display: flex
flex-direction: column
.blood-chart-element-header
flex: 0 0 100px
.blood-chart-coin
border-radius: 80px
margin-left: auto
margin-right: auto
position: relative
margin-bottom: 16px
overflow: hidden
// overflow: hidden
height: 80px
width: 80px
@media (min-width: 992px)
height: 60px
width: 60px
height: 72px
width: 72px
img
height: 100%
width: 100%
&.logo
height: 100%
width: 100%
border: 1px solid yellow
border-radius: 50%
img
&.crown
position: absolute
top: -10px
transform: translate(-50%, -50%)
left: 50%
.blood-chart-coin-title
text-align: center
margin-bottom: 32px
.blood-chart-element-body
background-color: rgba(233, 233, 233, 0.2)
flex: 0 0 500px
flex: 1 1 100%
width: 60px
border-radius: 8px 8px 40px 40px
text-align: left
overflow: hidden
@@ -285,10 +238,6 @@ function getPercentageBloodChart(amount, goal) {
.swiper-slide
width: 80px
.swiper-test
display: flex
flex-direction: column
.blood-arrow
min-width: 30px
File diff suppressed because one or more lines are too long
+3 -27
View File
@@ -1,4 +1,3 @@
<!-- zukünftig card component -->
<template>
<div
class="connected-stake bloodline-border card"
@@ -21,14 +20,6 @@
</div>
<slot name="actions"></slot>
<slot></slot>
<!-- <div class="connected-stake-buttons" v-if="!stakeMenu">
<div class="btn btn-immortal" @click="openStake">Stake</div>
<div v-if="walletStore.memeToken?.staked === 0 && !stakeonly" class="btn btn-immortal btn--disabled">
Unstake
</div>
<div v-else-if="!stakeonly" class="btn btn-immortal" @click="openUnstake">Unstake</div>
</div> -->
</div>
</template>
@@ -38,8 +29,6 @@ import { useWalletStoreV2 } from "@/stores/walletV2";
import { ref } from "vue";
import { useSlots } from "vue";
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
const slots = useSlots();
const props = defineProps({
@@ -54,19 +43,6 @@ const props = defineProps({
default: false,
},
});
const stakeMenu = ref(false);
const stake = ref(null);
function openStake() {
stake.value = true;
stakeMenu.value = true;
}
function openUnstake() {
stake.value = false;
stakeMenu.value = true;
}
</script>
<style lang="sass">
@@ -93,13 +69,13 @@ function openUnstake() {
display: flex
text-align: left
gap: 16px
height: 56px
.token-logo
margin-left: auto
.connected-stake-buttons
display: flex
text-align: center
gap: 16px
div
flex: 1 1 50%
justify-content: center
// div
// flex: 1 1 50%
</style>
+63 -65
View File
@@ -4,12 +4,12 @@
<template v-slot:body>
<token-name-price
:name="tokenStore.getToken(walletStore.memeToken?.contractAddress)?.name"
:price="walletStore.memeToken?.unclaimedRewards"
:price="formatNumber(walletStore.unclaimedRewards, 10n ** tokenStore.memeToken.decimals)"
></token-name-price>
<token-logo img="/assets/img/token/bloodline.png" :alt="'bloodline logo'"></token-logo>
</template>
<template v-slot:actions>
<template v-if="walletStore.memeToken?.unclaimedRewards > 0">
<template v-if="walletStore.unclaimedRewards > 0n">
<Transition name="smooth">
<div class="connected-stake-buttons" v-show="!stakeMenu">
<div class="btn btn-immortal mid-mid-text" @click="claimAll" v-if="stateStake === 0">Claim</div>
@@ -19,32 +19,45 @@
<div class="btn btn-immortal stake-button" disabled v-else-if="stateStake === 3">
<loading-component></loading-component>
</div>
<div class="btn btn-immortal mid-mid-text" @click="openStake">Stake</div>
<div class="btn btn-immortal mid-mid-text" @click="openStake" v-if="stateStake === 0">
Stake
</div>
</div>
</Transition>
<Transition name="smooth">
<stake-menu
v-model="tokenNumber"
@close="stakeMenu = false"
:amount="walletStore.memeToken?.unclaimedRewards"
:amount="walletStore.unclaimedRewards"
:stake="stake"
v-if="stakeMenu"
>
<template v-slot:body>
<div class="btn btn-immortal stake-button" disabled v-if="stateClaimComp === 0">
<div
class="btn btn-immortal stake-button"
disabled
v-if="
tokenNumber > 0 &&
BigInt(tokenNumber) * 10n ** tokenStore.memeToken.decimals >
walletStore.unclaimedRewards
"
>
Insufficient Balance
</div>
<div class="btn btn-immortal stake-button" disabled v-else-if="stateClaimComp === 0">
Enter Amount
</div>
<div
class="btn btn-immortal stake-button"
v-else-if="stateClaimComp === 1"
@click="stakeAndClaimAllRounds"
@click="stakeAndClaimAllCycles"
>
Stake & Claim Rest
</div>
<div class="btn btn-immortal stake-button" disabled v-if="stateClaimComp === 2">
<div class="btn btn-immortal stake-button" disabled v-else-if="stateClaimComp === 2">
Sign Transaction
</div>
<div class="btn btn-immortal stake-button" disabled v-if="stateClaimComp === 3">
<div class="btn btn-immortal stake-button" disabled v-else-if="stateClaimComp === 3">
<loading-component></loading-component>
</div>
<div
@@ -55,13 +68,20 @@
</div>
</template>
<template v-slot:message-end>
<div class="input-balance">Balance: {{ walletStore.memeToken?.unclaimedRewards }}</div>
<div class="input-balance">
Balance:
{{ formatNumber(walletStore.unclaimedRewards, 10n ** tokenStore.memeToken.decimals) }}
</div>
</template>
</stake-menu>
</Transition>
<div class="connected-stake-first-round small-text text-center">
You can claim, once the cycle is over.
</template>
<template v-else-if="cycleStore.rewardsSacrificeCurrentCycle > 0n">
<div class="connected-stake-buttons">
<div class="btn btn-immortal mid-mid-text btn--disabled">Claim</div>
<div class="btn btn-immortal mid-mid-text btn--disabled">Stake</div>
</div>
<div class="text-center">You can claim, once the cycle is over</div>
</template>
<template v-else>
<div class="btn btn-immortal mid-mid-text text-center" @click="router.push({ name: 'home' })">
@@ -83,16 +103,21 @@ import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue";
import StakeSuccessToast from "@/components/toasts/StakeSuccessToast.vue";
import { useCycleStore } from "@/stores/cycles";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useRouter } from "vue-router";
import { useToast } from "vue-toastification";
import { formatNumber } from "@/helper/helper.js";
import { showSuccessToast } from "@/helper/toast.js";
const toast = useToast();
const rewardLockerStore = useRewardLockerStore();
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
const cycleStore = useCycleStore();
const router = useRouter();
const props = defineProps({
@@ -121,31 +146,32 @@ function openStake() {
stakeMenu.value = true;
}
function openUnstake() {
stake.value = false;
stakeMenu.value = true;
}
async function stakeAndClaimAllRounds() {
async function stakeAndClaimAllCycles() {
try {
const unclaimedRewards = walletStore.memeToken?.unclaimedRewards;
stateClaim.value = 2;
console.log("tokenNumber.value", tokenNumber.value);
console.log("walletStore.memeToken?.unclaimedRewards", walletStore.memeToken?.unclaimedRewards);
const coefficient = (10000 * tokenNumber.value) / walletStore.memeToken?.unclaimedRewards;
var hash = await rewardLockerStore.stakeAndClaimAllRounds(coefficient);
const coefficient = BigInt(10000 * tokenNumber.value) / walletStore.unclaimedRewards;
var hash = await rewardLockerStore.stakeAndClaimAllCycles(coefficient);
stateClaim.value = 3;
const data = await waitForTransaction({
hash: hash,
});
stateClaim.value = 4;
await walletStore.loadWalletData();
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xd0813ff03c470dcc7baa9ce36914dc2febdfd276d639deffaac383fd3db42ba3"
);
});
//
console.log("rewardData", rewardData);
//ClaimedReward (address staker, uint256 reward)
const outputClaim = formatNumber(BigInt(rewardData.topics[2]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast(
unclaimedRewards,
outputClaim,
"Success!",
"You just claimed and staked",
"Join the next cycle to increase your rewards and win with your clan"
);
await walletStore.loadWalletData();
} catch (error) {
stateClaim.value = 0;
console.error(error);
@@ -161,14 +187,22 @@ async function claimAll() {
const data = await waitForTransaction({
hash: hash,
});
console.log("data", data);
await walletStore.loadWalletData();
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xd0813ff03c470dcc7baa9ce36914dc2febdfd276d639deffaac383fd3db42ba3"
);
});
//
console.log("rewardData", rewardData);
//ClaimedReward (address staker, uint256 reward)
const outputClaim = formatNumber(BigInt(rewardData.topics[2]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast(
walletStore.memeToken?.unclaimedRewards,
outputClaim,
"Success!",
"You just claimed",
"Join the next cycle to increase your rewards and win with your clan."
);
await walletStore.loadWalletData();
} catch (error) {
state.value = 0;
console.error(error);
@@ -193,7 +227,7 @@ const stateClaimComp = computed(() => {
tokenNumber.value === null ||
tokenNumber.value === "" ||
tokenNumber.value === 0 ||
tokenNumber.value > walletStore.memeToken?.unclaimedRewards
BigInt(tokenNumber.value) > walletStore.unclaimedRewards / 10n ** tokenStore.memeToken.decimals
) {
returnState = 0;
} else if (stateClaim.value === 2) {
@@ -205,42 +239,6 @@ const stateClaimComp = computed(() => {
}
return returnState;
});
function showSuccessToast(value, header, subheader, info) {
// Define the content object with the component, props and listeners
const content = {
component: StakeSuccessToast,
// Any prop can be passed, but don't expect them to be reactive
props: {
// counter: this.counter,
// value: tokenStore.activeToken.rewards?.toFixed(5),
value: value,
header: header,
subheader: subheader,
info: info,
},
// Listen and react to events using callbacks. In this case we listen for
// the "click" event emitted when clicking the toast button
listeners: {},
};
// Render the toast and its contents
toast(content, {
position: "top-center",
icon: false,
closeOnClick: false,
toastClassName: "modal-overlay",
closeButton: false,
hideProgressBar: true,
timeout: false,
});
}
</script>
<style lang="sass">
// .smooth-enter-active, .smooth-leave-active
// transition: opacity 0.1s
// .smooth-enter, .smooth-leave-to
// height: 0
</style>
<style lang="sass"></style>
+43 -18
View File
@@ -5,13 +5,26 @@
<div class="connectors-wrapper">
<div
class="connectors-element card"
:class="[[connector.id]]"
v-for="connector in walletStore.config?.connectors"
@click="connectWallet(connector)"
>
<div class="connector-icon">
<img :src="`/assets/img/connectors/${connector.id}.svg`" :alt="`${connector.name} Logo`" />
<template v-if="connector.id === 'injected'">
<template v-if="connector.name === 'MetaMask'">
<img :src="`/assets/img/connectors/metaMask.svg`" :alt="`${connector.name} Logo`" />
</template>
<template v-else>
<font-awesome-icon :icon="['fas', 'wallet']" />
</template>
</template>
<template v-else>
<img :src="`/assets/img/connectors/${connector.id}.svg`" :alt="`${connector.name} Logo`" />
</template>
</div>
<div class="connector-name">
{{ connector.name }}
</div>
<div class="connector-name">{{ connector.name }}</div>
</div>
</div>
<div>Are you coming from Binance, Bybit, Kucoin or any other crypto exchange?</div>
@@ -23,7 +36,7 @@
<div class="connected-header-avatar">
<img :src="getblocky(walletStore.address)" alt="avatar" />
</div>
<div class="connected-header-address">
<div class="connected-header-address" :title="walletStore.address">
{{ getAddressShortName(walletStore.address) }}
</div>
<div class="connected-header-logout" @click="disconnectWallet">
@@ -35,7 +48,9 @@
<div class="connected-token" v-for="token in walletStore.token">
<token-name-price
:name="tokenStore.getToken(token.contractAddress).name"
:price="token.balanceOf"
:price="
formatNumber(token.balanceOf, 10n ** tokenStore.getToken(token.contractAddress).decimals)
"
></token-name-price>
<div class="connected-token-button">
<div class="bloodline-badge grey" @click="badgeClick(token)">
@@ -60,13 +75,11 @@
import { ref, toRaw, onMounted, onUnmounted, getCurrentInstance } from "vue";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import Meme1Json from "@/assets/contracts/Meme1.json";
import TokenNamePrice from "./TokenNamePrice.vue";
import TokenLogo from "./TokenLogo.vue";
import TokenInput from "./TokenInput.vue";
import StakeComponentV1 from "@/components/StakeComponentV1.vue";
import { getAddressShortName, getblocky } from "@/helper/helper.js";
import { getAddressShortName, getblocky, formatNumber } from "@/helper/helper.js";
import { useRoute, useRouter } from "vue-router";
import { disconnect } from "@wagmi/core";
@@ -76,11 +89,7 @@ const router = useRouter();
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
const goerliKey = import.meta.env.VITE_GOERLI_KEY;
const fromAddress = ref(null);
const accountSub = ref(null);
// const goerliKey = import.meta.env.VITE_GOERLI_KEY;
const instance = getCurrentInstance();
@@ -89,21 +98,28 @@ async function disconnectWallet() {
try {
instance.parent.emit("update:modelValue", false);
await disconnect();
// walletStore.connected = false;
// walletStore.address = null;
} catch (error) {
console.log("error", error);
}
}
function isMetaMaskInstalled(connector) {
const metamaskInstalled = connector?.options?.getProvider();
if (metamaskInstalled) {
return true;
}
return false;
}
//go to the sacrifice-page and select the clicked token
//if contract === bloodline show buy
//we could also show buy, if there is no pepe
function badgeClick(token) {
var tokenData = tokenStore.getToken(token.contractAddress);
tokenStore.activeToken = tokenData;
// router.push({ name: "home", hash: `#${tokenData.name}` });
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 {
@@ -112,7 +128,9 @@ function badgeClick(token) {
}
}
//special case for metaMask, but I think that is the most used wallet
async function connectWallet(connector) {
console.log("connector", connector);
instance.parent.emit("update:modelValue", false);
await walletStore.connectWallet(toRaw(connector));
}
@@ -136,6 +154,14 @@ async function connectWallet(connector) {
&:hover, &:active, &:focus
background-color: lighten(#858585, 20%)
cursor: pointer
&.injected
.connector-icon
background-color: white
display: flex
justify-content: center
align-items: center
svg
font-size: 25px
.connector-icon
border-radius: 12px
width: 40px
@@ -179,7 +205,6 @@ async function connectWallet(connector) {
display: flex
gap: 16px
align-items: center
height: 56px
.connected-token-button
margin-left: auto
.bloodline-badge
+4 -21
View File
@@ -26,9 +26,7 @@
</div>
</div>
<div v-if="!isMobile">
<!-- <div v-if="!connected" class="btn btn-immortal" @click="walletStore.connectWallet">connect</div> -->
<div v-if="!address" class="btn btn-immortal mid-text" @click="showPanel = true">connect</div>
<!-- <span v-else @click="showPanel = true"> test</span> -->
<div v-if="!address" class="btn btn-immortal mid-text" @click="showPanel = true">Connect</div>
<div class="login-icon-desktop mid-text" v-else @click="showPanel = true">
<img :src="getblocky(address)" alt="avatar" />
<div>{{ getAddressShortName(walletStore.address) }}</div>
@@ -58,7 +56,7 @@ import { useRoute, useRouter } from "vue-router";
const emit = defineEmits(["showPanel"]);
const walletStore = useWalletStoreV2();
const { connected, address } = storeToRefs(walletStore);
const { address } = storeToRefs(walletStore);
const isMobile = inject("isMobile");
const showPanel = inject("showPanel");
@@ -117,7 +115,7 @@ onBeforeUnmount(() => {
transition: transform .3s ease,visibility 0s .3s linear
height: 82px
@media (min-width: 992px)
height: 96px
height: 80px
// &.navbar--hidden
// transform: translate3d(0,-100%,0)
.navbar-inner
@@ -143,27 +141,12 @@ onBeforeUnmount(() => {
letter-spacing: 0.138em
line-height: 73.107px
@media (min-width: 992px)
font-size: 48px
font-size: 42px
a
text-decoration: none
color: white
.navbar-center
display: flex
margin-left: auto
.navbar-social-links
display: flex
gap: 18px
.social-bloodline-badge
font-size: 16px
padding: 8px 16px 8px 16px
border-radius: 14px
background-color: #0F0F0F
display: flex
&:hover,&:active,&:focus
background-color: lighten(#0F0F0F, 10%)
cursor: pointer
.social-bloodline-badge-icon
margin-right: 8px
.navbar-end
display: flex
margin-left: auto
+4 -3
View File
@@ -1,7 +1,8 @@
<template>
<div class="rewards-wrapper">
<div class="rewards-headline low-mid-text">
{{ props.title }}
<div class="rewards-title">{{ props.title }}</div>
<div class="rewards-sub-title" v-if="props.subTitle">{{ props.subTitle }}</div>
</div>
<div class="rewards-inner">
<token-name-price name="$BLOOD" :price="props.amount"></token-name-price>
@@ -16,8 +17,9 @@ import TokenLogo from "@/components/TokenLogo.vue";
const props = defineProps({
title: String,
subTitle: String,
info: String,
amount: String,
amount: [String, Number],
image: String,
});
</script>
@@ -33,6 +35,5 @@ const props = defineProps({
padding: 0 6px 6px 6px
border-bottom: 1px solid var(--grey, #858585)
justify-content: space-between
height: 56px
box-sizing: content-box
</style>
+165 -328
View File
@@ -1,6 +1,5 @@
<template>
<div class="sacrifice-wrapper card card--glow bloodline-wrapper">
<!-- {{ activeToken.allowance }} -->
<div class="sacrifice-wrapper card card--glow">
<div class="sacrifice-headline">Select Sacrifice</div>
<div class="sacrifice-select-tokens">
<div class="sacrifice-tokens">
@@ -15,7 +14,7 @@
]"
v-for="token in props.data"
:key="token.contractAddress"
@click="tokenStore.changeActiveToken(token)"
@click="changeActiveToken(token)"
>
<div class="sacrifice-token-logo">
<img v-if="isMobile" :src="token.logoMobile" alt="token logo" />
@@ -26,37 +25,41 @@
</div>
</div>
<div class="sacrifice-from-to-wrapper" v-if="activeToken.contractAddress">
<div
:class="{
'sacrifice-from-wrapper': true,
'bloodline-border': true,
'bloodline-border--variant1': true,
purple: true,
}"
>
<div class="sacrifice-from-wrapper bloodline-border bloodline-border--variant1 purple">
<token-input
:modelValue="tokenNumber"
:modelValue="sacrificeStore.sacrificeNumber / 10n ** activeToken.decimals"
@input="
($event) => {
tokenNumber = $event.target.value;
return processChange($event.target.value);
const value = BigInt($event.target.value) * 10n ** activeToken.decimals;
sacrificeStore.sacrificeNumber = value;
processChange(value);
}
"
:max="activeWalletToken.balanceOf"
:max="activeWalletToken?.balanceOf"
:logo="activeToken.logo"
>
<template v-slot:message>
<div class="sacrifice-adder-step bloodline-badge" @click="addTokens(10000000)">+10m</div>
<div class="sacrifice-adder-step bloodline-badge" @click="addTokens(100000000)">+100m</div>
<div class="sacrifice-adder-step bloodline-badge" @click="addTokens(1000000000)">+1b</div>
<div
class="sacrifice-adder-step bloodline-badge"
v-for="steps in activeToken.addSteps"
:key="steps.name"
@click="addTokens(steps.amount)"
>
<template
v-if="
!walletStore.connected ||
sacrificeStore.sacrificeNumber < activeWalletToken?.balanceOf
"
>
+{{ steps.name }}
</template>
<template v-else> -{{ steps.name }} </template>
</div>
</template>
<template v-slot:message-end>
<template v-slot:message-end v-if="activeWalletToken?.balanceOf >= 0">
<div class="input-balance tiny-text">
Balance:
{{
walletStore.token.find((obj) => obj.contractAddress === activeToken.contractAddress)
.balanceOf
}}
{{ formatNumber(activeWalletToken?.balanceOf, 10n ** activeToken.decimals) }}
</div>
<div class="input-max tiny-text" @click="addMaxTokens">Max</div>
</template>
@@ -74,8 +77,11 @@
}"
>
<div class="sacrifice-to-body">
<token-name-price name="$BLOOD" :price="`≈${output?.toFixed(5)}`"></token-name-price>
<token-logo img="/assets/img/token/bloodline.png" :alt="'bloodline logo'"></token-logo>
<token-name-price
name="$BLOOD"
:price="`≈${formatNumber(output, 10n ** activeToken.decimals)}`"
></token-name-price>
<token-logo :img="activeToken.vamp.logo" :size="64" :alt="activeToken.vamp.name"></token-logo>
</div>
<div class="sacrifice-staking-bonus">
@@ -87,7 +93,16 @@
}
"
>
<div class="mid-mid-text">+ Staking Bonus</div>
<div class="mid-mid-text" v-if="!walletStore.connected">+ Staking Bonus</div>
<div
class="mid-mid-text"
v-else-if="walletStore.memeToken?.staked === 0 || cycleStore.currentCycle === 1"
>
No Staking Bonus
</div>
<div class="mid-mid-text" v-else>
+ {{ formatNumber(stakingOutput, 10n ** activeToken.decimals) }} Staking Bonus
</div>
<div class="icon">
<font-awesome-icon icon="chevron-down" />
</div>
@@ -103,45 +118,41 @@
<img src="/assets/img/moon.png" alt="moon" />
</div>
</div>
<div class="sacrifice-fees-info-wrapper">
<div class="sacrifice-fees-img">
<img src="/assets/img/fuel-noozle.png" alt="fuel noozle" />
</div>
<div class="sacrifice-fees-body">
<div class="sacrifice-fees-body-header mid-text">
<div class="sacrifice-fees-body-header-title">Gas Subsidy</div>
<div class="sacrifice-fees-body-header-amount">≤30 Gwei</div>
</div>
<div class="sacrifice-fees-body-subheader">The clan pays your transaction.</div>
</div>
</div>
<div class="sacrifice-buttons-function-wrapper">
{{ stateComputed }}
<template v-if="walletStore.connected">
<div class="btn btn-immortal sub-header" disabled v-if="stateComputed === 0">Enter Amount</div>
<div
class="btn btn-immortal sub-header"
v-if="
disabled
v-else-if="sacrificeStore.sacrificeNumber > activeWalletToken?.balanceOf"
>
Insufficient Balance
</div>
<div
class="btn btn-immortal sub-header"
v-else-if="
activeToken.allowance > 0 &&
activeToken.allowance >= tokenNumber &&
activeToken.allowance >= sacrificeStore.sacrificeNumber &&
(stateComputed === 1 || stateComputed === 4)
"
@click="sacrificeToken(tokenNumber)"
@click="sacrificeToken"
>
Sacrifice 🩸
</div>
<div
class="btn btn-immortal sub-header"
v-if="
(!activeToken.allowance || activeToken.allowance < tokenNumber) &&
v-else-if="
(!activeToken.allowance || activeToken.allowance < sacrificeStore.sacrificeNumber) &&
(stateComputed === 1 || stateComputed === 4)
"
@click="approveToken(tokenNumber)"
@click="approveToken(sacrificeStore.sacrificeNumber)"
>
Approve Token
</div>
<div class="btn btn-immortal sub-header" disabled v-if="stateComputed === 2">Sign Transaction</div>
<div class="btn btn-immortal sub-header" disabled v-if="stateComputed === 3">
<div class="btn btn-immortal sub-header" disabled v-else-if="stateComputed === 2">
Sign Transaction
</div>
<div class="btn btn-immortal sub-header" disabled v-else-if="stateComputed === 3">
<loading-component></loading-component>
</div>
</template>
@@ -154,52 +165,48 @@
</template>
<script setup>
import { ref, defineProps, watch, inject, nextTick, onMounted, onBeforeUnmount, computed } from "vue";
import { ref, defineProps, watch, inject, nextTick, onMounted, onBeforeUnmount, computed, markRaw } from "vue";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useCycleStore } from "@/stores/cycles";
import { useTokenStore } from "@/stores/tokens";
import { useMemeburnerStore } from "@/stores/memeburner";
import { useUniswapStore } from "@/stores/uniswap";
import { useSacrificeStore } from "@/stores/sacrifice";
import StakeComponentV1 from "@/components/StakeComponentV1.vue";
import LoadingComponent from "@/components/LoadingComponent.vue";
import TokenInput from "@/components/TokenInput.vue";
import TokenNamePrice from "@/components/TokenNamePrice.vue";
import TokenLogo from "@/components/TokenLogo.vue";
import StakeSuccessToast from "@/components/toasts/StakeSuccessToast.vue";
import ApprovedToast from "@/components/toasts/ApprovedToast.vue";
import { useToast } from "vue-toastification";
const toast = useToast();
import { storeToRefs } from "pinia";
import { waitForTransaction, readContract, watchBlockNumber, multicall } from "@wagmi/core";
import Helper from "@/utils/helper.js";
const cycleStore = useCycleStore();
const sacrificeStore = useSacrificeStore();
const toast = useToast();
import { debounce, formatNumber } from "@/helper/helper.js";
const isMobile = inject("isMobile");
const showPanel = inject("showPanel");
const splashBlood = inject("splashBlood");
const walletStore = useWalletStoreV2();
// const { connected } = storeToRefs(walletStore);
const tokenStore = useTokenStore();
const { activeToken } = storeToRefs(tokenStore);
const memeburnerStore = useMemeburnerStore();
const uniswapStore = useUniswapStore();
const props = defineProps({
data: Array,
});
// watch(
// activeToken,
// () => {
// tokenNumber.value = null;
// },
// { deep: true }
// );
const tokenNumber = ref(null);
const output = ref(0);
const loading = ref(false);
const stakingOutput = ref(null);
const blockEvent = ref(null);
const approveToast = ref(null);
const addOperator = ref(true);
const splashesUsed = ref([]);
/**
* state 0 enter amount
* state 1 rdy to go
@@ -207,7 +214,6 @@ const blockEvent = ref(null);
* state 3 loading
* state 4 sacrificed
*/
const state = ref(0);
const showStakingMenu = ref(false);
const approvalData = ref(null);
@@ -221,18 +227,31 @@ const activeWalletToken = computed(() => {
const stateComputed = computed(() => {
let returnState = 0;
if (tokenNumber.value === null || tokenNumber.value === "" || tokenNumber.value === 0) {
if (
sacrificeStore.sacrificeNumber === null ||
sacrificeStore.sacrificeNumber === "" ||
sacrificeStore.sacrificeNumber === 0n
) {
returnState = 0;
} else if (state.value === 2) {
} else if (sacrificeStore.sacrificeState === 2) {
returnState = 2;
} else if (state.value === 3) {
} else if (sacrificeStore.sacrificeState === 3) {
returnState = 3;
} else if (tokenNumber.value !== null || tokenNumber.value !== "" || tokenNumber.value > 0) {
} else if (
sacrificeStore.sacrificeNumber !== null ||
sacrificeStore.sacrificeNumber !== "" ||
sacrificeStore.sacrificeNumber > 0
) {
returnState = 1;
}
return returnState;
});
const processChange = Helper.debounce((value) => getRewardsFor(value));
const processChange = debounce(async (value) => {
const rewardValue = await sacrificeStore.getRewardsFor(value, activeToken.value);
console.log("rewardValue", rewardValue);
output.value = rewardValue.output;
stakingOutput.value = rewardValue.staking;
});
onMounted(() => {
blockEvent.value = watchBlockNumber(
@@ -241,37 +260,11 @@ onMounted(() => {
},
async (blockNumber) => {
console.log("blockNumber", blockNumber);
await getRewardsFor(tokenNumber.value);
// if (tokenNumber.value && tokenNumber.value > 0) {
// console.log("tokenNumber.value", tokenNumber.value);
// var quoteRewards = await uniswapStore.quoteExactInputSingle(
// tokenNumber.value * Math.pow(10, tokenStore.activeToken.decimals)
// );
// const quoteRewards1 = Number(quoteRewards) / Math.pow(10, tokenStore.activeToken.decimals);
// console.log("quoteRewards", quoteRewards);
// const rewardsForResult = await memeburnerStore.getRewardFor(
// tokenNumber.value * Math.pow(10, tokenStore.activeToken.decimals)
// );
// const rewardsForResult1 = Number(rewardsForResult) / Math.pow(10, tokenStore.activeToken.decimals);
// console.log("rewardsForResult1", rewardsForResult1);
// console.log("quoteRewards1", quoteRewards1);
// console.log("compare", quoteRewards1 * 0.995);
// console.log("ifcompare1", quoteRewards1 * 0.995 > rewardsForResult1);
// //return bigger number
// if (quoteRewards1 * 0.995 > rewardsForResult1) {
// //sacrificememe
// output.value = quoteRewards1;
// // const hash = await memeburnerStore.sacrificeMeme(tokenNumber.value);
// } else {
// output.value = rewardsForResult1;
// //sacrificeMemeAndBuyBLOOD
// // const hash = await memeburnerStore.sacrificeMeme(tokenNumber.value);
// }
// }
//
var rewardValue = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, activeToken.value);
output.value = rewardValue.output;
stakingOutput.value = rewardValue.staking;
}
);
console.log("blockEvent.value", blockEvent.value);
});
onBeforeUnmount(() => {
@@ -279,265 +272,106 @@ onBeforeUnmount(() => {
blockEvent.value();
});
async function sacrificeToken(amount) {
console.log("sacrificeToken");
try {
state.value = 2;
const getRewards = await getRewardsFor(amount);
console.log("getRewards123", getRewards);
let hash = null;
if (getRewards.variant === "sacrifice") {
console.log("sacrifice");
hash = await memeburnerStore.sacrificeMeme(amount);
console.log("hash", hash);
} else {
console.log("buy");
hash = await memeburnerStore.sacrificeMemeAndBuyBLOOD(amount);
console.log("hash", hash);
}
console.log("hierabc");
console.log("state.value = 2");
console.log("hash", hash);
state.value = 3;
console.log("state.value = 3");
const data = await waitForTransaction({
hash: hash,
});
console.log("data", data);
activeToken.value.allowance = await tokenStore.allowance();
state.value = 4;
console.log("state.value = 4");
showSuccessToast(
tokenStore.activeToken.rewards?.toFixed(5),
"Success!",
"You turned your meme into:",
"You can claim once the current cycle is finished and your clan bonus was calculated."
);
} catch (error) {
state.value = 0;
console.error(error);
throw new Error(error);
}
}
async function approveToken(amount) {
try {
state.value = 2;
console.log("amount", amount);
sacrificeStore.sacrificeState = 2;
const hash = await tokenStore.approveToken(amount);
state.value = 3;
sacrificeStore.sacrificeState = 3;
const data = await waitForTransaction({
hash: hash,
});
console.log("data", data);
activeToken.value.allowance = await tokenStore.allowance();
state.value = 1;
sacrificeStore.sacrificeState = 1;
showApprovedToast();
} catch (error) {
console.error(error);
throw new Error(error);
}
}
async function getRewardsFor(value) {
console.log("getRewardsFor", value);
loading.value = true;
let variant = null;
let newOutput = 0;
// if (activeToken.value.allowance >= value) {
// const amountDecimal = BigInt(value * Math.pow(10, tokenStore.activeToken.decimals));
// const hash = await readContract({
// address: memeburnerStore.contract.address,
// abi: memeburnerStore.contract.abi,
// functionName: "sacrificeMeme",
// args: [tokenStore.activeToken.contractAddress, amountDecimal.toString(), 0],
// account: walletStore.address,
// });
// console.log("hash", hash);
// // var hash = await memeburnerStore.contract.simulate.sacrificeMeme([
// // tokenStore.activeToken.contractAddress,
// // amountDecimal.toString(),
// // 0,
// // ]);
// // console.log("hash", hash);
// // state.value = 3;
// // const data = await waitForTransaction({
// // hash: hash,
// // });
// // console.log("datahash", data);
// }
try {
if (!value || isNaN(value)) {
output.value = 0;
state.value = 0;
return;
}
const rewardsForResult = await memeburnerStore.getRewardFor(
BigInt(value * Math.pow(10, activeToken.value.decimals))
);
const rewardsForResultNumber = Number(rewardsForResult) / Math.pow(10, tokenStore.activeToken.decimals);
var quoteRewards = await uniswapStore.quoteExactInputSingle(
tokenNumber.value * Math.pow(10, tokenStore.activeToken.decimals)
);
let variant = "sacrifice";
if (quoteRewards.result) {
console.log("quoteRewards", quoteRewards);
const quoteRewardsNumber = Number(quoteRewards.amount) / Math.pow(10, tokenStore.activeToken.decimals);
if (quoteRewardsNumber * 0.995 > rewardsForResultNumber) {
variant = "buy";
}
} else {
/**
* case 4
* quoter threw an error
*/
//
newOutput = rewardsForResultNumber;
}
const amountDecimal = BigInt(value * Math.pow(10, tokenStore.activeToken.decimals));
console.log("amountDecimal", amountDecimal);
if (!walletStore.connected || (walletStore.connected && activeToken.value.allowance < tokenNumber.value)) {
/**
* case 1
* user is not logged in or Allowance is less than Input, then I show getRewardsForSacrifice Value
* variante not relevant
*/
newOutput = rewardsForResultNumber;
} else if (walletStore.connected && variant === "sacrifice") {
/**
* case 2
* user is logged in and allowance is greater or equal input and variant is sacrifice
*/
newOutput = rewardsForResultNumber;
} else if (walletStore.connected && variant === "buy") {
/**
* case 3
* user is logged in and allowance is greater or equal input and variant is buy
* compare sacrificeMeme-result and sacrificeMemeAndBuyBLOOD-result
*/
const amountSacrifice = await readContract({
address: memeburnerStore.contract.address,
abi: memeburnerStore.contract.abi,
functionName: "sacrificeMeme",
args: [tokenStore.activeToken.contractAddress, amountDecimal.toString(), 0],
account: walletStore.address,
});
console.log("amountSacrifice", amountSacrifice);
const amountBuy = await readContract({
address: memeburnerStore.contract.address,
abi: memeburnerStore.contract.abi,
functionName: "sacrificeMemeAndBuyBLOOD",
args: [tokenStore.activeToken.contractAddress, amountDecimal.toString(), 0],
account: walletStore.address,
});
const amountBuyNumber = Number(amountBuy) / Math.pow(10, tokenStore.activeToken.decimals);
const amountSacrificeNumber = Number(amountSacrifice) / Math.pow(10, tokenStore.activeToken.decimals);
if (amountBuyNumber * 0.995 > amountSacrificeNumber) {
variant = "buy";
newOutput = amountBuyNumber;
} else {
variant = "sacrifice";
newOutput = amountSacrificeNumber;
}
}
// if (!walletStore.connected && variant === "sacrifice") {
// newOutput = rewardsForResultNumber;
// } else if (!walletStore.connected && variant === "buy") {
// newOutput = rewardsForResultNumber;
// }
// if (!walletStore.connected || (walletStore.connected && activeToken.value.allowance < tokenNumber.value)) {
// //case 1
// // user is not logged in or Allowance is less than Input, then I show getRewardsForSacrifice Value
// newOutput = rewardsForResultNumber;
// variant = "sacrifice";
// } else {
// const rewardsForResult = await memeburnerStore.getRewardFor(
// BigInt(value * Math.pow(10, activeToken.value.decimals))
// );
// console.log(
// "tokenNumber.value * Math.pow(10, tokenStore.activeToken.decimals)",
// tokenNumber.value * Math.pow(10, tokenStore.activeToken.decimals)
// );
// console.log("tokenNumber.value", tokenNumber.value);
// var quoteRewards = await uniswapStore.quoteExactInputSingle(
// tokenNumber.value * Math.pow(10, tokenStore.activeToken.decimals)
// );
// console.log("quoteRewards", quoteRewards);
// const rewardsForResultNumber = Number(rewardsForResult[0]) / Math.pow(10, tokenStore.activeToken.decimals);
// console.log("rewardsForResultNumber", rewardsForResultNumber);
// const quoteRewardsNumber = Number(quoteRewards) / Math.pow(10, tokenStore.activeToken.decimals);
// console.log("quoteRewardsNumber", quoteRewardsNumber);
// if (quoteRewardsNumber * 0.995 > rewardsForResultNumber) {
// //sacrificememe
// newOutput = quoteRewardsNumber;
// variant = "buy";
// // const hash = await memeburnerStore.sacrificeMeme(tokenNumber.value);
// } else {
// newOutput = rewardsForResultNumber;
// variant = "sacrifice";
// //sacrificeMemeAndBuyBLOOD
// // const hash = await memeburnerStore.sacrificeMeme(tokenNumber.value);
// }
// }
// console.log("variant", variant);
// tokenStore.activeToken.rewards = newOutput;
output.value = newOutput;
return { ouput: newOutput, variant: variant };
} catch (error) {
console.log("error", error);
} finally {
loading.value = false;
sacrificeStore.sacrificeState = 0;
}
}
async function addTokens(value) {
tokenNumber.value = Number(tokenNumber.value) + Number(value);
output.value = await getRewardsFor(tokenNumber.value).output;
if (!walletStore.connected || sacrificeStore.sacrificeNumber < activeWalletToken.value?.balanceOf) {
sacrificeStore.sacrificeNumber = BigInt(sacrificeStore.sacrificeNumber) + value;
} else {
sacrificeStore.sacrificeNumber = sacrificeStore.sacrificeNumber - value;
if (sacrificeStore.sacrificeNumber < 0n) {
sacrificeStore.sacrificeNumber = 0n;
}
}
const rewardValue = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, activeToken.value);
output.value = rewardValue.output;
stakingOutput.value = rewardValue.staking;
}
async function addMaxTokens() {
tokenNumber.value = activeWalletToken.value.balanceOf;
output.value = await getRewardsFor(tokenNumber.value).output;
addOperator.value = !addOperator.value;
sacrificeStore.sacrificeNumber = activeWalletToken.value?.balanceOf;
const rewardValue = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, activeToken.value);
console.log("rewardValue", rewardValue);
output.value = rewardValue.output;
stakingOutput.value = rewardValue.staking;
}
function showSuccessToast(value, header, subheader, info) {
function showApprovedToast(value, header, subheader, info) {
// Define the content object with the component, props and listeners
const content = {
component: StakeSuccessToast,
component: ApprovedToast,
// Any prop can be passed, but don't expect them to be reactive
props: {
// counter: this.counter,
// value: tokenStore.activeToken.rewards?.toFixed(5),
value: value,
header: header,
subheader: subheader,
info: info,
},
// Listen and react to events using callbacks. In this case we listen for
// the "click" event emitted when clicking the toast button
listeners: {},
listeners: {
// sacrificed: showSplash,
},
};
// Render the toast and its contents
toast(content, {
position: "top-center",
return toast(content, {
position: "top-right",
icon: false,
timeout: 5000,
closeOnClick: false,
toastClassName: "modal-overlay",
closeButton: false,
// toastClassName: "modal-overlay",
hideProgressBar: true,
timeout: false,
toastClassName: "approve-toast toast-card",
});
}
function showSplash() {
splashBlood.value++;
}
//call function in the store and remove icon,
async function sacrificeToken() {
console.log("activeToken.value", activeToken.value);
var result = await sacrificeStore.sacrificeToken(sacrificeStore.sacrificeNumber, activeToken.value);
if (result) {
showSplash();
}
toast.dismiss(approveToast.value);
}
async function changeActiveToken(token) {
console.log("changeActiveToken");
tokenStore.activeToken = token;
if (walletStore.connected) {
// //TODO, wenn connected, dann all diese Daten laden?
// tokenStore.activeToken.balance = await walletStore.getTokenBalance(token);
tokenStore.activeToken.allowance = Number(await tokenStore.allowance());
}
var rewards = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, token);
console.log("rewards", rewards);
output.value = rewards.output;
stakingOutput.value = rewards.staking;
}
</script>
<style lang="sass">
@@ -556,14 +390,15 @@ function showSuccessToast(value, header, subheader, info) {
font-size: 24px
margin-bottom: 32px
@media (min-width: 992px)
font-size: 36px
font-size: 32px
.sacrifice-select-tokens
display: flex
margin-bottom: 32px
width: 100%
.sacrifice-tokens
display: flex
width: 100%
justify-content: center
justify-content: space-between
flex-wrap: wrap
gap: 12px
@@ -653,8 +488,10 @@ function showSuccessToast(value, header, subheader, info) {
.value-adder
display: flex
gap: 6px
flex-wrap: wrap
.sacrifice-adder-step
font-size: 14px
font-size: 12px
align-items: center
background: var(--grey, #858585)
color: var(--midnight-black, #0F0F0F)
&:hover,
@@ -662,8 +499,8 @@ function showSuccessToast(value, header, subheader, info) {
&:focus
background-color: var(--grey-light)
cursor: pointer
@media (min-width: 992px)
font-size: 12px
// @media (min-width: 992px)
// font-size: 12px
// .sacrifice-adder-balance
// margin-left: auto
// .sacrifice-adder-max
@@ -682,7 +519,6 @@ function showSuccessToast(value, header, subheader, info) {
.sacrifice-to-body
display: flex
justify-content: space-between
height: 56px
.sacrificed-info
display: flex
padding: 8px 24px
@@ -708,6 +544,7 @@ function showSuccessToast(value, header, subheader, info) {
.input-max
color: var(--grey, #858585)
font-weight: bold
&:hover, &:active, &:focus
color: var(--grey-light, #858585)
cursor: pointer
+151 -73
View File
@@ -31,31 +31,61 @@
<div class="connected-stake-body">
<slot name="body">
<token-name-price
:name="tokenStore.getToken(walletStore.memeToken?.contractAddress)?.name"
:price="walletStore.memeToken?.staked"
name="$BLOOD staked"
:price="formatNumber(walletStore.staked, 10n ** tokenStore.memeToken.decimals)"
></token-name-price>
<token-logo img="/assets/img/token/bloodline.png" :alt="'^y '"></token-logo>
<token-name-price class="stake-reward" name="Extra Reward" price="+25%"></token-name-price>
<token-logo img="/assets/img/token/bloodline.png" :alt="'bloodline-token'"></token-logo>
<token-name-price :variant="true" class="stake-reward" name="Bonus" price="+25%"></token-name-price>
</slot>
</div>
<slot name="actions">
<div class="connected-stake-buttons" v-if="!stakeMenu">
<div class="btn btn-immortal mid-mid-text" disabled v-if="roundStore.currentRound === 1">Stake</div>
<div class="btn btn-immortal mid-mid-text" v-else @click="openStake">Stake</div>
<div
v-if="(walletStore.memeToken?.staked === 0 && !stakeonly) || roundStore.currentRound === 1"
class="btn btn-immortal btn--disabled mid-mid-text"
>
Unstake
</div>
<div v-else-if="!stakeonly" class="btn btn-immortal mid-mid-text" @click="openUnstake">Unstake</div>
<template v-if="!walletStore.connected">
<div class="mid-mid-text text-center" disabled>Please Connect Your Wallet</div>
</template>
<template v-else-if="walletStore.connected && !ableToUnstake">
<div class="btn btn-immortal mid-mid-text" disabled v-if="cycleStore.currentCycle === 1">
Stake
</div>
<div
class="btn btn-immortal mid-mid-text"
v-else-if="cycleStore.currentCycle > 1"
@click="openStake"
>
Stake
</div>
<div
v-if="(walletStore.memeToken?.staked === 0n && !stakeonly) || cycleStore.currentCycle === 1"
class="btn btn-immortal btn--disabled mid-mid-text"
>
Unstake
</div>
<div v-else-if="!stakeonly" class="btn btn-immortal mid-mid-text" @click="openUnstake">
Order Unstake
</div>
</template>
<template v-else-if="walletStore.connected && ableToUnstake">
<div
class="btn btn-immortal mid-mid-text text-center"
v-if="unstakeState === 0 && walletStore.orderedUnstakedAmount > 0n && ableToUnstake"
@click="unstake"
>
Claim Unstaked $BLOOD
</div>
<div class="btn btn--disabled mid-mid-text text-center" v-else-if="unstakeState === 1">
Sign Transaction
</div>
<div class="btn btn--disabled mid-mid-text text-center" v-else-if="unstakeState === 2">
<loading-component></loading-component>
</div>
</template>
</div>
<Transition name="smooth">
<stake-menu
v-model="tokenNumber"
@close="stakeMenu = false"
:stake="stake"
:amount="walletStore.memeToken.balanceOf"
:amount="walletStore.balanceOf"
v-if="stakeMenu & !unstakeMenu"
>
<template v-slot:body>
@@ -79,7 +109,10 @@
</div>
</template>
<template v-slot:message-end>
<div class="input-balance">Balance: {{ walletStore.memeToken.balanceOf }}</div>
<div class="input-balance">
Balance:
{{ formatNumber(walletStore.balanceOf, 10n ** tokenStore.memeToken.decimals) }}
</div>
</template>
</stake-menu>
<div class="unstake-menu" v-else-if="stakeMenu & unstakeMenu">
@@ -87,10 +120,16 @@
To prevent users from farming rewards you can claim your stake next cycle.
</div>
<div class="unstake-menu-actions">
<div class="btn btn-immortal stake-button" v-if="!loading" @click="orderUnstake">
<div class="btn btn-immortal stake-button" v-if="stateStake <= 1" @click="orderUnstake">
Unstake Next Cycle
</div>
<div class="btn btn--disabled" v-else>Sign Transaction</div>
<div class="btn btn--disabled mid-mid-text text-center" v-else-if="stateStake === 2">
Sign Transaction
</div>
<div class="btn btn--disabled mid-mid-text text-center" v-else-if="stateStake === 3">
<loading-component></loading-component>
</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
@@ -100,11 +139,16 @@
</div>
</div>
</Transition>
<div class="connected-stake-first-round small-text text-center" v-if="roundStore.currentRound === 0">
<div class="connected-stake-first-round small-text text-center" v-if="cycleStore.currentCycle === 1">
No $BLOOD on the market. Staking is activated after the first cycle is finished.
</div>
<div class="connected-stake-claim-info low-mid-text text-center">
You can claim your stake next cycle.
<div
class="connected-stake-first-round small-text text-center"
v-if="walletStore.orderedUnstakedAmount > 0n && !ableToUnstake"
>
You can claim
{{ formatNumber(walletStore.orderedUnstakedAmount, 10n ** tokenStore.memeToken.decimals) }}
$BLOOD next cycle.
</div>
</slot>
<slot></slot>
@@ -114,25 +158,25 @@
<script setup>
import { ref, useSlots, computed } from "vue";
import CardComponent from "@/components/CardComponent.vue";
import StakeSuccessToast from "@/components/toasts/StakeSuccessToast.vue";
import StakeMenu from "@/components/StakeMenu.vue";
import TokenNamePrice from "@/components/TokenNamePrice.vue";
import TokenLogo from "@/components/TokenLogo.vue";
import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue";
import { showSuccessToast } from "@/helper/toast.js";
import { useRoundsStore } from "@/stores/rounds";
import { useCycleStore } from "@/stores/cycles";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import { useToast } from "vue-toastification";
import { formatNumber } from "@/helper/helper.js";
const toast = useToast();
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
const rewardLockerStore = useRewardLockerStore();
const roundStore = useRoundsStore();
const cycleStore = useCycleStore();
const slots = useSlots();
const props = defineProps({
stakeonly: {
@@ -145,6 +189,11 @@ const props = defineProps({
required: false,
default: null,
},
dense: {
type: Boolean,
required: false,
default: false,
},
});
const stakeMenu = ref(false);
@@ -161,6 +210,7 @@ const loading = ref(false);
* state 4 staked
*/
const state = ref(0);
const unstakeState = ref(0);
function openStake() {
stake.value = true;
@@ -174,88 +224,116 @@ function openUnstake() {
stakeMenu.value = true;
}
async function unstake() {
try {
unstakeState.value = 1;
const hash = await rewardLockerStore.unstake();
unstakeState.value = 2;
const data = await waitForTransaction({
hash: hash,
});
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xb89343427f692590c388d6346a8e42ea497eb6682a04db1a53f77ea81771ca91"
);
});
console.log("rewardData", rewardData);
const outputClaim = formatNumber(BigInt(rewardData.topics[3]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast(outputClaim, "Success!", "You just unstaked");
await walletStore.loadWalletData();
} catch (error) {
console.error("unstake", error);
} finally {
unstakeState.value = 0;
}
}
async function orderUnstake() {
loading.value = true;
state.value = 2;
var hash = await rewardLockerStore.orderUnstake();
state.value = 3;
const data = await waitForTransaction({
hash: hash,
});
state.value = 4;
await walletStore.loadWalletData();
showSuccessToast();
loading.value = false;
try {
state.value = 2;
var hash = await rewardLockerStore.orderUnstake();
state.value = 3;
const data = await waitForTransaction({
hash: hash,
});
state.value = 4;
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xf86340d97020c624010a208b733db95795281fbc45cb6e6a40d161f91fa3e4a0"
);
});
console.log("rewardData", rewardData);
const outputClaim = formatNumber(BigInt(rewardData.topics[3]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast(outputClaim, "Success!", "You just unstaked", "You can claim your stake next cycle.");
stakeMenu.value = false;
} catch (error) {
console.error("orderUnstake", error);
} finally {
await walletStore.loadWalletData();
state.value = 0;
}
}
async function stakeToken() {
try {
console.log("stakeToken");
state.value = 2;
const hash = await rewardLockerStore.stakeBloodline(tokenNumber.value);
state.value = 3;
const data = await waitForTransaction({
hash: hash,
});
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xf496bf2b14b1d178412b6f7a745900105b49b38b315cfdfbfabad31a6f995c6f"
);
});
//
console.log("rewardData", rewardData);
const outputClaim = formatNumber(BigInt(rewardData.topics[3]), 10n ** tokenStore.memeToken.decimals);
console.log("data", data);
state.value = 4;
await walletStore.loadWalletData();
state.value = 0;
showSuccessToast(
tokenNumber.value,
outputClaim,
"Success!",
"You just staked",
"Your next sacrifice will get an extra staking bonus as a reward."
);
//reload data
await walletStore.loadWalletData();
stakeMenu.value = false;
} catch (error) {
state.value = 0;
console.error(error);
throw new Error(error);
} finally {
state.value = 0;
}
}
const ableToUnstake = computed(() => {
var cycleList = walletStore.memeToken?.orderedUnstakedCycles?.findIndex((obj) => obj.result > 0n);
console.log("cycleList", cycleList);
if (cycleList && cycleList > -1 && cycleList + 1 <= cycleStore.currentCycle) {
return true;
}
return false;
});
const stateStake = computed(() => {
let returnState = 0;
if (tokenNumber.value === null || tokenNumber.value === "" || tokenNumber.value === 0) {
returnState = 0;
} else if (state.value === 2) {
if (state.value === 2) {
returnState = 2;
} else if (state.value === 3) {
returnState = 3;
} else if (tokenNumber.value !== null || tokenNumber.value !== "" || tokenNumber.value > 0) {
returnState = 1;
} else if (tokenNumber.value === null || tokenNumber.value === "" || tokenNumber.value === 0) {
returnState = 0;
}
return returnState;
});
function showSuccessToast(value, header, subheader, info) {
// Define the content object with the component, props and listeners
const content = {
component: StakeSuccessToast,
// Any prop can be passed, but don't expect them to be reactive
props: {
// counter: this.counter,
// value: tokenStore.activeToken.rewards?.toFixed(5),
value: value,
header: header,
subheader: subheader,
info: info,
},
// Listen and react to events using callbacks. In this case we listen for
// the "click" event emitted when clicking the toast button
listeners: {},
};
// Render the toast and its contents
toast(content, {
position: "top-center",
icon: false,
closeOnClick: false,
toastClassName: "modal-overlay",
closeButton: false,
hideProgressBar: true,
timeout: false,
});
}
</script>
<style lang="sass">
+61 -42
View File
@@ -2,10 +2,10 @@
<div class="stake-menu">
<token-input :modelValue="props.modelValue" @input="emit('update:modelValue', Number($event.target.value))">
<template v-slot:message>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(25)">25%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(50)">50%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(75)">75%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(100)">100%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(25n)">25%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(50n)">50%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(75n)">75%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(100n)">100%</div>
</template>
<template v-slot:message-end>
<slot name="message-end"> </slot>
@@ -14,7 +14,13 @@
<div class="stake-menu-actions">
<slot name="body">
<div class="input-balance">Balance: {{ walletStore.memeToken.balanceOf }}</div>
<div class="btn btn-immortal stake-button" @click="stakeBloodline" v-if="props.stake">Stake</div>
<div
class="btn btn-immortal stake-button"
@click="rewardLockerStore.stakeBloodline(tokenNumber)"
v-if="props.stake"
>
Stake
</div>
<div class="btn btn-immortal stake-button" @click="unstakeBloodline" v-else>Unstake for Next Cycle</div>
<div class="btn btn-immortal black" @click="emit('close')">Cancel</div>
</slot>
@@ -30,6 +36,7 @@ import { useWalletStoreV2 } from "@/stores/walletV2";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useTokenStore } from "@/stores/tokens";
import { createPermitObject, getSignatureRSV } from "@/helper/blockchain.js";
import { formatNumber } from "@/helper/helper.js";
import { signTypedData } from "@wagmi/core";
@@ -39,65 +46,77 @@ const tokenStore = useTokenStore();
const props = defineProps({
stake: Boolean,
modelValue: Number,
amount: Number,
modelValue: [Number, BigInt],
amount: [Number, BigInt],
});
const emit = defineEmits(["close", "update:modelValue"]);
async function addTokensPercent(value) {
console.log("value", value);
console.log(walletStore.memeToken.balanceOf);
console.log("props.amount", props.amount);
let amount;
if (props.amount !== undefined || props.amount !== null) {
amount = (props.amount * value) / 100;
//todo function to calculate correct bigInt value (maybe use string and split)
amount = (BigInt(props.amount) * value) / 100n;
} else if (props.stake) {
amount = (walletStore.memeToken.balanceOf * value) / 100;
amount = (walletStore.memeToken.balanceOf * value) / 100n;
} else {
amount = (walletStore.memeToken.staked * value) / 100;
amount = (walletStore.memeToken.staked * value) / 100n;
}
emit("update:modelValue", Number(amount));
console.log("amount123", amount);
amount = amount / 10n ** tokenStore.memeToken.decimals;
console.log("amount", amount);
emit("update:modelValue", amount);
}
async function unstakeBloodline() {
const fromAddress = walletStore.address;
try {
const fromAddress = walletStore.address;
var test1 = await rewardLockerStore.contract.read.unstakeOrdered([4, fromAddress]);
console.log("test1", test1);
var test = true;
if (test) {
return;
var unstakedOrdered = await rewardLockerStore.contract.read.unstakeOrdered([4, fromAddress]);
//check if states needed here
var hash = await rewardLockerStore.contract.write.orderUnstake();
console.log("hash", hash);
const data = await waitForTransaction({
hash: hash,
});
console.log("data", data);
} catch (error) {
console.error("unstakeBloodline", error);
}
var hash = await rewardLockerStore.contract.write.orderUnstake();
console.log("hash", hash);
const data = await waitForTransaction({
hash: hash,
});
console.log("data", data);
}
async function stakeBloodline() {
const fromAddress = walletStore.address;
const spender = rewardLockerStore.config.contractAddress;
const deadline = Date.now() + 20 * 60;
const decimals = tokenStore.getToken(walletStore.memeToken.contractAddress).decimals;
const value = (tokenNumber.value * Math.pow(10, decimals)).toString();
const nonce = await tokenStore.memeToken.contract.read.nonces([fromAddress]);
console.log("nonce", nonce);
const { types, message, domain, primaryType } = createPermitObject(fromAddress, spender, nonce, deadline, value);
try {
console.log("stakeBloodline");
const fromAddress = walletStore.address;
const spender = rewardLockerStore.config.contractAddress;
const deadline = Date.now() + 20 * 60;
const decimals = tokenStore.getToken(walletStore.memeToken.contractAddress).decimals;
const value = BigInt(tokenNumber.value) * 10n ** decimals;
const nonce = await tokenStore.memeToken.contract.read.nonces([fromAddress]);
const { types, message, domain, primaryType } = createPermitObject(
fromAddress,
spender,
nonce,
deadline,
value
);
const signature = await signTypedData({
domain: domain,
message: message,
primaryType: primaryType,
types: types,
});
const signature = await signTypedData({
domain: domain,
message: message,
primaryType: primaryType,
types: types,
});
const { r, s, v } = getSignatureRSV(signature);
const { r, s, v } = getSignatureRSV(signature);
var resultStake = await rewardLockerStore.contract.write.stakeToBeSecured([value, deadline, v, r, s]);
console.log("resultStake", resultStake);
var resultStake = await rewardLockerStore.contract.write.stakeToBeSecured([value, deadline, v, r, s]);
} catch (error) {
console.error("stakeBloodline", error);
}
}
</script>
+189 -45
View File
@@ -1,12 +1,12 @@
<template>
<div class="claim bloodline-border bloodline-border__thin grey">
<div class="claim-headline sub-header">You Cycle Rewards</div>
<div class="claim-headline sub-header">Your Cycle Rewards</div>
<!-- <div class="rewards-wrapper" v-if="!isMobile">
<rewards-wrapper
title="Sacrafice Reward"
coin="$BLOOD"
:amount="getCurrentRoundData?.rewards_sacrifice"
:amount="getCurrentCycleData?.rewards_sacrifice"
image="/assets/img/vampir.png"
/>
<div class="rewards-divider bloodline-devider">
@@ -15,7 +15,7 @@
<rewards-wrapper
title="Clan Reward"
coin="$BLOOD"
:amount="getCurrentRoundData?.rewards_clan"
:amount="getCurrentCycleData?.rewards_clan"
image="/assets/img/vampir.png"
/>
</div> -->
@@ -23,54 +23,73 @@
<rewards-wrapper
title="Sacrafice Reward"
coin="$BLOOD"
:amount="getCurrentRoundData?.rewards_sacrifice.toFixed(2)"
:amount="formatNumber(rewardsSacrifice, 10n ** tokenStore.memeToken.decimals)"
image="/assets/img/vampir.png"
/>
<rewards-wrapper
title="Staking Bonus"
coin="$BLOOD"
:amount="getCurrentRoundData?.rewards_staking.toFixed(2)"
info="max: 312m"
:amount="formatNumber(rewardsStaking, 10n ** tokenStore.memeToken.decimals)"
image="/assets/img/vampir.png"
/>
<rewards-wrapper
title="Clan Bonus"
:subTitle="rewardsClan > 0 ? clanBonusPercentage : null"
coin="$BLOOD"
:amount="getCurrentRoundData?.rewards_clan.toFixed(2)"
image="/assets/img/vampir.png"
:amount="formatNumber(rewardsClan, 10n ** tokenStore.memeToken.decimals)"
:image="
activeCycle === currentCycle || !cycleStore.getCurrentCycleData?.winner.vamplogo
? '/assets/img/token/notoken.png'
: cycleStore.getCurrentCycleData?.winner.vamplogo
"
/>
</div>
<div class="rewards-total-wrapper">
<div class="rewards-total-headline low-mid-text">Total Reward</div>
<div class="rewards-total-inner bloodline-border bloodline-border--variant1">
<div class="rewards-total-headline sub-header">Total Reward</div>
<div
class="rewards-total-inner bloodline-border bloodline-border--variant1"
:class="{ purple: rewardsTotal > 0n && activeCycle !== currentCycle }"
>
<token-name-price
name="$BLOOD"
:price="getCurrentRoundData?.rewards_total?.toFixed(5)"
:price="formatNumber(rewardsTotal, 10n ** tokenStore.memeToken.decimals)"
></token-name-price>
<token-logo img="/assets/img/vampir.png" :alt="'vampire'"></token-logo>
<!-- <div class="rewards-coin low-mid-text">$BLOOD</div>
<div class="rewards-amount header" v-if="activeRound === currentRound">0</div>
<div class="rewards-amount header" v-else>{{ getCurrentRoundData?.rewards_total.toFixed(5) }}</div> -->
<!-- </div> -->
<!-- <img class="bloodline-token" src="/assets/img/token/bloodline.png" alt="vampir" /> -->
<token-logo img="/assets/img/vampir.png" :size="64" :alt="'vampire'"></token-logo>
</div>
</div>
<div class="claim-button">
<template v-if="!walletStore.connected">
<button class="btn btn-immortal sub-header" @click="showPanel = true">Connect</button>
</template>
<template v-else-if="activeRound === currentRound">
<button class="btn btn-immortal sub-header" @click="router.push({ name: 'home' })">Sacrifice</button>
<template v-else-if="activeCycle === currentCycle">
<template v-if="rewardsSacrifice > 0n">
<div class="stake-buttons">
<button class="btn btn-immortal sub-header btn--disabled">Claim</button>
<button class="btn btn-immortal sub-header btn--disabled">Stake</button>
</div>
<div>You can claim once the current cycle is finished and the clan bonus calculated</div>
</template>
<template v-else>
<button class="btn btn-immortal sub-header" @click="router.push({ name: 'home' })">
Sacrifice
</button>
</template>
</template>
<template v-else-if="getCurrentRoundData?.rewards_total > 0">
<template v-else-if="rewardsTotal > 0">
<Transition name="smooth">
<div class="stake-buttons" v-show="!stakeMenu">
<div class="btn btn-immortal" v-if="stateClaimedComp === 0" @click="claimRewards">Claim</div>
<div class="btn btn-immortal" disabled v-if="stateClaimedComp === 2">Sign Transaction</div>
<div class="btn btn-immortal" disabled v-if="stateClaimedComp === 3">
<div class="btn btn-immortal sub-header" v-if="stateClaimedComp === 0" @click="claimRewards">
Claim
</div>
<div class="btn btn-immortal sub-header" disabled v-if="stateClaimedComp === 2">
Sign Transaction
</div>
<div class="btn btn-immortal sub-header" disabled v-if="stateClaimedComp === 3">
<loading-component></loading-component>
</div>
<div class="btn btn-immortal" @click="openStake">Stake</div>
<div class="btn btn-immortal sub-header" v-if="stateClaimedComp === 0" @click="openStake">
Stake
</div>
</div>
</Transition>
<Transition name="smooth">
@@ -78,11 +97,38 @@
v-model="tokenNumber"
@close="stakeMenu = false"
:stake="stake"
:amount="getCurrentRoundData?.rewards_total"
:amount="rewardsTotal"
v-if="stakeMenu"
>
<template v-slot:body>
<div class="btn btn-immortal stake-button" @click="stakeAndClaim">Stake & Claim Rest</div>
<div
class="btn btn-immortal sub-header stake-button"
disabled
v-if="stateStakeClaimComp === 0"
>
Enter Amount
</div>
<div
class="btn btn-immortal sub-header stake-button"
v-else-if="stateStakeClaimComp === 1"
@click="stakeAndClaim"
>
Stake & Claim Rest
</div>
<div
class="btn btn-immortal sub-header stake-button"
disabled
v-if="stateStakeClaimComp === 2"
>
Sign Transaction
</div>
<div
class="btn btn-immortal sub-header stake-button"
disabled
v-if="stateStakeClaimComp === 3"
>
<loading-component></loading-component>
</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
@@ -106,36 +152,87 @@ import RewardsWrapper from "@/components/RewardsWrapper.vue";
import { inject, ref, onMounted, computed } from "vue";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useRoundsStore } from "@/stores/rounds";
import { useTokenStore } from "@/stores/tokens";
import { useCycleStore } from "@/stores/cycles";
import { useRouter } from "vue-router";
import StakeMenu from "@/components/StakeMenu.vue";
import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue";
import TokenNamePrice from "@/components/TokenNamePrice.vue";
import TokenLogo from "@/components/TokenLogo.vue";
import { formatNumber, formatBigIntDivision } from "@/helper/helper.js";
import { showSuccessToast } from "@/helper/toast.js";
const clanRewards = ref(0);
const rewards = ref(0);
const isMobile = inject("isMobile");
const showPanel = inject("showPanel");
const rewardLockerStore = useRewardLockerStore();
const walletStore = useWalletStoreV2();
const roundStore = useRoundsStore();
const { address } = storeToRefs(walletStore);
const tokenStore = useTokenStore();
const cycleStore = useCycleStore();
const router = useRouter();
const { activeRound, currentRound, getCurrentRoundData } = storeToRefs(roundStore);
const { activeCycle, currentCycle, getCurrentCycleData, rewardsSacrifice, rewardsStaking, rewardsClan, rewardsTotal } =
storeToRefs(cycleStore);
const stakeMenu = ref(false);
const stake = ref(null);
const tokenNumber = ref(null);
const stateClaim = ref(0);
const stateStakeClaim = ref(0);
async function stakeAndClaim() {
console.log(tokenNumber.value);
console.log(getCurrentRoundData.value.rewards_total);
const coefficient = (10000 * tokenNumber.value) / getCurrentRoundData.value.rewards_total;
var result = await rewardLockerStore.stakeAndClaimRound(coefficient, roundStore.activeRound);
try {
console.log("stakeAndClaim");
console.log(tokenNumber.value);
console.log(rewardsTotal.value);
stateStakeClaim.value = 2;
console.log("hier1");
const coefficient = (10000n * BigInt(tokenNumber.value)) / rewardsTotal.value;
var hash = await rewardLockerStore.stakeAndClaimCycle(coefficient, cycleStore.activeCycle);
console.log("hier2");
stateStakeClaim.value = 3;
console.log("hash");
const data = await waitForTransaction({
hash: hash,
});
console.log("data", data);
stateStakeClaim.value = 4;
//ClaimedReward (address staker, uint256 reward)
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xd0813ff03c470dcc7baa9ce36914dc2febdfd276d639deffaac383fd3db42ba3"
);
});
var stakeData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xf496bf2b14b1d178412b6f7a745900105b49b38b315cfdfbfabad31a6f995c6f"
);
});
//
console.log("rewardData", rewardData);
console.log("stakeData", stakeData);
const outputClaim = BigInt(rewardData?.topics[2]);
const outputStaked = BigInt(stakeData?.topics[3]);
showSuccessToast(
formatNumber(outputClaim + outputStaked, 10n ** tokenStore.memeToken.decimals),
"Success!",
"You just claimed and staked",
"Join the next cycle to increase your rewards and win with your clan."
);
tokenNumber.value = 0;
stakeMenu.value = false;
await walletStore.loadWalletData();
} catch (error) {
console.error("stakeAndClaim", error);
} finally {
const walletStore = useWalletStoreV2();
await walletStore.loadWalletData();
console.log("finally1");
await cycleStore.fillCycle(activeCycle.value, true);
console.log("finally2");
stateStakeClaim.value = 1;
}
}
function openStake() {
@@ -148,25 +245,50 @@ onMounted(async () => {});
async function claimRewards() {
try {
stateClaim.value = 2;
console.log("getCurrentRoundData", getCurrentRoundData);
console.log("activeRound.value", activeRound.value);
var hash = await rewardLockerStore.claim([activeRound.value]);
console.log("getCurrentCycleData", getCurrentCycleData);
console.log("activeCycle.value", activeCycle.value);
var hash = await rewardLockerStore.claim([activeCycle.value]);
stateClaim.value = 3;
console.log("hash", hash);
const data = await waitForTransaction({
hash: hash,
});
stateClaim.value = 4;
//reload
await roundStore.fillRound(activeRound.value, true);
// ClaimedReward (address staker, uint256 reward)
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xd0813ff03c470dcc7baa9ce36914dc2febdfd276d639deffaac383fd3db42ba3"
);
});
//
console.log("rewardData", rewardData);
const outputClaim = formatNumber(BigInt(rewardData.topics[2]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast(
outputClaim,
"Success!",
"You just claimed",
"Join the next cycle to increase your rewards and win with your clan."
);
await cycleStore.fillCycle(activeCycle.value, true);
await walletStore.loadWalletData();
} catch (error) {
stateClaim.value = 0;
console.error(error);
throw new Error(error);
throw Error(error);
}
}
const clanBonusPercentage = computed(() => {
return (
(
(formatBigIntDivision(rewardsClan.value, 10n ** tokenStore.memeToken.decimals, 8) /
formatBigIntDivision(rewardsTotal.value, 10n ** tokenStore.memeToken.decimals, 8)) *
100
).toFixed(2) + "%"
);
});
const stateClaimedComp = computed(() => {
let returnState = 0;
if (stateClaim.value === 2) {
@@ -176,6 +298,26 @@ const stateClaimedComp = computed(() => {
}
return returnState;
});
const stateStakeClaimComp = computed(() => {
console.log("stateStakeClaimComp");
let returnState = 0;
if (stateStakeClaim.value === 2) {
returnState = 2;
} else if (stateStakeClaim.value === 3) {
returnState = 3;
} else if (tokenNumber.value !== null || tokenNumber.value !== "" || tokenNumber.value > 0) {
returnState = 1;
} else if (
tokenNumber.value === null ||
tokenNumber.value === "" ||
tokenNumber.value === 0 ||
BigInt(tokenNumber.value) > walletStore.unclaimedRewards / 10n ** tokenStore.memeToken.decimals
) {
returnState = 0;
}
return returnState;
});
</script>
<style lang="sass">
@@ -190,6 +332,9 @@ const stateClaimedComp = computed(() => {
text-align: left
.claim-button
text-align: center
display: flex
flex-direction: column
gap: 24px
.stake-buttons
display: flex
text-align: center
@@ -213,7 +358,6 @@ const stateClaimedComp = computed(() => {
justify-content: space-between
text-align: left
box-sizing: content-box
height: 56px
.rewards-left
display: flex
flex-direction: column
+6 -7
View File
@@ -7,6 +7,7 @@
:value="props.modelValue"
:placeholder="0"
type="number"
pattern="\d*"
/>
<div class="value-adder">
<slot class="value-adder" name="message"></slot>
@@ -14,11 +15,7 @@
</div>
</div>
<div class="right-side">
<token-logo :img="props.logo" :alt="'vampir'"></token-logo>
<!-- <div class="sacrifice-logo" v-if="props.logo">
<img :src="props.logo" alt="vampir" />
</div> -->
<token-logo v-if="props.logo" :img="props.logo" :alt="'vampir'"></token-logo>
</div>
</div>
</div>
@@ -30,7 +27,7 @@ import TokenLogo from "@/components/TokenLogo.vue";
const props = defineProps({
modelValue: [String, Number],
logo: String,
max: Number,
max: [BigInt, Number],
});
const emit = defineEmits(["update:modelValue"]);
@@ -66,10 +63,12 @@ const emit = defineEmits(["update:modelValue"]);
.stake-adder-step
padding: 4px 16px
color: var(--black)
font-size: 14px
font-size: 12px
border-width: 1px
border-color: transparent
border-style: solid
@media (min-width: 992px)
font-size: 14px
&:hover,&:active, &:focus
background-color: var(--grey-light)
cursor: pointer
+6 -4
View File
@@ -1,13 +1,17 @@
<template>
<div class="token-logo">
<img :src="props.img" :alt="props.alt" />
<img :src="props.img" :alt="props.alt" :style="{ height: `${size}px`, width: `${size}px` }" />
</div>
</template>
<script setup>
const props = defineProps({
img: String,
alt: Number,
alt: String,
size: {
type: Number,
default: 45,
},
});
</script>
@@ -15,8 +19,6 @@ const props = defineProps({
.token-logo
height: 100%
img
width: 45px
height: 45px
border-radius: 50%
pointer-events: none
@media (min-width: 992px)
+9 -2
View File
@@ -1,7 +1,9 @@
<template>
<div class="token-price-wrapper">
<div class="token-name small-text">{{ props.name }}</div>
<div class="token-price sub-header">{{ props.price }}</div>
<div class="token-name tiny-text">{{ props.name }}</div>
<div class="token-price" :class="{ 'sub-header-2': !props.variant, 'sub-header': props.variant }">
{{ props.price }}
</div>
</div>
</template>
@@ -9,6 +11,11 @@
const props = defineProps({
name: String,
price: [Number, String],
variant: {
type: Boolean,
required: false,
default: false,
},
});
</script>
+53
View File
@@ -0,0 +1,53 @@
<template>
<div class="approve-card">
<div class="left-side low-mid-text">Transaction Successful</div>
</div>
</template>
<script setup>
import LoadingComponent from "@/components/LoadingComponent.vue";
import { getCurrentInstance, computed, watch, inject } from "vue";
import { useTokenStore } from "@/stores/tokens";
import { useSacrificeStore } from "@/stores/sacrifice";
import CardComponent from "@/components/CardComponent.vue";
import { useToast } from "vue-toastification";
const emit = defineEmits(["sacrificed"]);
const props = defineProps({
value: String,
header: String,
subheader: String,
info: String,
});
const toast = useToast();
const tokenStore = useTokenStore();
const sacrificeStore = useSacrificeStore();
const instance = getCurrentInstance();
const id = instance.attrs["toast-id"];
const splashBlood = inject("splashBlood");
function closeToast() {
toast.dismiss(id);
}
</script>
<style lang="sass">
.Vue-Toastification__container
.Vue-Toastification__toast--default
&.approve-toast
background: transparent
&.toast-card
padding: 24px 16px
border-radius: 10px
border: 2px solid var(--dark-purple, #4B0082)
background: var(--midnight-black, #0F0F0F)
.Vue-Toastification__toast-component-body
.approve-card
display: flex
flex-direction: row
display: flex
align-items: center
gap: 29px
</style>
+1 -1
View File
@@ -10,7 +10,7 @@
</div>
<div class="amount-number">
<div class="token-amount number-mobile">{{ props.value }}</div>
<div class="token-name">$Blood</div>
<div class="token-name">$BLOOD</div>
</div>
<div class="info toast-body">
{{ props.info }}
@@ -0,0 +1,86 @@
<template>
<div class="network-switch-card">
<div>Please switch Network to</div>
<div>
<b>{{ props.network.chains[0].name }}</b>
</div>
</div>
</template>
<script setup>
import LoadingComponent from "@/components/LoadingComponent.vue";
import { getCurrentInstance, computed, watch, inject } from "vue";
import { useTokenStore } from "@/stores/tokens";
import { useSacrificeStore } from "@/stores/sacrifice";
import CardComponent from "@/components/CardComponent.vue";
import { useToast } from "vue-toastification";
const emit = defineEmits(["sacrificed"]);
const props = defineProps({
network: Object,
});
const toast = useToast();
const tokenStore = useTokenStore();
const sacrificeStore = useSacrificeStore();
const instance = getCurrentInstance();
const id = instance.attrs["toast-id"];
const splashBlood = inject("splashBlood");
function closeToast() {
toast.dismiss(id);
}
const stateComputed = computed(() => {
let returnState = 0;
if (
sacrificeStore.sacrificeNumber === null ||
sacrificeStore.sacrificeNumber === "" ||
sacrificeStore.sacrificeNumber === 0
) {
returnState = 0;
} else if (sacrificeStore.sacrificeState === 2) {
returnState = 2;
} else if (sacrificeStore.sacrificeState === 3) {
returnState = 3;
} else if (
sacrificeStore.sacrificeNumber !== null ||
sacrificeStore.sacrificeNumber !== "" ||
sacrificeStore.sacrificeNumber > 0
) {
returnState = 1;
}
return returnState;
});
async function sacrificeClick() {
try {
var result = await sacrificeStore.sacrificeToken(sacrificeStore.sacrificeNumber, tokenStore.activeToken);
if (result) {
emit("sacrificed");
}
} catch (error) {
console.error("error", error);
} finally {
closeToast();
}
}
</script>
<style lang="sass">
.Vue-Toastification__container
.Vue-Toastification__toast--default
&.approve-toast
background: transparent
&.toast-card
padding: 24px 16px
border-radius: 10px
border: 2px solid var(--dark-purple, #4B0082)
background: var(--midnight-black, #0F0F0F)
.Vue-Toastification__toast-component-body
.network-switch-card
display: flex
flex-direction: column
display: flex
</style>
-88
View File
@@ -1,88 +0,0 @@
<script>
export default {
name: `TransitionExpand`,
functional: true,
render(createElement, context) {
const data = {
props: {
name: `expand`,
},
on: {
afterEnter(element) {
// eslint-disable-next-line no-param-reassign
element.style.height = `auto`;
},
enter(element) {
const { width } = getComputedStyle(element);
/* eslint-disable no-param-reassign */
element.style.width = width;
element.style.position = `absolute`;
element.style.visibility = `hidden`;
element.style.height = `auto`;
/* eslint-enable */
const { height } = getComputedStyle(element);
/* eslint-disable no-param-reassign */
element.style.width = null;
element.style.position = null;
element.style.visibility = null;
element.style.height = 0;
/* eslint-enable */
// Force repaint to make sure the
// animation is triggered correctly.
// eslint-disable-next-line no-unused-expressions
getComputedStyle(element).height;
requestAnimationFrame(() => {
// eslint-disable-next-line no-param-reassign
element.style.height = height;
});
},
leave(element) {
const { height } = getComputedStyle(element);
// eslint-disable-next-line no-param-reassign
element.style.height = height;
// Force repaint to make sure the
// animation is triggered correctly.
// eslint-disable-next-line no-unused-expressions
getComputedStyle(element).height;
requestAnimationFrame(() => {
// eslint-disable-next-line no-param-reassign
element.style.height = 0;
});
},
},
};
return createElement(`transition`, data, context.children);
},
};
</script>
<style scoped>
* {
will-change: height;
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000px;
}
</style>
<style>
.expand-enter-active,
.expand-leave-active {
transition: height 1s ease-in-out;
overflow: hidden;
}
.expand-enter,
.expand-leave-to {
height: 0;
}
</style>
+52 -14
View File
@@ -1,18 +1,43 @@
export function getImageUrl(url) {
return new URL(url, import.meta.url).href;
}
export function getPercentage(amount, goal) {
return ((Number(amount) / Number(goal)) * 100).toFixed(2);
}
export function compactNumber(number) {
return Intl.NumberFormat("en-US", {
return Intl.NumberFormat("en-US", {
notation: "compact",
maximumFractionDigits: 2,
}).format(parseInt(number));
}).format(number);
}
export function formatNumber(nominator, denominator) {
let number = formatBigIntDivision(nominator, denominator);
number = InsertCommaNumber(number).toString();
return number;
}
export function formatBigIntDivision(nominator, denominator, digits = 2) {
console.log("nominator", nominator);
console.log("denominator", denominator);
if (!nominator) {
return 0n
}
let integer = Number(nominator / denominator);
// pick how much digits after point to show
const fraction = (nominator % denominator).toString().substring(0, digits);
// output type number
return Number(integer + "." + fraction);
}
export function InsertCommaNumber(number) {
if (!number) {
return 0
}
const formattedWithOptions = number.toLocaleString("en-US");
return formattedWithOptions;
}
export function getAddressShortName(address) {
@@ -23,13 +48,6 @@ export function getAddressShortName(address) {
}
export function numberWithCommas(x, ) {
x = x.toString();
var pattern = /(-?\d+)(\d{3})/;
while (pattern.test(x)) x = x.replace(pattern, "$1,$2");
return x;
}
export function getblocky(address) {
var blockiesData = blockies
.create({
@@ -41,3 +59,23 @@ export function getblocky(address) {
return blockiesData;
}
export function debounce(func, timeout = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
return func.apply(this, args);
}, timeout);
};
}
export function createDebounce() {
let timeout = null;
return function (fnc, delayMs) {
clearTimeout(timeout);
timeout = setTimeout(() => {
fnc();
}, delayMs || 500);
};
}
+32
View File
@@ -0,0 +1,32 @@
import StakeSuccessToast from "@/components/toasts/StakeSuccessToast.vue";
import { useToast } from "vue-toastification";
const toast = useToast();
export function showSuccessToast(value, header, subheader, info) {
// Define the content object with the component, props and listeners
const content = {
component: StakeSuccessToast,
// Any prop can be passed, but don't expect them to be reactive
props: {
value: value,
header: header,
subheader: subheader,
info: info,
},
// Listen and react to events using callbacks. In this case we listen for
// the "click" event emitted when clicking the toast button
listeners: {},
};
// Render the toast and its contents
toast(content, {
position: "top-center",
icon: false,
closeOnClick: false,
toastClassName: "modal-overlay",
closeButton: false,
hideProgressBar: true,
timeout: false,
});
}
+85 -58
View File
@@ -4,7 +4,7 @@ import { useTokenStore } from "@/stores/tokens";
import { useMemeburnerStore } from "@/stores/memeburner";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useUniswapStore } from "@/stores/uniswap";
import { useRoundsStore } from "@/stores/rounds";
import { useCycleStore } from "@/stores/cycles";
import { createApp } from 'vue'
import { createPinia } from 'pinia'
@@ -13,24 +13,16 @@ import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
import {
createConfig,
configureChains,
getAccount,
getNetwork,
getContract,
connect,
disconnect,
InjectedConnector,
watchAccount,
watchWalletClient,
watchPublicClient,
watchContractEvent,
watchNetwork,
getWalletClient,
fetchBalance,
multicall,
} from "@wagmi/core";
import { WalletConnectConnector } from "@wagmi/core/connectors/walletConnect";
import { MetaMaskConnector } from "@wagmi/core/connectors/metaMask";
import { CoinbaseWalletConnector } from "@wagmi/core/connectors/coinbaseWallet";
import { InjectedConnector } from "@wagmi/core/connectors/injected";
import { goerli, mainnet } from "@wagmi/core/chains";
import { publicProvider } from "@wagmi/core/providers/public";
@@ -46,13 +38,15 @@ import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
/* import specific icons */
import { faArrowDown, faArrowRight, faSpinner, faPlus, faCaretLeft, faCaretRight, faBars, faAnglesRight, faChevronDown, faChevronUp, faArrowRightToBracket, faArrowRightFromBracket, faDroplet, faMoon, faPerson } from "@fortawesome/free-solid-svg-icons";
import { faArrowDown, faArrowRight, faSpinner, faPlus, faCaretLeft, faCaretRight, faBars, faAnglesRight, faChevronDown, faChevronUp, faArrowRightToBracket, faArrowRightFromBracket, faDroplet, faMoon, faPerson, faWallet, faBlog } from "@fortawesome/free-solid-svg-icons";
import { faDiscord, faTwitter, faTelegram } from "@fortawesome/free-brands-svg-icons";
import Toast from "vue-toastification";
// Import the CSS or use your own!
import "vue-toastification/dist/index.css";
import SwitchNetworkToast from "@/components/toasts/SwitchNetworkToast.vue";
import { useToast } from "vue-toastification";
/* add icons to the library */
library.add(
@@ -71,11 +65,23 @@ library.add(
faArrowRightFromBracket,
faChevronDown,
faChevronUp,
faDroplet,
faMoon,
faPerson
faDroplet,
faMoon,
faPerson,
faWallet,
faBlog
);
var logging = localStorage.getItem("LOGGING");
if (logging === "true") {
} else {
if (!window.console) window.console = {};
var methods = ["log", "debug", "warn", "info"];
for (let i = 0; i < methods.length; i++) {
console[methods[i]] = function () {};
}
}
const app = createApp(App)
@@ -86,7 +92,39 @@ app.use(pinia);
app.use(Toast, {});
app.use(Toast, {
transition: "Vue-Toastification__fade",
containerClassName: "bloodline-toast-container",
});
function showSwitchNetworkToast(network) {
const toast = useToast();
// Define the content object with the component, props and listeners
const content = {
component: SwitchNetworkToast,
// Any prop can be passed, but don't expect them to be reactive
props: {
network
},
// Listen and react to events using callbacks. In this case we listen for
// the "click" event emitted when clicking the toast button
listeners: {},
};
// Render the toast and its contents
return toast(content, {
position: "top-right",
icon: false,
closeOnClick: false,
// toastClassName: "modal-overlay",
hideProgressBar: true,
timeout: false,
toastClassName: "approve-toast toast-card",
});
}
try {
@@ -94,14 +132,15 @@ try {
const tokenStore = useTokenStore();
const memeBurnerStore = useMemeburnerStore();
const rewardLockerStore = useRewardLockerStore();
const roundsStore = useRoundsStore();
const cycleStore = useCycleStore();
const uniswapStore = useUniswapStore();
const goerliKey = import.meta.env.VITE_GOERLI_KEY;
const projectId = "d8e5ecb0353c02e21d4c0867d4473ac5";
console.log("hier chains");
const { chains, publicClient, webSocketPublicClient } = configureChains(
[goerli, mainnet],
// [goerli, mainnet],
[goerli],
[alchemyProvider({ apiKey: goerliKey }), publicProvider()]
);
@@ -114,7 +153,11 @@ try {
appName: "wagmi demo",
},
}),
new MetaMaskConnector({ chains }),
// new MetaMaskConnector({ chains }),
new InjectedConnector({
chains,
getProvider: () => (typeof window !== "undefined" ? window.myInjectedWallet : undefined),
}),
new WalletConnectConnector({
chains,
options: {
@@ -134,25 +177,6 @@ try {
});
walletStore.publicClient = publicClient;
const networkId = getNetwork()?.chain?.id;
// watchWalletClient(
// {
// chainId: networkId,
// },
// async (walletClient) => {
// console.log("watchWalletClient", walletClient);
// walletStore.walletClient = walletClient;
// }
// );
// watchPublicClient(
// {
// chainId: networkId,
// },
// (publicClient) => console.log("publicClient", publicClient)
// );
watchContractEvent(
{
address: memeBurnerStore.config.contractAddress,
@@ -162,7 +186,7 @@ try {
async (log) => {
console.log("memeSacrificedEvent", log);
const token = log[0].args.sacrificedToken;
await roundsStore.updateCurrentRound(token);
await cycleStore.updateCurrentCycle(token);
}
);
@@ -170,13 +194,13 @@ try {
{
address: rewardLockerStore.config.contractAddress,
abi: rewardLockerStore.config.abi,
eventName: "RoundCompleted",
eventName: "CycleCompleted",
},
async (log) => {
console.log("roundCompleted", log);
await roundsStore.fillRound(roundsStore.currentRound);
roundsStore.currentRound++;
await roundsStore.fillRound(roundsStore.currentRound);
console.log("CycleCompleted", log);
await cycleStore.fillCycle(cycleStore.currentCycle, true);
cycleStore.currentCycle++;
await cycleStore.fillCycle(cycleStore.currentCycle, true);
}
);
@@ -202,7 +226,8 @@ try {
await memeBurnerStore.init();
await tokenStore.initV2();
await rewardLockerStore.init();
await walletStore.loadWalletData();
await walletStore.loadWalletData();
await cycleStore.fillCycle(cycleStore.currentCycle, true);
await uniswapStore.init();
} else {
walletStore.address = null;
@@ -211,24 +236,26 @@ try {
}
});
watchNetwork((network) => {
watchNetwork((network) => {
if (!network.chain?.network) {
return;
}
const chainAllowed = network.chains?.find((obj) => {
return obj.network === network.chain.network;
});
if (!chainAllowed) {
console.log("chain not allowed", network.chain);
showSwitchNetworkToast(network);
return
} else {
console.log("chain allowed", network.chain);
}
if (network.chain) {
walletStore.chain = network.chain;
}
});
});
// watchContractEvent(
// {
// address: memeBurnerStore.config.contractAddress,
// abi: memeBurnerStore.config.abi,
// eventName: "MemeSacrificed",
// },
// async (log) => {
// console.log("memeSacrificedEvent", log);
// const token = log[0].args.sacrificedToken;
// await roundsStore.updateCurrentRound(token);
// }
// );
await walletStore.init();
await tokenStore.initV2();
-12
View File
@@ -1,12 +0,0 @@
import { defineStore } from "pinia";
export const useContractStore = defineStore("contracts", {
state: () => ({
list: {
}
}),
getters: {
},
actions: {
}
});
+230
View File
@@ -0,0 +1,230 @@
import { defineStore } from "pinia";
import { useMemeburnerStore } from "./memeburner";
import { useTokenStore } from "./tokens";
import { useRewardLockerStore } from "./rewardlocker";
import { useWalletStoreV2 } from "./walletV2";
import { multicall } from "@wagmi/core";
export const useCycleStore = defineStore("cycles", {
state: () => ({
cycles: [],
activeCycle: null,
currentCycle: null,
}),
getters: {
//cycle winner is the token who reached the goal
//todo winner is now in the cycle object, no reason for that function anymore
getCycleWinner() {
const goal = this.getCurrentCycleData?.goal;
if (!goal) {
return;
}
const winnerCoin = this.cycles[this.activeCycle]?.token.find((token) => token.amount === goal);
if (winnerCoin) {
return winnerCoin;
} else {
return false;
}
},
getCurrentCycleData() {
return this.cycles[this.activeCycle];
},
rewardsSacrifice() {
const tokenStore = useTokenStore();
if (!this.cycles[this.activeCycle]?.rewards_sacrifice) {
return 0n;
}
return this.cycles[this.activeCycle]?.rewards_sacrifice;
},
rewardsSacrificeCurrentCycle() {
const tokenStore = useTokenStore();
if (!this.cycles[this.currentCycle]?.rewards_sacrifice) {
return 0n;
}
return this.cycles[this.currentCycle]?.rewards_sacrifice;
},
rewardsStaking() {
const tokenStore = useTokenStore();
if (!this.cycles[this.activeCycle]?.rewards_staking) {
return 0n;
}
return this.cycles[this.activeCycle]?.rewards_staking;
},
rewardsClan() {
const tokenStore = useTokenStore();
if (!this.cycles[this.activeCycle]?.rewards_clan) {
return 0n;
}
return this.cycles[this.activeCycle]?.rewards_clan;
},
rewardsTotal() {
const tokenStore = useTokenStore();
if (!this.cycles[this.activeCycle]?.rewards_total) {
return 0n;
}
return this.cycles[this.activeCycle]?.rewards_total;
},
},
actions: {
//todo check if still needed
// async loadRewardsCycles() {
// const walletStore = useWalletStoreV2();
// const rewardLockerStore = useRewardLockerStore();
// console.log("this.currentCycle", this.currentCycle);
// const contracts = [];
// for (let index = 0; index < this.currentCycle; index++) {
// console.log("load cycle: " + index);
// console.log({ index, address: walletStore.address });
// contracts.push({
// ...rewardLockerStore.contract,
// functionName: "getTotalRewardsOf",
// args: [walletStore.address, [index + 1]],
// });
// }
// const data = await multicall({
// contracts,
// });
// for (let index = 0; index < data.length; index++) {
// const element = data[index];
// if (!this.cycles[index]) {
// this.cycles[index] = {};
// }
// }
// },
//todo check if needed, or use fillcycle
async updateCurrentCycle(sacrificedToken) {
console.log("updateCurrentCycle");
const memeBurnerStore = useMemeburnerStore();
const rewardLockerStore = useRewardLockerStore();
var data = await memeBurnerStore.getSacrificedCycle(this.currentCycle);
var tokenTotalSacrificed = await rewardLockerStore.getTotalSacrificeRewardsForAllToken(this.currentCycle);
console.log("this.currentCycle", this.currentCycle);
console.log("this.cycles", this.cycles);
if (this.cycles[this.currentCycle]) {
var tokenIndex = this.cycles[this.currentCycle].token.findIndex(
(tokenData) => tokenData.contractAddress === sacrificedToken
);
this.cycles[this.currentCycle].token[tokenIndex].amount = data[tokenIndex].result[1];
this.cycles[this.currentCycle].token[tokenIndex].amountInBLD = tokenTotalSacrificed[tokenIndex].result;
}
},
/**
* main function to fill a round, will not be filled when already loaded
* you can use the refillcycle to overwrite information, because if you claim or stake the values will change
*/
async fillCycle(cycleNumber, refillCycle = false) {
console.log("fillCycle", cycleNumber);
const memeBurnerStore = useMemeburnerStore();
const tokenStore = useTokenStore();
const walletStore = useWalletStoreV2();
const rewardLockerStore = useRewardLockerStore();
if (!this.cycles[cycleNumber]?.goal || refillCycle || !this.cycles[cycleNumber]?.connected) {
console.log("fill cycle");
//multicall getSacrificedMeme for each token for this cycle
var data = await memeBurnerStore.getSacrificedCycle(cycleNumber);
let rewardData = null;
if (walletStore.connected) {
//getRewards multicall for all tokens
rewardData = await rewardLockerStore.getRewardsForAllToken(cycleNumber);
}
console.log("hier");
//getTotalSacrificeRewardsForToken multicall for all tokens
const tokenTotalSacrificed = await rewardLockerStore.getTotalSacrificeRewardsForAllToken(cycleNumber);
console.log("hier1");
var goal = await memeBurnerStore.getGoal(cycleNumber);
console.log("hier123");
var tokenArray = [];
var rewards_clan = 0n;
var rewards_sacrifice = 0n;
var rewards_staking = 0n;
console.log("hier123");
for (let index = 0; index < data.length; index++) {
var tokenData = {};
const token = tokenStore.token[index];
//why no multicall? todo
var coefficent = await rewardLockerStore.getSacrificedTokenCoefficient(
cycleNumber,
token.contractAddress
);
console.log("coefficent", coefficent);
tokenData.name = token.name;
tokenData.contractAddress = token.contractAddress;
tokenData.vamplogo = token.vamp.logo;
tokenData.vampwinner = token.vamp.winner;
tokenData.vampwinner2 = token.vamp.winner2;
tokenData.vampname = token.vamp.name;
tokenData.amount = data[index].result[1];
tokenData.amountInBLD = tokenTotalSacrificed[index].result;
if (walletStore.connected) {
//if user is connected fill user specific data for the token
const sacrificeClanReward = rewardData[index].result[1];
let clanwin = 0n;
if (cycleNumber !== this.currentCycle) {
clanwin = (sacrificeClanReward * coefficent) / 10000n - sacrificeClanReward;
console.log("clanwin", clanwin);
}
const sacrificeRewards = sacrificeClanReward;
tokenData.rewards_ges = rewardData[index].result[1] + rewardData[index].result[0];
tokenData.rewards_clan = clanwin;
tokenData.rewards_staking = rewardData[index].result[0];
tokenData.rewards_sacrifice = sacrificeRewards;
console.log("rewards_clan", rewards_clan);
console.log("tokenData.rewards_clan", tokenData.rewards_clan);
console.log("tokenData.rewards_sacrifice", tokenData.rewards_sacrifice);
rewards_clan = rewards_clan + tokenData.rewards_clan;
rewards_sacrifice = rewards_sacrifice + tokenData.rewards_sacrifice;
rewards_staking = rewards_staking + tokenData.rewards_staking;
}
tokenArray.push(tokenData);
}
const goalDecimal = goal[0];
const winner = tokenArray.find((token) => token.amount === goalDecimal);
const goalInBLD = await memeBurnerStore.getGoalInBLOOD(cycleNumber);
//replace vamplogo cause it will automatically change the token for the cycle view (new design)
// if (winner) {
// winner.vamplogo = winner.vampwinner;
// }
this.cycles[cycleNumber] = {
goal: goal[0],
goalInBLD: goalInBLD,
expirationTimestamp: goal[2],
rewards_clan: rewards_clan,
rewards_staking: rewards_staking,
rewards_sacrifice: rewards_sacrifice,
rewards_total: rewards_clan + rewards_sacrifice + rewards_staking,
token: tokenArray,
connected: walletStore.connected,
winner: winner,
};
console.log("this.cycles[cycleNumber]", this.cycles[cycleNumber]);
} else {
console.log("cycle already filled");
}
},
async getFinshedCycleNumbers() {
const array = [];
const rewardLockerStore = useRewardLockerStore();
const lastCompletedCycle = await rewardLockerStore.lastCompletedCycle();
for (let index = 1; index <= Number(lastCompletedCycle); index++) {
array.push(index);
}
console.log("array123", array);
return array;
},
},
});
+24 -31
View File
@@ -2,7 +2,7 @@ import { defineStore } from "pinia";
import MemeAltarJson from "@/assets/contracts/MemeAltar.json";
import { useTokenStore } from "./tokens";
import { useWalletStoreV2 } from "./walletV2";
import { useRoundsStore } from "@/stores/rounds";
import { useCycleStore } from "@/stores/cycles";
import { multicall, getContract, fetchToken, waitForTransaction, getWalletClient } from "@wagmi/core";
@@ -18,7 +18,7 @@ export const useMemeburnerStore = defineStore("memeburner", {
async init() {
console.log("-----------init memeburner-------------");
const walletStore = useWalletStoreV2();
// const roundsStore = useRoundsStore();
// const cycleStore = useCycleStore();
console.log("walletStore.walletClient", walletStore.walletClient);
this.contract = getContract({
address: this.config.contractAddress,
@@ -33,37 +33,34 @@ export const useMemeburnerStore = defineStore("memeburner", {
tokenStore.activeToken.contractAddress,
amount,
]);
console.log("tokenStore.activeToken.contractAddress", tokenStore.activeToken.contractAddress);
console.log("amount", amount);
console.log("rewards", rewards);
console.log("rewards", rewards);
return rewards;
},
async getCurrentRound() {
return await this.contract.read.currentRound();
async getCurrentCycle() {
return await this.contract.read.currentCycle();
},
async getGoal(roundnumber) {
return await this.contract.read.rounds([roundnumber]);
async getGoal(cycleNumber) {
console.log("hier123", cycleNumber);
return await this.contract.read.cycles([cycleNumber]);
},
//returns participated, amount achieved
async getSacrificedMeme(roundnumber, tokenAddress) {
return await this.contract.read.getSacrificedMeme([roundnumber, tokenAddress]);
async getSacrificedMeme(cycleNumber, tokenAddress) {
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 getSacrificedRound(roundnumber) {
console.log("getSacrificedRound", roundnumber);
async getSacrificedCycle(cycleNumber) {
console.log("getSacrificedCycle", cycleNumber);
const tokenStore = useTokenStore();
const contracts = [];
for (let index = 0; index < tokenStore.sacrificeToken.length; index++) {
const token = tokenStore.sacrificeToken[index];
console.log("token.contractAddress", token.contractAddress);
console.log("roundnumber", roundnumber);
// contracts.push(this.contract.methods.getSacrificedMeme(roundnumber, token.contractAddress));
contracts.push({
...this.contract,
functionName: "getSacrificedMeme",
args: [roundnumber, token.contractAddress],
args: [cycleNumber, token.contractAddress],
});
}
// console.log("this.contract", this.contract);
@@ -74,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) {
@@ -83,14 +80,11 @@ export const useMemeburnerStore = defineStore("memeburner", {
return;
}
this.loading = true;
const amountDecimal = BigInt(amount * Math.pow(10, tokenStore.activeToken.decimals));
console.log("this.contract", this.contract);
console.log("amountDecimal", amountDecimal.toString());
console.log("tokenStore.activeToken.contractAddress", tokenStore.activeToken.contractAddress);
var hash = await this.contract.write.sacrificeMeme([
tokenStore.activeToken.contractAddress,
amountDecimal.toString(),
0
amount,
minETH
]);
return hash;
} catch (error) {
@@ -100,25 +94,24 @@ 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));
var hash = await this.contract.write.sacrificeMemeAndBuyBLOOD([
tokenStore.activeToken.contractAddress,
amountDecimal.toString(),
0,
amount,
minBLOOD,
]);
return hash;
},
async getGoalInBLOOD(roundNumber) {
return await this.contract.read.getGoalInBLOOD([roundNumber]);
async getGoalInBLOOD(cycleNumber) {
return await this.contract.read.getGoalInBLOOD([cycleNumber]);
},
async getAmountETHBase(amount) {
console.log("getAmountETHBase");
const tokenStore = useTokenStore();
return await this.contract.read.getAmountETHBase([tokenStore.activeToken.contract.address, amount, true]);
}
},
+97 -89
View File
@@ -2,7 +2,7 @@ import { defineStore } from "pinia";
import RewardLockerJson from "@/assets/contracts/RewardLocker.json";
import { useTokenStore } from "./tokens";
import { useWalletStoreV2 } from "./walletV2";
import { useRoundsStore } from "@/stores/rounds";
import { useCycleStore } from "@/stores/cycles";
import { createPermitObject, getSignatureRSV } from "@/helper/blockchain.js";
import { multicall, getContract, signTypedData, getAccount, waitForTransaction } from "@wagmi/core";
@@ -26,108 +26,107 @@ export const useRewardLockerStore = defineStore("rewardlocker", {
},
/*
* @param {*} walletAddress
* @param {*} roundNumber
* @param {*} cycleNumber
* @param {*} tokenAddress
* @returns Rewards for specific token and specific round
* @returns Rewards for specific token and specific cycle
*/
async getRewards(walletAddress, roundNumber, tokenAddress) {
try {
return await this.contract.read.rewards([walletAddress, roundNumber, tokenAddress]);
} catch (error) {
async getRewards(walletAddress, cycleNumber, tokenAddress) {
try {
return await this.contract.read.getRewards([walletAddress, cycleNumber, tokenAddress]);
} catch (error) {
console.error("getRewards", error);
}
}
},
async getRewardsForAllToken(roundNumber) {
async getRewardsForAllToken(cycleNumber) {
console.log("getRewardsForAllToken");
const tokenStore = useTokenStore();
const walletStore = useWalletStoreV2();
const contracts = [];
for (let index = 0; index < tokenStore.sacrificeToken.length; index++) {
const token = tokenStore.sacrificeToken[index];
// calls.push(this.contract.methods.rewards(walletStore.address, roundNumber, token.contractAddress));
// calls.push(this.contract.methods.rewards(walletStore.address, cycleNumber, token.contractAddress));
contracts.push({
...this.contract,
functionName: "getRewards",
args: [walletStore.address, roundNumber, token.contractAddress],
args: [walletStore.address, cycleNumber, token.contractAddress],
});
}
const data = await multicall({
contracts,
});
// const multicallStore = useMultiCallStore();
return data;
},
async getSacrificedTokenCoefficient(roundNumber, sacrificedToken) {
try {
return await this.contract.read.getSacrificedTokenCoefficient([roundNumber, sacrificedToken]);
} catch (error) {
console.error("getSacrificedTokenCoefficient", error);
async getTotalSacrificeRewardsForAllToken(cycleNumber) {
try {
const tokenStore = useTokenStore();
const contracts = [];
for (let index = 0; index < tokenStore.sacrificeToken.length; index++) {
const token = tokenStore.sacrificeToken[index];
contracts.push({
...this.contract,
functionName: "getTotalSacrificeRewardsForToken",
args: [cycleNumber, token.contractAddress],
});
}
const data = await multicall({
contracts,
});
// const multicallStore = useMultiCallStore();
return data;
} catch (error) {
throw new Error(error);
}
},
async lastCompletedRound() {
try {
return await this.contract.read.lastCompletedRound();
} catch (error) {
console.error("lastCompletedRound", error);
}
async getSacrificedTokenCoefficient(cycleNumber, sacrificedToken) {
return await this.contract.read.getSacrificedTokenCoefficient([cycleNumber, sacrificedToken]);
},
async claim(round) {
try {
console.log("claim");
return await this.contract.write.claim([round]);
} catch (error) {
console.error("claim", error);
}
async getStakeRewardForSacrificeReward(sacrificedToken, reward) {
const walletStore = useWalletStoreV2();
const cycleStore = useCycleStore();
return await this.contract.read.getStakeRewardForSacrificeReward([
walletStore.address,
sacrificedToken,
reward,
]);
},
async lastCompletedCycle() {
return await this.contract.read.lastCompletedCycle();
},
async claim(cycle) {
console.log("claim");
return await this.contract.write.claim([cycle]);
},
async claimAll() {
console.log("claimAll");
const roundsStore = useRoundsStore();
const cycleStore = useCycleStore();
const account = getAccount();
console.log("acocunt", account);
const rounds = await roundsStore.getFinshedRoundNumbers();
return await this.contract.write.claim([rounds]);
const cycles = await cycleStore.getFinshedCycleNumbers();
return await this.contract.write.claim([cycles]);
},
async getTotalRewardsOf(address, rounds) {
try {
return await this.contract.read.getTotalRewardsOf([address, rounds]);
} catch (error) {
console.error("getTotalRewardsOf", error);
}
async getTotalRewardsOf(address, cycles) {
return await this.contract.read.getTotalRewardsOf([address, cycles]);
},
async getTotalRewards(address) {
try {
console.log("this.contract", this.contract);
const roundsStore = useRoundsStore();
const rounds = await roundsStore.getFinshedRoundNumbers();
return await this.contract.read.getTotalRewardsOf([address, rounds]);
} catch (error) {
console.error("getTotalRewards", error);
}
const cycleStore = useCycleStore();
const cycles = await cycleStore.getFinshedCycleNumbers();
return await this.contract.read.getTotalRewardsOf([address, cycles]);
},
async getStaked(address) {
try {
return await this.contract.read.staked([address]);
} catch (error) {
console.error("getStaked", error);
}
return await this.contract.read.staked([address]);
},
async orderUnstake() {
try {
return await this.contract.write.orderUnstake();
} catch (error) {
console.error("orderUnstake", error);
}
return await this.contract.write.orderUnstake();
},
async unstake(unstakeRound) {
try {
return await this.contract.write.unstake([unstakeRound]);
} catch (error) {
console.error("unstake", error);
async unstake() {
const walletStore = useWalletStoreV2();
const cycleStore = useCycleStore();
var cycleList = walletStore.memeToken.orderedUnstakedCycles.findIndex((obj) => obj.result > 0n);
if (cycleList && cycleList + 1 <= cycleStore.currentCycle) {
console.log("cycleList", cycleList);
const hash = await this.contract.write.unstake([cycleList + 1]);
return hash;
}
},
async stakeBloodline(tokenNumber) {
@@ -137,9 +136,9 @@ export const useRewardLockerStore = defineStore("rewardlocker", {
const fromAddress = walletStore.address;
const spender = this.config.contractAddress;
const deadline = Date.now() + 20 * 60;
const deadline = BigInt(Date.now()) / 1000n + 1200n;
const decimals = tokenStore.getToken(walletStore.memeToken.contractAddress).decimals;
const value = (tokenNumber * Math.pow(10, decimals)).toString();
const value = BigInt(tokenNumber) * 10n ** decimals;
const nonce = await tokenStore.memeToken.contract.read.nonces([fromAddress]);
console.log("nonce", nonce);
const { types, message, domain, primaryType } = createPermitObject(
@@ -158,34 +157,43 @@ export const useRewardLockerStore = defineStore("rewardlocker", {
});
const { r, s, v } = getSignatureRSV(signature);
console.log("value, deadline, v, r, s", value, deadline, v, r, s);
console.log("value, deadline, v, r, s", value, deadline, v, r, s);
const hash = await this.contract.write.stakeToBeSecured([value, deadline, v, r, s]);
return hash;
return hash;
},
async stakeAndClaimRound(stakeCoefficient, round) {
async stakeAndClaimCycle(stakeCoefficient, cycle) {
// stakeCoefficient 25% = 2500, 50% = 5000
const tokenStore = useTokenStore();
const addresses = tokenStore.sacrificeToken.map((obj) => obj.contractAddress);
const hash = await this.contract.write.stakeAndClaim([stakeCoefficient, [round], addresses]);
const data = await waitForTransaction({
hash: hash,
});
const walletStore = useWalletStoreV2();
await walletStore.loadWalletData();
// todo reload roundData and wallet data
const hash = await this.contract.write.stakeAndClaim([stakeCoefficient, [cycle], addresses]);
return hash;
},
async stakeAndClaimAllRounds(stakeCoefficient) {
console.log("stakeAndClaimAllRounds");
async stakeAndClaimAllCycles(stakeCoefficient) {
console.log("stakeAndClaimAllCycles", stakeCoefficient);
const tokenStore = useTokenStore();
const roundsStore = useRoundsStore();
const rounds = await roundsStore.getFinshedRoundNumbers();
const addresses = tokenStore.sacrificeToken.map((obj) => obj.contractAddress);
console.log({ stakeCoefficient, rounds, addresses });
console.log("stakeCoefficient", stakeCoefficient);
var stakeCoefficientInt = Math.round(stakeCoefficient);
const hash = await this.contract.write.stakeAndClaim([stakeCoefficientInt, rounds, addresses]);
return hash;
const cycleStore = useCycleStore();
const cycles = await cycleStore.getFinshedCycleNumbers();
const addresses = tokenStore.sacrificeToken.map((obj) => obj.contractAddress);
const hash = await this.contract.write.stakeAndClaim([stakeCoefficient, cycles, addresses]);
return hash;
},
async unstakeOrdered() {
const cycleStore = useCycleStore();
const walletStore = useWalletStoreV2();
const contracts = [];
for (let index = 1; index < cycleStore.currentCycle + 2; index++) {
contracts.push({
...this.contract,
functionName: "unstakeOrdered",
args: [index, walletStore.address],
});
}
const data = await multicall({
contracts,
});
console.log("data123", data);
return data;
},
},
});
-207
View File
@@ -1,207 +0,0 @@
import { defineStore } from "pinia";
import { useMemeburnerStore } from "./memeburner";
import { useTokenStore } from "./tokens";
import { useRewardLockerStore } from "./rewardlocker";
import { useWalletStoreV2 } from "./walletV2";
import { multicall } from "@wagmi/core";
export const useRoundsStore = defineStore("rounds", {
state: () => ({
rounds: [],
activeRound: null,
currentRound: null,
}),
getters: {
getRoundWinner() {
const goal = this.getCurrentRoundData?.goal;
if (!goal) {
return;
}
const winnerCoin = this.rounds[this.activeRound]?.token.find((token) => token.amount === goal);
if (winnerCoin) {
return winnerCoin;
} else {
return false;
}
},
getCurrentRoundData() {
console.log("this.rounds", this.rounds);
console.log("this.rounds[this.activeRound]", this.rounds[this.activeRound]);
return this.rounds[this.activeRound];
},
},
actions: {
async init() {
//fill initial round
},
async loadRewardsRounds() {
const walletStore = useWalletStoreV2();
const rewardLockerStore = useRewardLockerStore();
console.log("this.currentRound", this.currentRound);
const contracts = [];
for (let index = 0; index < this.currentRound; index++) {
console.log("load round: " + index);
// await this.fillRound(index)
console.log({ index, address: walletStore.address });
contracts.push({
...rewardLockerStore.contract,
functionName: "getTotalRewardsOf",
args: [walletStore.address, [index + 1]],
});
}
const data = await multicall({
contracts,
});
// var test = await rewardLockerStore.getTotalRewardsOf(walletStore.address, rounds)
for (let index = 0; index < data.length; index++) {
const element = data[index];
if (!this.rounds[index]) {
this.rounds[index] = {};
}
console.log("vor Fehler");
// this.rounds[index].round = index + 1;
// this.rounds[index].rewards_total = element.result;
}
},
async updateCurrentRound(sacrificedToken) {
console.log("updateCurrentRound");
const tokenStore = useTokenStore();
const memeBurnerStore = useMemeburnerStore();
var data = await memeBurnerStore.getSacrificedRound(this.currentRound);
var tokenIndex = this.rounds[this.currentRound].token.findIndex(
(tokenData) => tokenData.contractAddress === sacrificedToken
);
const token = tokenStore.getToken(sacrificedToken);
// console.log(
// "this.rounds[this.currentRound].token[tokenIndex].amount",
// this.rounds[this.currentRound].token[tokenIndex].amount
// );
// console.log("Number(data[tokenIndex].result[1] / BigInt(Math.pow(10, token.decimals))", Number(data[tokenIndex].result[1] / BigInt(Math.pow(10, token.decimals))));
this.rounds[this.currentRound].token[tokenIndex].amount =
Number(data[tokenIndex].result[1]) / Math.pow(10, token.decimals)
},
async fillRound(roundNumber, refillRound = false) {
console.log("fillRound");
const memeBurnerStore = useMemeburnerStore();
const tokenStore = useTokenStore();
const walletStore = useWalletStoreV2();
const rewardLockerStore = useRewardLockerStore();
// if (this.activeRound === this.currentRound) {
// console.log("activeRound is not completed");
// } else
if (!this.rounds[roundNumber]?.goal || refillRound) {
console.log("round not filled --> fill round");
console.log("vor error");
var data = await memeBurnerStore.getSacrificedRound(roundNumber);
let rewardData = null;
if (walletStore.connected) {
rewardData = await rewardLockerStore.getRewardsForAllToken(roundNumber);
}
var goal = await memeBurnerStore.getGoal(roundNumber);
console.log("goal", goal);
var tokenArray = [];
var rewards_clan = 0;
var rewards_sacrifice = 0;
var rewards_staking = 0;
console.log("data", data);
for (let index = 0; index < data.length; index++) {
var tokenData = {};
const token = tokenStore.token[index];
var coefficent = await rewardLockerStore.getSacrificedTokenCoefficient(
roundNumber,
token.contractAddress
);
console.log("coefficent", coefficent);
tokenData.name = token.name;
tokenData.contractAddress = token.contractAddress;
tokenData.vamplogo = token.vamp.logo;
tokenData.vampname = token.vamp.name;
// tokenData.amount = data[index].result[1];
tokenData.amount = Number(data[index].result[1]) / Math.pow(10, token.decimals);
// tokenData.getAmountToReachGoal =
// Number(await memeBurnerStore.getAmountToReachGoal(token.contractAddress)) /
// Math.pow(10, token.decimals);
if (walletStore.connected) {
const stakeReward = Number(rewardData[index].result[0]);
const sacrificeClanReward = Number(rewardData[index].result[1]);
let clanwin = 0;
if (this.activeRound !== this.currentRound) {
clanwin = (Number(coefficent) / 10000 - 1) * sacrificeClanReward;
console.log("clanwin", clanwin);
}
const sacrificeRewards = Number(sacrificeClanReward) - clanwin;
tokenData.rewards_ges = Number(
rewardData[index].result[1] / BigInt(Math.pow(10, token.decimals)) +
rewardData[index].result[0] / BigInt(Math.pow(10, token.decimals))
);
tokenData.rewards_clan = clanwin / Math.pow(10, token.decimals);
tokenData.rewards_staking = Number(
rewardData[index].result[0] / BigInt(Math.pow(10, token.decimals))
);
tokenData.rewards_sacrifice = sacrificeRewards / Math.pow(10, token.decimals);
rewards_clan = rewards_clan + tokenData.rewards_clan;
rewards_sacrifice = rewards_sacrifice + tokenData.rewards_sacrifice;
rewards_staking = rewards_staking + tokenData.rewards_staking;
}
tokenArray.push(tokenData);
}
console.log("clanwin123", rewards_clan);
const goalInBLD = await memeBurnerStore.getGoalInBLOOD(roundNumber);
this.rounds[roundNumber] = {
goal: Number(goal[0]) / Math.pow(10, tokenStore.memeToken.decimals),
goalInBLD: Number(goalInBLD / BigInt(Math.pow(10, tokenStore.memeToken.decimals))),
expirationTimestamp: Number(goal[2]),
rewards_clan: Number(rewards_clan),
rewards_staking: Number(rewards_staking),
rewards_sacrifice: Number(rewards_sacrifice),
rewards_total: Number(rewards_clan) + Number(rewards_sacrifice) + Number(rewards_staking),
token: tokenArray,
};
console.log("this.rounds[roundNumber]", this.rounds[roundNumber]);
} else {
console.log("round already filled");
}
},
async getFinshedRoundNumbers() {
const array = [];
const rewardLockerStore = useRewardLockerStore();
const lastCompletedRound = await rewardLockerStore.lastCompletedRound();
console.log("lastCompletedRound", lastCompletedRound);
for (let index = 0; index <= Number(lastCompletedRound); index++) {
array.push(index);
}
// for (let index = 1; index <= Number(lastCompletedRound) + 1; index++) {
// array.push(index);
// }
console.log("array", array);
return array;
},
/**
* function to get finished rounds, active round and the next round to check if there is a round the user called unstakeOrdered.
* with Backend it would be much easier because we could store the event data in the database
*/
async getRoundsNumberWithNext() {
const array = [];
const rewardLockerStore = useRewardLockerStore();
const lastCompletedRound = await rewardLockerStore.lastCompletedRound();
for (let index = 1; index <= Number(lastCompletedRound) + 1; index++) {
array.push(index);
}
return array;
},
},
});
+214
View File
@@ -0,0 +1,214 @@
import { defineStore } from "pinia";
import { useMemeburnerStore } from "@/stores/memeburner";
import { useUniswapStore } from "@/stores/uniswap";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useCycleStore } from "@/stores/cycles";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useTokenStore } from "@/stores/tokens";
import { waitForTransaction, readContract, watchBlockNumber, multicall } from "@wagmi/core";
import { showSuccessToast } from "@/helper/toast.js";
import { formatNumber } from "@/helper/helper.js";
export const useSacrificeStore = defineStore("sacrifice", {
state: () => ({
sacrificeNumber: 0n,
sacrificeState: 0,
}),
getters: {},
actions: {
async sacrificeToken(amount, token) {
console.log("sacrificeToken", { amount, token });
const memeburnerStore = useMemeburnerStore();
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
const cycleStore = useCycleStore();
try {
this.sacrificeState = 2;
const getRewards = await this.getRewardsFor(amount, token);
console.log("getRewards", getRewards);
let hash = null;
if (getRewards.variant === "sacrifice") {
console.log("sacrifice");
hash = await memeburnerStore.sacrificeMeme(amount, getRewards.minETH);
console.log("hash", hash);
} else {
console.log("buy");
hash = await memeburnerStore.sacrificeMemeAndBuyBLOOD(amount, getRewards.minBLOOD);
console.log("hash", hash);
}
this.sacrificeState = 3;
const data = await waitForTransaction({
hash: hash,
onReplaced: (transaction) => console.log("check transaction canceled", transaction),
});
console.log("data", data);
// var rewardData = data.logs.find((logObject) => {
// return logObject.topics.find(
// (topic) => topic === "0x5e60ccd3c81486143d815dce24867a494d7fee585a0a44282cf479b19a5186ee"
// );
// });
var rewardData = data.logs.filter((logObject) => {
return logObject.topics.find(
(topic) => topic === "0x5e60ccd3c81486143d815dce24867a494d7fee585a0a44282cf479b19a5186ee"
);
});
console.log("rewardData", rewardData);
//output
let outputSacrifice = rewardData.reduce((x, y) => {
return x + BigInt(y.data);
}, 0n);
outputSacrifice = formatNumber(outputSacrifice, 10n ** token.decimals);
console.log("outputSacrifice", outputSacrifice);
token.allowance = await tokenStore.allowance();
this.sacrificeState = 4;
showSuccessToast(
outputSacrifice,
"Success!",
"You turned your meme into:",
"You can claim once the current cycle is finished and your clan bonus was calculated."
);
await walletStore.loadWalletData();
console.log("cycleStore.currentCycle", cycleStore.currentCycle);
await cycleStore.fillCycle(cycleStore.currentCycle, true);
return true;
} catch (error) {
//we should show the user an issue
throw new Error(error);
} finally {
this.sacrificeState = 0;
}
},
async getRewardsFor(amount, token) {
console.log("getRewardsFor", { amount, token });
const memeburnerStore = useMemeburnerStore();
const uniswapStore = useUniswapStore();
const walletStore = useWalletStoreV2();
const rewardLockerStore = useRewardLockerStore();
let output = 0n;
let minBLOOD;
try {
if (!amount) {
this.sacrificeState = 0;
return {
output: 0n,
};
}
const amountETHBase = await memeburnerStore.getAmountETHBase(amount);
// take 99.5% of amount ETH got for selling meme, 0.5% allowed slippage
const minETH = (amountETHBase[1] * 995n) / 1000n;
const rewardsForResult = await memeburnerStore.getRewardFor(amount);
const rewardsForResultSum = rewardsForResult[0] + rewardsForResult[1];
// quote blood amount against ETH base amount
var quoteRewards = await uniswapStore.quoteExactInputSingle(amountETHBase[0]);
let variant = "sacrifice";
// here you are setting only variant, let's show by default rewardsForResultSum
output = rewardsForResultSum;
if (quoteRewards.result) {
// 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: quoteRewards.amount,
rewardsForResultSum,
});
} else {
console.log("use sacrifice-function", {
quoteRewardsNumber: quoteRewards.amount,
rewardsForResultSum,
});
}
}
console.log("variant", variant);
console.log("amount", amount);
if (!walletStore.connected || (walletStore.connected && token.allowance < amount)) {
/**
* case 1
* user is not logged in or Allowance is less than Input, then I show getRewardsForSacrifice Value
* variante not relevant
*/
output = rewardsForResultSum;
if (variant === "buy") {
output = quoteRewards.amount;
}
} else if (walletStore.connected && variant === "sacrifice" && token.allowance >= amount) {
/**
* case 2
* user is logged in and allowance is greater or equal input and variant is sacrifice
*/
// in this case you should use eth_call, so you are showing exact reward in cases of completing cycles
const amountSacrifice = await readContract({
address: memeburnerStore.contract.address,
abi: memeburnerStore.contract.abi,
functionName: "sacrificeMeme",
args: [token.contractAddress, amount.toString(), minETH.toString()],
account: walletStore.address,
});
output = amountSacrifice;
} else if (walletStore.connected && variant === "buy" && token.allowance >= amount) {
/**
* case 3
* user is logged in and allowance is greater or equal input and variant is buy
* compare sacrificeMeme-result and sacrificeMemeAndBuyBLOOD-result
*/
const amountSacrifice = await readContract({
address: memeburnerStore.contract.address,
abi: memeburnerStore.contract.abi,
functionName: "sacrificeMeme",
args: [token.contractAddress, amount.toString(), minETH.toString()],
account: walletStore.address,
});
const amountBuy = await readContract({
address: memeburnerStore.contract.address,
abi: memeburnerStore.contract.abi,
functionName: "sacrificeMemeAndBuyBLOOD",
args: [token.contractAddress, amount.toString(), minBLOOD.toString()],
account: walletStore.address,
});
if ((amountBuy * 95n) / 100n > amountSacrifice) {
variant = "buy";
output = amountBuy;
console.log("use buy after comparison sacrificeMemeAndBuyBLOOD and sacrificeMeme");
} else {
variant = "sacrifice";
output = amountSacrifice;
console.log("use sacrifice after comparison sacrificeMemeAndBuyBLOOD and sacrificeMeme");
}
}
//potential staking rewards
let stakingRewardsNumber = 0;
if (output > 0 && walletStore.connected) {
const stakingReward = await rewardLockerStore.getStakeRewardForSacrificeReward(
token.contractAddress,
output
);
stakingRewardsNumber = stakingReward;
}
return {
output: output,
variant: variant,
minETH: minETH,
minBLOOD: minBLOOD,
staking: stakingRewardsNumber,
};
} catch (error) {
console.error("getRewardsFor", error);
}
},
},
});
+66 -39
View File
@@ -1,7 +1,6 @@
import { defineStore } from "pinia";
import { markRaw } from "vue";
import { useWalletStoreV2 } from "./walletV2";
import { useContractStore } from "./contracts";
import { useMemeburnerStore } from "./memeburner";
import Meme1Json from "@/assets/contracts/Meme1.json";
import Meme2Json from "@/assets/contracts/Meme2.json";
@@ -14,6 +13,7 @@ import { multicall, getContract, fetchToken, getWalletClient, waitForTransaction
export const useTokenStore = defineStore("token", {
state: () => ({
//some static data for the coin
token: [
{
name: "$PEPE",
@@ -22,10 +22,26 @@ export const useTokenStore = defineStore("token", {
vamp: {
logo: "/assets/img/token/pepevamp.png",
name: "$PEPE Vamp Token",
winner: "/assets/img/token/pepewinner.png",
winner2: "/assets/img/token/pepewinnerborder.png",
},
backgroundColor: "#4b8501",
abi: Meme1Json.abi,
contractAddress: Meme1Json.contractAddress,
addSteps: [
{
amount: 10000000000000000000000000n,
name: "10m",
},
{
amount: 100000000000000000000000000n,
name: "100m",
},
{
amount: 1000000000000000000000000000n,
name: "1b",
},
],
},
{
name: "$SHIB",
@@ -34,9 +50,25 @@ export const useTokenStore = defineStore("token", {
vamp: {
logo: "/assets/img/token/shibvamp.png",
name: "$SHIBA Vamp Token",
winner: "/assets/img/token/shibwinner.png",
winner2: "/assets/img/token/shibwinnerborder.png",
},
abi: Meme2Json.abi,
contractAddress: Meme2Json.contractAddress,
addSteps: [
{
amount: 1000000000000000000000000n,
name: "1m",
},
{
amount: 10000000000000000000000000n,
name: "10m",
},
{
amount: 100000000000000000000000000n,
name: "100m",
},
],
},
{
name: "$ELON",
@@ -45,9 +77,25 @@ export const useTokenStore = defineStore("token", {
vamp: {
logo: "/assets/img/token/elonvamp.png",
name: "$ELON Vamp Token",
winner: "/assets/img/token/elonwinner.png",
winner2: "/assets/img/token/elonwinnerborder.png",
},
abi: Meme3Json.abi,
contractAddress: Meme3Json.contractAddress,
addSteps: [
{
amount: 10000000000000000000000000n,
name: "10m",
},
{
amount: 100000000000000000000000000n,
name: "100m",
},
{
amount: 1000000000000000000000000000n,
name: "1b",
},
],
},
// {
// name: "$BITCOIN",
@@ -56,6 +104,8 @@ export const useTokenStore = defineStore("token", {
// vamp: {
// logo: "/assets/img/token/bitcoin.png",
// name: "$ELON Vamp Token",
// winner: "/assets/img/token/bitcoinwinner.png"
// winner2: "/assets/img/token/bitcoinwinnerborder.png"
// },
// abi: Meme4Json.abi,
// contractAddress: Meme4Json.contractAddress,
@@ -71,7 +121,8 @@ export const useTokenStore = defineStore("token", {
// abi: Meme5Json.abi,
// contractAddress: Meme5Json.contractAddress,
// },
{
{
name: "$BLOOD",
abi: BloodlineJson.abi,
contractAddress: BloodlineJson.contractAddress,
logo: "/assets/img/token/bloodline.png",
@@ -100,7 +151,7 @@ export const useTokenStore = defineStore("token", {
async initV2() {
console.log("-----------init token-------------");
try {
const walletStore = useWalletStoreV2();
const walletStore = useWalletStoreV2();
for (let index = 0; index < this.token.length; index++) {
const contracts = [];
const token = this.token[index];
@@ -111,49 +162,30 @@ export const useTokenStore = defineStore("token", {
});
contracts.push({ ...token.contract, functionName: "decimals" });
contracts.push({ ...token.contract, functionName: "name" });
// contracts.push({ ...token.contract, functionName: "name" });
contracts.push({ ...token.contract, functionName: "symbol" });
contracts.push({ ...token.contract, functionName: "totalSupply" });
const data = await multicall({
contracts,
});
token.decimals = data[0].result;
token.name = data[1].result;
token.symbol = data[2].result;
token.totalSupply = data[3].result;
});
token.decimals = BigInt(data[0].result);
// token.name = data[1].result;
token.symbol = data[1].result;
token.totalSupply = data[2].result;
}
} catch (error) {
console.error("initV2", error);
}
},
async changeActiveToken(token) {
console.log("changeActiveToken");
this.activeToken = token;
const walletStore = useWalletStoreV2();
if (walletStore.connected) {
//TODO, wenn connected, dann all diese Daten laden?
this.activeToken.balance = await walletStore.getTokenBalance(token);
this.activeToken.allowance = Number(await this.allowance());
} catch (error) {
console.error("initV2", error);
}
},
async allowance() {
console.log("allowance");
const walletStore = useWalletStoreV2();
const memeBurnerStore = useMemeburnerStore();
// var allowance = await this.contract.methods
// .allowance(walletStore.address, memeBurnerStore.config.contractAddress)
// .call();
console.log("this.activeToken.contract", this.activeToken.contract);
var allowance = await this.activeToken.contract.read.allowance([
walletStore.address,
memeBurnerStore.config.contractAddress,
]);
// var decimals = await this.contract.methods.decimals().call();
// console.log("decimals", decimals);
const decimals = this.activeToken.decimals;
allowance = BigInt(allowance / BigInt(Math.pow(10, decimals)));
console.log("allowance", allowance);
return allowance;
},
@@ -162,21 +194,16 @@ export const useTokenStore = defineStore("token", {
console.log("amount", amount);
this.loading = true;
const memeBurnerStore = useMemeburnerStore();
// var approve = await this.contract.methods
// .approve(memeBurnerStore.config.contractAddress, amount)
// .send({ from: walletStore.address});
console.log("approve");
console.log("this.activeToken.contract", this.activeToken.contract);
var approveHash = await this.activeToken.contract.write.approve([
memeBurnerStore.config.contractAddress,
amount * Math.pow(10, this.activeToken.decimals),
amount,
]);
console.log("approveHash", approveHash);
return approveHash;
return approveHash;
} catch (error) {
console.error(error);
throw new Error(error)
console.error(error);
throw new Error(error);
} finally {
this.loading = false;
}
+23 -59
View File
@@ -1,21 +1,17 @@
import { defineStore } from "pinia";
import { useWalletStoreV2 } from "@/stores/walletV2";
import QuoterJson from "@/assets/contracts/Quoter.json";
import UniswapPoolJson from "@/assets/contracts/UniswapPool.json";
import { useMemeburnerStore } from "@/stores/memeburner";
import WethJson from "@/assets/contracts/WETH.json";
import BloodlineJson from "@/assets/contracts/Bloodline.json";
import { getContract, multicall } from "@wagmi/core";
export const useUniswapStore = defineStore("uniswap", {
state: () => ({
quoateV3Contract: {},
quoateV2Contract: {},
uniswapPoolContract: {},
poolData: {
token0: null,
token1: null,
fee: null,
},
tokenIn: WethJson.contractAddress,
tokenOut: BloodlineJson.contractAddress,
fee: 10000n,
}),
getters: {},
actions: {
@@ -29,64 +25,32 @@ export const useUniswapStore = defineStore("uniswap", {
walletClient: walletStore.walletClient || walletStore.publicClient,
});
this.uniswapPoolContract = getContract({
address: UniswapPoolJson.contractAddress,
abi: UniswapPoolJson.abi,
walletClient: walletStore.walletClient || walletStore.publicClient,
});
this.getPoolData();
},
async quoteExactInputSingle(amount) {
async quoteExactInputSingle(ethBase) {
try {
console.log("quoteExactInputSingle");
const memeBurnerStore = useMemeburnerStore();
var amountEthBase = await memeBurnerStore.getAmountETHBase(amount);
console.log("amountEthBase", amountEthBase);
console.log("123", {
token0: this.poolData.token0,
token1: this.poolData.token1,
fee: this.poolData.fee,
amountEthBase: amountEthBase,
pricelimit: 0, //sqrtPriceLimitX96
console.log("quoteExactInputSingle-parameter", {
tokenIn: this.tokenIn, // WETH
tokenOut: this.tokenOut, // BLOOD
fee: this.fee,
amountEthBase: ethBase,
pricelimit: 0n, //sqrtPriceLimitX96
});
const quotedAmountOut = await this.quoateV3Contract.read.quoteExactInputSingle([
this.poolData.token0, //bloodline
this.poolData.token1, //weth
this.poolData.fee,
amountEthBase,
0, //sqrtPriceLimitX96
]);
this.tokenIn, //weth
this.tokenOut, //bloodline
this.fee,
ethBase,
0n, //sqrtPriceLimitX96
]);
console.log("quotedAmountOut", quotedAmountOut);
return {result: true, amount: quotedAmountOut};
} catch (error) {
return { result: false, amount: null };
}
},
async getPoolData() {
console.log("getPoolData");
const contracts = [];
contracts.push(
{
...this.uniswapPoolContract,
functionName: "token0",
},
{
...this.uniswapPoolContract,
functionName: "token1",
},
{
...this.uniswapPoolContract,
functionName: "fee",
}
);
const data = await multicall({
contracts,
});
this.poolData.token0 = data[0].result;
this.poolData.token1 = data[1].result;
this.poolData.fee = data[2].result;
console.log("this.poolData", this.poolData);
},
},
}
}
});
+75 -75
View File
@@ -2,7 +2,7 @@ import { defineStore } from "pinia";
import { markRaw } from "vue";
import { useTokenStore } from "./tokens";
import { useRewardLockerStore } from "./rewardlocker";
import { formatNumber } from "@/helper/helper.js";
import {
createConfig,
configureChains,
@@ -15,7 +15,7 @@ import {
getWalletClient,
fetchBalance,
multicall,
getNetwork,
getNetwork,
} from "@wagmi/core";
import { WalletConnectConnector } from "@wagmi/core/connectors/walletConnect";
@@ -26,10 +26,8 @@ import { goerli, mainnet } from "@wagmi/core/chains";
import { publicProvider } from "@wagmi/core/providers/public";
import { alchemyProvider } from "@wagmi/core/providers/alchemy";
export const useWalletStoreV2 = defineStore("walletV2", {
state: () => ({
count: 0,
alchemy: null,
connected: false,
address: null,
@@ -39,55 +37,61 @@ export const useWalletStoreV2 = defineStore("walletV2", {
walletClient: null,
config: null,
chain: null,
token: [],
initialized1: false,
token: [],
}),
getters: {
sacrificeToken: (state) => state.token.filter((obj) => {
const tokenStore = useTokenStore();
return obj.contractAddress !== tokenStore.memeToken.contractAddress;
}),
memeToken: (state) => state.token.find((obj) => {
const tokenStore = useTokenStore();
return obj.contractAddress === tokenStore.memeToken.contractAddress;
}),
sacrificeToken: (state) =>
state.token.filter((obj) => {
const tokenStore = useTokenStore();
return obj.contractAddress !== tokenStore.memeToken.contractAddress;
}),
memeToken: (state) =>
state.token.find((obj) => {
const tokenStore = useTokenStore();
return obj.contractAddress === tokenStore.memeToken.contractAddress;
}),
unclaimedRewards() {
if (!this.memeToken?.unclaimedRewards) {
return 0n;
}
return this.memeToken.unclaimedRewards;
},
orderedUnstakedAmount() {
if (!this.memeToken?.orderedUnstakedAmount) {
return 0n;
}
return this.memeToken?.orderedUnstakedAmount;
},
staked() {
if (!this.memeToken?.staked) {
return 0n;
}
return this.memeToken?.staked;
},
balanceOf() {
if (!this.memeToken?.balanceOf) {
return 0n;
} else {
return this.memeToken?.balanceOf;
}
},
},
actions: {
async init() {
console.log("wallet init");
const account = getAccount();
if (account.address) {
this.address = account.address;
this.connected = true;
}
// await this.isConnected();
// const goerliKey = import.meta.env.VITE_GOERLI_KEY;
// if (this.connected) {
// const web3 = new Web3(window.ethereum);
// this.web3 = markRaw(web3);
// console.log("hierabc");
// window.ethereum.on("accountsChanged", async (data) => {
// console.log("accountsChanged", data);
// console.log("data", data);
// if (data.length > 0) {
// this.address = data[0];
// this.connected = true;
// } else {
// this.address = null;
// this.connected = false;
// }
// });
const account = getAccount();
if (account.address) {
this.address = account.address;
this.connected = true;
}
},
async connectWallet(connector) {
try {
console.log("connector.name", connector.name);
console.log("connector.name", connector.name);
// if (!account.isConnected) {
const connection = await connect({
chainId: goerli.id,
@@ -95,26 +99,22 @@ export const useWalletStoreV2 = defineStore("walletV2", {
});
console.log("connection", connection);
} catch (error) {
if (error.message.includes("Connector not found")) {
} catch (error) {
if (error.message.includes("Connector not found")) {
console.warn("Connector not found");
}
console.error(error);
}
console.error(error);
}
// this.address = connection.account;
},
async getTokenBalance(token) {
console.log("token", token);
console.log("address", this.address);
const result = await token.contract.read.balanceOf([this.address]);
return result;
},
async getTokenBalances() {
console.log("getTokenBalances");
this.token = []
console.log("getTokenBalances");
this.token = [];
const tokenStore = useTokenStore();
console.log("tokenStore.token.length", tokenStore.token.length);
var contracts = [];
for (let index = 0; index < tokenStore.token.length; index++) {
const token = tokenStore.token[index];
@@ -124,35 +124,35 @@ export const useWalletStoreV2 = defineStore("walletV2", {
const data = await multicall({
contracts,
});
console.log("data", data);
for (let index = 0; index < tokenStore.token.length; index++) {
const token = tokenStore.token[index];
console.log("token", token);
console.log("data[index].result", data[index].result);
const balanceOfDecimal = data[index].result / BigInt(Math.pow(10, token.decimals));
const token = tokenStore.token[index];
this.token.push({
contractAddress: token.contractAddress,
balanceOf: Number(balanceOfDecimal),
balanceOf: data[index].result,
});
}
},
async loadWalletData() {
if (!this.connected) {
return
}
console.log("loadWalletData");
},
async loadWalletData() {
if (!this.connected) {
return;
}
console.log("loadWalletData");
const rewardlockerStore = useRewardLockerStore();
await this.getTokenBalances();
//MemeToken Staked
const tokenStore = useTokenStore();
const staked = await rewardlockerStore.getStaked(this.address);
this.memeToken.staked = Number(staked / BigInt(Math.pow(10, tokenStore.memeToken.decimals)));
const unclaimedRewardsArray = await rewardlockerStore.getTotalRewards(this.address);
const unclaimedRewards = unclaimedRewardsArray[0] + unclaimedRewardsArray[1];
this.memeToken.unclaimedRewards = Number(unclaimedRewards/ BigInt(Math.pow(10, tokenStore.memeToken.decimals)))
}
await this.getTokenBalances();
//MemeToken Staked
const tokenStore = useTokenStore();
this.memeToken.staked = await rewardlockerStore.getStaked(this.address);
const unclaimedRewardsArray = await rewardlockerStore.getTotalRewards(this.address);
const unclaimedRewards = unclaimedRewardsArray[0] + unclaimedRewardsArray[1];
this.memeToken.unclaimedRewards = unclaimedRewards;
this.memeToken.orderedUnstakedCycles = await rewardlockerStore.unstakeOrdered();
console.log("this.memeToken.orderedUnstakedCycles", this.memeToken.orderedUnstakedCycles);
this.memeToken.orderedUnstakedAmount = this.memeToken.orderedUnstakedCycles.reduce((x, y) => {
return x + y.result;
}, 0n);
},
},
persist: true,
// persist: true,
});
-22
View File
@@ -1,22 +0,0 @@
export default class Helper {
static debounce(func, timeout = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, timeout);
};
}
static createDebounce() {
let timeout = null;
return function (fnc, delayMs) {
clearTimeout(timeout);
timeout = setTimeout(() => {
fnc();
}, delayMs || 500);
};
}
}
+113 -72
View File
@@ -2,19 +2,20 @@
<div class="cycle-page">
<div class="cycle-header container container--variant1">
<div class="bloodline-page-headline header" ref="observerElement">Bloodline Cycle</div>
<div class="bloodline-page-description low-mid-text">
Claim and trade your $BDL at each cycle's end. Become the most powerful bloodline and win extra rewards.
<div class="bloodline-page-description mid-mid-text">
Claim and trade your $BLOOD at each cycle's end. Become the most powerful bloodline and win extra
rewards.
</div>
</div>
<div class="slider-wrapper" :class="{ sticking: sticking }" ref="target">
<font-awesome-icon
:class="{ 'slider-prev': true, disabled: roundsStore.activeRound <= 1 }"
:class="{ 'slider-prev': true, disabled: cycleStore.activeCycle <= 1 }"
@click="prevSlide"
:icon="['fas', 'caret-left']"
/>
<div class="slider-text sub-header">Cycle {{ roundsStore.activeRound }}</div>
<div class="slider-text sub-header">Cycle {{ cycleStore.activeCycle }}</div>
<font-awesome-icon
:class="{ 'slider-next': true, disabled: roundsStore.currentRound === roundsStore.activeRound }"
:class="{ 'slider-next': true, disabled: cycleStore.currentCycle === cycleStore.activeCycle }"
@click="nextSlide"
:icon="['fas', 'caret-right']"
/>
@@ -22,42 +23,51 @@
<div class="cycle card card--glow container container--variant1 bloodline-wrapper">
<div
class="bloodline-border round-finish-info low-mid-text"
v-if="difference > 0 && roundsStore.currentRound === roundsStore.activeRound"
:class="{ loading: difference <= 0 }"
v-if="cycleStore.currentCycle === cycleStore.activeCycle"
>
<!-- <div class="round-finish-info-element low-mid-text"> -->
<div class="round-finish-info-key">Sacrifice Goal:</div>
<div class="round-finish-info-value">{{ roundsStore.getCurrentRoundData?.goalInBLD }} $BDL</div>
<!-- </div> -->
<!-- <div class="round-finish-info-element low-mid-text"> -->
<div class="round-finish-info-key">Time left:</div>
<div class="round-finish-info-value">{{ days }} {{ hours }} {{ minutes }}</div>
<!-- </div> -->
<template v-if="difference > 0">
<div class="round-finish-info-key">Sacrifice Goal:</div>
<div class="round-finish-info-value">
{{ cycleStore.getCurrentCycleData?.goalInBLD / 10n ** tokenStore.memeToken.decimals }} $BLOOD
</div>
<div class="round-finish-info-key">Time left:</div>
<div class="round-finish-info-value">{{ days }} {{ hours }} {{ minutes }}</div>
</template>
<template v-else>
<loading-component></loading-component>
</template>
</div>
<template v-if="roundsStore.currentRound !== roundsStore.activeRound">
<div
class="bloodline-border bloodline-border__thin grey cycle-winner"
v-if="roundsStore.getRoundWinner"
>
<template v-if="cycleStore.currentCycle !== cycleStore.activeCycle">
<div class="bloodline-border bloodline-border purple cycle-winner" v-if="cycleStore.getCycleWinner">
<div class="cycle-winner-left">
<div class="cycle-winner-headline">Clan Winner</div>
<div class="cycle-winner-subheadline">+25% Clan Bonus</div>
<div class="cycle-winner-headline">Cycle Winner</div>
<div class="cycle-winner-subheadline">
+ Clan Bonus on {{ cycleStore.getCycleWinner.name }} Sacrifice
</div>
</div>
<div class="cycle-winner-right">
<div class="cycle-winner-logo">
<img :src="roundsStore.getRoundWinner.vamplogo" alt="" />
<img class="logo" :src="cycleStore.getCycleWinner.vamplogo" alt="" />
<img class="crown" src="/assets/img/winnerCrown.png" alt="" />
</div>
<div class="cycle-winner-name">{{ roundsStore.getRoundWinner.name }}</div>
<div class="cycle-winner-name">{{ cycleStore.getCycleWinner.name }}</div>
</div>
</div>
<div class="bloodline-border bloodline-border__thin grey cycle-winner" v-else>
<div class="cycle-winner-left">
<div class="cycle-winner-headline">No Clan Winner</div>
<div class="cycle-winner-subheadline">time limit reached or activeround</div>
</div>
<div class="cycle-winner-right">
<div class="cycle-winner-logo inactive">
<img src="/assets/img/token/bloodline.png" alt="" />
<template v-if="cycleStore.getCycleWinner">
<div class="cycle-winner-left">
<div class="cycle-winner-headline">No Clan Winner</div>
<div class="cycle-winner-subheadline">time limit has been reached</div>
</div>
<div class="cycle-winner-right">
<div class="cycle-winner-logo inactive">
<img src="/assets/img/token/bloodline.png" alt="" />
</div>
</div>
</template>
<div class="cycle-winner-loading" v-else>
<loading-component></loading-component>
</div>
</div>
</template>
@@ -67,13 +77,18 @@
<div class="bloodline-clan">
<div class="sub-header">Bloodline Clan</div>
<p class="mid-text">
Win extra rewards for you and your clan. Increase the strength of your bloodline by sacrificing more
memes.
Claim extra rewards when your clan wins the cycle. Increase the strength of your bloodline by
sacrificing more memes.
</p>
<div class="bloodline-container">
<div class="bloodline-border purple">Get up to +100% Clan Bonus <br />on your sacrifice.</div>
<div class="bloodline-border purple">Get up to +25% Clan Bonus on your sacrifice.</div>
</div>
<blood-chart :data="roundsStore.rounds[roundsStore.activeRound]"></blood-chart>
<template v-if="!cycleStore.cycles[cycleStore.activeCycle]">
<Vue3Lottie :animationData="ChartLoading" :height="400" :width="400" />
</template>
<template v-else>
<blood-chart :data="cycleStore.cycles[cycleStore.activeCycle]"></blood-chart>
</template>
</div>
</div>
</div>
@@ -84,13 +99,19 @@ import { inject, ref, onMounted, onBeforeUnmount } from "vue";
import BloodChart from "@/components/BloodChart.vue";
import TokenClaim from "@/components/TokenClaim.vue";
import { useMemeburnerStore } from "@/stores/memeburner";
import CardComponent from "@/components/CardComponent.vue";
import { useTokenStore } from "@/stores/tokens";
import { useRoundsStore } from "@/stores/rounds";
import { useMemeburnerStore } from "@/stores/memeburner";
import LoadingComponent from "@/components/LoadingComponent.vue";
import { useCycleStore } from "@/stores/cycles";
import { useRewardLockerStore } from "@/stores/rewardlocker";
const roundsStore = useRoundsStore();
import { Vue3Lottie } from "vue3-lottie";
import ChartLoading from "@/assets/lottie/ChartLoading.json";
const cycleStore = useCycleStore();
const tokenStore = useTokenStore();
const days = ref(null);
const hours = ref(null);
@@ -104,36 +125,26 @@ const observer = ref(null);
const observerElement = ref(null);
const memeBurnerStore = useMemeburnerStore();
const rewardLockerStore = useRewardLockerStore();
const isMobile = inject("isMobile");
onMounted(async () => {
console.log("onmounted", roundsStore.activeRound);
// await memeBurnerStore.init();
// await rewardLockerStore.init();
if (!roundsStore.currentRound) {
roundsStore.currentRound = parseInt(await memeBurnerStore.getCurrentRound());
console.log("roundsStore.currentRound", roundsStore.currentRound);
roundsStore.activeRound = roundsStore.currentRound;
//check if that still needed or old stuff
if (!cycleStore.currentCycle) {
cycleStore.currentCycle = parseInt(await memeBurnerStore.getCurrentCycle());
console.log("cycleStore.currentCycle", cycleStore.currentCycle);
cycleStore.activeCycle = cycleStore.currentCycle;
}
await roundsStore.fillRound(roundsStore.activeRound);
console.log("roundsStore.getCurrentRoundData", roundsStore.getCurrentRoundData);
if (roundsStore.currentRound === roundsStore.activeRound) {
const expirationTimestamp = roundsStore.getCurrentRoundData.expirationTimestamp;
await cycleStore.fillCycle(cycleStore.activeCycle);
if (cycleStore.currentCycle === cycleStore.activeCycle) {
const expirationTimestamp = cycleStore.getCurrentCycleData.expirationTimestamp;
timer.value = setInterval(function () {
timeBetweenDates(expirationTimestamp);
}, 1000);
}
const headerEl = document.querySelector(".slider-wrapper");
//if cycle header is getting sticky than grey the background
const handler = (entries) => {
console.log(entries);
// entries is an array of observed dom nodes
// we're only interested in the first one at [0]
// because that's our .sentinal node.
// Here observe whether or not that node is in the viewport
if (!entries[0].isIntersecting) {
headerEl.classList.add("stuck");
} else {
@@ -143,14 +154,12 @@ onMounted(async () => {
// create the observer
observer.value = new window.IntersectionObserver(handler);
// give the observer some dom nodes to keep an eye on
if (observerElement.value) {
observer.value.observe(observerElement.value);
}
});
onBeforeUnmount(() => {
console.log("clear");
clearInterval(timer.value);
if (observer.value) {
observer.value.unobserve(observerElement.value);
@@ -158,17 +167,16 @@ onBeforeUnmount(() => {
});
async function prevSlide() {
console.log("blub1", roundsStore.activeRound);
if (roundsStore.activeRound > 1) {
roundsStore.activeRound--;
await roundsStore.fillRound(roundsStore.activeRound);
if (cycleStore.activeCycle > 1) {
cycleStore.activeCycle--;
await cycleStore.fillCycle(cycleStore.activeCycle);
}
}
async function nextSlide() {
if (roundsStore.activeRound < roundsStore.currentRound) {
roundsStore.activeRound++;
await roundsStore.fillRound(roundsStore.activeRound);
if (cycleStore.activeCycle < cycleStore.currentCycle) {
cycleStore.activeCycle++;
await cycleStore.fillCycle(cycleStore.activeCycle);
}
}
@@ -221,7 +229,7 @@ function timeBetweenDates(expirationTimestamp) {
&.stuck
background: #2D2D2D
@media (min-width: 992px)
top: 96px
top: 80px
.slider-text
margin: 0 24px
margin-top: auto
@@ -265,18 +273,48 @@ function timeBetweenDates(expirationTimestamp) {
.cycle-winner-headline
font-size: 24px
.cycle-winner-subheadline
font-size: 12px
font-size: 14px
.cycle-winner-right
display: flex
flex-direction: column
justify-content: space-between
align-items: center
.cycle-winner-logo
height: 72px
width: 72px
position: relative
img
height: 49px
width: 49px
border-radius: 50%
&.logo
height: 100%
width: 100%
border: 1px solid yellow
border-radius: 50%
img
&.crown
position: absolute
top: -10px
transform: translate(-50%, -50%)
left: 50%
// height: 72px
// width: 72px
// border-radius: 50%
// position: absolute
// left: 50%
// top: 10px
// transform: translate(-50%, -50%)
&.inactive
img
height: 100%
width: 100%
top: unset
left: unset
transform: unset
position: unset
opacity: 0.3
.cycle-winner-name
font-size: 16px
.cycle-winner-loading
width: 100%
.bloodline-clan
@@ -290,6 +328,9 @@ function timeBetweenDates(expirationTimestamp) {
display: grid
grid-template-columns: 1fr 1fr
text-align: right
&.loading
grid-template-columns: 1fr
.round-finish-info-key
text-align: right
.round-finish-info-value
+6 -14
View File
@@ -30,30 +30,22 @@
<img v-else src="/assets/img/tokenomics.png" alt="tokenomics" />
</div>
</section>
<div class="tutorial-footer">
$BLOOD is 100%<br />
community owned.<br />
No team %, no pre-mine.
</div>
<div class="tutorial-footer mid-text">Only 3% elders fee upon sacrifice.</div>
</Collapse>
</div>
</div>
</template>
<script setup>
import { ref, computed, inject, onMounted, onBeforeUnmount } from "vue";
import { ref, inject } from "vue";
import { storeToRefs } from "pinia";
import SacrificeToken from "@/components/SacrificeToken.vue";
import { Collapse } from "vue-collapsed";
// import { useWalletStore } from "@/stores/wallet";
import { useTokenStore } from "@/stores/tokens";
import { useRoundsStore } from "@/stores/rounds";
const tokenStore = useTokenStore();
const roundsStore = useRoundsStore();
const { getCurrentRoundData } = storeToRefs(roundsStore);
const { currentRound, activeRound, rounds } = storeToRefs(roundsStore);
const tutorialWrapper = ref(null);
const openTutorial = ref(false);
const isMobile = inject("isMobile");
@@ -62,7 +54,6 @@ function openTutorialFunc(e) {
openTutorial.value = !openTutorial.value;
setTimeout(function () {
let element = document.getElementById("section-header-container");
console.log("element", element);
element.scrollIntoView({ behavior: "smooth" });
}, 200);
}
@@ -75,6 +66,7 @@ function openTutorialFunc(e) {
text-align: center
margin-top: 24px
margin-bottom: 48px
padding: 0 12px
@media (min-width: 992px)
font-size: 48px
margin-top: 0px
@@ -82,6 +74,7 @@ function openTutorialFunc(e) {
text-shadow: unset
line-height: 80px
font-weight: 600
padding: 0
.chart-wrapper-coin
display: flex
@@ -115,8 +108,7 @@ function openTutorialFunc(e) {
margin-right: auto
pointer-events: none
user-select: none
@media (min-width: 992px)
width: 100%
width: 100%
.chart-wrapper
width: 600px
height: 600px
@@ -138,7 +130,7 @@ function openTutorialFunc(e) {
#section-header-container
margin: 24px 0
margin: 48px 0
scroll-margin: 150px
.tutorial-header
display: flex
+9 -132
View File
@@ -68,157 +68,34 @@
</div>
</div>
</template>
<!-- <div class="cycle-wrapper">
<div class="cycle-inner">
<div class="cycle-headline">Cycles</div>
<div class="cycle-header">
<div class="cycle-header-left">Cycle</div>
<div class="cycle-header-right">Reward</div>
</div>
<div class="cycle-rounds">
<div class="cycle-round" v-for="(round, index) in rounds" :key="index">
<template v-if="round">
<div class="cycle-round-inner">
<div class="cycle-round-number">{{ round.round }}</div>
<div class="cycle-round-badget" v-if="roundsStore.currentRound === round.round">
active
</div>
<div class="cycle-round-reward" v-if="roundsStore.currentRound === round.round">
todo
</div>
<div class="cycle-round-reward" v-else>
{{ Number(round.rewards_total / BigInt(Math.pow(10, 18))) }} $BDL
</div>
<div class="cycle-round-more" @click="openRound(index)">
<font-awesome-icon
v-if="openCycleElement && index === activeRound"
icon="chevron-up"
/>
<font-awesome-icon v-else icon="chevron-down" />
</div>
</div>
<div class="cycle-round-detail" v-if="openCycleElement && index === activeRound">
<div class="cycle-round-detail-inner">
<div class="sacrifice-reward-wrapper">
<div class="sacrifice-reward-inner">
<div class="sacrifice-reward-header">
<div class="sacrifice-reward-header-name">Sacrifice Reward</div>
<div class="sacrifice-reward-header-amount">+2,000 $BDL</div>
</div>
<table class="sacrifice-coins">
<tr class="sacrifice-coin">
<td>2b PEPE</td>
<td class="arrow"><font-awesome-icon icon="arrow-right" /></td>
<td>1,500 $BDL</td>
</tr>
<tr class="sacrifice-coin">
<td>10m SHIB</td>
<td class="arrow"><font-awesome-icon icon="arrow-right" /></td>
<td class="bloodline">500 $BDL</td>
</tr>
</table>
</div>
</div>
<div class="sacrifice-reward-wrapper">
<div class="sacrifice-reward-inner">
<div class="sacrifice-reward-header">
<div class="sacrifice-reward-header-name">Staking Bonus</div>
<div class="sacrifice-reward-header-amount">+1,000 $BDL</div>
</div>
<table class="sacrifice-coins">
<tr class="sacrifice-coin">
<td>Staked</td>
<td class="arrow"></td>
<td class="bloodline">1,000 $BDL</td>
</tr>
</table>
</div>
</div>
<div class="sacrifice-reward-wrapper">
<div class="sacrifice-reward-inner">
<div class="sacrifice-reward-header">
<div class="sacrifice-reward-header-name">Competition Bonus</div>
<div class="sacrifice-reward-header-amount">+200 $BDL</div>
</div>
<table class="sacrifice-coins">
<tr class="sacrifice-coin">
<td><img src="/assets/img/winner.png" alt="" /></td>
<td><img src="/assets/img/token/pepevamp.png" alt="" /></td>
<td>$PEPE</td>
<td class="arrow"></td>
<td class="bloodline">1,000 $BDL</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div> -->
</div>
</template>
<script setup>
import { ref, onMounted, computed, inject } from "vue";
import { useRoundsStore } from "@/stores/rounds";
import { useCycleStore } from "@/stores/cycles";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { getblocky, getAddressShortName } from "@/helper/helper.js";
import CardComponent from "@/components/CardComponent.vue";
import StakeComponentV1 from "@/components/StakeComponentV1.vue";
import ClaimComponent from "@/components/ClaimComponent.vue";
import { useMemeburnerStore } from "@/stores/memeburner";
import { useRewardLockerStore } from "@/stores/rewardlocker";
const roundsStore = useRoundsStore();
const cycleStore = useCycleStore();
const walletStore = useWalletStoreV2();
const rewardLockerStore = useRewardLockerStore();
const memeBurnerStore = useMemeburnerStore();
const isMobile = inject("isMobile");
const showPanel = inject("showPanel");
const activeRound = ref(null);
const openCycleElement = ref(false);
function openRound(index) {
if (activeRound.value === index && openCycleElement.value) {
openCycleElement.value = false;
} else {
openCycleElement.value = true;
}
activeRound.value = index;
}
onMounted(async () => {
// await memeBurnerStore.init();
// await rewardLockerStore.init();
console.log("loadRounds");
if (!roundsStore.currentRound) {
roundsStore.currentRound = parseInt(await memeBurnerStore.getCurrentRound());
console.log("roundsStore.currentRound", roundsStore.currentRound);
roundsStore.activeRound = roundsStore.currentRound;
//todo check that code, probably old stuff
if (!cycleStore.currentCycle) {
cycleStore.currentCycle = parseInt(await memeBurnerStore.getCurrentCycle());
console.log("cycleStore.currentCycle", cycleStore.currentCycle);
cycleStore.activeCycle = cycleStore.currentCycle;
}
//brauche ich das?
// await roundsStore.loadRewardsRounds();
console.log("roundsStore.rounds", roundsStore.rounds);
});
const rounds = computed(() => {
var tetst = roundsStore.rounds
.filter((round) => {
if (round.round) {
return true;
} else {
return false;
}
})
.reverse();
return tetst;
console.log("cycleStore.cycles", cycleStore.cycles);
});
</script>
@@ -364,7 +241,7 @@ const rounds = computed(() => {
justify-content: space-between
padding: 8px 16px
font-size: 18px
.cycle-rounds
.cycle-cycles
gap: 8px
display: flex
flex-direction: column
+15 -1
View File
@@ -2,6 +2,7 @@
<div>
<button @click="mintToken">mint</button>
<button @click="mintToken2">mint2</button>
<button @click="mintToken3">mint3</button>
<button @click="sacrificeMeme">sacrifice Meme</button>
<button @click="approveMeme1">approve Meme1</button>
<button @click="tokenStore.approveToken(MemeBurnerJson, 10)">wallet approve</button>
@@ -152,7 +153,20 @@ async function mintToken() {
async function mintToken2() {
try {
var mint = await tokenStore.token[0].contract.write.mint(["100000000000000000000"]);
var mint = await tokenStore.token[1].contract.write.mint(["100000000000000000000000"]);
// .send({ from: web3.value.eth.Contract.defaultAccount });
console.log("mint", mint);
} catch (error) {
console.log(error);
}
// var balanceOf = await contract.methods.balanceOf("0x66422602B2f4885c57EE794174f98d9E4DDBBBC6").call();
// console.log("balanceOf", balanceOf);
// var totalSupply = await contract.methods.totalSupply().call();
// console.log("totalSupply", totalSupply);
}
async function mintToken3() {
try {
var mint = await tokenStore.token[2].contract.write.mint(["100000000000000000000000"]);
// .send({ from: web3.value.eth.Contract.defaultAccount });
console.log("mint", mint);
} catch (error) {
+2 -1
View File
@@ -1,4 +1,5 @@
import { fileURLToPath, URL } from 'node:url'
import svgLoader from "vite-svg-loader";
import { defineConfig } from 'vite'
import GlobalsPolyfills from "@esbuild-plugins/node-globals-polyfill";
@@ -9,7 +10,7 @@ import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
base: "./",
plugins: [vue()],
plugins: [vue(), svgLoader()],
optimizeDeps: {
esbuildOptions: {
plugins: [
+136 -4
View File
@@ -726,6 +726,11 @@
"@stablelib/random" "^1.0.2"
"@stablelib/wipe" "^1.0.1"
"@trysound/sax@0.2.0":
version "0.2.0"
resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz"
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
"@types/connect@^3.4.33":
version "3.4.35"
resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz"
@@ -797,7 +802,7 @@
"@vue/compiler-core" "3.3.4"
"@vue/shared" "3.3.4"
"@vue/compiler-sfc@3.3.4":
"@vue/compiler-sfc@^3.2.20", "@vue/compiler-sfc@3.3.4":
version "3.3.4"
resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz"
integrity sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==
@@ -1543,6 +1548,11 @@ commander@^2.20.3:
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^7.2.0:
version "7.2.0"
resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
@@ -1571,11 +1581,50 @@ cross-spawn@^7.0.2:
shebang-command "^2.0.0"
which "^2.0.1"
css-select@^5.1.0:
version "5.1.0"
resolved "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz"
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
dependencies:
boolbase "^1.0.0"
css-what "^6.1.0"
domhandler "^5.0.2"
domutils "^3.0.1"
nth-check "^2.0.1"
css-tree@^2.2.1:
version "2.3.1"
resolved "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz"
integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==
dependencies:
mdn-data "2.0.30"
source-map-js "^1.0.1"
css-tree@~2.2.0:
version "2.2.1"
resolved "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz"
integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==
dependencies:
mdn-data "2.0.28"
source-map-js "^1.0.1"
css-what@^6.1.0:
version "6.1.0"
resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
csso@^5.0.5:
version "5.0.5"
resolved "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz"
integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==
dependencies:
css-tree "~2.2.0"
csstype@^3.1.1:
version "3.1.2"
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz"
@@ -1625,6 +1674,36 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz"
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.2"
entities "^4.2.0"
domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"
domutils@^3.0.1:
version "3.1.0"
resolved "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz"
integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
duplexify@^4.1.2:
version "4.1.2"
resolved "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz"
@@ -1665,6 +1744,11 @@ end-of-stream@^1.4.1:
dependencies:
once "^1.4.0"
entities@^4.2.0:
version "4.5.0"
resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
es6-promise@^4.0.3:
version "4.2.8"
resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz"
@@ -2415,6 +2499,11 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
lodash-es@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
lodash.isequal@4.5.0:
version "4.5.0"
resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz"
@@ -2437,6 +2526,11 @@ loose-envify@^1.1.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
lottie-web@5.12.2:
version "5.12.2"
resolved "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz"
integrity sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz"
@@ -2458,6 +2552,16 @@ magic-string@^0.30.0:
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.15"
mdn-data@2.0.28:
version "2.0.28"
resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz"
integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==
mdn-data@2.0.30:
version "2.0.30"
resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz"
integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==
micro-ftch@^0.3.1:
version "0.3.1"
resolved "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz"
@@ -2534,7 +2638,7 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
nth-check@^2.1.1:
nth-check@^2.0.1, nth-check@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz"
integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
@@ -2986,7 +3090,7 @@ sonic-boom@^2.2.1:
dependencies:
atomic-sleep "^1.0.0"
source-map-js@^1.0.2, "source-map-js@>=0.6.2 <2.0.0":
source-map-js@^1.0.1, source-map-js@^1.0.2, "source-map-js@>=0.6.2 <2.0.0":
version "1.0.2"
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
@@ -3081,6 +3185,18 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
svgo@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz"
integrity sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==
dependencies:
"@trysound/sax" "0.2.0"
commander "^7.2.0"
css-select "^5.1.0"
css-tree "^2.2.1"
csso "^5.0.5"
picocolors "^1.0.0"
swiper@^9.4.1:
version "9.4.1"
resolved "https://registry.npmjs.org/swiper/-/swiper-9.4.1.tgz"
@@ -3242,6 +3358,14 @@ viem@^1.0.0, viem@^1.4.1, viem@>=0.3.35:
isomorphic-ws "5.0.0"
ws "8.12.0"
vite-svg-loader@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/vite-svg-loader/-/vite-svg-loader-4.0.0.tgz"
integrity sha512-0MMf1yzzSYlV4MGePsLVAOqXsbF5IVxbn4EEzqRnWxTQl8BJg/cfwIzfQNmNQxZp5XXwd4kyRKF1LytuHZTnqA==
dependencies:
"@vue/compiler-sfc" "^3.2.20"
svgo "^3.0.2"
vite@^4.0.0, vite@^4.3.5:
version "4.4.9"
resolved "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz"
@@ -3288,7 +3412,7 @@ vue-toastification@^2.0.0-rc.5:
resolved "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz"
integrity sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==
"vue@^2.6.14 || ^3.3.0", "vue@^3.0.0-0 || ^2.6.0", vue@^3.0.2, vue@^3.2.0, vue@^3.2.25, vue@^3.3.2, "vue@>= 3.0.0 < 4", vue@3.3.4:
"vue@^2.6.14 || ^3.3.0", "vue@^3.0.0-0 || ^2.6.0", vue@^3.0.2, vue@^3.2, vue@^3.2.0, vue@^3.2.25, vue@^3.3.2, "vue@>= 3.0.0 < 4", vue@3.3.4:
version "3.3.4"
resolved "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz"
integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==
@@ -3299,6 +3423,14 @@ vue-toastification@^2.0.0-rc.5:
"@vue/server-renderer" "3.3.4"
"@vue/shared" "3.3.4"
vue3-lottie@^3.2.0:
version "3.2.0"
resolved "https://registry.npmjs.org/vue3-lottie/-/vue3-lottie-3.2.0.tgz"
integrity sha512-PtNXbv7iD4XGmK8CXd71aLWmILIR6P6VzLMDw6ZzmDAeuJZuJ0MdOVnn50LOARgq+cOFJsn/2z+7tZh0F9T9qw==
dependencies:
lodash-es "^4.17.21"
lottie-web "5.12.2"
web3-eth-abi@^1.2.1:
version "1.10.1"
resolved "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.1.tgz"