Add token verification (#173)

This commit is contained in:
Szymon Szlachtowicz 2021-07-30 12:28:45 +02:00 committed by GitHub
parent 3cc6f6873c
commit bdb8c4464f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 873 additions and 28 deletions

View File

@ -0,0 +1,230 @@
{
"contractName": "ERC20",
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": true,
"name": "to",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "owner",
"type": "address"
},
{
"indexed": true,
"name": "spender",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "owner",
"type": "address"
},
{
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "to",
"type": "address"
},
{
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "spender",
"type": "address"
},
{
"name": "value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "from",
"type": "address"
},
{
"name": "to",
"type": "address"
},
{
"name": "value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "spender",
"type": "address"
},
{
"name": "addedValue",
"type": "uint256"
}
],
"name": "increaseAllowance",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "spender",
"type": "address"
},
{
"name": "subtractedValue",
"type": "uint256"
}
],
"name": "decreaseAllowance",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b506105dd806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a5576000357c01000000000000000000000000000000000000000000000000000000009004806370a082311161007857806370a0823114610166578063a457c2d71461018c578063a9059cbb146101b8578063dd62ed3e146101e4576100a5565b8063095ea7b3146100aa57806318160ddd146100ea57806323b872dd14610104578063395093511461013a575b600080fd5b6100d6600480360360408110156100c057600080fd5b50600160a060020a038135169060200135610212565b604080519115158252519081900360200190f35b6100f2610290565b60408051918252519081900360200190f35b6100d66004803603606081101561011a57600080fd5b50600160a060020a03813581169160208101359091169060400135610296565b6100d66004803603604081101561015057600080fd5b50600160a060020a03813516906020013561035f565b6100f26004803603602081101561017c57600080fd5b5035600160a060020a031661040f565b6100d6600480360360408110156101a257600080fd5b50600160a060020a03813516906020013561042a565b6100d6600480360360408110156101ce57600080fd5b50600160a060020a038135169060200135610475565b6100f2600480360360408110156101fa57600080fd5b50600160a060020a038135811691602001351661048b565b6000600160a060020a038316151561022957600080fd5b336000818152600160209081526040808320600160a060020a03881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b60025490565b600160a060020a03831660009081526001602090815260408083203384529091528120546102ca908363ffffffff6104b616565b600160a060020a03851660009081526001602090815260408083203384529091529020556102f98484846104cb565b600160a060020a0384166000818152600160209081526040808320338085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b6000600160a060020a038316151561037657600080fd5b336000908152600160209081526040808320600160a060020a03871684529091529020546103aa908363ffffffff61059816565b336000818152600160209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600160a060020a031660009081526020819052604090205490565b6000600160a060020a038316151561044157600080fd5b336000908152600160209081526040808320600160a060020a03871684529091529020546103aa908363ffffffff6104b616565b60006104823384846104cb565b50600192915050565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b6000828211156104c557600080fd5b50900390565b600160a060020a03821615156104e057600080fd5b600160a060020a038316600090815260208190526040902054610509908263ffffffff6104b616565b600160a060020a03808516600090815260208190526040808220939093559084168152205461053e908263ffffffff61059816565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000828201838110156105aa57600080fd5b939250505056fea165627a7a72305820722c0187518ce2856a424bdba350d5a263c8f98fcb19cb4cc161372bc3b794c90029",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a5576000357c01000000000000000000000000000000000000000000000000000000009004806370a082311161007857806370a0823114610166578063a457c2d71461018c578063a9059cbb146101b8578063dd62ed3e146101e4576100a5565b8063095ea7b3146100aa57806318160ddd146100ea57806323b872dd14610104578063395093511461013a575b600080fd5b6100d6600480360360408110156100c057600080fd5b50600160a060020a038135169060200135610212565b604080519115158252519081900360200190f35b6100f2610290565b60408051918252519081900360200190f35b6100d66004803603606081101561011a57600080fd5b50600160a060020a03813581169160208101359091169060400135610296565b6100d66004803603604081101561015057600080fd5b50600160a060020a03813516906020013561035f565b6100f26004803603602081101561017c57600080fd5b5035600160a060020a031661040f565b6100d6600480360360408110156101a257600080fd5b50600160a060020a03813516906020013561042a565b6100d6600480360360408110156101ce57600080fd5b50600160a060020a038135169060200135610475565b6100f2600480360360408110156101fa57600080fd5b50600160a060020a038135811691602001351661048b565b6000600160a060020a038316151561022957600080fd5b336000818152600160209081526040808320600160a060020a03881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b60025490565b600160a060020a03831660009081526001602090815260408083203384529091528120546102ca908363ffffffff6104b616565b600160a060020a03851660009081526001602090815260408083203384529091529020556102f98484846104cb565b600160a060020a0384166000818152600160209081526040808320338085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b6000600160a060020a038316151561037657600080fd5b336000908152600160209081526040808320600160a060020a03871684529091529020546103aa908363ffffffff61059816565b336000818152600160209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600160a060020a031660009081526020819052604090205490565b6000600160a060020a038316151561044157600080fd5b336000908152600160209081526040808320600160a060020a03871684529091529020546103aa908363ffffffff6104b616565b60006104823384846104cb565b50600192915050565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b6000828211156104c557600080fd5b50900390565b600160a060020a03821615156104e057600080fd5b600160a060020a038316600090815260208190526040902054610509908263ffffffff6104b616565b600160a060020a03808516600090815260208190526040808220939093559084168152205461053e908263ffffffff61059816565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000828201838110156105aa57600080fd5b939250505056fea165627a7a72305820722c0187518ce2856a424bdba350d5a263c8f98fcb19cb4cc161372bc3b794c90029",
"compiler": {
"name": "solc",
"version": "0.5.4+commit.9549d8ff.Emscripten.clang"
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,145 @@
{
"abi": [
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "bytes",
"name": "callData",
"type": "bytes"
}
],
"internalType": "struct Multicall.Call[]",
"name": "calls",
"type": "tuple[]"
}
],
"name": "aggregate",
"outputs": [
{
"internalType": "uint256",
"name": "blockNumber",
"type": "uint256"
},
{
"internalType": "bytes[]",
"name": "returnData",
"type": "bytes[]"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "blockNumber",
"type": "uint256"
}
],
"name": "getBlockHash",
"outputs": [
{
"internalType": "bytes32",
"name": "blockHash",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getCurrentBlockCoinbase",
"outputs": [
{
"internalType": "address",
"name": "coinbase",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getCurrentBlockDifficulty",
"outputs": [
{
"internalType": "uint256",
"name": "difficulty",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getCurrentBlockGasLimit",
"outputs": [
{
"internalType": "uint256",
"name": "gaslimit",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getCurrentBlockTimestamp",
"outputs": [
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "addr",
"type": "address"
}
],
"name": "getEthBalance",
"outputs": [
{
"internalType": "uint256",
"name": "balance",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getLastBlockHash",
"outputs": [
{
"internalType": "bytes32",
"name": "blockHash",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
}
],
"bytecode": "608060405234801561001057600080fd5b5061066e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806372425d9d1161005b57806372425d9d146100e757806386d516e8146100ef578063a8b0574e146100f7578063ee82ac5e1461010c57610088565b80630f28c97d1461008d578063252dba42146100ab57806327e86d6e146100cc5780634d2301cc146100d4575b600080fd5b61009561011f565b6040516100a2919061051e565b60405180910390f35b6100be6100b93660046103b6565b610123565b6040516100a292919061052c565b610095610231565b6100956100e2366004610390565b61023a565b610095610247565b61009561024b565b6100ff61024f565b6040516100a2919061050a565b61009561011a3660046103eb565b610253565b4290565b60006060439150825160405190808252806020026020018201604052801561015f57816020015b606081526020019060019003908161014a5790505b50905060005b835181101561022b576000606085838151811061017e57fe5b6020026020010151600001516001600160a01b031686848151811061019f57fe5b6020026020010151602001516040516101b891906104fe565b6000604051808303816000865af19150503d80600081146101f5576040519150601f19603f3d011682016040523d82523d6000602084013e6101fa565b606091505b50915091508161020957600080fd5b8084848151811061021657fe5b60209081029190910101525050600101610165565b50915091565b60001943014090565b6001600160a01b03163190565b4490565b4590565b4190565b4090565b600061026382356105d4565b9392505050565b600082601f83011261027b57600080fd5b813561028e61028982610573565b61054c565b81815260209384019390925082018360005b838110156102cc57813586016102b68882610325565b84525060209283019291909101906001016102a0565b5050505092915050565b600082601f8301126102e757600080fd5b81356102f561028982610594565b9150808252602083016020830185838301111561031157600080fd5b61031c8382846105ee565b50505092915050565b60006040828403121561033757600080fd5b610341604061054c565b9050600061034f8484610257565b825250602082013567ffffffffffffffff81111561036c57600080fd5b610378848285016102d6565b60208301525092915050565b600061026382356105df565b6000602082840312156103a257600080fd5b60006103ae8484610257565b949350505050565b6000602082840312156103c857600080fd5b813567ffffffffffffffff8111156103df57600080fd5b6103ae8482850161026a565b6000602082840312156103fd57600080fd5b60006103ae8484610384565b60006102638383610497565b61041e816105d4565b82525050565b600061042f826105c2565b61043981856105c6565b93508360208202850161044b856105bc565b60005b84811015610482578383038852610466838351610409565b9250610471826105bc565b60209890980197915060010161044e565b50909695505050505050565b61041e816105df565b60006104a2826105c2565b6104ac81856105c6565b93506104bc8185602086016105fa565b6104c58161062a565b9093019392505050565b60006104da826105c2565b6104e481856105cf565b93506104f48185602086016105fa565b9290920192915050565b600061026382846104cf565b602081016105188284610415565b92915050565b60208101610518828461048e565b6040810161053a828561048e565b81810360208301526103ae8184610424565b60405181810167ffffffffffffffff8111828210171561056b57600080fd5b604052919050565b600067ffffffffffffffff82111561058a57600080fd5b5060209081020190565b600067ffffffffffffffff8211156105ab57600080fd5b506020601f91909101601f19160190565b60200190565b5190565b90815260200190565b919050565b6000610518826105e2565b90565b6001600160a01b031690565b82818337506000910152565b60005b838110156106155781810151838201526020016105fd565b83811115610624576000848401525b50505050565b601f01601f19169056fea265627a7a72305820978cd44d5ce226bebdf172bdf24918753b9e111e3803cb6249d3ca2860b7a47f6c6578706572696d656e74616cf50037"
}

View File

@ -1,4 +1,7 @@
import VotingContract from './../build/VotingContract.json'
import Directory from './../build/Directory.json'
import ERC20 from './ERC20.json'
import ERC20Mock from './ERC20Mock.json'
import MultiCall from './MultiCall.json'
export { VotingContract, Directory }
export { VotingContract, Directory, ERC20, MultiCall, ERC20Mock }

View File

@ -1,5 +1,6 @@
pragma solidity ^0.8.5;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol';
import '@openzeppelin/contracts/utils/math/SafeMath.sol';
import './Directory.sol';
@ -33,6 +34,7 @@ contract VotingContract {
address public owner;
Directory public directory;
IERC20 public token;
uint256 private latestVoting = 1;
mapping(uint256 => VotingRoom) public votingRoomMap;
@ -41,8 +43,9 @@ contract VotingContract {
uint256[] public activeVotingRooms;
mapping(uint256 => uint256) private indexOfActiveVotingRooms;
constructor() {
constructor(IERC20 _address) {
owner = msg.sender;
token = _address;
}
function setDirectory(Directory _address) public {
@ -94,6 +97,7 @@ contract VotingContract {
if (voteType == VoteType.ADD) {
require(!directory.isCommunityInDirectory(publicKey), 'Community already in directory');
}
require(token.balanceOf(msg.sender) >= voteAmount, 'not enough token');
VotingRoom storage newVotingRoom = votingRoomMap[latestVoting];
newVotingRoom.startBlock = block.number;
newVotingRoom.endAt = block.timestamp.add(VOTING_LENGTH);
@ -140,6 +144,9 @@ contract VotingContract {
emit VotingRoomFinalized(roomId, community, passed, votingRoomMap[roomId].voteType);
}
event VoteCast(uint256 roomId, address voter);
event NotEnoughToken(uint256 roomId, address voter);
struct SignedVote {
address voter;
uint256 roomIdAndType;
@ -147,7 +154,6 @@ contract VotingContract {
bytes32 r;
bytes32 vs;
}
event VoteCast(uint256 roomId, address voter);
function castVotes(SignedVote[] calldata votes) public {
for (uint256 i = 0; i < votes.length; i++) {
@ -162,14 +168,18 @@ contract VotingContract {
VotingRoom storage room = votingRoomMap[roomId];
require(room.endAt > block.timestamp, 'vote closed');
if (room.voted[vote.voter] == false) {
if (vote.roomIdAndType & 1 == 1) {
room.totalVotesFor = room.totalVotesFor.add(vote.sntAmount);
if (token.balanceOf(vote.voter) >= vote.sntAmount) {
if (vote.roomIdAndType & 1 == 1) {
room.totalVotesFor = room.totalVotesFor.add(vote.sntAmount);
} else {
room.totalVotesAgainst = room.totalVotesAgainst.add(vote.sntAmount);
}
room.voters.push(vote.voter);
room.voted[vote.voter] = true;
emit VoteCast(roomId, vote.voter);
} else {
room.totalVotesAgainst = room.totalVotesAgainst.add(vote.sntAmount);
emit NotEnoughToken(roomId, vote.voter);
}
room.voters.push(vote.voter);
room.voted[vote.voter] = true;
emit VoteCast(roomId, vote.voter);
}
}
}

View File

@ -1,8 +1,6 @@
import { ethers } from 'ethers'
import { deployContract } from 'ethereum-waffle'
import MockContract from '../build/MockContract.json'
import Directory from '../build/Directory.json'
import MultiCall from '../build/MultiCall.json'
import { VotingContract, Directory } from '../abi'
const deploy = async () => {
const providerName = process.env.ETHEREUM_PROVIDER
@ -14,14 +12,13 @@ const deploy = async () => {
const provider = ethers.getDefaultProvider(process.env.ETHEREUM_PROVIDER)
const wallet = new ethers.Wallet(privateKey, provider)
const mockContract = await deployContract(wallet, MockContract)
console.log(`Voting contract deployed with address: ${mockContract.address}`)
const votingContract = await deployContract(wallet, VotingContract,[process.env.ETHEREUM_TOKEN_ADDRESS])
console.log(`Voting contract deployed with address: ${votingContract.address}`)
const directoryContract = await deployContract(wallet,Directory,[mockContract.address])
await mockContract.setDirectory(directoryContract.address)
const directoryContract = await deployContract(wallet,Directory,[votingContract.address])
await votingContract.setDirectory(directoryContract.address)
console.log(`Directory contract deployed with address: ${directoryContract.address}`)
const multiCall = await deployContract(wallet, MultiCall)
console.log(`MultiCall deployed with address: ${multiCall.address}`)
}
}

View File

@ -0,0 +1,33 @@
import { BigNumber, ethers } from 'ethers'
import { deployContract } from 'ethereum-waffle'
import {VotingContract, Directory, MultiCall, ERC20Mock} from '../abi'
const deploy = async () => {
const providerName = process.env.ETHEREUM_PROVIDER
const privateKey = process.env.ETHEREUM_PRIVATE_KEY
console.log(privateKey)
if (privateKey && providerName) {
console.log(`deploying on ${providerName}`)
const provider = ethers.getDefaultProvider(process.env.ETHEREUM_PROVIDER)
const wallet = new ethers.Wallet(privateKey, provider)
const ercArgs = ['MSNT', 'Mock SNT', wallet.address, BigNumber.from('0x33B2E3C9FD0803CE8000000')]
const erc20 = await deployContract(wallet,ERC20Mock,ercArgs)
console.log(`ERC20 Token deployed with address: ${erc20.address}`)
const votingContract = await deployContract(wallet, VotingContract,[erc20.address])
console.log(`Voting contract deployed with address: ${votingContract.address}`)
const directoryContract = await deployContract(wallet,Directory,[votingContract.address])
await votingContract.setDirectory(directoryContract.address)
console.log(`Directory contract deployed with address: ${directoryContract.address}`)
const multiCall = await deployContract(wallet, MultiCall)
console.log(`MultiCall deployed with address: ${multiCall.address}`)
}
}
deploy()

View File

@ -1,7 +1,6 @@
import { expect, use } from 'chai'
import { loadFixture, deployContract, MockProvider, solidity } from 'ethereum-waffle'
import VotingContract from '../build/VotingContract.json'
import Directory from '../build/Directory.json'
import { VotingContract, Directory, ERC20Mock } from '../abi'
import { utils, BigNumber, Wallet, Contract } from 'ethers'
use(solidity)
@ -72,13 +71,17 @@ const voteAndFinalize = async (
describe('Contract', () => {
async function fixture([alice, firstAddress, secondAddress]: any[], provider: any) {
const contract = await deployContract(alice, VotingContract)
const erc20 = await deployContract(alice, ERC20Mock, ['MSNT', 'Mock SNT', alice.address, 100000])
await erc20.transfer(firstAddress.address, 10000)
await erc20.transfer(secondAddress.address, 10000)
const contract = await deployContract(alice, VotingContract, [erc20.address])
const directory = await deployContract(alice, Directory, [contract.address])
await contract.setDirectory(directory.address)
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
return { contract, directory, alice, firstAddress, secondAddress, provider }
}
loadFixture(fixture)
it('deploys properly', async () => {
const { contract, directory } = await loadFixture(fixture)
expect(await contract.directory()).to.eq(directory.address)
@ -94,10 +97,10 @@ describe('Contract', () => {
describe('initialization', () => {
it('initializes', async () => {
const { contract, firstAddress, secondAddress } = await loadFixture(fixture)
expect(await contract.initializeVotingRoom(1, firstAddress.address, BigNumber.from(100)))
await expect(await contract.initializeVotingRoom(1, firstAddress.address, BigNumber.from(100)))
.to.emit(contract, 'VotingRoomStarted')
.withArgs(1, firstAddress.address)
expect(await contract.initializeVotingRoom(1, secondAddress.address, BigNumber.from(100)))
await expect(await contract.initializeVotingRoom(1, secondAddress.address, BigNumber.from(100)))
.to.emit(contract, 'VotingRoomStarted')
.withArgs(2, secondAddress.address)
await expect(contract.initializeVotingRoom(1, secondAddress.address, BigNumber.from(100))).to.be.revertedWith(
@ -105,6 +108,13 @@ describe('Contract', () => {
)
})
it('not enough token', async () => {
const { contract } = await loadFixture(fixture)
await expect(
contract.initializeVotingRoom(1, '0xAcdd71e5Ef3Ab3356d62da78A941aAc08a18CF2b', BigNumber.from(10000000000000))
).to.be.revertedWith('not enough token')
})
describe('directory interaction', () => {
it('remove missing', async () => {
const { contract } = await loadFixture(fixture)
@ -169,7 +179,7 @@ describe('Contract', () => {
BigNumber.from(1),
])
await provider.send('evm_mine', [Math.floor(Date.now() / 1000 + 2000)])
expect(await contract.finalizeVotingRoom(1))
await expect(await contract.finalizeVotingRoom(1))
.to.emit(contract, 'VotingRoomFinalized')
.withArgs(1, firstAddress.address, true, 1)
expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
@ -184,7 +194,7 @@ describe('Contract', () => {
describe('directory interaction', () => {
it('add community', async () => {
const { contract, directory, alice, provider, firstAddress } = await loadFixture(fixture)
const { contract, directory, provider, firstAddress } = await loadFixture(fixture)
await contract.initializeVotingRoom(1, '0xAcdd71e5Ef3Ab3356d62da78A941aAc08a18CF2b', BigNumber.from(100))
await voteAndFinalize(1, 1, firstAddress, contract, provider)
expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
@ -199,7 +209,7 @@ describe('Contract', () => {
})
it('remove community', async () => {
const { contract, directory, alice, provider, firstAddress } = await loadFixture(fixture)
const { contract, directory, provider, firstAddress } = await loadFixture(fixture)
await contract.initializeVotingRoom(1, '0xAcdd71e5Ef3Ab3356d62da78A941aAc08a18CF2b', BigNumber.from(100))
await voteAndFinalize(1, 1, firstAddress, contract, provider)
@ -211,7 +221,7 @@ describe('Contract', () => {
})
it('failed add vote', async () => {
const { contract, directory, alice, provider, firstAddress } = await loadFixture(fixture)
const { contract, directory, provider, firstAddress } = await loadFixture(fixture)
await contract.initializeVotingRoom(1, '0xAcdd71e5Ef3Ab3356d62da78A941aAc08a18CF2b', BigNumber.from(100))
await voteAndFinalize(1, 0, firstAddress, contract, provider)
@ -219,7 +229,7 @@ describe('Contract', () => {
})
it('failed remove vote', async () => {
const { contract, directory, alice, provider, firstAddress } = await loadFixture(fixture)
const { contract, directory, provider, firstAddress } = await loadFixture(fixture)
await contract.initializeVotingRoom(1, '0xAcdd71e5Ef3Ab3356d62da78A941aAc08a18CF2b', BigNumber.from(100))
await voteAndFinalize(1, 1, firstAddress, contract, provider)
@ -284,6 +294,34 @@ describe('Contract', () => {
expect(await contract.listRoomVoters(1)).to.deep.eq([alice.address, secondAddress.address])
})
it('not enough tokens', async () => {
const { contract, firstAddress } = await loadFixture(fixture)
await contract.initializeVotingRoom(1, '0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24', BigNumber.from(100))
const types = ['address', 'uint256', 'uint256']
const message = [firstAddress.address, BigNumber.from(1).mul(2).add(1), BigNumber.from(100000000000)]
const signedMessage = [...message]
const signature = utils.splitSignature(
await firstAddress.signMessage(utils.arrayify(utils.solidityPack(types, message)))
)
signedMessage.push(signature.r)
signedMessage.push(signature._vs)
await expect(await contract.castVotes([signedMessage]))
.to.emit(contract, 'NotEnoughToken')
.withArgs(1, firstAddress.address)
await expect((await contract.votingRoomMap(1)).slice(2)).to.deep.eq([
1,
false,
'0xabA1eF51ef4aE360a9e8C9aD2d787330B602eb24',
BigNumber.from(100),
BigNumber.from(0),
BigNumber.from(1),
])
})
it('success', async () => {
const { contract, alice, firstAddress, secondAddress } = await loadFixture(fixture)
const { signedMessages } = await getSignedMessages(alice, firstAddress, secondAddress)