2021-06-17 13:33:35 +02:00
|
|
|
import { expect, use } from 'chai'
|
2021-07-06 13:59:28 +02:00
|
|
|
import { loadFixture, deployContract, MockProvider, solidity } from 'ethereum-waffle'
|
2021-06-17 13:33:35 +02:00
|
|
|
import MockContract from '../build/MockContract.json'
|
2021-07-06 13:59:28 +02:00
|
|
|
import { utils, BigNumber, Wallet } from 'ethers'
|
2021-06-17 13:33:35 +02:00
|
|
|
|
|
|
|
use(solidity)
|
|
|
|
|
2021-07-06 13:59:28 +02:00
|
|
|
const getSignedMessages = async (
|
|
|
|
alice: Wallet,
|
|
|
|
firstAddress: Wallet,
|
|
|
|
secondAddress: Wallet
|
|
|
|
): Promise<{ messages: any[]; signedMessages: any[] }> => {
|
|
|
|
const votes = [
|
|
|
|
{
|
|
|
|
voter: alice,
|
|
|
|
vote: 1,
|
|
|
|
sntAmount: BigNumber.from(100),
|
|
|
|
sessionID: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
voter: firstAddress,
|
|
|
|
vote: 0,
|
|
|
|
sntAmount: BigNumber.from(100),
|
|
|
|
sessionID: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
voter: secondAddress,
|
|
|
|
vote: 1,
|
|
|
|
sntAmount: BigNumber.from(100),
|
|
|
|
sessionID: 1,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
const types = ['address', 'uint256', 'uint256']
|
|
|
|
const messages = votes.map((vote) => [
|
|
|
|
vote.voter.address,
|
|
|
|
BigNumber.from(vote.sessionID).mul(2).add(vote.vote),
|
|
|
|
vote.sntAmount,
|
|
|
|
])
|
|
|
|
|
|
|
|
const signedMessages = await Promise.all(
|
|
|
|
messages.map(async (message, idx) => {
|
|
|
|
const returnArray = [...message]
|
|
|
|
const signature = utils.splitSignature(
|
|
|
|
await votes[idx].voter.signMessage(utils.arrayify(utils.solidityPack(types, message)))
|
|
|
|
)
|
|
|
|
returnArray.push(signature.r)
|
|
|
|
returnArray.push(signature._vs)
|
|
|
|
return returnArray
|
|
|
|
})
|
|
|
|
)
|
|
|
|
|
|
|
|
return { messages, signedMessages }
|
|
|
|
}
|
|
|
|
|
|
|
|
describe('Contract story', () => {
|
2021-06-17 13:33:35 +02:00
|
|
|
const provider = new MockProvider()
|
2021-06-23 23:33:25 +02:00
|
|
|
const [alice, firstAddress, secondAddress] = provider.getWallets()
|
2021-06-17 13:33:35 +02:00
|
|
|
|
2021-07-06 13:59:28 +02:00
|
|
|
const types = [0, 1]
|
|
|
|
for (const index in [0, 1]) {
|
|
|
|
const type = types[index]
|
|
|
|
|
|
|
|
it(`type ${type}`, async () => {
|
|
|
|
const contract = await deployContract(alice, MockContract)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
|
|
|
|
|
|
|
expect(await contract.initializeVotingRoom(type, '0x0FA1A5CC3911A5697B625EF1C75eF4caE764bd34'))
|
|
|
|
.to.emit(contract, 'VotingRoomStarted')
|
|
|
|
.withArgs(1)
|
|
|
|
|
|
|
|
expect(await contract.initializeVotingRoom(type, '0x95863d16bA2fb60B7d9Ca725f22df76fA5dEe61D'))
|
|
|
|
.to.emit(contract, 'VotingRoomStarted')
|
|
|
|
.withArgs(2)
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
contract.initializeVotingRoom(type, '0x95863d16bA2fb60B7d9Ca725f22df76fA5dEe61D')
|
|
|
|
).to.be.revertedWith('vote already ongoing')
|
|
|
|
|
|
|
|
const { signedMessages } = await getSignedMessages(alice, firstAddress, secondAddress)
|
|
|
|
|
|
|
|
await contract.castVotes(signedMessages)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() + 10000)])
|
|
|
|
await contract.finalizeVotingRoom(1)
|
|
|
|
|
|
|
|
expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
|
|
|
|
type,
|
|
|
|
true,
|
|
|
|
'0x0FA1A5CC3911A5697B625EF1C75eF4caE764bd34',
|
|
|
|
BigNumber.from(200),
|
|
|
|
BigNumber.from(100),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('Contract', () => {
|
|
|
|
async function fixture([alice, firstAddress, secondAddress]: any[], provider: any) {
|
|
|
|
const contract = await deployContract(alice, MockContract)
|
|
|
|
return { contract, alice, firstAddress, secondAddress, provider }
|
|
|
|
}
|
2021-06-23 23:33:25 +02:00
|
|
|
|
|
|
|
describe('Voting Room', () => {
|
|
|
|
it('initializes', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, firstAddress, secondAddress, provider } = await loadFixture(fixture)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
expect(await contract.initializeVotingRoom(1, firstAddress.address))
|
|
|
|
.to.emit(contract, 'VotingRoomStarted')
|
|
|
|
.withArgs(1)
|
|
|
|
expect(await contract.initializeVotingRoom(1, secondAddress.address))
|
|
|
|
.to.emit(contract, 'VotingRoomStarted')
|
|
|
|
.withArgs(2)
|
|
|
|
await expect(contract.initializeVotingRoom(1, secondAddress.address)).to.be.revertedWith('vote already ongoing')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('gets', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, firstAddress, secondAddress, provider } = await loadFixture(fixture)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await contract.initializeVotingRoom(1, firstAddress.address)
|
|
|
|
expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
|
|
|
|
1,
|
|
|
|
false,
|
|
|
|
firstAddress.address,
|
|
|
|
BigNumber.from(0),
|
|
|
|
BigNumber.from(0),
|
|
|
|
])
|
|
|
|
|
|
|
|
await contract.initializeVotingRoom(1, secondAddress.address)
|
|
|
|
expect((await contract.votingRoomMap(2)).slice(2)).to.deep.eq([
|
|
|
|
1,
|
|
|
|
false,
|
|
|
|
secondAddress.address,
|
|
|
|
BigNumber.from(0),
|
|
|
|
BigNumber.from(0),
|
|
|
|
])
|
|
|
|
expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
|
|
|
|
1,
|
|
|
|
false,
|
|
|
|
firstAddress.address,
|
|
|
|
BigNumber.from(0),
|
|
|
|
BigNumber.from(0),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
it('finalizes', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, firstAddress, provider } = await loadFixture(fixture)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await contract.initializeVotingRoom(1, firstAddress.address)
|
|
|
|
expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
|
|
|
|
1,
|
|
|
|
false,
|
|
|
|
firstAddress.address,
|
|
|
|
BigNumber.from(0),
|
|
|
|
BigNumber.from(0),
|
|
|
|
])
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000 + 2000)])
|
|
|
|
expect(await contract.finalizeVotingRoom(1))
|
|
|
|
.to.emit(contract, 'VotingRoomFinalized')
|
|
|
|
.withArgs(1)
|
|
|
|
expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
|
|
|
|
1,
|
|
|
|
true,
|
|
|
|
firstAddress.address,
|
|
|
|
BigNumber.from(0),
|
|
|
|
BigNumber.from(0),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('helpers', () => {
|
|
|
|
it('get active votes', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, firstAddress, secondAddress, provider } = await loadFixture(fixture)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await contract.initializeVotingRoom(1, firstAddress.address)
|
|
|
|
expect(await contract.getActiveVotingRooms()).to.deep.eq([BigNumber.from(1)])
|
|
|
|
|
|
|
|
await contract.initializeVotingRoom(1, secondAddress.address)
|
|
|
|
expect(await contract.getActiveVotingRooms()).to.deep.eq([BigNumber.from(1), BigNumber.from(2)])
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000 + 2000)])
|
|
|
|
await contract.finalizeVotingRoom(1)
|
|
|
|
expect(await contract.getActiveVotingRooms()).to.deep.eq([BigNumber.from(2)])
|
|
|
|
await contract.finalizeVotingRoom(2)
|
|
|
|
expect(await contract.getActiveVotingRooms()).to.deep.eq([])
|
|
|
|
await contract.initializeVotingRoom(1, secondAddress.address)
|
|
|
|
expect(await contract.getActiveVotingRooms()).to.deep.eq([BigNumber.from(3)])
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('voting', () => {
|
|
|
|
it('check voters', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, alice, firstAddress, secondAddress, provider } = await loadFixture(fixture)
|
|
|
|
const { signedMessages } = await getSignedMessages(alice, firstAddress, secondAddress)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await contract.initializeVotingRoom(1, '0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24')
|
|
|
|
|
|
|
|
expect(await contract.listRoomVoters(1)).to.deep.eq([])
|
|
|
|
await contract.castVotes(signedMessages.slice(2))
|
|
|
|
expect(await contract.listRoomVoters(1)).to.deep.eq([secondAddress.address])
|
|
|
|
await contract.castVotes(signedMessages.slice(0, 1))
|
|
|
|
expect(await contract.listRoomVoters(1)).to.deep.eq([secondAddress.address, alice.address])
|
|
|
|
})
|
|
|
|
|
|
|
|
it('success', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, alice, firstAddress, secondAddress, provider } = await loadFixture(fixture)
|
|
|
|
const { signedMessages } = await getSignedMessages(alice, firstAddress, secondAddress)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await contract.initializeVotingRoom(1, '0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24')
|
|
|
|
await contract.castVotes(signedMessages)
|
|
|
|
expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
|
|
|
|
1,
|
|
|
|
false,
|
|
|
|
'0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24',
|
|
|
|
BigNumber.from(200),
|
|
|
|
BigNumber.from(100),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
it('double vote', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, alice, firstAddress, secondAddress, provider } = await loadFixture(fixture)
|
|
|
|
const { signedMessages } = await getSignedMessages(alice, firstAddress, secondAddress)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await contract.initializeVotingRoom(1, '0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24')
|
|
|
|
await contract.castVotes(signedMessages)
|
|
|
|
await contract.castVotes(signedMessages)
|
|
|
|
expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
|
|
|
|
1,
|
|
|
|
false,
|
|
|
|
'0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24',
|
|
|
|
BigNumber.from(200),
|
|
|
|
BigNumber.from(100),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
it('random bytes', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, provider } = await loadFixture(fixture)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await contract.initializeVotingRoom(1, '0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24')
|
|
|
|
await expect(contract.castVotes([new Uint8Array([12, 12, 12])])).to.be.reverted
|
|
|
|
})
|
|
|
|
|
|
|
|
it('none existent room', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, alice, firstAddress, secondAddress, provider } = await loadFixture(fixture)
|
|
|
|
const { signedMessages } = await getSignedMessages(alice, firstAddress, secondAddress)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await expect(contract.castVotes(signedMessages)).to.be.reverted
|
|
|
|
})
|
|
|
|
|
|
|
|
it('old room', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, alice, firstAddress, secondAddress, provider } = await loadFixture(fixture)
|
|
|
|
const { signedMessages } = await getSignedMessages(alice, firstAddress, secondAddress)
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await contract.initializeVotingRoom(1, '0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24')
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000 + 2000)])
|
|
|
|
await expect(contract.castVotes(signedMessages)).to.be.reverted
|
|
|
|
})
|
|
|
|
|
|
|
|
it('wrong signature', async () => {
|
2021-07-06 13:59:28 +02:00
|
|
|
const { contract, alice, firstAddress, secondAddress, provider } = await loadFixture(fixture)
|
|
|
|
const { messages } = await getSignedMessages(alice, firstAddress, secondAddress)
|
|
|
|
const types = ['address', 'uint256', 'uint256']
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
2021-06-23 23:33:25 +02:00
|
|
|
await contract.initializeVotingRoom(1, '0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24')
|
|
|
|
await provider.send('evm_mine', [Math.floor(Date.now() / 1000 + 2000)])
|
|
|
|
|
2021-07-06 13:59:28 +02:00
|
|
|
const signedMessages = await Promise.all(
|
2021-06-23 23:33:25 +02:00
|
|
|
messages.map(async (message) => {
|
|
|
|
const returnArray = [...message]
|
|
|
|
const signature = utils.splitSignature(
|
|
|
|
await alice.signMessage(utils.arrayify(utils.solidityPack(types, message)))
|
|
|
|
)
|
|
|
|
returnArray.push(signature.r)
|
|
|
|
returnArray.push(signature._vs)
|
|
|
|
return returnArray
|
|
|
|
})
|
|
|
|
)
|
|
|
|
|
|
|
|
await expect(contract.castVotes(signedMessages)).to.be.reverted
|
|
|
|
})
|
2021-06-17 13:33:35 +02:00
|
|
|
})
|
|
|
|
})
|