Fix lint/core functions and decimals

This commit is contained in:
Szymon Szlachtowicz 2022-01-20 01:19:47 +01:00
parent 60e17d454c
commit edc5e40295
23 changed files with 76 additions and 66 deletions

View File

@ -1,7 +1,7 @@
import { expect, use } from 'chai'
import { loadFixture, deployContract, MockProvider, solidity } from 'ethereum-waffle'
import { loadFixture, deployContract, solidity } from 'ethereum-waffle'
import { VotingContract, ERC20Mock } from '../abi'
import { utils, Wallet, Contract } from 'ethers'
import { utils, Wallet } from 'ethers'
import { signTypedMessage, TypedMessage } from 'eth-sig-util'
import { BigNumber } from '@ethersproject/bignumber'
import { JsonRpcProvider } from '@ethersproject/providers'

View File

@ -67,7 +67,7 @@ All api functions use `provider.getSigner()` to define signer
- `createVote(question: string, descripiton: string, tokenAmount: BigNumber)` creates new votingRoom on blockchain
- `getVotingRooms()` which return a list o VotingRoom
- `getProposals()` which return a list o Proposals
```
export type VotingRoom = {
@ -95,7 +95,7 @@ export type VotingRoom = {
- `commitVotes(votes: VoteMsg[])` commits votes to blockchain
- `getVotingRoom(id: number)` gets VotingRoom with given id
- `getProposal(id: number)` gets proposal with given id
# Polls

View File

@ -3,7 +3,6 @@ import { WakuMessage } from 'js-waku'
import { BigNumber } from 'ethers'
import { Web3Provider } from '@ethersproject/providers'
import { Contract } from '@ethersproject/contracts'
import { Interface } from '@ethersproject/abi'
import { ERC20 } from '../abi'
import { createWaku } from '../utils/createWaku'
import { WakuMessagesSetup } from '../types/WakuMessagesSetup'
@ -35,6 +34,8 @@ export class WakuMessaging {
public tokenDecimals: number | undefined
public tokenSymbol: string | undefined
protected tokenMultiDecimals: BigNumber = BigNumber.from(0)
protected constructor(
appName: string,
tokenAddress: string,
@ -50,7 +51,6 @@ export class WakuMessaging {
this.chainId = chainId
this.token = new Contract(tokenAddress, ERC20, this.provider)
this.multicall = new Contract(multicall, ABI, this.provider)
wakuMessagesSetup.forEach((setupData) => {
this.wakuMessages[setupData.name] = {
topic: `/${this.appName}/0.0.1/${setupData.name}/proto/`,
@ -70,6 +70,7 @@ export class WakuMessaging {
protected async setObserver() {
this.tokenDecimals = await this.token.decimals()
this.tokenMultiDecimals = BigNumber.from(10).pow(this.tokenDecimals ?? 0)
this.tokenSymbol = await this.token.symbol()
this.waku = await createWaku(this.waku)
await Promise.all(

View File

@ -1,15 +1,11 @@
import { Waku } from 'js-waku'
import { JsonRpcSigner } from '@ethersproject/providers'
import { PollInitMsg } from '../models/PollInitMsg'
import { PollType } from '../types/PollType'
import { BigNumber, Wallet } from 'ethers'
import { WakuMessage } from 'js-waku'
import { BigNumber } from 'ethers'
import { TimedPollVoteMsg } from '../models/TimedPollVoteMsg'
import { DetailedTimedPoll } from '../models/DetailedTimedPoll'
import { createWaku } from '../utils/createWaku'
import { WakuMessaging } from './WakuMessaging'
import { Web3Provider } from '@ethersproject/providers'
import { WakuMessagesSetup } from '../types/WakuMessagesSetup'
const MinTokenDefaultValue = BigNumber.from(1)
@ -71,6 +67,9 @@ export class WakuPolling extends WakuMessaging {
minToken?: BigNumber,
endTime?: number
) {
if (minToken) {
minToken = minToken.mul(this.tokenMultiDecimals)
}
const signer = this.provider.getSigner()
const address = await signer.getAddress()
await this.updateBalances([address])
@ -89,6 +88,9 @@ export class WakuPolling extends WakuMessaging {
}
public async sendTimedPollVote(pollId: string, selectedAnswer: number, tokenAmount?: BigNumber) {
if (tokenAmount) {
tokenAmount = tokenAmount.mul(this.tokenMultiDecimals)
}
const signer = this.provider.getSigner()
const address = await signer.getAddress()
const poll = this.wakuMessages['pollInit'].arr.find((poll: PollInitMsg): poll is PollInitMsg => poll.id === pollId)
@ -129,7 +131,8 @@ export class WakuPolling extends WakuMessaging {
this.addressesBalances[poll.owner] &&
this.addressesBalances[vote.voter]?.gt(poll.minToken ?? MinTokenDefaultValue)
)
.filter((e): e is TimedPollVoteMsg => !!e)
.filter((e): e is TimedPollVoteMsg => !!e),
this.tokenMultiDecimals
)
} else {
return undefined

View File

@ -1,14 +1,12 @@
import { VotingContract } from '@waku/vote-sdk-contracts/abi'
import { WakuMessaging } from './WakuMessaging'
import { Contract, Wallet, BigNumber, ethers, utils } from 'ethers'
import { Waku, WakuMessage } from 'js-waku'
import { createWaku } from '../utils/createWaku'
import { JsonRpcSigner, Web3Provider } from '@ethersproject/providers'
import { Contract, BigNumber, utils } from 'ethers'
import { Waku } from 'js-waku'
import { Web3Provider } from '@ethersproject/providers'
import { VoteMsg } from '../models/VoteMsg'
import { VotingRoom } from '../types/PollType'
import { DetailedVotingRoom } from '../models/DetailedVotingRoom'
const ABI = [
export const ABI = [
'function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)',
]
@ -72,7 +70,7 @@ export class WakuVoting extends WakuMessaging {
if (this.provider) {
const signer = this.provider.getSigner()
this.votingContract = await this.votingContract.connect(signer)
await this.votingContract.initializeVotingRoom(question, descripiton, tokenAmount)
await this.votingContract.initializeProposal(question, descripiton, tokenAmount.mul(this.tokenMultiDecimals))
}
}
@ -80,7 +78,7 @@ export class WakuVoting extends WakuMessaging {
private lastGetPollsBlockNumber = 0
private lastActivePoll = 0
public async getVotingRooms() {
public async getProposals() {
const blockNumber = await this.provider.getBlockNumber()
if (blockNumber != this.lastGetPollsBlockNumber) {
this.lastGetPollsBlockNumber = blockNumber
@ -89,7 +87,7 @@ export class WakuVoting extends WakuMessaging {
if (this.lastActivePoll < 0) {
this.lastActivePoll = this.lastPolls.length
}
const polls = await this.votingContract.getVotingRoomsFrom(this.lastActivePoll)
const polls = await this.votingContract.getProposalFromId(this.lastActivePoll)
polls.forEach((poll: any) => {
const timeLeft = poll[1].toNumber() * 1000 - Date.now()
const votingRoom: VotingRoom = {
@ -97,10 +95,10 @@ export class WakuVoting extends WakuMessaging {
endAt: poll[1],
question: poll[2],
description: poll[3],
totalVotesFor: poll[4],
totalVotesAgainst: poll[5],
wakuTotalVotesFor: poll[4],
wakuTotalVotesAgainst: poll[5],
totalVotesFor: poll[4].div(this.tokenMultiDecimals),
totalVotesAgainst: poll[5].div(this.tokenMultiDecimals),
wakuTotalVotesFor: poll[4].div(this.tokenMultiDecimals),
wakuTotalVotesAgainst: poll[5].div(this.tokenMultiDecimals),
voters: poll[7],
id: BigNumber.from(poll[6]).toNumber(),
timeLeft,
@ -133,7 +131,7 @@ export class WakuVoting extends WakuMessaging {
roomId,
selectedAnswer,
this.chainId,
tokenAmount,
tokenAmount.mul(this.tokenMultiDecimals),
this.votingContract.address
)
await this.sendWakuMessage(this.wakuMessages['vote'], vote)
@ -149,11 +147,11 @@ export class WakuVoting extends WakuMessaging {
this.votingContract.castVotes(mappedVotes)
}
public async getVotingRoom(id: number) {
public async getProposal(id: number) {
await this.updateBalances()
let votingRoom: VotingRoom
try {
await this.getVotingRooms()
await this.getProposals()
votingRoom = this.lastPolls[id]
votingRoom.wakuVotes = undefined
votingRoom.wakuTotalVotesAgainst = votingRoom.totalVotesAgainst
@ -173,14 +171,18 @@ export class WakuVoting extends WakuMessaging {
if (
vote.roomId === id &&
this.addressesBalances[vote.voter] &&
this.addressesBalances[vote.voter]?.gt(vote.tokenAmount)
this.addressesBalances[vote.voter]?.gte(vote.tokenAmount.div(this.tokenMultiDecimals))
) {
if (!votersHashMap[vote.voter]) {
votersHashMap[vote.voter] = true
if (vote.answer === 0) {
votingRoom.wakuTotalVotesAgainst = votingRoom.wakuTotalVotesAgainst.add(vote.tokenAmount)
votingRoom.wakuTotalVotesAgainst = votingRoom.wakuTotalVotesAgainst.add(
vote.tokenAmount.div(this.tokenMultiDecimals)
)
} else {
votingRoom.wakuTotalVotesFor = votingRoom.wakuTotalVotesFor.add(vote.tokenAmount)
votingRoom.wakuTotalVotesFor = votingRoom.wakuTotalVotesFor.add(
vote.tokenAmount.div(this.tokenMultiDecimals)
)
}
return true
}
@ -188,7 +190,10 @@ export class WakuVoting extends WakuMessaging {
return false
}) as VoteMsg[]
const sum = wakuVotes.reduce((prev, curr) => prev.add(curr.tokenAmount), BigNumber.from(0))
const sum = wakuVotes.reduce(
(prev, curr) => prev.add(curr.tokenAmount.div(this.tokenMultiDecimals)),
BigNumber.from(0)
)
votingRoom.wakuVotes = { sum, votes: wakuVotes }
return votingRoom
}

View File

@ -14,7 +14,7 @@ export class DetailedTimedPoll {
public votesMessages: TimedPollVoteMsg[]
public numberOfVotes: BigNumber = BigNumber.from(0)
constructor(poll: PollInitMsg, answers: TimedPollVoteMsg[]) {
constructor(poll: PollInitMsg, answers: TimedPollVoteMsg[], tokenDecimals: BigNumber) {
this.poll = poll
const summedAnswers = poll.answers.map((answer) => {
return { text: answer, votes: BigNumber.from(0) }
@ -26,8 +26,10 @@ export class DetailedTimedPoll {
if (filteredAnswers.findIndex((val) => val.voter === answer.voter) === -1) {
if (poll.pollType === PollType.WEIGHTED && answer.tokenAmount) {
filteredAnswers.push(answer)
summedAnswers[answer.answer].votes = summedAnswers[answer.answer].votes.add(answer.tokenAmount)
this.numberOfVotes = this.numberOfVotes.add(answer.tokenAmount)
summedAnswers[answer.answer].votes = summedAnswers[answer.answer].votes.add(
answer.tokenAmount.div(tokenDecimals)
)
this.numberOfVotes = this.numberOfVotes.add(answer.tokenAmount.div(tokenDecimals))
}
if (poll.pollType === PollType.NON_WEIGHTED) {
filteredAnswers.push(answer)

View File

@ -1,7 +1,4 @@
import { MockProvider } from '@ethereum-waffle/provider'
import { expect } from 'chai'
import { Waku } from 'js-waku'
import { WakuMessaging } from '../src'
describe('WakuVoting', () => {
it('success', async () => {

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'
import React, { useState } from 'react'
import { useConfig, useEthers } from '@usedapp/core'
import styled from 'styled-components'
@ -21,7 +21,7 @@ export function WakuPolling({ appName, signer, theme }: WakuPollingProps) {
const [selectConnect, setSelectConnect] = useState(false)
const wakuPolling = useWakuPolling(
appName,
'0x80ee48b5ba5c3ea556b7ff6d850d2fb2c4bc7412',
'0xdef06eb7cf63ef68cb326b8bc658cf61d888d25a',
library,
config?.multicallAddresses?.[chainId ?? 1337]
)

View File

@ -1,4 +1,4 @@
import React, { ReactNode, useState } from 'react'
import React, { ReactNode, useMemo, useState } from 'react'
import styled from 'styled-components'
import { PollType } from '@waku/vote-poll-sdk-core/dist/esm/src/types/PollType'
import { WakuPolling } from '@waku/vote-poll-sdk-core'
@ -7,7 +7,7 @@ import { MESSAGE_SENDING_RESULT } from '@waku/vote-poll-sdk-core/dist/esm/src/cl
const defaultPollDuration = 7 * 24 * 60 * 60 * 1000 // One week in ms.
function getLocaleIsoTime(dateTime: Date) {
export function getLocaleIsoTime(dateTime: Date) {
const MS_PER_MINUTE = 60000
const milliseconds = dateTime.getTime() - dateTime.getTimezoneOffset() * MS_PER_MINUTE
const newDate = new Date(milliseconds)
@ -46,8 +46,8 @@ export function PollCreation({ wakuPolling, theme, setShowPollCreation }: PollCr
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() + defaultPollDuration))
const selectedType = useMemo(() => PollType.NON_WEIGHTED, [])
const endTimePicker = useMemo(() => new Date(new Date().getTime() + defaultPollDuration), [])
return (
<Modal heading="Create a poll" setShowModal={setShowPollCreation} theme={theme}>

View File

@ -1,6 +1,6 @@
import { WakuPolling } from '@waku/vote-poll-sdk-core'
import { DetailedTimedPoll } from '@waku/vote-poll-sdk-core/dist/esm/src/models/DetailedTimedPoll'
import React, { useEffect, useState } from 'react'
import { useEffect, useState } from 'react'
export function usePollList(wakuPolling: WakuPolling | undefined) {
const [polls, setPolls] = useState<DetailedTimedPoll[]>([])

View File

@ -1,4 +1,4 @@
import styled, { css } from 'styled-components'
import styled from 'styled-components'
import { orangeTheme, Theme } from '../../style/themes'
import closeButton from '../../assets/svg/close.svg'
import blueCloseButton from '../../assets/svg/blueClose.svg'

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'
import { useEffect, useState } from 'react'
export function useMobileVersion(sizeThreshold: number) {
const [mobileVersion, setMobileVersion] = useState(false)

View File

@ -1,6 +1,6 @@
import { WakuMessaging } from '@waku/vote-poll-sdk-core'
import { BigNumber } from 'ethers'
import React, { useEffect, useState } from 'react'
import { useEffect, useState } from 'react'
export function useTokenBalance(address: string | null | undefined, wakuVoting: WakuMessaging) {
const [tokenBalance, setTokenBalance] = useState(0)

View File

@ -1,5 +1,5 @@
import React from 'react'
import { Redirect, Route, Switch, useHistory } from 'react-router'
import { Route, Switch, useHistory } from 'react-router'
import { BrowserRouter } from 'react-router-dom'
import styled from 'styled-components'
import { VotingRoomMobile, NewVotingRoomMobile } from '@waku/vote-sdk-react-components'

View File

@ -31,7 +31,7 @@ function VotingWrapper() {
const config = useConfig()
const waku = useWakuVoting(
'test',
'0x965a61B9A91400AdA142b591ab0E235024c94E3D',
'0x2c818275a741c3d6d222f981ee8ec37bc0e3c0eb',
library,
config?.multicallAddresses?.[chainId ?? 1337]
)

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react'
import styled from 'styled-components'
import { FinalBtn, VoteBtnAgainst, VoteBtnFor } from '../Buttons'
import { VoteBtnAgainst, VoteBtnFor } from '../Buttons'
import { VoteSubmitButton } from './VoteSubmitButton'
import { VoteChart } from './VoteChart'
import { ViewLink } from '../ViewLink'

View File

@ -1,4 +1,4 @@
import React, { useMemo, useRef } from 'react'
import React, { useMemo } from 'react'
import CountUp from 'react-countup'
import styled from 'styled-components'
import { addCommas } from '../../helpers/addCommas'
@ -8,7 +8,6 @@ import crossIcon from '../../assets/svg/cross.svg'
import crossWinnerIcon from '../../assets/svg/crossWinner.svg'
import checkIcon from '../../assets/svg/check.svg'
import checkWinnerIcon from '../../assets/svg/checkWinner.svg'
import { useMobileVersion } from '@waku/vote-poll-sdk-react-components'
import { VotingRoom } from '@waku/vote-poll-sdk-core/dist/esm/src/types/PollType'
import { WakuVoting } from '@waku/vote-poll-sdk-core'
@ -39,7 +38,13 @@ export function VoteChart({
() => totalVotesFor.add(totalVotesAgainst),
[totalVotesFor.toString(), totalVotesAgainst.toString()]
)
const graphWidth = useMemo(() => totalVotesAgainst.mul(100).div(voteSum).toNumber(), [voteSum])
const graphWidth = useMemo(() => {
if (voteSum.gt(0)) {
return totalVotesAgainst.mul(100).div(voteSum).toNumber()
} else {
return 1
}
}, [voteSum])
const balanceWidth = useMemo(() => {
if (!proposingAmount) {

View File

@ -1,5 +1,5 @@
import { WakuVoting } from '@waku/vote-poll-sdk-core'
import React, { useCallback, useMemo } from 'react'
import React, { useMemo } from 'react'
import { useState } from 'react'
import styled from 'styled-components'
import { addCommas } from '../helpers/addCommas'

View File

@ -1,7 +1,7 @@
import React, { useEffect, useMemo, useState } from 'react'
import React, { useMemo, useState } from 'react'
import { useParams } from 'react-router'
import styled from 'styled-components'
import { FinalBtn, VoteBtnAgainst, VoteBtnFor } from '../Buttons'
import { VoteBtnAgainst, VoteBtnFor } from '../Buttons'
import { VoteSubmitButton } from '../ProposalVoteCard/VoteSubmitButton'
import { VoteChart } from '../ProposalVoteCard/VoteChart'
import { ProposalInfo } from '../ProposalInfo'

View File

@ -1,5 +1,4 @@
import { WakuVoting } from '@waku/vote-poll-sdk-core'
import { useEthers } from '@usedapp/core'
import React, { useState } from 'react'
import styled from 'styled-components'
import { ProposingBtn } from '../Buttons'

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState, useRef } from 'react'
import { useEffect, useState } from 'react'
import { WakuVoting } from '@waku/vote-poll-sdk-core'
import { VotingRoom } from '@waku/vote-poll-sdk-core/dist/esm/src/types/PollType'
@ -6,7 +6,7 @@ export function useVotingRoom(id: number, wakuVoting: WakuVoting) {
const [votingRoom, setVotingRoom] = useState<VotingRoom | undefined>(undefined)
useEffect(() => {
const updateFunction = async () => {
const votingRoom = await wakuVoting.getVotingRoom(id)
const votingRoom = await wakuVoting.getProposal(id)
setVotingRoom(votingRoom)
if (votingRoom?.timeLeft && votingRoom.timeLeft < 0) {
clearInterval(interval)

View File

@ -1,21 +1,19 @@
import { id } from '@ethersproject/hash'
import { WakuVoting } from '@waku/vote-poll-sdk-core'
import { VotingRoom } from '@waku/vote-poll-sdk-core/dist/esm/src/types/PollType'
import React, { useEffect, useRef, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
export function useVotingRoomsId(wakuVoting: WakuVoting) {
const [votes, setVotes] = useState<number[]>([])
const votesLength = useRef(0)
useEffect(() => {
const interval = setInterval(async () => {
const newRooms = (await wakuVoting.getVotingRooms()).map((e) => e.id)
const newRooms = (await wakuVoting.getProposals()).map((e) => e.id)
if (newRooms.length != votesLength.current) {
setVotes(newRooms)
votesLength.current = newRooms.length
}
}, 10000)
setVotes([])
wakuVoting.getVotingRooms().then((e) => {
wakuVoting.getProposals().then((e) => {
setVotes(e.map((vote) => vote.id))
votesLength.current = e.length
})

View File

@ -1,5 +1,5 @@
import { WakuVoting } from '@waku/vote-poll-sdk-core'
import React, { useEffect, useRef, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import { Web3Provider } from '@ethersproject/providers'
export function useWakuVoting(