From d7cefb522b7886df5c4e694cc1bef57442b7863f Mon Sep 17 00:00:00 2001
From: Szymon Szlachtowicz <38212223+Szymx95@users.noreply.github.com>
Date: Mon, 6 Sep 2021 11:34:42 +0200
Subject: [PATCH] Check tokens when creating polls and votes (#53)
---
packages/core/src/classes/WakuPolling.ts | 45 ++++++++++++--
.../src/components/Poll.tsx | 20 ++++++-
.../src/components/PollCreation.tsx | 58 +++++++++++++------
3 files changed, 96 insertions(+), 27 deletions(-)
diff --git a/packages/core/src/classes/WakuPolling.ts b/packages/core/src/classes/WakuPolling.ts
index ca1c3e4..6a4a539 100644
--- a/packages/core/src/classes/WakuPolling.ts
+++ b/packages/core/src/classes/WakuPolling.ts
@@ -16,6 +16,13 @@ const ABI = [
'function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)',
]
+export enum MESSEGAGE_SENDING_RESULT {
+ ok = 0,
+ notEnoughToken = 1,
+ errorCreatingMessage = 2,
+ pollNotFound = 3,
+}
+
export class WakuPolling extends WakuVoting {
protected multicall: string
@@ -78,8 +85,19 @@ export class WakuPolling extends WakuVoting {
minToken?: BigNumber,
endTime?: number
) {
- const pollInit = await PollInitMsg.create(signer, question, answers, pollType, this.chainId, minToken, endTime)
- await this.sendWakuMessage(this.wakuMessages['pollInit'], pollInit)
+ const address = await signer.getAddress()
+ await this.updateBalances(address)
+ if (this.addressesBalances[address] && this.addressesBalances[address]?.gt(minToken ?? BigNumber.from(0))) {
+ const pollInit = await PollInitMsg.create(signer, question, answers, pollType, this.chainId, minToken, endTime)
+ if (pollInit) {
+ await this.sendWakuMessage(this.wakuMessages['pollInit'], pollInit)
+ return MESSEGAGE_SENDING_RESULT.ok
+ } else {
+ return MESSEGAGE_SENDING_RESULT.errorCreatingMessage
+ }
+ } else {
+ return MESSEGAGE_SENDING_RESULT.notEnoughToken
+ }
}
public async sendTimedPollVote(
@@ -88,18 +106,35 @@ export class WakuPolling extends WakuVoting {
selectedAnswer: number,
tokenAmount?: BigNumber
) {
- const pollVote = await TimedPollVoteMsg.create(signer, pollId, selectedAnswer, this.chainId, tokenAmount)
- await this.sendWakuMessage(this.wakuMessages['pollVote'], pollVote)
+ const address = await signer.getAddress()
+ const poll = this.wakuMessages['pollInit'].arr.find((poll: PollInitMsg): poll is PollInitMsg => poll.id === pollId)
+ if (poll) {
+ await this.updateBalances(address)
+ if (this.addressesBalances[address] && this.addressesBalances[address]?.gt(poll.minToken ?? BigNumber.from(0))) {
+ const pollVote = await TimedPollVoteMsg.create(signer, pollId, selectedAnswer, this.chainId, tokenAmount)
+ if (pollVote) {
+ await this.sendWakuMessage(this.wakuMessages['pollVote'], pollVote)
+ } else {
+ return MESSEGAGE_SENDING_RESULT.errorCreatingMessage
+ }
+ } else {
+ return MESSEGAGE_SENDING_RESULT.notEnoughToken
+ }
+ } else {
+ return MESSEGAGE_SENDING_RESULT.pollNotFound
+ }
}
protected addressesBalances: { [address: string]: BigNumber } = {}
protected lastBlockBalances = 0
- protected async updateBalances() {
+ protected async updateBalances(newAddress?: string) {
const addresses: string[] = [
...this.wakuMessages['pollInit'].arr.map((msg) => msg.owner),
...this.wakuMessages['pollVote'].arr.map((msg) => msg.voter),
]
+
+ if (newAddress) addresses.push(newAddress)
const addressesToUpdate: { [addr: string]: boolean } = {}
const addAddressToUpdate = (addr: string) => {
diff --git a/packages/polling-components/src/components/Poll.tsx b/packages/polling-components/src/components/Poll.tsx
index 5f345be..cba786f 100644
--- a/packages/polling-components/src/components/Poll.tsx
+++ b/packages/polling-components/src/components/Poll.tsx
@@ -8,7 +8,7 @@ import styled from 'styled-components'
import { RadioGroup, SmallButton } from '@status-waku-voting/react-components'
import { PollResults } from './PollResults'
import { useEthers } from '@usedapp/core'
-
+import { Modal } from '@status-waku-voting/react-components'
type PollProps = {
poll: DetailedTimedPoll
wakuPolling: WakuPolling | undefined
@@ -21,6 +21,7 @@ export function Poll({ poll, wakuPolling, signer }: PollProps) {
const [tokenAmount, setTokenAmount] = useState(0)
const [address, setAddress] = useState('')
const [userInVoters, setUserInVoters] = useState(-1)
+ const [showNotEnoughTokens, setShowNotEnoughTokens] = useState(false)
useEffect(() => {
if (signer) {
@@ -63,14 +64,17 @@ export function Poll({ poll, wakuPolling, signer }: PollProps) {
{userInVoters < 0 && (
{
+ onClick={async () => {
if (wakuPolling && signer) {
- wakuPolling.sendTimedPollVote(
+ const result = await wakuPolling.sendTimedPollVote(
signer,
poll.poll.id,
selectedAnswer ?? 0,
poll.poll.pollType === PollType.WEIGHTED ? BigNumber.from(tokenAmount) : undefined
)
+ if (result === 1) {
+ setShowNotEnoughTokens(true)
+ }
}
}}
>
@@ -78,10 +82,20 @@ export function Poll({ poll, wakuPolling, signer }: PollProps) {
Vote
)}
+ {showNotEnoughTokens && (
+
+ You don't have enough tokens to vote
+
+ )}
)
}
+const ModalTextWrapper = styled.div`
+ text-align: center;
+ margin: 32px 0;
+`
+
const VotingWrapper = styled.div`
margin-top: 40px;
margin-left: 32px;
diff --git a/packages/polling-components/src/components/PollCreation.tsx b/packages/polling-components/src/components/PollCreation.tsx
index 6a3e467..d4e98e3 100644
--- a/packages/polling-components/src/components/PollCreation.tsx
+++ b/packages/polling-components/src/components/PollCreation.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from 'react'
+import React, { ReactNode, useEffect, useState } from 'react'
import { Wallet } from 'ethers'
import { JsonRpcSigner } from '@ethersproject/providers'
import styled from 'styled-components'
@@ -13,6 +13,27 @@ function getLocaleIsoTime(dateTime: Date) {
return newDate.toISOString().slice(0, -8)
}
+type ConfirmScreenProps = {
+ setShowModal: (val: boolean) => void
+ children: ReactNode
+}
+
+function ConfirmScreen({ children, setShowModal }: ConfirmScreenProps) {
+ return (
+
+ {children}
+ {
+ e.preventDefault()
+ setShowModal(false)
+ }}
+ >
+ Close
+
+
+ )
+}
+
type PollCreationProps = {
signer: JsonRpcSigner | Wallet
wakuPolling: WakuPolling | undefined
@@ -23,13 +44,14 @@ export function PollCreation({ signer, wakuPolling, setShowPollCreation }: PollC
const [answers, setAnswers] = useState(['', ''])
const [question, setQuestion] = useState('')
const [showCreateConfirmation, setShowCreateConfirmation] = useState(false)
+ const [showNotEnoughTokens, setShowNotEnoughTokens] = useState(false)
const [selectedType, setSelectedType] = useState(PollType.NON_WEIGHTED)
const [endTimePicker, setEndTimePicker] = useState(new Date(new Date().getTime() + 10000000))
return (
- {!showCreateConfirmation && (
+ {!showCreateConfirmation && !showNotEnoughTokens && (
{
e.preventDefault()
- await wakuPolling?.createTimedPoll(
+ const result = await wakuPolling?.createTimedPoll(
signer,
question,
answers,
@@ -73,7 +95,12 @@ export function PollCreation({ signer, wakuPolling, setShowPollCreation }: PollC
undefined,
endTimePicker.getTime()
)
- setShowCreateConfirmation(true)
+ if (result === 0) {
+ setShowCreateConfirmation(true)
+ }
+ if (result === 1) {
+ setShowNotEnoughTokens(true)
+ }
}}
>
Create a poll
@@ -82,21 +109,14 @@ export function PollCreation({ signer, wakuPolling, setShowPollCreation }: PollC
)}
{showCreateConfirmation && (
-
-
- Your poll has been created!
-
- It will appear at the top of the poll list.
-
- {
- e.preventDefault()
- setShowPollCreation(false)
- }}
- >
- Close
-
-
+
+ Your poll has been created!
+
+ It will appear at the top of the poll list.
+
+ )}
+ {showNotEnoughTokens && (
+ You don't have enough tokens to create poll
)}
{' '}