oXjzXt;%CyW_M&
zd#|~ra#~D{TJ*O!(oN`Uz3-0Gilo%4iILrDEAZOqxjye|hnqxb)B~Ux39?oRwMd%0(bT|1r4(abTM>);fAH!_gW$z9zE
zi1uD{3umXbVvx0Y!k|KTS9gM7VRSRfX$GnBHSh+rfrU=>iIaWR@*Jld+qeHf)y9>M>BN5~Ku1C7hc9u~@J
z7EcFCBXS_fD5Bi9Vw8rk;`zV)ZeoD^Z;32tb(|1S;?a|FR?%3EIxQIApuhEbU
z9lFQVES1|%oOqRQ)KAG7oP!7dg`}`hPBSXpf4X0)7k52Z+|LT9R$LU?O~{IY;#
z=DEJt{D-88(GEChs75I=Mk&Mp$p2!oZzBVVIb@7SMsOJ4GM2ZJAP;b|g%{{q27w
zEzr+y<$%NnYJ6?y>nlo;v>hERSPJ2hnDf$FZ%7_9q`lX?o`8FqtPyJ`_15wbLI-9-
zc+}HTI&nH9oq5)t=!yiK^jYrRh_mcf3P32KBMZNejGWts@XQl)osnFdqnxI>oHE+a
zUZWJV?9HUrFw+h*jWibesI4MB7fri4#$Z1?mb-UQ!18o3M~|sl+2MvCtkHU@I+CA@
z_ULAd{p@Kr#jC!pLeemd~*1XZIA?fD$+|QqXL+$go*v}r9()Lkc
zLOXhdm99A?=4NJ|Am=)gZjRk)nh#ln^Vw?@a9!Srh@;1tS+ActGaC&bEIN`KSG02^
z2IsT)J)3xT^-`GQB0F>LTl~y#6+_<8>*Bl|cC0GkTBEcwEQs|&+Avsr1%>9gt
zjO4}@?a|HFCc4HNI7fm=hVCm^NzR==|C_?L$4Zu%G|Oqy`|7(Pm3(VP+R-DdG}BE;;CEW5EIm2l6CiyWvpdQ2%!&Xq}#jT<*aC7&W8<>uPuG_1?9UD*ht$+u=y
z96e@1^BYgVjZmaU8p(|-nxmVMaCMPiN7K<0OqAWUkLQ&@vSCECoQC9^p?&7T+gp1<
z)6o->r=9AlFKDE(IB6tJB-iFzg%9Sf*1gy#T
zk};73OKbFIOsv@f9O}Scroh@4)7U^jZRZc@BGCw~bi5m|sqn(VVMGmYB9h76S
zm&qW=Fi%X}$T#|A^eUNz>c-{Em&MlRcmNKYz{I=&2)Xfq%nYF34ATo)5IQg|cBimp
zLgc_&*1a7y>!FcTI4)Y~c=P5;-L`-C}U(!=rL8kF0t6}B10K@C)XgejzNR7ltHqRjBAG{=^P0%lXPoGme%O4
z@O8Trl!odA3v*}eTI7JTKTT!O#A-$7L7UFW*ia>TX>l$0RQFYyzQ|lUIHa
zB=0BqflzMvn&g2{?(+B5n%*Np1~D(
+
+
+
+
+
+
diff --git a/src/App.vue b/src/App.vue
index 47494ef5..6011f7fd 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -90,6 +90,7 @@ const themeMap = {
meter: 'meter',
taiko: 'taiko',
etherlink: 'etherlink',
+ 'vana-moksha': 'vana-moksha',
};
// Function to update theme based on the route slug
const updateTheme = () => {
diff --git a/src/assets/css/tailwind.css b/src/assets/css/tailwind.css
index fe81c777..54f3990b 100644
--- a/src/assets/css/tailwind.css
+++ b/src/assets/css/tailwind.css
@@ -606,20 +606,18 @@ html[data-theme='etherlink'] {
--color-orange-700: 180, 83, 9;
}
-html[data-theme='telos'] {
- /* Green */
- --color-blue-50: 225, 255, 239;
- --color-blue-100: 199, 255, 225;
- --color-blue-200: 163, 255, 205;
- --color-blue-300: 112, 255, 180;
+html[data-theme='vana-moksha'] {
+ /* Blue */
+ --color-blue-50: 243, 241, 244;
+ --color-blue-100: 237, 235, 240;
+ --color-blue-200: 230, 228, 234;
+ --color-blue-300: 231, 228, 233;
--color-blue-400: 231, 228, 233; /* New Primary Color */
- --color-blue-500: 50, 230, 140;
- --color-blue-600: 42, 200, 120;
- --color-blue-700: 34, 170, 102;
- --color-blue-800: 28, 140, 84;
- --color-blue-900: 22, 110, 66;
-
- /* Gray */
+ --color-blue-500: 184, 183, 187;
+ --color-blue-600: 138, 137, 142;
+ --color-blue-700: 92, 91, 96;
+ --color-blue-800: 46, 45, 50;
+ --color-blue-900: 22, 21, 25;
/* Gray */
--color-gray-50: 230, 230, 230;
@@ -639,15 +637,15 @@ html[data-theme='telos'] {
--color-pink-100: 255, 210, 220;
--color-pink-200: 255, 180, 195;
--color-pink-300: 255, 150, 175;
- --color-pink-400: 0, 100, 0; /* Gradient Loading */
+ --color-pink-400: 27, 27, 27; /* Gradient Loading */
--color-pink-500: 255, 226, 160; /* Stars Gradient */
- --color-pink-600: 34, 170, 102; /* Gradient Base */
- --color-pink-700: 0, 128, 128; /* Gradient Hover */
+ --color-pink-600: 69, 69, 69; /* Gradient Base */
+ --color-pink-700: 57, 57, 57; /* Gradient Hover */
--color-pink-800: 205, 80, 120;
--color-pink-900: 180, 65, 100;
/* Yellow */
- --color-yellow-500: 122, 255, 189; /* Stars Gradient */
+ --color-yellow-500: 255, 255, 255; /* Stars Gradient */
/* Purple */
--color-purple-500: 255, 226, 160; /* Ve Stars Gradient */
@@ -656,6 +654,7 @@ html[data-theme='telos'] {
--color-orange-300: 252, 211, 77; /* Stars on Add liquidity */
--color-orange-600: 217, 119, 6;
--color-orange-700: 180, 83, 9;
+ --bg-white: 240, 240, 234;
}
@layer utilities {
diff --git a/src/assets/data/contracts/vana-moksha.json b/src/assets/data/contracts/vana-moksha.json
new file mode 100644
index 00000000..16db824d
--- /dev/null
+++ b/src/assets/data/contracts/vana-moksha.json
@@ -0,0 +1,16 @@
+{
+ "Authorizer": "0x1Fe0eBD7B53fC434Ea0a69074406503F9Ab0e2FC",
+ "BalancerHelpers": "0xF4d9D664BAD7754A9292A03D0255e0b901FCE752",
+ "BalancerQueries": "0xc1abdF9542BB46F4a128C5c93Ee5D101E481Bd05",
+ "BalancerRelayer": "0xEC72775206091e6cee0e9801189aC9Ca19266dB7",
+ "BatchRelayerLibrary": "0x69331C1c1A93C1093d42DC951FF779eda7B3ED57",
+ "BatchRelayerQueryLibrary": "0xF2170C34e49D60b0A3ab5b5098C3844d5385935b",
+ "ComposableStablePoolFactory": "0xC7623faa9e41DaAf854F07B5b45e70Cf1d68583E",
+ "MockComposableStablePool": "0x8aDCD44510d0327Fd221011feb028b1CfeDDbCBa",
+ "MockWeightedPool": "0x25943e5758611C635b5106bB663Aa2DD4EDFcaeA",
+ "ProtocolFeePercentagesProvider": "0x6166DA5fde541398149BC69E4e1E9430FC78B77e",
+ "ProtocolFeesCollector": "0x2EC5B1C5865D88D36cA9DD724A4e2f7C8d4C6bed",
+ "SymmToken": "0x4e4131dC27ed9501ac5fEb76F94572fDAe9f0fD0",
+ "Vault": "0xBA96c3dE0d8c2AD73962ee43Ab60CE3e094453De",
+ "WeightedPoolFactory": "0x8670184F35F9A7b4E28269BEE0a7475ea681493D"
+}
diff --git a/src/assets/images/icons/networks/vana-moksha.svg b/src/assets/images/icons/networks/vana-moksha.svg
new file mode 100644
index 00000000..bc26343c
--- /dev/null
+++ b/src/assets/images/icons/networks/vana-moksha.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/components/contextual/pages/pool/staking/PointsIncentivesCard.vue b/src/components/contextual/pages/pool/staking/PointsIncentivesCard.vue
new file mode 100644
index 00000000..9a2b3f09
--- /dev/null
+++ b/src/components/contextual/pages/pool/staking/PointsIncentivesCard.vue
@@ -0,0 +1,284 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('staked') }} {{ $t('lpTokens') }}
+
+
+
+
+
+
+ {{ fNum(fiatValueOfStakedShares, FNumFormats.fiat) }}
+
+
+
+
+
+
+ {{ $t('unstaked') }} {{ $t('lpTokens') }}
+
+
+
+
+
+
+ {{ fNum(fiatValueOfUnstakedShares, FNumFormats.fiat) }}
+
+
+
+
+
+
+
+ {{ $t('stake') }}
+
+
+ {{ $t('unstake') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/contextual/pages/pool/staking/StakeSummary.vue b/src/components/contextual/pages/pool/staking/StakeSummary.vue
index a9fd9bc0..b4d19432 100644
--- a/src/components/contextual/pages/pool/staking/StakeSummary.vue
+++ b/src/components/contextual/pages/pool/staking/StakeSummary.vue
@@ -25,9 +25,7 @@ const { fNum } = useNumbers();
{{ $t('totalValueTo') }}
-
- {{ action === 'stake' ? $t('stake') : $t('unstake') }}:
-
+ {{ $t(action) }}:
diff --git a/src/components/contextual/pages/pool/staking/composables/useStakePreview.ts b/src/components/contextual/pages/pool/staking/composables/useStakePreview.ts
index 5504a284..02b37f1a 100644
--- a/src/components/contextual/pages/pool/staking/composables/useStakePreview.ts
+++ b/src/components/contextual/pages/pool/staking/composables/useStakePreview.ts
@@ -14,11 +14,19 @@ import {
import { getAddress } from '@ethersproject/address';
import { useI18n } from 'vue-i18n';
import useTokenApprovalActions from '@/composables/approvals/useTokenApprovalActions';
+import useStakedSharesQuery from '@/composables/queries/useStakedSharesQuery';
+import { GaugeShare } from '@/composables/queries/useUserGaugeSharesQuery';
/**
* TYPES
*/
-export type StakeAction = 'stake' | 'unstake' | 'restake';
+export type StakeAction =
+ | 'stake'
+ | 'unstake'
+ | 'restake'
+ | 'stakeForPoints'
+ | 'unstakeForPoints';
+
export type StakePreviewProps = {
pool: AnyPool;
action: StakeAction;
@@ -43,18 +51,44 @@ export function useStakePreview(props: StakePreviewProps, emit) {
const { getTokenApprovalActions } = useTokenApprovalActions();
const {
isLoading: isPoolStakingLoading,
+ isPointsLoading,
stake,
unstake,
+ stakeForPoints,
+ unstakeForPoints,
stakedShares,
refetchAllPoolStakingData,
preferentialGaugeAddress,
+ pointsGaugeAddress,
} = usePoolStaking();
// Staked or unstaked shares depending on action type.
- const currentShares =
- props.action === 'stake'
- ? balanceFor(getAddress(props.pool.address))
- : stakedShares.value;
+ let currentShares = '0';
+
+ if (props.action === 'stake' || props.action === 'stakeForPoints') {
+ currentShares = balanceFor(getAddress(props.pool.address));
+ } else if (props.action === 'unstakeForPoints') {
+ const { data: stakedPointsShares } = useStakedSharesQuery(
+ ref([
+ {
+ balance: '0',
+ gauge: {
+ id: pointsGaugeAddress.value,
+ poolAddress: getAddress(props.pool.address),
+ poolId: props.pool.id,
+ totalSupply: '0',
+ isPreferentialGauge: true,
+ isKilled: false,
+ },
+ },
+ ] as GaugeShare[])
+ );
+ currentShares = stakedPointsShares.value
+ ? stakedPointsShares.value[props.pool.id]
+ : '0';
+ } else {
+ currentShares = stakedShares.value;
+ }
const stakeAction = {
label: t('stake'),
@@ -75,6 +109,22 @@ export function useStakePreview(props: StakePreviewProps, emit) {
: t('staking.unstakeTooltip'),
};
+ const stakeForPointsAction = {
+ label: t('stakeForPoints'),
+ loadingLabel: t('staking.staking'),
+ confirmingLabel: t('confirming'),
+ action: () => txWithNotification(stakeForPoints, 'stakeForPoints'),
+ stepTooltip: t('staking.stakeTooltip'),
+ };
+
+ const unstakeForPointsAction = {
+ label: t('unstakeForPoints'),
+ loadingLabel: t('staking.unstaking'),
+ confirmingLabel: t('confirming'),
+ action: () => txWithNotification(unstakeForPoints, 'unstakeForPoints'),
+ stepTooltip: t('staking.unstakeTooltip'),
+ };
+
/**
* COMPUTED
*/
@@ -99,9 +149,15 @@ export function useStakePreview(props: StakePreviewProps, emit) {
},
]);
- const isLoading = computed(
- () => isLoadingApprovalsForGauge.value || isPoolStakingLoading.value
- );
+ const isLoading = computed(() => {
+ if (
+ props.action === 'stakeForPoints' ||
+ props.action === 'unstakeForPoints'
+ ) {
+ return isLoadingApprovalsForGauge.value || isPointsLoading.value;
+ }
+ return isLoadingApprovalsForGauge.value || isPoolStakingLoading.value;
+ });
/**
* METHODS
@@ -150,6 +206,20 @@ export function useStakePreview(props: StakePreviewProps, emit) {
if (approvalActions) stakeActions.value.unshift(...approvalActions);
}
+ async function loadApprovalsForPointsGauge() {
+ const approvalActions = await trackLoading(async () => {
+ if (!pointsGaugeAddress.value) return;
+
+ return await getTokenApprovalActions({
+ amountsToApprove: amountsToApprove.value,
+ spender: pointsGaugeAddress.value,
+ actionType: ApprovalAction.Staking,
+ });
+ }, isLoadingApprovalsForGauge);
+
+ if (approvalActions) stakeActions.value.unshift(...approvalActions);
+ }
+
async function handleSuccess(receipt: TransactionReceipt) {
isActionConfirmed.value = true;
confirmationReceipt.value = receipt;
@@ -173,6 +243,12 @@ export function useStakePreview(props: StakePreviewProps, emit) {
if (props.action === 'unstake') {
stakeActions.value = [unstakeAction];
}
+ if (props.action === 'stakeForPoints') {
+ stakeActions.value = [stakeForPointsAction];
+ }
+ if (props.action === 'unstakeForPoints') {
+ stakeActions.value = [unstakeForPointsAction];
+ }
if (props.action === 'restake')
stakeActions.value = [unstakeAction, stakeAction];
},
@@ -180,15 +256,25 @@ export function useStakePreview(props: StakePreviewProps, emit) {
);
watch(preferentialGaugeAddress, async () => {
- if (props.action === 'unstake') return;
+ if (props.action !== 'unstake' && props.action !== 'unstakeForPoints')
+ return;
await loadApprovalsForGauge();
});
+ watch(pointsGaugeAddress, async () => {
+ if (props.action !== 'stakeForPoints') return;
+ await loadApprovalsForPointsGauge();
+ });
+
/**
* LIFECYCLE
*/
onBeforeMount(async () => {
- if (props.action !== 'unstake') await loadApprovalsForGauge();
+ if (props.action === 'stakeForPoints') {
+ await loadApprovalsForPointsGauge();
+ } else if (props.action !== 'unstake') {
+ await loadApprovalsForGauge();
+ }
});
return {
diff --git a/src/composables/useNetwork.ts b/src/composables/useNetwork.ts
index 5dcab810..4f36bdf1 100644
--- a/src/composables/useNetwork.ts
+++ b/src/composables/useNetwork.ts
@@ -24,7 +24,7 @@ const NETWORK_ID =
urlNetworkId ||
localStorageNetworkId ||
(Number(import.meta.env.VITE_NETWORK) as Network) ||
- Network.CELO;
+ Network.VANAMOKSHA;
if (windowAvailable) localStorage.setItem('networkId', NETWORK_ID.toString());
export const networkSlug = config[NETWORK_ID].slug;
export const networkConfig = config[NETWORK_ID];
@@ -116,6 +116,9 @@ export const symmSymbol = computed(() => {
if (networkId.value === Network.GNOSIS) {
return 'gSYMM';
}
+ if (networkId.value === Network.VANAMOKSHA) {
+ return 'vSYMM';
+ }
return 'mSYMM';
});
diff --git a/src/composables/useTransactions.ts b/src/composables/useTransactions.ts
index 518bd338..51e21de5 100644
--- a/src/composables/useTransactions.ts
+++ b/src/composables/useTransactions.ts
@@ -53,6 +53,8 @@ export type TransactionAction =
| 'voteForGauge'
| 'unstake'
| 'stake'
+ | 'stakeForPoints'
+ | 'unstakeForPoints'
| 'restake'
| 'sync'
| 'userGaugeCheckpoint';
diff --git a/src/lib/config/index.ts b/src/lib/config/index.ts
index 578a99da..2f2ac504 100644
--- a/src/lib/config/index.ts
+++ b/src/lib/config/index.ts
@@ -4,26 +4,28 @@ import { Config, Network } from './types';
// import avalanche from './avalanche';
// import base from './base';
// import goerli from './goerli';
-import gnosisChain from './gnosis-chain';
+// import gnosisChain from './gnosis-chain';
// import mainnet from './mainnet';
// import optimism from './optimism';
// import polygon from './polygon';
// import sepolia from './sepolia';
// import zkevm from './zkevm';
-import telos from './telos';
+// import telos from './telos';
// import telosTestnet from './telos-testnet';
-import celo from './celo';
-import meter from './meter';
-import taiko from './taiko';
-import etherlink from './etherlink';
+// import celo from './celo';
+// import meter from './meter';
+// import taiko from './taiko';
+// import etherlink from './etherlink';
+import vanaMoksha from './vana-moksha';
const config: Record = {
- [Network.TELOS]: telos,
- [Network.CELO]: celo,
- [Network.GNOSIS]: gnosisChain,
- [Network.METER]: meter,
- [Network.TAIKO]: taiko,
- [Network.ETHERLINK]: etherlink,
+ // [Network.TELOS]: telos,
+ // [Network.CELO]: celo,
+ // [Network.GNOSIS]: gnosisChain,
+ // [Network.METER]: meter,
+ // [Network.TAIKO]: taiko,
+ // [Network.ETHERLINK]: etherlink,
+ [Network.VANAMOKSHA]: vanaMoksha,
};
export default config;
diff --git a/src/lib/config/taiko/pools.ts b/src/lib/config/taiko/pools.ts
index 3a9cbd01..4d125ca9 100644
--- a/src/lib/config/taiko/pools.ts
+++ b/src/lib/config/taiko/pools.ts
@@ -31,6 +31,10 @@ const pools: Pools = {
'0x65d5eebb5f1c767ce42c3ccc8cfd00fb3a114122000000000000000000000003', //USDC-USDC.e
],
},
+ PointsGauges: {
+ '0x65d5eebb5f1c767ce42c3ccc8cfd00fb3a114122000000000000000000000003':
+ '0x0447cb41A2a0D4C4A76cA3e2b1be65076DD48A06', //USDC-USDC.e
+ },
Investment: {
AllowList: [],
},
diff --git a/src/lib/config/types.ts b/src/lib/config/types.ts
index d2fede85..65da79d6 100644
--- a/src/lib/config/types.ts
+++ b/src/lib/config/types.ts
@@ -93,6 +93,7 @@ export enum Network {
CELO = 42220,
TAIKO = 167000,
ETHERLINK = 42793,
+ VANAMOKSHA = 14800,
}
type Reward = {
diff --git a/src/lib/config/vana-moksha/contracts.ts b/src/lib/config/vana-moksha/contracts.ts
new file mode 100644
index 00000000..dbef424f
--- /dev/null
+++ b/src/lib/config/vana-moksha/contracts.ts
@@ -0,0 +1,30 @@
+import { Contracts } from '../types';
+import * as vanaMoksha from '@/assets/data/contracts/vana-moksha.json';
+
+const contracts: Contracts = {
+ merkleRedeem: '',
+ merkleOrchard: '',
+ merkleOrchardV2: '',
+ multicall: '0x9A8F4bA7D632E0D510e7982fF5A9C9e898c102b9',
+ authorizer: vanaMoksha.Authorizer,
+ vault: vanaMoksha.Vault,
+ weightedPoolFactory: vanaMoksha.WeightedPoolFactory,
+ stablePoolFactory: vanaMoksha.ComposableStablePoolFactory,
+ lidoRelayer: '',
+ balancerHelpers: vanaMoksha.BalancerHelpers,
+ balancerQueries: vanaMoksha.BalancerQueries,
+ batchRelayer: vanaMoksha.BalancerRelayer,
+ veBAL: '',
+ gaugeController: '',
+ gaugeFactory: '',
+ balancerMinter: '',
+ tokenAdmin: '',
+ veDelegationProxy: '',
+ veBALHelpers: '',
+ feeDistributor: '',
+ feeDistributorDeprecated: '',
+ faucet: '0x2642b088DdB47A617Ece81bAe2D1F6F7a265D58C',
+ omniVotingEscrow: '',
+};
+
+export default contracts;
diff --git a/src/lib/config/vana-moksha/index.ts b/src/lib/config/vana-moksha/index.ts
new file mode 100644
index 00000000..d3c14b5d
--- /dev/null
+++ b/src/lib/config/vana-moksha/index.ts
@@ -0,0 +1,72 @@
+import { Config } from '../types';
+import contracts from './contracts';
+import keys from './keys';
+import pools from './pools';
+import tokenlists from './tokenlists';
+import tokens from './tokens';
+import rateProviders from './rateProviders';
+
+const config: Config = {
+ key: '14800',
+ chainId: 14800,
+ chainName: 'Moksha',
+ name: 'Vana Moksha',
+ shortName: 'vana-moksha',
+ monorepoName: 'vana-moksha',
+ slug: 'vana-moksha',
+ network: 'vana-moksha',
+ trustWalletNetwork: 'vana-moksha',
+ unknown: false,
+ visibleInUI: true,
+ testNetwork: true,
+ rpc: `https://rpc.moksha.vana.org`,
+ ws: ``,
+ explorer: 'https://moksha.vanascan.io/',
+ explorerName: 'Vanascan',
+ subgraph:
+ 'https://api.goldsky.com/api/public/project_clnbo3e3c16lj33xva5r2aqk7/subgraphs/symmetric-moksha/1.0.0/gn',
+ balancerApi: '',
+ poolsUrlV2:
+ 'https://storageapi.fleek.co/johngrantuk-team-bucket/poolsV2.json',
+ subgraphs: {
+ main: [
+ 'https://api.goldsky.com/api/public/project_clnbo3e3c16lj33xva5r2aqk7/subgraphs/symmetric-moksha/1.0.0/gn',
+ ],
+ aave: '',
+ gauge: '',
+ blocks: '',
+ },
+ bridgeUrl: '',
+ supportsEIP1559: true,
+ supportsElementPools: false,
+ blockTime: 32,
+ nativeAsset: {
+ name: 'VANA',
+ address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ symbol: 'VANA',
+ decimals: 18,
+ deeplinkId: 'vana',
+ logoURI: 'tokens/vana.png',
+ minTransactionBuffer: '0.0005',
+ },
+ thirdParty: {
+ coingecko: {
+ nativeAssetId: 'vana',
+ platformId: 'ethereum',
+ },
+ },
+ addresses: {
+ ...contracts,
+ },
+ pools,
+ tokens,
+ keys,
+ gauges: {
+ type: 2,
+ weight: 100,
+ },
+ tokenlists,
+ rateProviders,
+};
+
+export default config;
diff --git a/src/lib/config/vana-moksha/keys.ts b/src/lib/config/vana-moksha/keys.ts
new file mode 100644
index 00000000..b9731e6b
--- /dev/null
+++ b/src/lib/config/vana-moksha/keys.ts
@@ -0,0 +1,5 @@
+import { Keys } from '../types';
+
+const keys: Keys = {};
+
+export default keys;
diff --git a/src/lib/config/vana-moksha/pools.ts b/src/lib/config/vana-moksha/pools.ts
new file mode 100644
index 00000000..57bb1cfc
--- /dev/null
+++ b/src/lib/config/vana-moksha/pools.ts
@@ -0,0 +1,62 @@
+import { Pools } from '@/types/pools';
+
+const pools: Pools = {
+ IdsMap: {
+ veBAL: '',
+ },
+ Pagination: {
+ PerPage: 15,
+ PerPool: 15,
+ PerPoolInitial: 5,
+ },
+ BoostsEnabled: true,
+ DelegateOwner: '0x7255Db0d1C1B93Fb756157074fa0613Aa6878F31',
+ ZeroAddress: '0x0000000000000000000000000000000000000000',
+ DynamicFees: {
+ Gauntlet: [],
+ },
+ BlockList: [''],
+ IncludedPoolTypes: [
+ 'Weighted',
+ 'Stable',
+ 'MetaStable',
+ 'LiquidityBootstrapping',
+ 'Investment',
+ 'StablePhantom',
+ 'ComposableStable',
+ 'Managed',
+ ],
+ Stable: {
+ AllowList: [
+ '0xe9b5659a77148a7ec25de40388d0bf9e89331ad0000000000000000000000003', //USDC-USDT
+ ],
+ },
+
+ Investment: {
+ AllowList: [],
+ },
+ Weighted: {
+ // Only effective after given timestamp here: usePool.ts#createdAfterTimestamp
+ // see useDisabledJoinPool.ts#nonAllowedWeightedPoolAfterTimestamp for logic.
+ AllowList: [
+ '0xd31a782e34c342a8d6d0108b1430f31b3ef3a995000200000000000000000002', //WVANA-USDC
+ ],
+ },
+ Factories: {
+ '0x8670184f35f9a7b4e28269bee0a7475ea681493d': 'weightedPool', // Weighted V5
+ '0xc7623faa9e41daaf854f07b5b45e70cf1d68583e': 'composableStablePool', // ComposableStable V5
+ },
+ Stakable: {
+ VotingGaugePools: [],
+ AllowList: [],
+ },
+ Metadata: {},
+ Deep: [],
+ Deprecated: {},
+ GaugeMigration: {},
+ BoostedApr: [],
+ DisabledJoins: [],
+ Issues: {},
+};
+
+export default pools;
diff --git a/src/lib/config/vana-moksha/rateProviders.ts b/src/lib/config/vana-moksha/rateProviders.ts
new file mode 100644
index 00000000..a2072658
--- /dev/null
+++ b/src/lib/config/vana-moksha/rateProviders.ts
@@ -0,0 +1,9 @@
+import { RateProviders } from '../types';
+
+const rateProviders: RateProviders = {
+ '*': {
+ '0x0000000000000000000000000000000000000000': true,
+ },
+};
+
+export default rateProviders;
diff --git a/src/lib/config/vana-moksha/rewards.ts b/src/lib/config/vana-moksha/rewards.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/src/lib/config/vana-moksha/tokenlists.ts b/src/lib/config/vana-moksha/tokenlists.ts
new file mode 100644
index 00000000..27fd711e
--- /dev/null
+++ b/src/lib/config/vana-moksha/tokenlists.ts
@@ -0,0 +1,14 @@
+import { TokenListURLMap } from '@/types/TokenList';
+
+const tokenlists: TokenListURLMap = {
+ Balancer: {
+ Allowlisted:
+ 'https://raw.githubusercontent.com/centfinance/tokenlists/main/generated/symmetric.tokenlist.json',
+ },
+ External: [
+ // 'https://raw.githubusercontent.com/telosnetwork/token-list/main/telosevm.tokenlist.json',
+ // 'https://raw.githubusercontent.com/swapsicledex/swapsicle-default-token-list/master/swapsicle.tokenlist.json',
+ ],
+};
+
+export default tokenlists;
diff --git a/src/lib/config/vana-moksha/tokens.ts b/src/lib/config/vana-moksha/tokens.ts
new file mode 100644
index 00000000..b5641b25
--- /dev/null
+++ b/src/lib/config/vana-moksha/tokens.ts
@@ -0,0 +1,36 @@
+import { TokenConstants } from '../types';
+
+const tokens: TokenConstants = {
+ Popular: {
+ Symbols: ['vSYMM', 'WVANA', 'USDC', 'USDT'],
+ },
+ InitialSwapTokens: {
+ input: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ output: '0xa9d23408b9ba935c230493c40c73824df71a0975',
+ },
+ Addresses: {
+ nativeAsset: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ wNativeAsset: '0xbccc4b4c6530F82FE309c5E845E50b5E9C89f2AD',
+ WETH: '0xbccc4b4c6530F82FE309c5E845E50b5E9C89f2AD',
+ BAL: '0x4e4131dC27ed9501ac5fEb76F94572fDAe9f0fD0',
+ rETH: '',
+ reward: '',
+ rewards: '',
+ erc4626Wrappers: {},
+ // wstETH: '0xB4B01216a5Bc8F1C8A33CD990A1239030E60C905',
+ },
+ PriceChainMap: {
+ /**
+ * Addresses must be lower case and map from goerli to mainnet, e.g
+ * [goerli address]: mainnet address
+ */
+ // USDT
+ '0x01079c78199e05d44bbff9e50dbdf765489f16e1':
+ '0xdac17f958d2ee523a2206206994597c13d831ec7',
+ // USDC
+ '0xb39a50b5806039c82932bb96cefbcbc61231045c':
+ '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
+ },
+};
+
+export default tokens;
diff --git a/src/lib/scripts/addresses-vana-moksha.json b/src/lib/scripts/addresses-vana-moksha.json
new file mode 100644
index 00000000..81d8a834
--- /dev/null
+++ b/src/lib/scripts/addresses-vana-moksha.json
@@ -0,0 +1,98 @@
+{
+ "20210418-authorizer": {
+ "contracts": [
+ {
+ "name": "Authorizer",
+ "address": "0x1Fe0eBD7B53fC434Ea0a69074406503F9Ab0e2FC"
+ }
+ ],
+ "status": "ACTIVE"
+ },
+ "20210418-vault": {
+ "contracts": [
+ {
+ "name": "Vault",
+ "address": "0xBA96c3dE0d8c2AD73962ee43Ab60CE3e094453De"
+ },
+ {
+ "name": "ProtocolFeesCollector",
+ "address": "0x2EC5B1C5865D88D36cA9DD724A4e2f7C8d4C6bed"
+ },
+ {
+ "name": "BalancerHelpers",
+ "address": "0xF4d9D664BAD7754A9292A03D0255e0b901FCE752"
+ }
+ ],
+ "status": "ACTIVE"
+ },
+ "20220721-balancer-queries": {
+ "contracts": [
+ {
+ "name": "BalancerQueries",
+ "address": "0xc1abdF9542BB46F4a128C5c93Ee5D101E481Bd05"
+ }
+ ],
+ "status": "ACTIVE"
+ },
+ "20220725-protocol-fee-percentages-provider": {
+ "contracts": [
+ {
+ "name": "ProtocolFeePercentagesProvider",
+ "address": "0x6166DA5fde541398149BC69E4e1E9430FC78B77e"
+ }
+ ],
+ "status": "ACTIVE"
+ },
+ "20230320-weighted-pool-v4": {
+ "contracts": [
+ {
+ "name": "WeightedPoolFactory",
+ "address": "0x8670184F35F9A7b4E28269BEE0a7475ea681493D"
+ },
+ {
+ "name": "MockWeightedPool",
+ "address": "0x25943e5758611C635b5106bB663Aa2DD4EDFcaeA"
+ }
+ ],
+ "status": "ACTIVE"
+ },
+ "20231031-batch-relayer-v6": {
+ "contracts": [
+ {
+ "name": "BatchRelayerLibrary",
+ "address": "0x69331C1c1A93C1093d42DC951FF779eda7B3ED57"
+ },
+ {
+ "name": "BatchRelayerQueryLibrary",
+ "address": "0xF2170C34e49D60b0A3ab5b5098C3844d5385935b"
+ },
+ {
+ "name": "BalancerRelayer",
+ "address": "0xEC72775206091e6cee0e9801189aC9Ca19266dB7"
+ }
+ ],
+ "status": "ACTIVE"
+ },
+ "20231122-symm-token": {
+ "contracts": [
+ {
+ "name": "SymmToken",
+ "address": "0x4e4131dC27ed9501ac5fEb76F94572fDAe9f0fD0"
+ }
+ ],
+ "status": "ACTIVE"
+ },
+ "20240223-composable-stable-pool-v6": {
+ "contracts": [
+ {
+ "name": "ComposableStablePoolFactory",
+ "address": "0xC7623faa9e41DaAf854F07B5b45e70Cf1d68583E"
+ },
+ {
+ "name": "MockComposableStablePool",
+ "address": "0x8aDCD44510d0327Fd221011feb028b1CfeDDbCBa"
+ }
+ ],
+ "status": "ACTIVE"
+ }
+}
diff --git a/src/lib/scripts/contract-addresses.generator.ts b/src/lib/scripts/contract-addresses.generator.ts
index 9d9a5662..66e60e47 100644
--- a/src/lib/scripts/contract-addresses.generator.ts
+++ b/src/lib/scripts/contract-addresses.generator.ts
@@ -58,7 +58,7 @@ interface AddressValue {
type Addresses = Record;
async function generate() {
- const network = 'etherlink';
+ const network = 'vana-moksha';
console.log(`Generating contract addresses for network ${network}...`);
const addresses: Addresses = require(`./addresses-${network}.json`);
diff --git a/src/locales/default.json b/src/locales/default.json
index 98ba6b19..9b28a24a 100644
--- a/src/locales/default.json
+++ b/src/locales/default.json
@@ -984,6 +984,7 @@
"somethingWentWrong": "Something went wrong",
"stablePool": "Stable pool",
"stake": "Stake",
+ "stakeForPoints": "Stake",
"staked": "Staked",
"staking": {
"minimumStakingApr": "Min staking APR",
@@ -1482,6 +1483,8 @@
"transactionAction": {
"stake": "Stake",
"unstake": "Unstake",
+ "stakeForPoints": "Stake",
+ "unstakeForPoints": "Unstake",
"approve": "Approve",
"claim": "Claim",
"createPool": "Create pool",
@@ -1533,6 +1536,8 @@
"transactionSummary": {
"stake": "{amount} in {pool}",
"unstake": "{amount} from {pool}",
+ "stakeForPoints": "{amount} in {pool}",
+ "unstakeForPoints": "{amount} from {pool}",
"approveForInvesting": "Approve {0} for adding liquidity",
"approveForLocking": "Approve {0} for locking",
"approveForStaking": "Approve {0} for staking",
@@ -1572,6 +1577,7 @@
"unlocked": "Unlocked",
"unlocking": "Unlocking",
"unstake": "Unstake",
+ "unstakeForPoints": "Unstake",
"unstaked": "Unstaked",
"restake": "Restake",
"restaked": "Restaked",
diff --git a/src/pages/index.vue b/src/pages/index.vue
index 3fede913..b41b51c0 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -203,7 +203,7 @@ onBeforeMount(async () => {
/>
diff --git a/src/pages/pool/_id.vue b/src/pages/pool/_id.vue
index 32627dbd..b58c6223 100644
--- a/src/pages/pool/_id.vue
+++ b/src/pages/pool/_id.vue
@@ -36,6 +36,7 @@ import PoolRisks from '@/components/contextual/pages/pool/risks/PoolRisks.vue';
import { usePool } from '@/providers/local/pool.provider';
import { provideUserStaking } from '@/providers/local/user-staking.provider';
import { providerUserPools } from '@/providers/local/user-pools.provider';
+import PointsIncentivesCard from '@/components/contextual/pages/pool/staking/PointsIncentivesCard.vue';
const userStaking = provideUserStaking();
providerUserPools(userStaking);
@@ -157,6 +158,13 @@ const titleTokens = computed
(() => {
return orderedPoolTokens(pool.value, pool.value.tokens);
});
+const isPointsStakablePool = computed(() => {
+ if (!pool.value || POOLS.PointsGauges === undefined) return false;
+ return Object.keys(POOLS.PointsGauges).includes(poolId);
+});
+
+console.log('isPointsStakablePool', isPointsStakablePool);
+
const isStakablePool = computed(
(): boolean =>
POOLS.Stakable.VotingGaugePools.includes(poolId) ||
@@ -286,6 +294,12 @@ watch(
class="staking-incentives"
@set-restake-visibility="setRestakeVisibility"
/>
+
{
+ /**
+ * STATE
+ */
+
+ const poolId = ref(_poolId);
+ const poolAddress = computed((): string | undefined =>
+ poolId.value ? getAddressFromPoolId(poolId.value) : undefined
+ );
+
+ // const isPointsPool = computed((): boolean => {
+ // if (!poolId.value) return false;
+ // return POOLS.PointsGauges?.[poolId.value] !== undefined;
+ // });
+
+ /**
+ * COMPOSABLES
+ */
+ const { balanceFor } = useTokens();
+ const { account, isWalletReady } = useWeb3();
+
+ // // Fetches all gauges for specified pool (incl. preferential gauge).
+ // const poolGaugesQuery = usePoolGaugesQuery(poolAddress);
+ // const { data: poolGauges, refetch: refetchPoolGauges } = poolGaugesQuery;
+
+ // // Access user data fetched on wallet connection/change.
+ // const { userGaugeSharesQuery, userBoostsQuery, stakedSharesQuery } =
+ // useUserData();
+ // const { data: userGaugeShares, refetch: refetchUserGaugeShares } =
+ // userGaugeSharesQuery;
+ // const { data: boostsMap, refetch: refetchUserBoosts } = userBoostsQuery;
+ // const {
+ // data: _stakedShares,
+ // refetch: refetchStakedShares,
+ // isRefetching: isRefetchingStakedShares,
+ // } = stakedSharesQuery;
+
+ /**
+ * COMPUTED
+ */
+ // const isLoading = computed(
+ // (): boolean =>
+ // isQueryLoading(poolGaugesQuery) ||
+ // (isWalletReady.value &&
+ // (isQueryLoading(stakedSharesQuery) ||
+ // isQueryLoading(userGaugeSharesQuery) ||
+ // isQueryLoading(userBoostsQuery)))
+ // );
+
+ const isLoading = computed((): boolean => !isWalletReady.value);
+
+ const pointsGaugeAddress = computed((): string | undefined | null => {
+ const gauges = configService.network.pools.PointsGauges;
+ if (!gauges || !poolId.value) return null;
+ return gauges[poolId.value] ? gauges[poolId.value] : null;
+ });
+
+ const isStakablePool = computed(
+ (): boolean => !!poolId.value && pointsGaugeAddress.value !== null
+ );
+
+ /**
+ * METHODS
+ */
+
+ /**
+ * Set current pool ID for this provider.
+ *
+ * @param {string} id - The pool ID to get staking data for.
+ */
+ function setCurrentPool(id: string) {
+ poolId.value = id;
+ }
+
+ // Triggers refetch of all queries in this provider.
+ async function refetchAllPoolStakingData() {
+ return Promise.all([
+ // refetchPoolGauges(),
+ // refetchStakedShares(),
+ // refetchUserGaugeShares(),
+ // refetchUserBoosts(),
+ ]);
+ }
+
+ /**
+ * stake
+ *
+ * Trigger stake transaction using the current user's full BPT balance for
+ * this pool.
+ */
+ // async function stake(): Promise {
+ // if (!poolAddress.value) throw new Error('No pool to stake.');
+ // if (!preferentialGaugeAddress.value) {
+ // throw new Error(
+ // `No preferential gauge found for this pool: ${poolId.value}`
+ // );
+ // }
+
+ // const gauge = new LiquidityGauge(preferentialGaugeAddress.value);
+ // // User's current full BPT balance for this pool.
+ // const userBptBalance = parseUnits(
+ // balanceFor(getAddress(poolAddress.value))
+ // );
+
+ // return await gauge.stake(userBptBalance);
+ // }
+
+ async function stakeForPoints(): Promise {
+ if (!poolAddress.value) throw new Error('No pool to stake.');
+ if (!pointsGaugeAddress.value) {
+ throw new Error(`No points gauge found for this pool: ${poolId.value}`);
+ }
+
+ const gauge = new LiquidityGauge(pointsGaugeAddress.value);
+ // User's current full BPT balance for this pool.
+ const userBptBalance = parseUnits(
+ balanceFor(getAddress(poolAddress.value))
+ );
+
+ return await gauge.stake(userBptBalance);
+ }
+
+ /**
+ * unstake
+ *
+ * Trigger unstake transaction using the first pool gauge that the user has a
+ * balance in.
+ */
+ // async function unstake(): Promise {
+ // if (!poolGauges.value?.pool?.gauges)
+ // throw new Error('Unable to unstake, no pool gauges');
+
+ // const gaugesWithUserBalance = await filterGaugesWhereUserHasBalance(
+ // poolGauges.value,
+ // account.value
+ // );
+ // const firstGaugeWithUserBalance = gaugesWithUserBalance[0];
+ // const gauge = new LiquidityGauge(firstGaugeWithUserBalance.id);
+ // const balance = await gauge.balance(account.value);
+ // return await gauge.unstake(balance);
+ // }
+
+ async function unstakeForPoints(): Promise {
+ if (!pointsGaugeAddress.value) {
+ throw new Error(`No points gauge found for this pool: ${poolId.value}`);
+ }
+ const gauge = new LiquidityGauge(pointsGaugeAddress.value);
+ const balance = await gauge.balance(account.value);
+ return await gauge.unstake(balance);
+ }
+
+ return {
+ isLoading,
+ // stakedShares,
+ isStakablePool,
+ pointsGaugeAddress,
+ setCurrentPool,
+ refetchAllPoolStakingData,
+ stakeForPoints,
+ unstakeForPoints,
+ };
+};
+
+/**
+ * Provide setup: response type + symbol.
+ */
+export type PoolStakingProviderResponse = ReturnType<
+ typeof poolStakingProvider
+>;
+export const PoolStakingProviderSymbol: InjectionKey =
+ Symbol(symbolKeys.Providers.PoolStaking);
+
+export function providePoolPointsStaking(poolId?: string) {
+ provide(PoolStakingProviderSymbol, poolStakingProvider(poolId));
+}
+
+export function usePoolPointsStaking(): PoolStakingProviderResponse {
+ return safeInject(PoolStakingProviderSymbol);
+}
diff --git a/src/providers/local/pool-staking.provider.ts b/src/providers/local/pool-staking.provider.ts
index f963cb99..1a62b44d 100644
--- a/src/providers/local/pool-staking.provider.ts
+++ b/src/providers/local/pool-staking.provider.ts
@@ -26,11 +26,19 @@ export const poolStakingProvider = (_poolId?: string) => {
/**
* STATE
*/
+
const poolId = ref(_poolId);
const poolAddress = computed((): string | undefined =>
poolId.value ? getAddressFromPoolId(poolId.value) : undefined
);
+ // const isPointsPool = computed((): boolean => {
+ // if (!poolId.value) return false;
+ // return (
+ // configService.network.pools.PointsGauges?.[poolId.value] !== undefined
+ // );
+ // });
+
/**
* COMPOSABLES
*/
@@ -65,12 +73,20 @@ export const poolStakingProvider = (_poolId?: string) => {
isQueryLoading(userBoostsQuery)))
);
+ const isPointsLoading = computed((): boolean => !isWalletReady.value);
+
// The current preferential gauge for the specified pool.
const preferentialGaugeAddress = computed(
(): string | undefined | null =>
poolGauges.value?.pool?.preferentialGauge?.id
);
+ const pointsGaugeAddress = computed((): string | undefined | null => {
+ const gauges = configService.network.pools.PointsGauges;
+ if (!gauges || !poolId.value) return null;
+ return gauges[poolId.value] ? gauges[poolId.value] : null;
+ });
+
// Is it possible to stake this pool's BPT?
const isStakablePool = computed(
(): boolean =>
@@ -81,6 +97,10 @@ export const poolStakingProvider = (_poolId?: string) => {
)
);
+ const isStakablePoolForPoints = computed(
+ (): boolean => !!poolId.value && pointsGaugeAddress.value !== null
+ );
+
const gaugeTotalSupply = computed((): string => {
return poolGauges.value?.liquidityGauges?.[0]?.totalSupply || '0';
});
@@ -178,6 +198,21 @@ export const poolStakingProvider = (_poolId?: string) => {
return await gauge.stake(userBptBalance);
}
+ async function stakeForPoints(): Promise {
+ if (!poolAddress.value) throw new Error('No pool to stake.');
+ if (!pointsGaugeAddress.value) {
+ throw new Error(`No points gauge found for this pool: ${poolId.value}`);
+ }
+
+ const gauge = new LiquidityGauge(pointsGaugeAddress.value);
+ // User's current full BPT balance for this pool.
+ const userBptBalance = parseUnits(
+ balanceFor(getAddress(poolAddress.value))
+ );
+
+ return await gauge.stake(userBptBalance);
+ }
+
/**
* unstake
*
@@ -198,6 +233,15 @@ export const poolStakingProvider = (_poolId?: string) => {
return await gauge.unstake(balance);
}
+ async function unstakeForPoints(): Promise {
+ if (!pointsGaugeAddress.value) {
+ throw new Error(`No points gauge found for this pool: ${poolId.value}`);
+ }
+ const gauge = new LiquidityGauge(pointsGaugeAddress.value);
+ const balance = await gauge.balance(account.value);
+ return await gauge.unstake(balance);
+ }
+
/**
* Fetch preferential gauge address for pool.
*
@@ -233,19 +277,24 @@ export const poolStakingProvider = (_poolId?: string) => {
return {
isLoading,
+ isPointsLoading,
stakedShares,
isStakablePool,
+ isStakablePoolForPoints,
boost,
hasNonPrefGaugeBalance,
isRefetchingStakedShares,
refetchStakedShares,
preferentialGaugeAddress,
fetchPreferentialGaugeAddress,
+ pointsGaugeAddress,
gaugeTotalSupply,
setCurrentPool,
refetchAllPoolStakingData,
stake,
unstake,
+ stakeForPoints,
+ unstakeForPoints,
poolGauges,
};
};
diff --git a/src/services/api/graphql/generated/api-types.ts b/src/services/api/graphql/generated/api-types.ts
index 73429948..26bd0f77 100644
--- a/src/services/api/graphql/generated/api-types.ts
+++ b/src/services/api/graphql/generated/api-types.ts
@@ -55,6 +55,9 @@ export enum GqlChain {
Zkevm = 'ZKEVM',
Telos = 'telos',
Meter = 'meter',
+ Taiko = 'taiko',
+ Etherlink = 'etherlink',
+ VanaMoksha = 'vana-moksha',
}
export type GqlContentNewsItem = {
diff --git a/src/services/api/graphql/mappers.ts b/src/services/api/graphql/mappers.ts
index 6e65537c..c0401594 100644
--- a/src/services/api/graphql/mappers.ts
+++ b/src/services/api/graphql/mappers.ts
@@ -32,6 +32,12 @@ export function mapApiChain(
return Network.TELOS;
case 'meter':
return Network.METER;
+ case 'taiko':
+ return Network.TAIKO;
+ case 'etherlink':
+ return Network.ETHERLINK;
+ case 'vana-moksha':
+ return Network.VANAMOKSHA;
default:
throw new Error(`Unexpected API chain: ${apiChain}`);
diff --git a/src/services/web3/wallet.service.ts b/src/services/web3/wallet.service.ts
index 1e2505e4..5decbf07 100644
--- a/src/services/web3/wallet.service.ts
+++ b/src/services/web3/wallet.service.ts
@@ -27,7 +27,9 @@ export default class WalletService {
private readonly config: ConfigService = configService
) {
this.appProvider = this.rpcProviderService.jsonProvider;
- this.ensProvider = this.rpcProviderService.getJsonProvider(Network.TELOS);
+ this.ensProvider = this.rpcProviderService.getJsonProvider(
+ Network.VANAMOKSHA
+ );
}
public setUserProvider(provider: ComputedRef) {
diff --git a/src/types/pools.ts b/src/types/pools.ts
index 03ee428c..521a9be0 100644
--- a/src/types/pools.ts
+++ b/src/types/pools.ts
@@ -162,6 +162,7 @@ export type Pools = {
// Pools that have additional rewards and therefore should be stakable but are not included in the VotingGaugePools list.
AllowList: string[];
};
+ PointsGauges?: Record;
Metadata: Record;
Deep: string[];
BoostedApr: string[];
From ddaa1bc1b991b0bf20e8e13da305c6a9318b4ac0 Mon Sep 17 00:00:00 2001
From: stephen <991266+stxphxn@users.noreply.github.com>
Date: Tue, 24 Sep 2024 19:49:28 +0100
Subject: [PATCH 3/5] feat: update initial swap tokens
---
src/lib/config/vana-moksha/tokens.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/config/vana-moksha/tokens.ts b/src/lib/config/vana-moksha/tokens.ts
index b5641b25..83fceddc 100644
--- a/src/lib/config/vana-moksha/tokens.ts
+++ b/src/lib/config/vana-moksha/tokens.ts
@@ -6,7 +6,7 @@ const tokens: TokenConstants = {
},
InitialSwapTokens: {
input: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
- output: '0xa9d23408b9ba935c230493c40c73824df71a0975',
+ output: '0xb39a50b5806039c82932bb96cefbcbc61231045c',
},
Addresses: {
nativeAsset: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
From 2276c4aaef78d460d8c112c956f651d12cbaa392 Mon Sep 17 00:00:00 2001
From: stephen <991266+stxphxn@users.noreply.github.com>
Date: Thu, 26 Sep 2024 13:28:42 +0100
Subject: [PATCH 4/5] Merge branch 'vana-moksha' into taiko-staking
From ef291d3529338494cdd1e6151fd113b18814add9 Mon Sep 17 00:00:00 2001
From: stephen <991266+stxphxn@users.noreply.github.com>
Date: Thu, 26 Sep 2024 19:14:47 +0100
Subject: [PATCH 5/5] Add Taiko staking
---
.../pool/staking/PointsIncentivesCard.vue | 52 +++++---------
.../staking/composables/useStakePreview.ts | 44 +++++-------
.../tables/FaucetTable/FaucetTable.vue | 3 +-
src/composables/useNetwork.ts | 2 +-
src/constants/symbol.keys.ts | 1 +
src/lib/config/index.ts | 28 ++++----
src/lib/config/taiko/pools.ts | 4 ++
src/locales/default.json | 2 +
src/pages/_layouts/PoolLayout.vue | 2 +
src/plugins/router/nav-guards.ts | 4 +-
.../local/pool-points-staking.provider.ts | 71 ++++++++++++-------
src/providers/tokens.provider.ts | 9 ++-
src/services/web3/wallet.service.ts | 4 +-
13 files changed, 119 insertions(+), 107 deletions(-)
diff --git a/src/components/contextual/pages/pool/staking/PointsIncentivesCard.vue b/src/components/contextual/pages/pool/staking/PointsIncentivesCard.vue
index 9a2b3f09..e4bbc47a 100644
--- a/src/components/contextual/pages/pool/staking/PointsIncentivesCard.vue
+++ b/src/components/contextual/pages/pool/staking/PointsIncentivesCard.vue
@@ -9,12 +9,10 @@ import { bnum } from '@/lib/utils';
import { Pool } from '@/services/pool/types';
import StakePreviewModal from './StakePreviewModal.vue';
-import { usePoolStaking } from '@/providers/local/pool-staking.provider';
+import { usePoolPointsStaking } from '@/providers/local/pool-points-staking.provider';
import { deprecatedDetails } from '@/composables/usePoolHelpers';
import { StakeAction } from './composables/useStakePreview';
-import { GaugeShare } from '@/composables/queries/useUserGaugeSharesQuery';
-import useStakedSharesQuery from '@/composables/queries/useStakedSharesQuery';
type Props = {
pool: Pool;
@@ -27,7 +25,6 @@ const props = defineProps();
const isStakePreviewVisible = ref(false);
const stakeAction = ref('stakeForPoints');
-const poolId = computed(() => props.pool.id);
const isOpenedByDefault = ref(true);
/**
* COMPOSABLES
@@ -35,40 +32,23 @@ const isOpenedByDefault = ref(true);
const { fNum } = useNumbers();
const { balanceFor } = useTokens();
const {
- isStakablePoolForPoints: isStakablePool,
- isPointsLoading: isLoadingStakingData,
+ isStakablePool,
+ isLoading: isLoadingStakingData,
+ isRefetchingStakedShares,
+ stakedShares,
pointsGaugeAddress,
-} = usePoolStaking();
+} = usePoolPointsStaking();
-const { data: stakedShares, isRefetching } = useStakedSharesQuery(
- ref([
- {
- balance: '0',
- gauge: {
- id: pointsGaugeAddress.value,
- poolAddress: getAddress(props.pool.address),
- poolId: props.pool.id,
- totalSupply: '0',
- isPreferentialGauge: true,
- isKilled: false,
- },
- },
- ] as GaugeShare[])
-);
+console.log(stakedShares.value);
-console.log('stakedShares', stakedShares);
/**
* COMPUTED
*/
-const stakedShare = computed(() => {
- return stakedShares.value ? stakedShares.value[poolId.value] : '0';
-});
-
const fiatValueOfStakedShares = computed(() => {
return bnum(props.pool.totalLiquidity)
.div(props.pool.totalShares)
- .times((stakedShare.value || '0').toString())
+ .times((stakedShares.value || '0').toString())
.toString();
});
@@ -115,7 +95,7 @@ function handlePreviewClose() {
:class="['shadow-2xl', { handle: isStakablePool }]"
:sections="[
{
- title: $t('staking.stakingIncentives'),
+ title: $t('staking.pointsStakingIncentives'),
id: 'staking-incentives',
handle: 'staking-handle',
isDisabled: isStakablePool,
@@ -142,7 +122,7 @@ function handlePreviewClose() {
-
{{ $t('staking.stakingIncentives') }}
+
{{ $t('staking.pointsStakingIncentives') }}
-
+
+
+
@@ -165,10 +147,10 @@ function handlePreviewClose() {
{{ $t('staked') }} {{ $t('lpTokens') }}
-
+
-
+
{{ fNum(fiatValueOfStakedShares, FNumFormats.fiat) }}
@@ -179,10 +161,10 @@ function handlePreviewClose() {
{{ $t('unstaked') }} {{ $t('lpTokens') }}
-
+
-
+
{{ fNum(fiatValueOfUnstakedShares, FNumFormats.fiat) }}
diff --git a/src/components/contextual/pages/pool/staking/composables/useStakePreview.ts b/src/components/contextual/pages/pool/staking/composables/useStakePreview.ts
index 02b37f1a..53600c22 100644
--- a/src/components/contextual/pages/pool/staking/composables/useStakePreview.ts
+++ b/src/components/contextual/pages/pool/staking/composables/useStakePreview.ts
@@ -14,8 +14,7 @@ import {
import { getAddress } from '@ethersproject/address';
import { useI18n } from 'vue-i18n';
import useTokenApprovalActions from '@/composables/approvals/useTokenApprovalActions';
-import useStakedSharesQuery from '@/composables/queries/useStakedSharesQuery';
-import { GaugeShare } from '@/composables/queries/useUserGaugeSharesQuery';
+import { usePoolPointsStaking } from '@/providers/local/pool-points-staking.provider';
/**
* TYPES
@@ -51,41 +50,29 @@ export function useStakePreview(props: StakePreviewProps, emit) {
const { getTokenApprovalActions } = useTokenApprovalActions();
const {
isLoading: isPoolStakingLoading,
- isPointsLoading,
stake,
unstake,
- stakeForPoints,
- unstakeForPoints,
stakedShares,
refetchAllPoolStakingData,
preferentialGaugeAddress,
- pointsGaugeAddress,
} = usePoolStaking();
+ const {
+ isLoading: isPointsLoading,
+ stakeForPoints,
+ unstakeForPoints,
+ stakedShares: stakedPointsShares,
+ refetchAllPoolStakingData: refetchAllPointsStakingData,
+ pointsGaugeAddress,
+ } = usePoolPointsStaking();
+
// Staked or unstaked shares depending on action type.
let currentShares = '0';
if (props.action === 'stake' || props.action === 'stakeForPoints') {
currentShares = balanceFor(getAddress(props.pool.address));
} else if (props.action === 'unstakeForPoints') {
- const { data: stakedPointsShares } = useStakedSharesQuery(
- ref([
- {
- balance: '0',
- gauge: {
- id: pointsGaugeAddress.value,
- poolAddress: getAddress(props.pool.address),
- poolId: props.pool.id,
- totalSupply: '0',
- isPreferentialGauge: true,
- isKilled: false,
- },
- },
- ] as GaugeShare[])
- );
- currentShares = stakedPointsShares.value
- ? stakedPointsShares.value[props.pool.id]
- : '0';
+ currentShares = stakedPointsShares.value;
} else {
currentShares = stakedShares.value;
}
@@ -223,7 +210,14 @@ export function useStakePreview(props: StakePreviewProps, emit) {
async function handleSuccess(receipt: TransactionReceipt) {
isActionConfirmed.value = true;
confirmationReceipt.value = receipt;
- await Promise.all([refetchBalances(), refetchAllPoolStakingData()]);
+ if (
+ props.action === 'unstakeForPoints' ||
+ props.action === 'stakeForPoints'
+ ) {
+ await Promise.all([refetchBalances(), refetchAllPointsStakingData()]);
+ } else {
+ await Promise.all([refetchBalances(), refetchAllPoolStakingData()]);
+ }
emit('success');
}
diff --git a/src/components/tables/FaucetTable/FaucetTable.vue b/src/components/tables/FaucetTable/FaucetTable.vue
index 9e825d37..da05be12 100644
--- a/src/components/tables/FaucetTable/FaucetTable.vue
+++ b/src/components/tables/FaucetTable/FaucetTable.vue
@@ -24,7 +24,7 @@ const tokens = computed(() => {
const tokensWithValues = Object.values(balancerTokenList.value.tokens)
.map(token => {
const balance = balanceFor(token.address);
- const price = priceFor(token.address);
+ const price = priceFor(token.address.toLowerCase());
const value = Number(balance) * price;
return {
...token,
@@ -34,6 +34,7 @@ const tokens = computed(() => {
};
})
.filter(t => t.address != '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE');
+ console.log('tokensWithValues', tokensWithValues);
return orderBy(tokensWithValues, ['value', 'balance'], ['desc', 'desc']);
});
diff --git a/src/composables/useNetwork.ts b/src/composables/useNetwork.ts
index 4f36bdf1..f7944186 100644
--- a/src/composables/useNetwork.ts
+++ b/src/composables/useNetwork.ts
@@ -24,7 +24,7 @@ const NETWORK_ID =
urlNetworkId ||
localStorageNetworkId ||
(Number(import.meta.env.VITE_NETWORK) as Network) ||
- Network.VANAMOKSHA;
+ Network.CELO;
if (windowAvailable) localStorage.setItem('networkId', NETWORK_ID.toString());
export const networkSlug = config[NETWORK_ID].slug;
export const networkConfig = config[NETWORK_ID];
diff --git a/src/constants/symbol.keys.ts b/src/constants/symbol.keys.ts
index 1cc8cd89..00e6f706 100644
--- a/src/constants/symbol.keys.ts
+++ b/src/constants/symbol.keys.ts
@@ -7,6 +7,7 @@ export default {
JoinPool: 'provider.joinPool',
ExitPool: 'provider.exitPool',
PoolStaking: 'provider.poolStaking',
+ PoolPointsStaking: 'provider.poolPointsStaking',
UserStaking: 'provider.userStaking',
UserData: 'provider.userData',
UserPools: 'provider.userPools',
diff --git a/src/lib/config/index.ts b/src/lib/config/index.ts
index 2f2ac504..245b9aac 100644
--- a/src/lib/config/index.ts
+++ b/src/lib/config/index.ts
@@ -4,28 +4,28 @@ import { Config, Network } from './types';
// import avalanche from './avalanche';
// import base from './base';
// import goerli from './goerli';
-// import gnosisChain from './gnosis-chain';
+import gnosisChain from './gnosis-chain';
// import mainnet from './mainnet';
// import optimism from './optimism';
// import polygon from './polygon';
// import sepolia from './sepolia';
// import zkevm from './zkevm';
-// import telos from './telos';
+import telos from './telos';
// import telosTestnet from './telos-testnet';
-// import celo from './celo';
-// import meter from './meter';
-// import taiko from './taiko';
-// import etherlink from './etherlink';
-import vanaMoksha from './vana-moksha';
+import celo from './celo';
+import meter from './meter';
+import taiko from './taiko';
+import etherlink from './etherlink';
+// import vanaMoksha from './vana-moksha';
const config: Record = {
- // [Network.TELOS]: telos,
- // [Network.CELO]: celo,
- // [Network.GNOSIS]: gnosisChain,
- // [Network.METER]: meter,
- // [Network.TAIKO]: taiko,
- // [Network.ETHERLINK]: etherlink,
- [Network.VANAMOKSHA]: vanaMoksha,
+ [Network.TELOS]: telos,
+ [Network.CELO]: celo,
+ [Network.GNOSIS]: gnosisChain,
+ [Network.METER]: meter,
+ [Network.TAIKO]: taiko,
+ [Network.ETHERLINK]: etherlink,
+ //[Network.VANAMOKSHA]: vanaMoksha,
};
export default config;
diff --git a/src/lib/config/taiko/pools.ts b/src/lib/config/taiko/pools.ts
index 4d125ca9..9beb2f8f 100644
--- a/src/lib/config/taiko/pools.ts
+++ b/src/lib/config/taiko/pools.ts
@@ -34,6 +34,10 @@ const pools: Pools = {
PointsGauges: {
'0x65d5eebb5f1c767ce42c3ccc8cfd00fb3a114122000000000000000000000003':
'0x0447cb41A2a0D4C4A76cA3e2b1be65076DD48A06', //USDC-USDC.e
+ '0xe0f51bf8d30db81d0a93125a17a2a40130ad9f7e000200000000000000000004':
+ '0xc4E44B978c814F9223784031474ba1498bd23335', //WETH-USDC
+ '0x27ebdb9db75b8ca967ec331cb1e74880f1d7f0a8000200000000000000000005':
+ '0x76930FbaAbDB2D04B41835029D2320B2A0139cc5', //TAIKO-WETH
},
Investment: {
AllowList: [],
diff --git a/src/locales/default.json b/src/locales/default.json
index 9b28a24a..b48a1ab2 100644
--- a/src/locales/default.json
+++ b/src/locales/default.json
@@ -999,6 +999,8 @@
"stakedPercentage": "Staked %",
"stakingAprTooltip": "Your potential staking APR",
"stakingIncentives": "Staking incentives",
+ "pointsStakingIncentives": "Earn SYMM Points",
+ "pointsIncentivesTooltip": "Earn SYMM Points for staking LP tokens in eligible pools. SYMM Points can be redeemed for rewards in the future.",
"totalShareTooltip": "Your current total share of LP tokens in the pool",
"restakeGauge": "Restake to receive future liquidity mining incentives",
"restakeGaugeDescription": "You are staking in a gauge which has been deprecated. Restake to the new gauge for this pool to receive future liquidity mining incentives.",
diff --git a/src/pages/_layouts/PoolLayout.vue b/src/pages/_layouts/PoolLayout.vue
index 3935ac2f..ac1b4198 100644
--- a/src/pages/_layouts/PoolLayout.vue
+++ b/src/pages/_layouts/PoolLayout.vue
@@ -4,6 +4,7 @@ import FocussedLayout from '@/components/layouts/FocussedLayout.vue';
import { createProviderComponent } from '@/providers/createProviderComponent';
import { providePool } from '@/providers/local/pool.provider';
import { providePoolStaking } from '@/providers/local/pool-staking.provider';
+import { providePoolPointsStaking } from '@/providers/local/pool-points-staking.provider';
import { provideUserTokens } from '@/providers/local/user-tokens.provider';
/**
@@ -24,6 +25,7 @@ const PoolProvider = createProviderComponent(() => {
providePool(poolId);
providePoolStaking(poolId);
+ providePoolPointsStaking(poolId);
provideUserTokens();
});
diff --git a/src/plugins/router/nav-guards.ts b/src/plugins/router/nav-guards.ts
index d9df45d8..ed9000b5 100644
--- a/src/plugins/router/nav-guards.ts
+++ b/src/plugins/router/nav-guards.ts
@@ -113,7 +113,7 @@ function applyNetworkPathRedirects(router: Router): Router {
) {
const newPath = to.redirectedFrom?.fullPath ?? to.fullPath;
router.push({
- path: `/${config[Network.VANAMOKSHA].slug}${newPath}`,
+ path: `/${config[Network.TELOS].slug}${newPath}`,
});
} else if (
!to.redirectedFrom ||
@@ -124,7 +124,7 @@ function applyNetworkPathRedirects(router: Router): Router {
} else {
const newPath = to.redirectedFrom?.fullPath ?? to.fullPath;
const newNetwork = newPath.includes('/pool')
- ? config[Network.VANAMOKSHA].slug
+ ? config[Network.TELOS].slug
: networkSlug;
router.push({ path: `/${newNetwork}${newPath}` });
}
diff --git a/src/providers/local/pool-points-staking.provider.ts b/src/providers/local/pool-points-staking.provider.ts
index aab13ac4..0afa2f3c 100644
--- a/src/providers/local/pool-points-staking.provider.ts
+++ b/src/providers/local/pool-points-staking.provider.ts
@@ -10,13 +10,15 @@ import useWeb3 from '@/services/web3/useWeb3';
// import { POOLS } from '@/constants/pools';
import { safeInject } from '../inject';
import { configService } from '@/services/config/config.service';
+import useStakedSharesQuery from '@/composables/queries/useStakedSharesQuery';
+import { GaugeShare } from '@/composables/queries/useUserGaugeSharesQuery';
/**
* PoolStakingProvider
*
* Fetches data and provides functionality for a specific pool's gauge.
*/
-export const poolStakingProvider = (_poolId?: string) => {
+export const poolPointsStakingProvider = (_poolId?: string) => {
/**
* STATE
*/
@@ -26,10 +28,31 @@ export const poolStakingProvider = (_poolId?: string) => {
poolId.value ? getAddressFromPoolId(poolId.value) : undefined
);
- // const isPointsPool = computed((): boolean => {
- // if (!poolId.value) return false;
- // return POOLS.PointsGauges?.[poolId.value] !== undefined;
- // });
+ const pointsGaugeAddress = computed((): string | undefined | null => {
+ const gauges = configService.network.pools.PointsGauges;
+ if (!gauges || !poolId.value) return null;
+ return gauges[poolId.value] ? gauges[poolId.value] : null;
+ });
+
+ const {
+ data: _stakedShares,
+ isRefetching: isRefetchingStakedShares,
+ refetch: refetchStakedShares,
+ } = useStakedSharesQuery(
+ ref([
+ {
+ balance: '0',
+ gauge: {
+ id: pointsGaugeAddress.value,
+ poolAddress: poolAddress.value,
+ poolId: poolId.value,
+ totalSupply: '0',
+ isPreferentialGauge: true,
+ isKilled: false,
+ },
+ },
+ ] as GaugeShare[])
+ );
/**
* COMPOSABLES
@@ -67,16 +90,17 @@ export const poolStakingProvider = (_poolId?: string) => {
const isLoading = computed((): boolean => !isWalletReady.value);
- const pointsGaugeAddress = computed((): string | undefined | null => {
- const gauges = configService.network.pools.PointsGauges;
- if (!gauges || !poolId.value) return null;
- return gauges[poolId.value] ? gauges[poolId.value] : null;
- });
-
const isStakablePool = computed(
(): boolean => !!poolId.value && pointsGaugeAddress.value !== null
);
+ // User's staked shares for pool (onchain data).
+ const stakedShares = computed((): string => {
+ if (!poolId.value) return '0';
+
+ return _stakedShares?.value?.[poolId.value] || '0';
+ });
+
/**
* METHODS
*/
@@ -92,12 +116,7 @@ export const poolStakingProvider = (_poolId?: string) => {
// Triggers refetch of all queries in this provider.
async function refetchAllPoolStakingData() {
- return Promise.all([
- // refetchPoolGauges(),
- // refetchStakedShares(),
- // refetchUserGaugeShares(),
- // refetchUserBoosts(),
- ]);
+ return Promise.all([refetchStakedShares()]);
}
/**
@@ -169,10 +188,12 @@ export const poolStakingProvider = (_poolId?: string) => {
return {
isLoading,
- // stakedShares,
+ stakedShares,
isStakablePool,
pointsGaugeAddress,
setCurrentPool,
+ isRefetchingStakedShares,
+ refetchStakedShares,
refetchAllPoolStakingData,
stakeForPoints,
unstakeForPoints,
@@ -182,16 +203,16 @@ export const poolStakingProvider = (_poolId?: string) => {
/**
* Provide setup: response type + symbol.
*/
-export type PoolStakingProviderResponse = ReturnType<
- typeof poolStakingProvider
+export type PoolPointsStakingProviderResponse = ReturnType<
+ typeof poolPointsStakingProvider
>;
-export const PoolStakingProviderSymbol: InjectionKey =
- Symbol(symbolKeys.Providers.PoolStaking);
+export const PoolPointsStakingProviderSymbol: InjectionKey =
+ Symbol(symbolKeys.Providers.PoolPointsStaking);
export function providePoolPointsStaking(poolId?: string) {
- provide(PoolStakingProviderSymbol, poolStakingProvider(poolId));
+ provide(PoolPointsStakingProviderSymbol, poolPointsStakingProvider(poolId));
}
-export function usePoolPointsStaking(): PoolStakingProviderResponse {
- return safeInject(PoolStakingProviderSymbol);
+export function usePoolPointsStaking(): PoolPointsStakingProviderResponse {
+ return safeInject(PoolPointsStakingProviderSymbol);
}
diff --git a/src/providers/tokens.provider.ts b/src/providers/tokens.provider.ts
index 6beedabe..004d31ec 100644
--- a/src/providers/tokens.provider.ts
+++ b/src/providers/tokens.provider.ts
@@ -534,6 +534,7 @@ export const tokensProvider = (
const response = await axios.get(
`https://symm-prices.symmetric.workers.dev/${networkSlug}/prices/${tokenAddressesString}`
);
+ console.log(response);
let symmPrice = 0;
let rewardPrice = 0;
response.data.forEach(price => {
@@ -567,7 +568,11 @@ export const tokensProvider = (
// Inject veBAL because it's not in tokenlists.
const { veBAL } = configService.network.addresses;
await injectTokens([veBAL]);
- if (networkSlug === 'telos' || networkSlug === 'meter') {
+ if (
+ networkSlug === 'telos' ||
+ networkSlug === 'meter' ||
+ networkSlug === 'vana-moksha'
+ ) {
await getTokenPrices();
}
queriesEnabled.value = true;
@@ -624,7 +629,9 @@ export function provideTokens(
userSettings: UserSettingsResponse,
tokenLists: TokenListsResponse
) {
+ console.log('PROVIDE TOKENS');
const tokensResponse = tokensProvider(userSettings, tokenLists);
+
provide(TokensProviderSymbol, tokensResponse);
return tokensResponse;
}
diff --git a/src/services/web3/wallet.service.ts b/src/services/web3/wallet.service.ts
index 5decbf07..1e2505e4 100644
--- a/src/services/web3/wallet.service.ts
+++ b/src/services/web3/wallet.service.ts
@@ -27,9 +27,7 @@ export default class WalletService {
private readonly config: ConfigService = configService
) {
this.appProvider = this.rpcProviderService.jsonProvider;
- this.ensProvider = this.rpcProviderService.getJsonProvider(
- Network.VANAMOKSHA
- );
+ this.ensProvider = this.rpcProviderService.getJsonProvider(Network.TELOS);
}
public setUserProvider(provider: ComputedRef) {