Skip to content

Commit 450f898

Browse files
author
Alberto Gualis
authored
Merge pull request #4366 from balancer/release/1.128.0
Release 1.128.0
2 parents d0f4d1d + baa5dc5 commit 450f898

File tree

26 files changed

+516
-460
lines changed

26 files changed

+516
-460
lines changed

package-lock.json

Lines changed: 90 additions & 77 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@balancer/frontend-v2",
3-
"version": "1.127.52",
3+
"version": "1.128.0",
44
"engines": {
55
"node": "=16",
66
"npm": ">=8"
@@ -91,7 +91,7 @@
9191
"@vitest/coverage-c8": "^0.30.1",
9292
"@vue/test-utils": "^2.4.1",
9393
"@vueuse/core": "^4.3.4",
94-
"@walletconnect/ethereum-provider": "^2.10.1",
94+
"@walletconnect/ethereum-provider": "^2.10.2",
9595
"@walletconnect/modal": "^2.6.2",
9696
"animejs": "^3.2.1",
9797
"autoprefixer": "^10.4.13",
@@ -126,7 +126,7 @@
126126
"nprogress": "^0.2.0",
127127
"numeral": "^2.0.4",
128128
"parse-filepath": "1.0.2",
129-
"postcss": "^8.4.21",
129+
"postcss": "^8.4.31",
130130
"postcss-comment": "^2.0.0",
131131
"prettier": "^2.7.1",
132132
"promise-worker": "^2.0.1",

src/components/contextual/pages/pool/PoolStatCards.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Pool } from '@/services/pool/types';
1414
import { AprBreakdown } from '@balancer-labs/sdk';
1515
import { useCrossChainSync } from '@/providers/cross-chain-sync.provider';
1616
import useNetwork from '@/composables/useNetwork';
17+
import useWeb3 from '@/services/web3/useWeb3';
1718
1819
/**
1920
* TYPES
@@ -41,6 +42,7 @@ const { fNum } = useNumbers();
4142
const { t } = useI18n();
4243
const { l2VeBalBalances } = useCrossChainSync();
4344
const { networkId } = useNetwork();
45+
const { isWalletReady } = useWeb3();
4446
4547
/**
4648
* COMPUTED
@@ -49,7 +51,7 @@ const aprLabel = computed((): string => {
4951
const poolAPRs = props.poolApr;
5052
if (!poolAPRs) return '0';
5153
52-
return totalAprLabel(poolAPRs, props.pool?.boost);
54+
return totalAprLabel(poolAPRs, props.pool?.boost, isWalletReady.value);
5355
});
5456
5557
const syncVeBalTooltip = computed(() => {

src/components/contextual/pages/vebal/LMVoting/LMVoting.vue

Lines changed: 13 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,24 @@
11
<script lang="ts" setup>
2-
import useDebouncedRef from '@/composables/useDebouncedRed';
32
import useVotingEscrowLocks from '@/composables/useVotingEscrowLocks';
43
import useVotingPools from '@/composables/useVotingPools';
54
65
import useNetwork from '@/composables/useNetwork';
6+
import useNumbers from '@/composables/useNumbers';
77
import useVeBal from '@/composables/useVeBAL';
88
import { useVeBalLockInfo } from '@/composables/useVeBalLockInfo';
9-
import configs from '@/lib/config';
10-
import { Network } from '@/lib/config/types';
9+
1110
import useWeb3 from '@/services/web3/useWeb3';
11+
import { isVotingCompleted, useVoting } from '../providers/voting.provider';
12+
import { bpsToPercentage } from '../voting-utils';
1213
import GaugesFilters from './GaugesFilters.vue';
1314
import GaugesTable from './GaugesTable.vue';
1415
import VotingAlert from './VotingAlert.vue';
15-
import { bpsToPercentage, isGaugeExpired } from '../voting-utils';
16-
import useNumbers from '@/composables/useNumbers';
17-
import { isVotingCompleted, useVoting } from '../providers/voting.provider';
18-
19-
/**
20-
* COMPOSABLES
21-
*/
22-
const router = useRouter();
16+
import { useLMVotingFilters } from './composables/useLMVotingFilters';
2317
2418
/**
2519
* DATA
2620
*/
2721
28-
const tokenFilter = useDebouncedRef<string>('', 500);
29-
const showExpiredGauges = useDebouncedRef<boolean>(false, 500);
30-
const activeNetworkFilters = useDebouncedRef<Network[]>(
31-
getDefaultActiveNetworkFilter(),
32-
500
33-
);
34-
35-
const networkFilters: Network[] = Object.entries(configs)
36-
.filter(details => {
37-
const config = details[1];
38-
return (
39-
!config.testNetwork && config.pools.Stakable.VotingGaugePools.length > 0
40-
);
41-
})
42-
.map(details => Number(details[0]) as Network);
43-
4422
/**
4523
* COMPOSABLES
4624
*/
@@ -70,48 +48,21 @@ const {
7048
loadRequestWithExistingVotes,
7149
} = useVoting();
7250
51+
const {
52+
showExpiredGauges,
53+
activeNetworkFilters,
54+
filteredVotingPools,
55+
tokenFilter,
56+
networkFilters,
57+
} = useLMVotingFilters(votingPools, expiredGauges);
58+
7359
/**
7460
* COMPUTED
7561
*/
7662
const unallocatedVotesFormatted = computed<string>(() =>
7763
bpsToPercentage(unallocatedVotes.value, fNum)
7864
);
7965
80-
const poolsFilteredByExpiring = computed(() => {
81-
if (showExpiredGauges.value) {
82-
return votingPools.value;
83-
}
84-
85-
return votingPools.value.filter(pool => {
86-
if (Number(pool.userVotes) > 0) {
87-
return true;
88-
}
89-
return !isGaugeExpired(expiredGauges.value, pool.gauge.address);
90-
});
91-
});
92-
93-
const filteredVotingPools = computed(() => {
94-
// put filter by expiring in separate computed to maintain readability
95-
return poolsFilteredByExpiring.value.filter(pool => {
96-
let showByNetwork = true;
97-
if (
98-
activeNetworkFilters.value.length > 0 &&
99-
!activeNetworkFilters.value.includes(pool.network)
100-
) {
101-
showByNetwork = false;
102-
}
103-
104-
return (
105-
showByNetwork &&
106-
pool.tokens.some(token => {
107-
return token.symbol
108-
?.toLowerCase()
109-
.includes(tokenFilter.value.toLowerCase());
110-
})
111-
);
112-
});
113-
});
114-
11566
const selectVotesDisabled = computed(
11667
(): boolean =>
11768
isLoading.value ||
@@ -155,20 +106,6 @@ function addIntersectionObserver(): void {
155106
observer.observe(intersectionSentinel.value);
156107
}
157108
158-
function getDefaultActiveNetworkFilter() {
159-
const param = router.currentRoute.value.query.chain;
160-
if (!param || typeof param !== 'string') {
161-
return [];
162-
}
163-
164-
const networkToFilter = Network[param.toUpperCase()];
165-
if (!networkToFilter) {
166-
return [];
167-
}
168-
169-
return [networkToFilter];
170-
}
171-
172109
onMounted(() => {
173110
addIntersectionObserver();
174111
});
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { mountComposableWithFakeTokensProvider as mountComposable } from '@tests/mount-helpers';
2+
3+
import { VotingPool } from '@/composables/queries/useVotingPoolsQuery';
4+
import { Network } from '@/lib/config/types';
5+
import { GqlChain } from '@/services/api/graphql/generated/api-types';
6+
import { LocationQuery, createRouter, createWebHistory } from 'vue-router';
7+
import { aVotingPool } from '../../MultiVoting/voting-pool.builders';
8+
import { useLMVotingFilters } from './useLMVotingFilters';
9+
10+
function buildRouterMock() {
11+
const router = createRouter({
12+
history: createWebHistory(),
13+
routes: [
14+
{
15+
path: '/blank',
16+
name: 'test route',
17+
component: {},
18+
},
19+
],
20+
});
21+
22+
// fake router params
23+
router.currentRoute.value.params = {};
24+
router.push = vi.fn();
25+
26+
function setRouteQuery(chain: LocationQuery) {
27+
router.currentRoute.value.query = chain;
28+
}
29+
30+
return { router, setRouteQuery };
31+
}
32+
33+
async function mountLmVotingFilters(
34+
votingPools: ComputedRef<VotingPool[]>,
35+
expiredGauges: Ref<readonly string[] | undefined>,
36+
routerMock = buildRouterMock().router
37+
) {
38+
const { result } = await mountComposable(
39+
() => useLMVotingFilters(votingPools, expiredGauges),
40+
{ routerMock }
41+
);
42+
return result;
43+
}
44+
45+
const expiredGauges = ref([]);
46+
47+
it('empty filters by default', async () => {
48+
const votingPools = computed(() => [aVotingPool()]);
49+
const { activeNetworkFilters } = await mountLmVotingFilters(
50+
votingPools,
51+
expiredGauges
52+
);
53+
expect(activeNetworkFilters.value).toEqual([]);
54+
});
55+
56+
it('when the url chain filter in the query string', async () => {
57+
const { router, setRouteQuery } = buildRouterMock();
58+
setRouteQuery({ chain: 'arbitrum' });
59+
60+
const anArbitrumPool = aVotingPool({
61+
network: Network.ARBITRUM,
62+
});
63+
const anMainnetPool = aVotingPool({ chain: GqlChain.Mainnet });
64+
65+
const votingPools = computed(() => [anArbitrumPool, anMainnetPool]);
66+
67+
const { activeNetworkFilters, filteredVotingPools } =
68+
await mountLmVotingFilters(votingPools, expiredGauges, router);
69+
70+
expect(activeNetworkFilters.value).toEqual([42161]);
71+
expect(filteredVotingPools.value).toEqual([anArbitrumPool]);
72+
});
73+
74+
it('filters by token symbol', async () => {
75+
const { router, setRouteQuery } = buildRouterMock();
76+
setRouteQuery({});
77+
const aVotingPoolWithGoldToken = aVotingPool();
78+
aVotingPoolWithGoldToken.tokens[0].symbol = 'Gold';
79+
80+
const votingPools = computed(() => [
81+
aVotingPoolWithGoldToken,
82+
aVotingPool({ tokens: [] }),
83+
]);
84+
85+
const { filteredVotingPools, tokenFilter, activeNetworkFilters } =
86+
await mountLmVotingFilters(votingPools, expiredGauges, router);
87+
88+
tokenFilter.value = 'Gol';
89+
90+
expect(activeNetworkFilters.value).toEqual([]);
91+
92+
expect(filteredVotingPools.value).toEqual([aVotingPoolWithGoldToken]);
93+
});
94+
95+
it('calculates networkFilters', async () => {
96+
const { networkFilters } = await mountLmVotingFilters(
97+
computed(() => []),
98+
expiredGauges
99+
);
100+
101+
expect(networkFilters).toEqual([1, 10, 100, 137, 1101, 8453, 42161, 43114]);
102+
});
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { VotingPool } from '@/composables/queries/useVotingPoolsQuery';
2+
import useDebouncedRef from '@/composables/useDebouncedRed';
3+
import { isGaugeExpired } from '../../voting-utils';
4+
import { Network } from '@/lib/config/types';
5+
import configs from '@/lib/config';
6+
7+
export function useLMVotingFilters(
8+
votingPools: ComputedRef<VotingPool[]>,
9+
expiredGauges: Ref<readonly string[] | undefined>
10+
) {
11+
const router = useRouter();
12+
13+
const showExpiredGauges = useDebouncedRef<boolean>(false, 500);
14+
const tokenFilter = useDebouncedRef<string>('', 500);
15+
const activeNetworkFilters = useDebouncedRef<Network[]>(
16+
getDefaultActiveNetworkFilter(),
17+
500
18+
);
19+
20+
const poolsFilteredByExpiring = computed(() => {
21+
if (showExpiredGauges.value) {
22+
return votingPools.value;
23+
}
24+
25+
return votingPools.value.filter(pool => {
26+
if (Number(pool.userVotes) > 0) {
27+
return true;
28+
}
29+
return !isGaugeExpired(expiredGauges.value, pool.gauge.address);
30+
});
31+
});
32+
33+
function getDefaultActiveNetworkFilter() {
34+
const param = router.currentRoute.value.query.chain;
35+
36+
if (!param || typeof param !== 'string') {
37+
return [];
38+
}
39+
40+
const networkToFilter = Network[param.toUpperCase()];
41+
if (!networkToFilter) {
42+
return [];
43+
}
44+
45+
return [networkToFilter];
46+
}
47+
48+
const filteredVotingPools = computed(() => {
49+
// put filter by expiring in separate computed to maintain readability
50+
return poolsFilteredByExpiring.value.filter(pool => {
51+
let showByNetwork = true;
52+
if (
53+
activeNetworkFilters.value.length > 0 &&
54+
!activeNetworkFilters.value.includes(pool.network)
55+
) {
56+
showByNetwork = false;
57+
}
58+
59+
return (
60+
showByNetwork &&
61+
pool.tokens.some(token => {
62+
return token.symbol
63+
?.toLowerCase()
64+
.includes(tokenFilter.value.toLowerCase());
65+
})
66+
);
67+
});
68+
});
69+
70+
const networkFilters: Network[] = Object.entries(configs)
71+
.filter(details => {
72+
const config = details[1];
73+
return (
74+
!config.testNetwork && config.pools.Stakable.VotingGaugePools.length > 0
75+
);
76+
})
77+
.map(details => Number(details[0]) as Network);
78+
return {
79+
showExpiredGauges,
80+
activeNetworkFilters,
81+
filteredVotingPools,
82+
tokenFilter,
83+
networkFilters,
84+
};
85+
}

src/components/contextual/pages/vebal/cross-chain-boost/StakingCardSyncAlert.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const canShowSyncAlert = computed(() => {
3939
if (
4040
isAffectedBy(PoolWarning.PoolProtocolFeeVulnWarning) ||
4141
isAffectedBy(PoolWarning.CspPoolVulnWarning) ||
42-
!gauge
42+
!gauge?.gauge.id
4343
) {
4444
return false;
4545
}

src/components/forms/lock_actions/LockForm/components/VeBalForm/VeBalForm.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,19 @@ const submissionDisabled = computed(() => {
6969
return true;
7070
}
7171
72+
const lockableAmount = bnum(lockablePoolBptBalance.value || '0');
73+
const toLockAmount = bnum(lockAmount.value || '0');
74+
75+
if (toLockAmount.isGreaterThan(lockableAmount)) {
76+
return true;
77+
}
78+
7279
if (props.veBalLockInfo?.hasExistingLock && !props.veBalLockInfo?.isExpired) {
7380
return !isIncreasedLockAmount.value && !isExtendedLockEndDate.value;
7481
}
7582
7683
return (
77-
!bnum(lockablePoolBptBalance.value).gt(0) ||
84+
!lockableAmount.gt(0) ||
7885
!isValidLockAmount.value ||
7986
!isValidLockEndDate.value
8087
);

0 commit comments

Comments
 (0)