diff --git a/package.json b/package.json
index 97984ccf..e7add067 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
"@shutter-network/shutter-crypto": "1.0.1",
"@snapshot-labs/lock": "^0.2.4",
"@snapshot-labs/pineapple": "^1.1.0",
- "@snapshot-labs/snapshot.js": "^0.11.17",
+ "@snapshot-labs/snapshot.js": "^0.11.24",
"@vue/apollo-composable": "4.0.0-beta.11",
"@vueuse/core": "^10.6.1",
"@vueuse/head": "^2.0.0",
diff --git a/snapshot-spaces b/snapshot-spaces
index 76519fcd..6fbb2064 160000
--- a/snapshot-spaces
+++ b/snapshot-spaces
@@ -1 +1 @@
-Subproject commit 76519fcd7d97b64da3a49f96f754a1f41f5d5258
+Subproject commit 6fbb206480132ac20c02440c74f6f275c65af038
diff --git a/src/components/ModalAccount.vue b/src/components/ModalAccount.vue
index a0bcb615..5c2c8070 100644
--- a/src/components/ModalAccount.vue
+++ b/src/components/ModalAccount.vue
@@ -17,6 +17,8 @@ const injected = computed(() => getInjected());
const filteredConnectors = computed(() => {
const baseConnectors = ['injected', 'walletconnect', 'walletlink'];
+ // If injected is Coinbase, hide WalletLink
+ if (injected.value?.name === 'Coinbase') connectors.walletlink.hidden = true;
if (isShowingAllConnectors.value) return Object.keys(connectors);
return Object.keys(connectors).filter(cId => baseConnectors.includes(cId));
});
diff --git a/src/components/SettingsTreasuriesBlockItemButton.vue b/src/components/SettingsTreasuriesBlockItemButton.vue
index 0f40cc10..a33cc902 100644
--- a/src/components/SettingsTreasuriesBlockItemButton.vue
+++ b/src/components/SettingsTreasuriesBlockItemButton.vue
@@ -2,6 +2,7 @@
import { TreasuryWallet } from '@/helpers/interfaces';
import { Network } from '@/plugins/oSnap/types';
import { ConfigError, getIsOsnapEnabled } from '@/plugins/oSnap/utils/getters';
+import { ConfigError, getIsOsnapEnabled } from '@/plugins/oSnap/utils/getters';
const props = defineProps<{
treasury: TreasuryWallet;
@@ -18,6 +19,7 @@ const emit = defineEmits<{
const isOsnapEnabled = ref(false);
const isChainSupported = ref(true);
+const isChainSupported = ref(true);
async function updateIsOsnapEnabled() {
if (!props.hasOsnapPlugin) return;
@@ -53,7 +55,7 @@ onUnmounted(() => {
{{ treasury.name }}
-
+
- Note that Boost is not available for this voting type. Please use
- Basic or Single Choice if you want to use Boost.
-
-
- Note that Boost is not available with Shutter encrypted voting. Please
- disable it in the space settings if you want to use Boost.
+ Note that Boost is not available for this voting type.
diff --git a/src/components/SpaceProposalBoost.vue b/src/components/SpaceProposalBoost.vue
index 799831fe..a737c946 100644
--- a/src/components/SpaceProposalBoost.vue
+++ b/src/components/SpaceProposalBoost.vue
@@ -46,14 +46,24 @@ const newBoostLink = computed(() => ({
const isActive = computed(() => props.proposal.state === 'active');
const isFinal = computed(() => props.proposal.scores_state === 'final');
+const winningChoice = computed(() => {
+ const maxScore = Math.max(...props.proposal.scores);
+ const maxScoreCount = props.proposal.scores.filter(
+ score => score === maxScore
+ ).length;
+ return maxScoreCount > 1 ? 0 : props.proposal.scores.indexOf(maxScore) + 1;
+});
+
function isEligible(boost: BoostSubgraph) {
+ const type = boost.strategy.eligibility.type;
const choice = boost.strategy.eligibility.choice;
if (!web3Account.value) return false;
- if (props.proposal.privacy === 'shutter' && !isFinal.value) return false;
+ if (!isFinal.value) return false;
if (!userVote.value) return false;
- if (choice === null) return true;
-
+ if (type === 'prediction')
+ return userVote.value.choice.toString() === winningChoice.value.toString();
+ if (type === 'incentive' && choice === null) return true;
return userVote.value.choice.toString() === choice;
}
diff --git a/src/components/SpaceProposalBoostClaimModalItem.vue b/src/components/SpaceProposalBoostClaimModalItem.vue
index 08bace57..7b48b006 100644
--- a/src/components/SpaceProposalBoostClaimModalItem.vue
+++ b/src/components/SpaceProposalBoostClaimModalItem.vue
@@ -32,10 +32,7 @@ const reward = computed(() => {
props.boost.token.decimals
);
- return formatNumber(
- Number(amountDecimal),
- getNumberFormatter({ maximumFractionDigits: 8 }).value
- );
+ return amountDecimal;
});
const claim = computed(() => {
@@ -84,7 +81,13 @@ async function handleClaimAndReload() {
{{ hasClaimed ? 'Claimed' : 'Reward' }}
- {{ reward }} {{ props.boost.token.symbol }}
+ {{
+ formatNumber(
+ Number(reward),
+ getNumberFormatter({ maximumFractionDigits: 8 }).value
+ )
+ }}
+ {{ props.boost.token.symbol }}
{
-
+
+ Anyone who votes for the winning choice
+
+
Who votes
import voting from '@snapshot-labs/snapshot.js/src/voting';
import { ExtendedSpace, Proposal, Results } from '@/helpers/interfaces';
+import { BOOST_ENABLED_VOTING_TYPES } from '@/helpers/constants';
const props = defineProps<{ space: ExtendedSpace; proposal: Proposal }>();
const emit = defineEmits(['reload-proposal']);
@@ -56,9 +57,7 @@ const strategies = computed(
const boostEnabled = computed(() => {
return (
- (props.proposal.type === 'basic' ||
- props.proposal.type === 'single-choice') &&
- props.proposal.privacy !== 'shutter' &&
+ BOOST_ENABLED_VOTING_TYPES.includes(props.proposal.type) &&
isWhitelisted(props.space.id) &&
props.space.boost.enabled
);
diff --git a/src/composables/useAliasAction.ts b/src/composables/useAliasAction.ts
index 11299396..5af755f0 100644
--- a/src/composables/useAliasAction.ts
+++ b/src/composables/useAliasAction.ts
@@ -39,7 +39,8 @@ export function useAliasAction() {
query: ALIASES_QUERY,
variables: {
address: web3.value.account,
- alias: aliasWallet.value.address
+ alias: aliasWallet.value.address,
+ created_gt: Math.floor(Date.now() / 1000) - 30 * 60 * 60 * 24
}
},
'aliases'
@@ -53,12 +54,10 @@ export function useAliasAction() {
async function setAlias() {
const rndWallet = Wallet.createRandom();
- aliases.value = Object.assign(
- {
- [web3.value.account]: rndWallet.privateKey
- },
- aliases.value
- );
+ aliases.value = {
+ ...aliases.value,
+ [web3.value.account]: rndWallet.privateKey
+ };
lsSet('aliases', aliases.value);
if (aliasWallet.value?.address) {
diff --git a/src/composables/useChangeNetwork.ts b/src/composables/useChangeNetwork.ts
index cdab7369..c3f0dbe5 100644
--- a/src/composables/useChangeNetwork.ts
+++ b/src/composables/useChangeNetwork.ts
@@ -1,6 +1,5 @@
import networks from '@snapshot-labs/snapshot.js/src/networks.json';
import { sleep } from '@snapshot-labs/snapshot.js/src/utils';
-import { hexlify } from '@ethersproject/bytes';
export function useChangeNetwork() {
const changingNetwork = ref(false);
@@ -11,7 +10,7 @@ export function useChangeNetwork() {
method: 'wallet_switchEthereumChain',
params: [
{
- chainId: hexlify(Number(networks[network].chainId))
+ chainId: `0x${Number(networks[network].chainId).toString(16)}`
}
]
});
diff --git a/src/composables/useFollowSpace.ts b/src/composables/useFollowSpace.ts
index 19de76c1..cb816074 100644
--- a/src/composables/useFollowSpace.ts
+++ b/src/composables/useFollowSpace.ts
@@ -63,12 +63,15 @@ export function useFollowSpace(spaceId: any = {}) {
async function follow(space) {
loadingFollow.value = spaceId;
+
try {
await checkAlias();
if (!aliasWallet.value || !isValidAlias.value) {
await setAlias();
follow(space);
} else {
+ const network = process.env.VITE_ENV === 'production' ? 's' : 's-tn';
+
if (isFollowing.value) {
// Also unsubscribe to the notifications if the user leaves the space.
if (isSubscribed.value) {
@@ -76,12 +79,14 @@ export function useFollowSpace(spaceId: any = {}) {
}
await client.unfollow(aliasWallet.value, aliasWallet.value.address, {
from: web3Account.value,
- space
+ space,
+ network
});
} else {
await client.follow(aliasWallet.value, aliasWallet.value.address, {
from: web3Account.value,
- space
+ space,
+ network
});
}
await loadFollows();
diff --git a/src/composables/useTreasury.ts b/src/composables/useTreasury.ts
index def4f472..1b9dffba 100644
--- a/src/composables/useTreasury.ts
+++ b/src/composables/useTreasury.ts
@@ -2,7 +2,7 @@ import snapshot from '@snapshot-labs/snapshot.js';
import { getTokenBalances, ETHER_CONTRACT } from '@/helpers/covalent';
import { TreasuryAsset } from '@/helpers/interfaces';
-const TOKEN_LIST_URL = 'https://gateway.ipfs.io/ipns/tokens.uniswap.org';
+const TOKEN_LIST_URL = 'https://ipfs.io/ipns/tokens.uniswap.org';
const tokenListContractAddresses = ref(null);
const treasuryAssets = ref<{ [key: string]: TreasuryAsset[] }>({});
diff --git a/src/composables/useWeb3.ts b/src/composables/useWeb3.ts
index 9e1e4d98..ae1c7e96 100644
--- a/src/composables/useWeb3.ts
+++ b/src/composables/useWeb3.ts
@@ -33,6 +33,7 @@ export function useWeb3() {
function logout() {
auth = getInstance();
+ if (auth.provider?.value?.isCoinbaseWallet) auth.provider.value.close();
auth.logout();
state.account = '';
}
diff --git a/src/helpers/boost/index.ts b/src/helpers/boost/index.ts
index 4414128d..31b22009 100644
--- a/src/helpers/boost/index.ts
+++ b/src/helpers/boost/index.ts
@@ -30,6 +30,7 @@ export const BOOST_WHITELIST_SETTINGS = {
'vote.vitadao.eth',
'shutterdao0x36.eth',
'testeteste123.eth',
+ 'alkimiexchange.eth',
// Internal testers
'testsnap.eth',
'fabien.eth',
@@ -122,7 +123,7 @@ export async function withdrawAndBurn(
): Promise {
const signer = web3.getSigner();
const contract = new Contract(BOOST_CONTRACTS[networkId], ABI, signer);
- return await contract.burn(boostId, to);
+ return await contract.withdrawAndBurn(boostId, to);
}
export async function getFees(web3: Web3Provider, networkId: string) {
diff --git a/src/helpers/boost/types.ts b/src/helpers/boost/types.ts
index 7aeeffe9..7a6ee807 100644
--- a/src/helpers/boost/types.ts
+++ b/src/helpers/boost/types.ts
@@ -71,7 +71,7 @@ export type BoostSubgraph = {
name: string;
proposal: string;
eligibility: {
- type: 'incentive' | 'bribe';
+ type: 'incentive' | 'prediction' | 'bribe';
choice: string | null;
};
distribution: {
diff --git a/src/helpers/connectors.ts b/src/helpers/connectors.ts
index 2e0fb416..677b8757 100644
--- a/src/helpers/connectors.ts
+++ b/src/helpers/connectors.ts
@@ -11,7 +11,7 @@ const connectors = {
projectId: 'e6454bd61aba40b786e866a69bd4c5c6',
chains: [1],
optionalChains: [
- 4, 5, 10, 42, 56, 100, 137, 246, 1088, 42161, 73799, 1115511
+ 4, 5, 10, 42, 56, 100, 137, 246, 1088, 42161, 73799, 11155111
],
methods: ['eth_sendTransaction', 'personal_sign', 'eth_signTypedData_v4'],
optionalMethods: ['eth_accounts'],
@@ -43,7 +43,8 @@ const connectors = {
chainId: 1,
ethJsonrpcUrl: `${import.meta.env.VITE_BROVIDER_URL}/1`
},
- icon: 'ipfs://QmbJKEaeMz6qR3DmJSTxtYtrZeQPptVfnnYK72QBsvAw5q'
+ icon: 'ipfs://QmbJKEaeMz6qR3DmJSTxtYtrZeQPptVfnnYK72QBsvAw5q',
+ hidden: false
},
portis: {
id: 'portis',
diff --git a/src/helpers/constants.ts b/src/helpers/constants.ts
index 5f43a797..e8da438f 100644
--- a/src/helpers/constants.ts
+++ b/src/helpers/constants.ts
@@ -16,7 +16,8 @@ export const KNOWN_HOSTS = [
'pilot.gnosisguild.org',
'metissafe.tech',
'multisig.mantle.xyz',
- 'wallet.ambire.com'
+ 'wallet.ambire.com',
+ 'multisig.moonbeam.network'
];
export const SPACE_CATEGORIES = [
@@ -95,3 +96,9 @@ export const TWO_WEEKS = 1209600;
export const ONE_DAY = 86400;
export const SNAPSHOT_HELP_LINK = 'https://help.snapshot.org/en';
+
+export const BOOST_ENABLED_VOTING_TYPES = [
+ 'basic',
+ 'single-choice',
+ 'ranked-choice'
+];
diff --git a/src/helpers/queries.ts b/src/helpers/queries.ts
index aea49a45..239aa051 100644
--- a/src/helpers/queries.ts
+++ b/src/helpers/queries.ts
@@ -192,8 +192,10 @@ export const SUBSCRIPTIONS_QUERY = gql`
`;
export const ALIASES_QUERY = gql`
- query Aliases($address: String!, $alias: String!) {
- aliases(where: { address: $address, alias: $alias }) {
+ query Aliases($address: String!, $alias: String!, $created_gt: Int) {
+ aliases(
+ where: { address: $address, alias: $alias, created_gt: $created_gt }
+ ) {
address
alias
}
diff --git a/src/locales/default.json b/src/locales/default.json
index 35777556..ec9f3720 100644
--- a/src/locales/default.json
+++ b/src/locales/default.json
@@ -717,7 +717,7 @@
"label": "Privacy",
"title": "Select voting privacy",
"information": "The type of privacy used on proposals. (Enforced on all future proposals)",
- "any": "Any",
+ "any": "No privacy",
"none": "None",
"shutter": {
"label": "Shutter",
diff --git a/src/views/SpaceBoost.vue b/src/views/SpaceBoost.vue
index a5a3c7b5..e2a469f4 100644
--- a/src/views/SpaceBoost.vue
+++ b/src/views/SpaceBoost.vue
@@ -38,7 +38,7 @@ const props = defineProps<{
type Form = {
eligibility: {
- choice: 'any' | number;
+ choice: 'any' | 'prediction' | number;
};
distribution: {
type: 'lottery' | 'weighted';
@@ -97,13 +97,23 @@ const isWrongNetwork = computed(() => {
return form.value.network !== web3.value.network.key.toString();
});
+const bribeEnabled = computed(() => {
+ return (
+ proposal.value.privacy !== 'shutter' &&
+ props.space.boost.bribeEnabled &&
+ ['basic', 'single-choice'].includes(proposal.value.type)
+ );
+});
+
const eligibilityOptions = computed(() => {
const proposalChoices = proposal.value?.choices.map(
(choice: string, index: number) => {
return {
value: index + 1,
label: `Who votes '${choice}'`,
- extras: { disabled: !props.space.boost.bribeEnabled }
+ extras: {
+ disabled: !bribeEnabled.value
+ }
};
}
);
@@ -113,6 +123,10 @@ const eligibilityOptions = computed(() => {
value: 'any',
label: 'Anyone who votes'
},
+ {
+ value: 'prediction',
+ label: 'Anyone who votes for the winning choice'
+ },
...proposalChoices
];
});
@@ -196,13 +210,20 @@ const strategyDistributionLimit = computed(() => {
});
const strategy = computed(() => {
- const choice =
- form.value.eligibility.choice === 'any'
- ? undefined
- : form.value.eligibility.choice.toString();
-
- const eligibilityType =
- form.value.eligibility.choice === 'any' ? 'incentive' : 'bribe';
+ let choice;
+ let eligibilityType;
+
+ switch (form.value.eligibility.choice) {
+ case 'any':
+ eligibilityType = 'incentive';
+ break;
+ case 'prediction':
+ eligibilityType = 'prediction';
+ break;
+ default:
+ choice = form.value.eligibility.choice.toString();
+ eligibilityType = 'bribe';
+ }
return {
name: 'Boost',
@@ -655,14 +676,28 @@ watch(
:items="eligibilityOptions"
label="Eligible to"
/>
-
+
- Selecting a specific choice is disabled for the
-
- {{ space.name }}
-
- space. Please enable strategic incentivization in the space
- settings to enable this feature.
+
+ Selecting a specific choice is disabled for the
+
+ {{ space.name }}
+
+ space. Please enable strategic incentivization in the space
+ settings to enable this feature.
+
+
+ Strategic incentivization is disabled for proposal with
+ shutter on.
+
+
+ Strategic incentivization is available only for basic and
+ single choice voting type.
+
diff --git a/yarn.lock b/yarn.lock
index e3f6b025..23bd1a8e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1666,10 +1666,10 @@
resolved "https://registry.yarnpkg.com/@snapshot-labs/prettier-config/-/prettier-config-0.1.0-beta.15.tgz#07e5ae35ed36304250462218e115bab1c1609812"
integrity sha512-va6zYSl8oIraBJeIZWEatOI292rfJQouyyvEeHv8qi9ns+LgxMsKayQtXSqn9GcmAfdWQVs/P9bDaCQ77FyJYw==
-"@snapshot-labs/snapshot.js@^0.11.17":
- version "0.11.17"
- resolved "https://registry.yarnpkg.com/@snapshot-labs/snapshot.js/-/snapshot.js-0.11.17.tgz#e54a14622956515aba8b6333cbe423e6af3f2250"
- integrity sha512-+zM274cRplyN17PQQpP391XhZOV+1ET/bppIY7YfvAIid+q+7TwaTK3VD2kq00ZA2AdasR/f0dwvieKUnTyTUg==
+"@snapshot-labs/snapshot.js@^0.11.24":
+ version "0.11.24"
+ resolved "https://registry.yarnpkg.com/@snapshot-labs/snapshot.js/-/snapshot.js-0.11.24.tgz#013d9306236dd0a74ac8bcb31a14c5edbd68a960"
+ integrity sha512-LORRX/0zFdy4pRMWLjoOEh0wB0foNjpxovKi3V5uho5RDB73V5sUSoj3NG4pmz/ZyQREAyqma2/LgpJqyHcirQ==
dependencies:
"@ensdomains/eth-ens-namehash" "^2.0.15"
"@ethersproject/abi" "^5.6.4"