Add token verification (#173)
This commit is contained in:
parent
3cc6f6873c
commit
bdb8c4464f
|
@ -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
|
@ -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"
|
||||
}
|
||||
|
|
@ -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 }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}`)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue