Code Monkey home page Code Monkey logo

poa-network-consensus-contracts's Introduction

poa-network-consensus-contracts

Build Status

Security Audit

Start POA network

  • Install npm dependencies npm i
  • Generate flat sources of contracts with the script ./make_flat.sh
  • We need a bytecode of PoaNetworkConsensus contract to add it to spec.json of the network.
    Go to scripts directory and run poa-bytecode.js:
$ cd scripts
$ npm i
$ MASTER_OF_CEREMONY=0x0039F22efB07A647557C7C5d17854CFD6D489eF3 node poa-bytecode.js

It will show the bytecode of PoaNetworkConsensus contract. Copy the bytecode and paste it into spec.json.

Add Contracts to Parity UI.

Start Parity UI. In the contracts section press Develop button. Select 0.4.24 Solidity compiler version. Set Optimize to true.

  • In Parity UI Contracts tab choose watch custom contract. Paste bytecode and ABI of PoaNetworkConsensus contract from Remix.

Compile and deploy contracts in the next sequence:

  • ProxyStorage_flat.sol - Deploy ProxyStorage contract.
  • EternalStorageProxy_flat.sol - Deploy EternalStorageProxy contract with constructor parameters:
    _proxyStorage - equal to zero, _implementationAddress - address of ProxyStorage contract.
  • Make a call to ProxyStorage init with _poaConsensus parameter equal to the address of PoaNetworkConsensus contract, using the address of EternalStorageProxy and ABI of ProxyStorage.
  • Select PoaNetworkConsensus contract and call setProxyStorage with the address of ProxyStorage contract.
  • KeysManager_flat.sol - Deploy KeysManager contract.
  • EternalStorageProxy_flat.sol - Deploy EternalStorageProxy contract with constructor parameters:
    _proxyStorage - address of ProxyStorage contract, _implementationAddress - address of KeysManager contract.
  • Make a call to KeysManager init with _previousKeysManager parameter equal to 0x0000000000000000000000000000000000000000, using the address of EternalStorageProxy and ABI of KeysManager.
  • BallotsStorage_flat.sol - Deploy BallotsStorage contract.
  • EternalStorageProxy_flat.sol - Deploy EternalStorageProxy contract with constructor parameters:
    _proxyStorage - address of ProxyStorage contract, _implementationAddress - address of BallotsStorage contract.
  • Make a call to BallotsStorage init with _thresholds parameter equal to [3, 2], using the address of EternalStorageProxy and ABI of BallotsStorage.
  • VotingToChangeKeys_flat.sol - Deploy VotingToChangeKeys contract.
  • EternalStorageProxy_flat.sol - Deploy EternalStorageProxy contract with constructor parameters:
    _proxyStorage - address of ProxyStorage contract, _implementationAddress - address of VotingToChangeKeys contract.
  • Make a call to VotingToChangeKeys init with _minBallotDuration parameter equal to 172800, using the address of EternalStorageProxy and ABI of VotingToChangeKeys.
  • Make a call to VotingToChangeKeys migrateDisable, using the address of EternalStorageProxy and ABI of VotingToChangeKeys.
  • VotingToChangeMinThreshold_flat.sol - Deploy VotingToChangeMinThreshold contract.
  • EternalStorageProxy_flat.sol - Deploy EternalStorageProxy contract with constructor parameters:
    _proxyStorage - address of ProxyStorage contract, _implementationAddress - address of VotingToChangeMinThreshold contract.
  • Make a call to VotingToChangeMinThreshold init with _minBallotDuration parameter equal to 172800 and _minPossibleThreshold parameter equal to 3, using the address of EternalStorageProxy and ABI of VotingToChangeMinThreshold.
  • Make a call to VotingToChangeMinThreshold migrateDisable, using the address of EternalStorageProxy and ABI of VotingToChangeMinThreshold.
  • VotingToChangeProxyAddress_flat.sol - Deploy VotingToChangeProxyAddress contract.
  • EternalStorageProxy_flat.sol - Deploy EternalStorageProxy contract with constructor parameters:
    _proxyStorage - address of ProxyStorage contract, _implementationAddress - address of VotingToChangeProxyAddress contract.
  • Make a call to VotingToChangeProxyAddress init with _minBallotDuration parameter equal to 172800, using the address of EternalStorageProxy and ABI of VotingToChangeProxyAddress.
  • Make a call to VotingToChangeProxyAddress migrateDisable, using the address of EternalStorageProxy and ABI of VotingToChangeProxyAddress.
  • ValidatorMetadata_flat.sol - Deploy ValidatorMetadata contract.
  • EternalStorageProxy_flat.sol - Deploy EternalStorageProxy contract with constructor parameters:
    _proxyStorage - address of ProxyStorage contract, _implementationAddress - address of ValidatorMetadata contract.
  • VotingToManageEmissionFunds_flat.sol - Deploy VotingToManageEmissionFunds contract.
  • EternalStorageProxy_flat.sol - Deploy EternalStorageProxy contract with constructor parameters:
    _proxyStorage - address of ProxyStorage contract, _implementationAddress - address of VotingToManageEmissionFunds contract.
  • EmissionFunds_flat.sol - Deploy EmissionFunds contract with constructor parameter _votingToManageEmissionFunds equal to EternalStorageProxy address of VotingToManageEmissionFunds contract.
  • RewardByBlock_flat.sol - Deploy RewardByBlock contract and replace emissionFunds constant value 0x00... inside it with the address of deployed EmissionFunds. Then deploy RewardByBlock.
  • EternalStorageProxy_flat.sol - Deploy EternalStorageProxy contract with constructor parameters:
    _proxyStorage - address of ProxyStorage contract, _implementationAddress - address of RewardByBlock contract.
  • Make a call to VotingToManageEmissionFunds init, using the address of EternalStorageProxy and ABI of VotingToManageEmissionFunds, with the next parameters:
    _emissionFunds - address of EmissionFunds contract, _emissionReleaseTime - your emission release unix timestamp, _emissionReleaseThreshold - your emission release threshold in seconds, _distributionThreshold - your distribution threshold in seconds.
  • Select deployed ProxyStorage contract and make a call from MoC address to initializeAddresses with relevant addresses.

Unit tests

Full Test Report

  Contract: BallotsStorage [all features]
    #init
      ✓ prevent from double init
      ✓ thresholds are correct (40ms)
    #migrate
      ✓ should copy thresholds from an old contract (282ms)
    #setThreshold
      ✓ can only be called from votingToChangeThreshold address (66ms)
      ✓ cannot be set for Invalid threshold (200ms)
      ✓ new value cannot be equal to 0 (124ms)
      ✓ sets new value for Keys threshold (57ms)
      ✓ sets new value for MetadataChange threshold (71ms)
    #getProxyThreshold
      ✓ return value is correct (392ms)
      ✓ return value is correct if MoC is removed (1286ms)
    #getVotingToChangeThreshold
      ✓ returns voting to change min threshold address (71ms)
    #getBallotLimitPerValidator
      ✓ returns correct limit (253ms)
      ✓ returns correct limit if MoC is removed (1044ms)
    #upgradeTo
      ✓ may only be called by ProxyStorage (131ms)
      ✓ should change implementation address (145ms)
      ✓ should increment implementation version (125ms)
      ✓ new implementation should work (156ms)
      ✓ new implementation should use the same proxyStorage address (121ms)
      ✓ new implementation should use the same storage (157ms)
  Contract: BallotsStorage upgraded [all features]
    #init
      ✓ prevent from double init
      ✓ thresholds are correct
    #migrate
      ✓ should copy thresholds from an old contract (222ms)
    #setThreshold
      ✓ can only be called from votingToChangeThreshold address (58ms)
      ✓ cannot be set for Invalid threshold (181ms)
      ✓ new value cannot be equal to 0 (138ms)
      ✓ sets new value for Keys threshold (53ms)
      ✓ sets new value for MetadataChange threshold (66ms)
    #getProxyThreshold
      ✓ return value is correct (370ms)
      ✓ return value is correct if MoC is removed (1220ms)
    #getVotingToChangeThreshold
      ✓ returns voting to change min threshold address (51ms)
    #getBallotLimitPerValidator
      ✓ returns correct limit (243ms)
      ✓ returns correct limit if MoC is removed (1079ms)
  Contract: EmissionFunds [all features]
    constructor
      ✓ should save VotingToManageEmissionFunds address
    #fallback
      ✓ should receive funds (327ms)
    #sendFundsTo
      ✓ may only be called by VotingToManageEmissionFunds (39ms)
      ✓ should send funds to receiver (332ms)
      ✓ should send entire amount (339ms)
      ✓ should not send funds if amount greater than balance (319ms)
      ✓ should not send funds if amount is too much (312ms)
      ✓ should be fulfilled if receiver is 0x0 (168ms)
      ✓ should be fulfilled if amount is zero (328ms)
      ✓ should fail if receiver address is not full (664ms)
    #burnFunds
      ✓ may only be called by VotingToManageEmissionFunds
      ✓ should burn funds (163ms)
      ✓ should burn entire amount (165ms)
      ✓ should not burn funds if amount greater than balance (165ms)
      ✓ should not burn funds if amount is too much (263ms)
      ✓ should be fulfilled if amount is zero (159ms)
    #freezeFunds
      ✓ may only be called by VotingToManageEmissionFunds (45ms)
      ✓ should freeze funds (168ms)
      ✓ should be fulfilled if amount is zero (159ms)
  Contract: EternalStorageProxy [all features]
    constructor
      ✓ should revert if implementation address is equal to 0x0
      ✓ should allow ProxyStorage address equal to 0x0 (53ms)
      ✓ should set ProxyStorage address (52ms)
      ✓ should set implementation address (61ms)
      ✓ should set owner (42ms)
    #renounceOwnership
      ✓ may only be called by an owner
      ✓ should set owner to 0x0
    #transferOwnership
      ✓ may only be called by an owner (129ms)
      ✓ should change owner
      ✓ should not change owner if its address is 0x0
    #upgradeTo
      ✓ may only be called by ProxyStorage (41ms)
      ✓ should not change implementation address if it is the same
      ✓ should not change implementation address if it is 0x0
      ✓ should change implementation address
      ✓ should increment version (53ms)
  Contract: KeysManager [all features]
    #constructor
      ✓ sets masterOfCeremony, proxyStorage, poaConsensus (133ms)
      ✓ adds masterOfCeremony to validators hash
      ✓ cannot be called twice
    #initiateKeys
      ✓ can only be called by master of ceremony (104ms)
      ✓ cannot allow 0x0 addresses (57ms)
      ✓ should not allow to initialize already initialized key (74ms)
      ✓ should not allow to initialize already initialized key after validator created mining key (172ms)
      ✓ should not equal to master of ceremony
      ✓ should not allow to initialize more than maxNumberOfInitialKeys (595ms)
      ✓ should increment initialKeyCount by 1 (80ms)
      ✓ should set initialKeys hash to activated status (103ms)
    #createKeys
      ✓ should only be called from initialized key (162ms)
      ✓ params should not be equal to 0x0 (209ms)
      ✓ params should not be equal to each other (138ms)
      ✓ any of params should not be equal to initialKey (231ms)
      ✓ should not allow passing the same key after it is already created (355ms)
      ✓ should assign mining, voting, payout keys to relative mappings (184ms)
      ✓ should assign voting <-> mining key and payout <-> mining key relationships (156ms)
      ✓ adds validator to poaConsensus contract (156ms)
      ✓ should set validatorKeys hash (149ms)
      ✓ should set validatorKeys hash (148ms)
    #addMiningKey
      ✓ may only be called if KeysManager.init had been called before (85ms)
      ✓ should only be called from votingToChangeKeys (111ms)
      ✓ should not let add more than maxLimit (64ms)
      ✓ should set validatorKeys hash (92ms)
    #addVotingKey
      ✓ may only be called if KeysManager.init had been called before (125ms)
      ✓ may only be called if params are not the same (150ms)
      ✓ should add VotingKey (165ms)
      ✓ should only be called if mining is active (239ms)
      ✓ swaps keys if voting already exists (236ms)
    #addPayoutKey
      ✓ may only be called if KeysManager.init had been called before (132ms)
      ✓ may only be called if params are not the same (147ms)
      ✓ should add PayoutKey (175ms)
      ✓ should only be called if mining is active (321ms)
      ✓ swaps keys if voting already exists (252ms)
    #removeMiningKey
      ✓ may only be called if KeysManager.init had been called before (183ms)
      ✓ should remove miningKey (667ms)
      ✓ removes validator from poaConsensus (331ms)
      ✓ removes MoC from poaConsensus (1040ms)
      ✓ should still enforce removal of votingKey to 0x0 even if voting key did not exist (299ms)
    #removeVotingKey
      ✓ may only be called if KeysManager.init had been called before (208ms)
      ✓ should be successful only for active voting key (245ms)
      ✓ should remove votingKey (283ms)
    #removePayoutKey
      ✓ may only be called if KeysManager.init had been called before (215ms)
      ✓ should be successful only for active payout key (257ms)
      ✓ should remove payoutKey (274ms)
    #swapMiningKey
      ✓ should swap mining key (702ms)
      ✓ should swap MoC (352ms)
      ✓ should keep voting and payout keys (531ms)
    #swapVotingKey
      ✓ should swap voting key (221ms)
    #swapPayoutKey
      ✓ should swap payout key (256ms)
    #migrateInitialKey
      ✓ can copy initial keys (390ms)
    #migrateMiningKey
      ✓ copies validator keys (1208ms)
      ✓ throws when trying to copy invalid mining key (208ms)
    #upgradeTo
      ✓ may only be called by ProxyStorage (99ms)
      ✓ should change implementation address (174ms)
      ✓ should increment implementation version (89ms)
      ✓ new implementation should work (123ms)
      ✓ new implementation should use the same proxyStorage address (186ms)
      ✓ new implementation should use the same storage (324ms)
  Contract: KeysManager upgraded [all features]
    #constructor
      ✓ sets masterOfCeremony, proxyStorage, poaConsensus (169ms)
      ✓ adds masterOfCeremony to validators hash
      ✓ cannot be called twice
    #initiateKeys
      ✓ can only be called by master of ceremony (81ms)
      ✓ cannot allow 0x0 addresses (64ms)
      ✓ should not allow to initialize already initialized key (87ms)
      ✓ should not allow to initialize already initialized key after validator created mining key (185ms)
      ✓ should not equal to master of ceremony (44ms)
      ✓ should not allow to initialize more than maxNumberOfInitialKeys (674ms)
      ✓ should increment initialKeyCount by 1 (82ms)
      ✓ should set initialKeys hash to activated status (100ms)
    #createKeys
      ✓ should only be called from initialized key (182ms)
      ✓ params should not be equal to 0x0 (246ms)
      ✓ params should not be equal to each other (149ms)
      ✓ any of params should not be equal to initialKey (152ms)
      ✓ should not allow passing the same key after it is already created (380ms)
      ✓ should assign mining, voting, payout keys to relative mappings (171ms)
      ✓ should assign voting <-> mining key and payout <-> mining key relationships (187ms)
      ✓ adds validator to poaConsensus contract (154ms)
      ✓ should set validatorKeys hash (165ms)
      ✓ should set validatorKeys hash (247ms)
    #addMiningKey
      ✓ may only be called if KeysManager.init had been called before (88ms)
      ✓ should only be called from votingToChangeKeys (122ms)
      ✓ should not let add more than maxLimit (50ms)
      ✓ should set validatorKeys hash (108ms)
    #addVotingKey
      ✓ may only be called if KeysManager.init had been called before (117ms)
      ✓ may only be called if params are not the same (156ms)
      ✓ should add VotingKey (179ms)
      ✓ should only be called if mining is active (239ms)
      ✓ swaps keys if voting already exists (238ms)
    #addPayoutKey
      ✓ may only be called if KeysManager.init had been called before (145ms)
      ✓ may only be called if params are not the same (143ms)
      ✓ should add PayoutKey (169ms)
      ✓ should only be called if mining is active (344ms)
      ✓ swaps keys if voting already exists (251ms)
    #removeMiningKey
      ✓ may only be called if KeysManager.init had been called before (181ms)
      ✓ should remove miningKey (707ms)
      ✓ removes validator from poaConsensus (348ms)
      ✓ removes MoC from poaConsensus (1048ms)
      ✓ should still enforce removal of votingKey to 0x0 even if voting key did not exist (308ms)
    #removeVotingKey
      ✓ may only be called if KeysManager.init had been called before (216ms)
      ✓ should be successful only for active voting key (229ms)
      ✓ should remove votingKey (377ms)
    #removePayoutKey
      ✓ may only be called if KeysManager.init had been called before (206ms)
      ✓ should be successful only for active payout key (231ms)
      ✓ should remove payoutKey (260ms)
    #swapMiningKey
      ✓ should swap mining key (737ms)
      ✓ should swap MoC (384ms)
      ✓ should keep voting and payout keys (523ms)
    #swapVotingKey
      ✓ should swap voting key (230ms)
    #swapPayoutKey
      ✓ should swap payout key (283ms)
    #migrateInitialKey
      ✓ can copy initial keys (445ms)
    #migrateMiningKey
      ✓ copies validator keys (1228ms)
      ✓ throws when trying to copy invalid mining key (205ms)
  Contract: ValidatorMetadata [all features]
    #createMetadata
      ✓ happy path (170ms)
      ✓ should not let create metadata if fullAddress is too long (200ms)
      ✓ should not let create metadata if called by non-voting key (86ms)
      ✓ should not let create metadata if called second time (153ms)
    #clearMetadata
      ✓ happy path (770ms)
    #moveMetadata
      ✓ happy path (1142ms)
    #initMetadata
      ✓ happy path (441ms)
    #changeRequest
      ✓ happy path (248ms)
      ✓ should not let call if there is no metadata
      ✓ resets confirmations when changeRequest recreated (515ms)
    #cancelPendingChange
      ✓ happy path (473ms)
      ✓ should not let delete records for someone else miningKey (490ms)
    #confirmPendingChange
      ✓ should not let confirm your own changes (236ms)
      ✓ should confirm changes (316ms)
      ✓ prevent from double voting (337ms)
      ✓ should not exceed confirmations limit (577ms)
    #finalize
      ✓ happy path (758ms)
    #getMinThreshold
      ✓ returns default value
    #upgradeTo
      ✓ may only be called by ProxyStorage (82ms)
      ✓ should change implementation address (79ms)
      ✓ should increment implementation version (80ms)
      ✓ new implementation should work (120ms)
      ✓ new implementation should use the same proxyStorage address (80ms)
      ✓ new implementation should use the same storage (321ms)
  Contract: ValidatorMetadata upgraded [all features]
    #createMetadata
      ✓ happy path (169ms)
      ✓ should not let create metadata if fullAddress is too long (210ms)
      ✓ should not let create metadata if called by non-voting key (88ms)
      ✓ should not let create metadata if called second time (145ms)
    #clearMetadata
      ✓ happy path (677ms)
    #moveMetadata
      ✓ happy path (1014ms)
    #initMetadata
      ✓ happy path (553ms)
    #changeRequest
      ✓ happy path (165ms)
      ✓ should not let call if there is no metadata
      ✓ resets confirmations when changeRequest recreated (495ms)
    #cancelPendingChange
      ✓ happy path (586ms)
      ✓ should not let delete records for someone else miningKey (490ms)
    #confirmPendingChange
      ✓ should not let confirm your own changes (415ms)
      ✓ should confirm changes (310ms)
      ✓ prevent from double voting (383ms)
      ✓ should not exceed confirmations limit (608ms)
    #finalize
      ✓ happy path (760ms)
    #getMinThreshold
      ✓ returns default value
  Contract: PoaNetworkConsensus [all features]
    default values
      ✓ finalized should be false
      ✓ checks systemAddress
      ✓ allows you to set current list of validators (87ms)
      ✓ validators in the list must differ (129ms)
    #finalizeChange
      ✓ should only be called by systemAddress (79ms)
      ✓ should set finalized to true (73ms)
      ✓ should set currentValidators to pendingList (78ms)
      ✓ set currentValidators to pendingList after addValidator call (301ms)
    #addValidator
      ✓ should only be called from keys manager (63ms)
      ✓ should not allow to add already existing validator (78ms)
      ✓ should not allow 0x0 addresses (74ms)
      ✓ should set validatorsState for new validator (80ms)
      ✓ should set finalized to false (72ms)
      ✓ should emit InitiateChange with blockhash and pendingList as params (284ms)
    #swapValidatorKey
      ✓ should swap validator key (294ms)
      ✓ should swap MoC (271ms)
    #removeValidator
      ✓ should remove validator (95ms)
      ✓ should remove MoC (249ms)
      ✓ should only be called from keys manager (112ms)
      ✓ should only be allowed to remove from existing set of validators (46ms)
      ✓ should decrease length of pendingList (258ms)
      ✓ should change validatorsState (100ms)
      ✓ should set finalized to false (114ms)
    #setProxyStorage
      ✓ can be called by MoC (62ms)
      ✓ can be called by owner (67ms)
      ✓ can only be called once
      ✓ cannot be set to 0x0 address
      ✓ sets proxyStorage (51ms)
      ✓ sets wasProxyStorageSet (47ms)
      ✓ emits MoCInitializedProxyStorage (38ms)
      ✓ #getKeysManager (58ms)
    #isValidator
      ✓ returns true for validator
    #isValidatorFinalized
      ✓ returns true for finalized validator (1654ms)
  Contract: ProxyStorage [all features]
    #constructor
      ✓ sets PoA
    #initializeAddresses
      ✓ sets all addresses (158ms)
      ✓ prevents Moc to call it more than once (89ms)
    #setContractAddress
      ✓ can only be called from votingToChangeProxy address (93ms)
      ✓ cannot be set to 0x0 address (69ms)
      ✓ sets keysManager (142ms)
      ✓ sets votingToChangeKeys (154ms)
      ✓ sets votingToChangeMinThreshold (253ms)
      ✓ sets ballotsStorage (142ms)
      ✓ sets poaConsensus (81ms)
      ✓ sets validatorMetadata (227ms)
      ✓ changes proxyStorage (itself) implementation (205ms)
    #upgradeTo
      ✓ may only be called by ProxyStorage (itself) (119ms)
      ✓ should change implementation address (115ms)
      ✓ should increment implementation version (127ms)
      ✓ new implementation should work (168ms)
      ✓ new implementation should use the same storage (182ms)
  Contract: ProxyStorage upgraded [all features]
    #constructor
      ✓ sets PoA
    #initializeAddresses
      ✓ sets all addresses (165ms)
      ✓ prevents Moc to call it more than once (81ms)
    #setContractAddress
      ✓ can only be called from votingToChangeProxy address (180ms)
      ✓ cannot be set to 0x0 address (67ms)
      ✓ sets keysManager (158ms)
      ✓ sets votingToChangeKeys (163ms)
      ✓ sets votingToChangeMinThreshold (144ms)
      ✓ sets ballotsStorage (253ms)
      ✓ sets poaConsensus (81ms)
      ✓ sets validatorMetadata (172ms)
      ✓ changes proxyStorage (itself) implementation (145ms)
  Contract: RewardByBlock [all features]
    #reward
      ✓ may only be called by system address (94ms)
      ✓ should revert if input array contains more than one item
      ✓ should revert if lengths of input arrays are not equal (38ms)
      ✓ should revert if `kind` parameter is not 0
      ✓ should revert if mining key does not exist (252ms)
      ✓ should assign rewards to payout key and EmissionFunds (88ms)
      ✓ should assign reward to mining key if payout key is 0 (143ms)
      ✓ should assign rewards to extra receivers and clear extra receivers list (369ms)
    #addExtraReceiver
      ✓ may only be called by bridge contract (59ms)
      ✓ should revert if receiver address is 0x0
      ✓ should revert if amount is 0 (39ms)
      ✓ can only be called once for the same recipient (79ms)
      ✓ should add receivers (214ms)
    #upgradeTo
      ✓ may only be called by ProxyStorage (111ms)
      ✓ should change implementation address (111ms)
      ✓ should increment implementation version (116ms)
      ✓ new implementation should work (154ms)
      ✓ new implementation should use the same proxyStorage address (112ms)
  Contract: RewardByBlock upgraded [all features]
    #reward
      ✓ may only be called by system address (89ms)
      ✓ should revert if input array contains more than one item
      ✓ should revert if lengths of input arrays are not equal (46ms)
      ✓ should revert if `kind` parameter is not 0 (48ms)
      ✓ should revert if mining key does not exist (246ms)
      ✓ should assign rewards to payout key and EmissionFunds (81ms)
      ✓ should assign reward to mining key if payout key is 0 (121ms)
      ✓ should assign rewards to extra receivers and clear extra receivers list (421ms)
    #addExtraReceiver
      ✓ may only be called by bridge contract (68ms)
      ✓ should revert if receiver address is 0x0 (45ms)
      ✓ should revert if amount is 0 (47ms)
      ✓ can only be called once for the same recipient (72ms)
      ✓ should add receivers (199ms)
  Contract: RewardByTime [all features]
    #reward
      ✓ may only be called by system address (152ms)
      ✓ should assign rewards to payout keys and EmissionFunds (3292ms)
      ✓ should work fine after some validators are removed and added (1355ms)
    #upgradeTo
      ✓ may only be called by ProxyStorage (108ms)
      ✓ should change implementation address (111ms)
      ✓ should increment implementation version (112ms)
      ✓ new implementation should work (259ms)
      ✓ new implementation should use the same proxyStorage address (113ms)
  Contract: RewardByTime upgraded [all features]
    #reward
      ✓ may only be called by system address (150ms)
      ✓ should assign rewards to payout keys and EmissionFunds (3160ms)
      ✓ should work fine after some validators are removed and added (1459ms)
  Contract: Voting to change keys [all features]
    #createBallot
      ✓ happy path (705ms)
      ✓ should not let create voting with invalid duration (170ms)
      ✓ should not let add votingKey for MoC (416ms)
      ✓ should not let add votingKey for 0x0 (447ms)
      ✓ should not let add payoutKey for 0x0 (588ms)
      ✓ should not let create more ballots than the limit (10140ms)
    #createBallotToAddNewValidator
      ✓ happy path (296ms)
      ✓ deny adding already existed voting key
      ✓ deny adding already existed payout key (199ms)
      ✓ should create validator with all keys after finalization (1282ms)
      ✓ should allow removing new validator if finalizeChange did not happen (2249ms)
    #vote
      ✓ should let a validator to vote (194ms)
      ✓ reject vote should be accepted (199ms)
      ✓ should allow multiple voters to vote (875ms)
      ✓ should not let vote nonVoting key (57ms)
      ✓ should not let vote before startTime key (102ms)
      ✓ should not let vote after endTime key (97ms)
      ✓ should not let vote with already voted key (271ms)
      ✓ should not let vote with invalid choice (267ms)
      ✓ should not let vote with invalid id (170ms)
    #finalize
      ✓ happy path - no action since it did not meet minimum number of totalVoters (803ms)
      ✓ finalize addition of payout key (933ms)
      ✓ finalize addition of VotingKey (1027ms)
      ✓ cannot create ballot for using previous mining key (2257ms)
      ✓ finalize addition of MiningKey (1144ms)
      ✓ finalize removal of MiningKey (2097ms)
      ✓ finalize removal of VotingKey (1237ms)
      ✓ finalize removal of PayoutKey (1178ms)
      ✓ finalize swap of VotingKey (1216ms)
      ✓ finalize swap of PayoutKey (1178ms)
      ✓ finalize swap of MiningKey (1373ms)
      ✓ prevent double finalize (1841ms)
      ✓ allowed at once after all validators gave their votes (1730ms)
    #migrate
      ✓ should copy a ballot to the new contract (2013ms)
    #upgradeTo
      ✓ may only be called by ProxyStorage (98ms)
      ✓ should change implementation address (101ms)
      ✓ should increment implementation version (98ms)
      ✓ new implementation should work (148ms)
      ✓ new implementation should use the same proxyStorage address (186ms)
      ✓ new implementation should use the same storage (963ms)
  Contract: Voting to change keys upgraded [all features]
    #createBallot
      ✓ happy path (782ms)
      ✓ should not let create voting with invalid duration (187ms)
      ✓ should not let add votingKey for MoC (624ms)
      ✓ should not let add votingKey for 0x0 (518ms)
      ✓ should not let add payoutKey for 0x0 (480ms)
      ✓ should not let create more ballots than the limit (10430ms)
    #createBallotToAddNewValidator
      ✓ happy path (316ms)
      ✓ deny adding already existed voting key
      ✓ deny adding already existed payout key (227ms)
      ✓ should create validator with all keys after finalization (1418ms)
      ✓ should allow removing new validator if finalizeChange did not happen (2165ms)
    #vote
      ✓ should let a validator to vote (190ms)
      ✓ reject vote should be accepted (196ms)
      ✓ should allow multiple voters to vote (831ms)
      ✓ should not let vote nonVoting key (57ms)
      ✓ should not let vote before startTime key (93ms)
      ✓ should not let vote after endTime key (94ms)
      ✓ should not let vote with already voted key (191ms)
      ✓ should not let vote with invalid choice (179ms)
      ✓ should not let vote with invalid id (173ms)
    #finalize
      ✓ happy path - no action since it did not meet minimum number of totalVoters (830ms)
      ✓ finalize addition of payout key (910ms)
      ✓ finalize addition of VotingKey (1022ms)
      ✓ cannot create ballot for using previous mining key (2234ms)
      ✓ finalize addition of MiningKey (1023ms)
      ✓ finalize removal of MiningKey (2017ms)
      ✓ finalize removal of VotingKey (1237ms)
      ✓ finalize removal of PayoutKey (1142ms)
      ✓ finalize swap of VotingKey (1172ms)
      ✓ finalize swap of PayoutKey (1155ms)
      ✓ finalize swap of MiningKey (1503ms)
      ✓ prevent double finalize (1828ms)
      ✓ allowed at once after all validators gave their votes (1722ms)
    #migrate
      ✓ should copy a ballot to the new contract (2024ms)
  Contract: VotingToChangeMinThreshold [all features]
    #createBallot
      ✓ happy path (377ms)
      ✓ proposed value should be more than or equal to 3
      ✓ proposed value should not be equal to the same value
      ✓ should not let create more ballots than the limit (10284ms)
    #vote
      ✓ should let a validator to vote (181ms)
      ✓ reject vote should be accepted (407ms)
      ✓ should allow multiple voters to vote (422ms)
      ✓ should not let vote nonVoting key (69ms)
      ✓ should not let vote before startTime key (91ms)
      ✓ should not let vote after endTime key (95ms)
      ✓ should not let vote with already voted key (209ms)
      ✓ should not let vote with invalid choice (166ms)
      ✓ should not let vote with invalid id (169ms)
    #finalize
      ✓ does not change if it did not pass minimum threshold (561ms)
      ✓ should change to proposedValue when quorum is reached (1253ms)
      ✓ prevents double finalize (1671ms)
      ✓ allowed at once after all validators gave their votes (2039ms)
      ✓ should decrease validator limit only once when calling finalize more than once (1589ms)
    #migrate
      ✓ should copy a ballot to the new contract (1495ms)
    #upgradeTo
      ✓ may only be called by ProxyStorage (77ms)
      ✓ should change implementation address (93ms)
      ✓ should increment implementation version (91ms)
      ✓ new implementation should work (120ms)
      ✓ new implementation should use the same proxyStorage address (89ms)
      ✓ new implementation should use the same storage (585ms)
  Contract: VotingToChangeMinThreshold upgraded [all features]
    #createBallot
      ✓ happy path (271ms)
      ✓ proposed value should be more than or equal to 3 (133ms)
      ✓ proposed value should not be equal to the same value
      ✓ should not let create more ballots than the limit (10305ms)
    #vote
      ✓ should let a validator to vote (194ms)
      ✓ reject vote should be accepted (190ms)
      ✓ should allow multiple voters to vote (481ms)
      ✓ should not let vote nonVoting key (51ms)
      ✓ should not let vote before startTime key (108ms)
      ✓ should not let vote after endTime key (108ms)
      ✓ should not let vote with already voted key (193ms)
      ✓ should not let vote with invalid choice (182ms)
      ✓ should not let vote with invalid id (262ms)
    #finalize
      ✓ does not change if it did not pass minimum threshold (560ms)
      ✓ should change to proposedValue when quorum is reached (1312ms)
      ✓ prevents double finalize (1806ms)
      ✓ allowed at once after all validators gave their votes (2331ms)
      ✓ should decrease validator limit only once when calling finalize more than once (1595ms)
    #migrate
      ✓ should copy a ballot to the new contract (1508ms)
  Contract: VotingToChangeProxyAddress [all features]
    #createBallot
      ✓ happy path (278ms)
      ✓ proposed address should not be 0x0
      ✓ can create multiple ballots (489ms)
      ✓ should not let create more ballots than the limit (9893ms)
    #vote
      ✓ should let a validator to vote (183ms)
      ✓ reject vote should be accepted (284ms)
      ✓ should allow multiple voters to vote (852ms)
      ✓ should not let vote nonVoting key (52ms)
      ✓ should not let vote before startTime key (103ms)
      ✓ should not let vote after endTime key (97ms)
      ✓ should not let vote with already voted key (195ms)
      ✓ should not let vote with invalid choice (181ms)
      ✓ should not let vote with invalid id (180ms)
    #finalize
      ✓ does not change if it did not pass minimum threshold (598ms)
      ✓ should change KeysManager implementation (920ms)
      ✓ should change VotingToChangeKeys implementation (1053ms)
      ✓ should change VotingToChangeMinThreshold implementation (995ms)
      ✓ should change VotingToChangeProxy implementation (1083ms)
      ✓ should change BallotsStorage implementation (1075ms)
      ✓ should change ValidatorMetadata implementation (1062ms)
      ✓ should change ProxyStorage implementation (1068ms)
      ✓ prevents double finalize (1513ms)
      ✓ allowed at once after all validators gave their votes (1768ms)
    #migrate
      ✓ should copy a ballot to the new contract (1995ms)
    #upgradeTo
      ✓ may only be called by ProxyStorage (88ms)
      ✓ should change implementation address (87ms)
      ✓ should increment implementation version (113ms)
      ✓ new implementation should work (139ms)
      ✓ new implementation should use the same proxyStorage address (86ms)
      ✓ new implementation should use the same storage (620ms)
  Contract: VotingToChangeProxyAddress upgraded [all features]
    #createBallot
      ✓ happy path (395ms)
      ✓ proposed address should not be 0x0 (119ms)
      ✓ can create multiple ballots (394ms)
      ✓ should not let create more ballots than the limit (10105ms)
    #vote
      ✓ should let a validator to vote (179ms)
      ✓ reject vote should be accepted (194ms)
      ✓ should allow multiple voters to vote (805ms)
      ✓ should not let vote nonVoting key (55ms)
      ✓ should not let vote before startTime key (103ms)
      ✓ should not let vote after endTime key (213ms)
      ✓ should not let vote with already voted key (224ms)
      ✓ should not let vote with invalid choice (225ms)
      ✓ should not let vote with invalid id (196ms)
    #finalize
      ✓ does not change if it did not pass minimum threshold (684ms)
      ✓ should change KeysManager implementation (1177ms)
      ✓ should change VotingToChangeKeys implementation (1182ms)
      ✓ should change VotingToChangeMinThreshold implementation (1065ms)
      ✓ should change VotingToChangeProxy implementation (1115ms)
      ✓ should change BallotsStorage implementation (985ms)
      ✓ should change ValidatorMetadata implementation (1082ms)
      ✓ should change ProxyStorage implementation (1080ms)
      ✓ prevents double finalize (1522ms)
      ✓ allowed at once after all validators gave their votes (1686ms)
    #migrate
      ✓ should copy a ballot to the new contract (2022ms)
  Contract: VotingToManageEmissionFunds [all features]
    #init
      ✓ should change state correctly (119ms)
      ✓ cannot be called more than once
    #createBallot
      ✓ happy path (866ms)
      ✓ may only be called by valid voting key (139ms)
      ✓ endTime must be greater than startTime
      ✓ startTime must be greater than current time (39ms)
      ✓ cannot be called before emission release time (64ms)
      ✓ ballot cannot last longer than distribution threshold (55ms)
      ✓ receiver address should not be 0x0 (64ms)
      ✓ cannot create multiple ballots during the same distribution period (435ms)
      ✓ should allow creating new ballot after the next emission release threshold (490ms)
    #cancelNewBallot
      ✓ happy path (880ms)
      ✓ cannot cancel nonexistent or finalized ballot (341ms)
      ✓ may only be called by creator of a ballot (232ms)
      ✓ may only be called within ballot canceling threshold (265ms)
      ✓ cannot cancel already cancelled ballot (221ms)
      ✓ should restore emission release time (493ms)
    #refreshEmissionReleaseTime
      ✓ should not update until the next threshold (130ms)
      ✓ should update to the next threshold (72ms)
      ✓ should update to the future threshold (86ms)
    #vote
      ✓ should let a validator to vote (959ms)
      ✓ should allow multiple voters to vote (1497ms)
      ✓ should not let vote by nonvoting key (57ms)
      ✓ should not let vote before startTime (94ms)
      ✓ should not let vote after endTime (260ms)
      ✓ should not let vote with already voted key (207ms)
      ✓ should not let vote with invalid choice (152ms)
      ✓ should not let vote with invalid id (164ms)
      ✓ should not let vote if already finalized (1535ms)
      ✓ should not let vote with old miningKey (2431ms)
      ✓ should not let vote if ballot is canceled (256ms)
    #finalize
      ✓ happy path (591ms)
      ✓ freeze funds if it did not pass minimum voters count (1036ms)
      ✓ freeze funds if there is no majority of 3 votes (1322ms)
      ✓ freeze funds if there is no majority of 4 votes (1678ms)
      ✓ send funds to receiver if most votes are for sending (2089ms)
      ✓ send funds to receiver if most votes are for sending (1749ms)
      ✓ burn funds if most votes are for burning (1704ms)
      ✓ prevents finalize with invalid id (280ms)
      ✓ do not let finalize if a ballot is active (189ms)
      ✓ finalize immediately if the last validator gave his vote (1187ms)
      ✓ does not finalize immediately until ballot canceling threshold is reached (1236ms)
      ✓ prevents double finalize (279ms)
      ✓ should refresh emission release time (256ms)
      ✓ deny finalization if the voting key is a contract (703ms)
      ✓ deny finalization within ballot canceling threshold (301ms)
      ✓ deny finalization of canceled ballot (461ms)
    #upgradeTo
      ✓ may only be called by ProxyStorage (91ms)
      ✓ should change implementation address (92ms)
      ✓ should increment implementation version (91ms)
      ✓ new implementation should work (129ms)
      ✓ new implementation should use the same proxyStorage address (92ms)
      ✓ new implementation should use the same storage (960ms)
  Contract: VotingToManageEmissionFunds upgraded [all features]
    #init
      ✓ should change state correctly (111ms)
      ✓ cannot be called more than once
    #createBallot
      ✓ happy path (835ms)
      ✓ may only be called by valid voting key (142ms)
      ✓ endTime must be greater than startTime (45ms)
      ✓ startTime must be greater than current time (126ms)
      ✓ cannot be called before emission release time (64ms)
      ✓ ballot cannot last longer than distribution threshold (41ms)
      ✓ receiver address should not be 0x0 (52ms)
      ✓ cannot create multiple ballots during the same distribution period (467ms)
      ✓ should allow creating new ballot after the next emission release threshold (464ms)
    #cancelNewBallot
      ✓ happy path (878ms)
      ✓ cannot cancel nonexistent or finalized ballot (300ms)
      ✓ may only be called by creator of a ballot (290ms)
      ✓ may only be called within ballot canceling threshold (250ms)
      ✓ cannot cancel already cancelled ballot (244ms)
      ✓ should restore emission release time (601ms)
    #refreshEmissionReleaseTime
      ✓ should not update until the next threshold (129ms)
      ✓ should update to the next threshold (273ms)
      ✓ should update to the future threshold (72ms)
    #vote
      ✓ should let a validator to vote (842ms)
      ✓ should allow multiple voters to vote (1572ms)
      ✓ should not let vote by nonvoting key (60ms)
      ✓ should not let vote before startTime (89ms)
      ✓ should not let vote after endTime (253ms)
      ✓ should not let vote with already voted key (202ms)
      ✓ should not let vote with invalid choice (173ms)
      ✓ should not let vote with invalid id (155ms)
      ✓ should not let vote if already finalized (1404ms)
      ✓ should not let vote with old miningKey (2283ms)
      ✓ should not let vote if ballot is canceled (152ms)
    #finalize
      ✓ happy path (569ms)
      ✓ freeze funds if it did not pass minimum voters count (1142ms)
      ✓ freeze funds if there is no majority of 3 votes (1393ms)
      ✓ freeze funds if there is no majority of 4 votes (1872ms)
      ✓ send funds to receiver if most votes are for sending (2304ms)
      ✓ send funds to receiver if most votes are for sending (1816ms)
      ✓ burn funds if most votes are for burning (1898ms)
      ✓ prevents finalize with invalid id (209ms)
      ✓ do not let finalize if a ballot is active (211ms)
      ✓ finalize immediately if the last validator gave his vote (1281ms)
      ✓ does not finalize immediately until ballot canceling threshold is reached (1316ms)
      ✓ prevents double finalize (292ms)
      ✓ should refresh emission release time (265ms)
      ✓ deny finalization if the voting key is a contract (737ms)
      ✓ deny finalization within ballot canceling threshold (305ms)
      ✓ deny finalization of canceled ballot (284ms)
  598 passing (18m)

poa-network-consensus-contracts's People

Contributors

eenae avatar igorbarinov avatar maxaleks avatar rstormsf avatar varasev avatar vbaranov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

poa-network-consensus-contracts's Issues

License status

Hi! Do you have a license defined for this repository? I want to use these contracts with another project.

VOTING_START_DATE issue in test/voting_to_change_*.js

VOTING_START_DATE must be equal to the current timestamp plus more than 2 seconds. Let's make the offset equal to 20 seconds:

VOTING_START_DATE = moment.utc().add(20, 'seconds').unix();

instead of

VOTING_START_DATE = moment.utc().add(2, 'seconds').unix();

Two seconds is a very small amount. This can cause revert on the next line in voting contracts:

require(_endTime > _startTime && _startTime > getTime());

I ran into this problem when running tests on a weak machine. Some tests did not have time to start before 2 seconds have elapsed since VOTING_START_DATE was initialized.

Here is the corresponding commit in my repo: varasev@8ae8b59

I will make a pull request later.

(Update) Steps to deploy and migrate all upgradable contracts to the network

The next steps need to be taken to update all contracts on the network after we finish making them upgradable and after security audit is done.

These steps are implemented inside scripts/migrate/migrateAll.js: https://github.com/varasev/poa-network-consensus-contracts/blob/master/scripts/migrate/migrateAll.js

  1. Deploy PoaNetworkConsensus contract with the current MoC and the current mining keys list in constructor.

  2. Deploy ProxyStorage contract and call its init method with PoaNetworkConsensus address as a parameter.

  3. Call PoaNetworkConsensus.setProxyStorage with the address of ProxyStorage as a parameter.

  4. Run scripts/migrate/migrateKeys.js. It will deploy and initialize KeysManager contract and migrate all keys from an old KeysManager contract.

  5. Run scripts/migrate/migrateVotings.js. It will deploy and initialize BallotsStorage, VotingToChangeKeys, VotingToChangeMinThreshold and VotingToChangeProxyAddress contracts and migrate all thresholds and ballots from old contracts.

  6. Deploy ValidatorMetadata.

  7. Call ProxyStorage.initializeAddresses method.

  8. Run scripts/migrate/migrateMetadataNew.js.

(Feature) Make ValidatorMetadata upgradable

ValidatorMetadata contract made upgradable. The changes are in my repo: https://github.com/varasev/poa-network-consensus-contracts/blob/master/contracts/ValidatorMetadata.sol

All the current tests are passing.

The next solution from zeppelinos (thanks!) was used: https://github.com/zeppelinos/labs/tree/master/upgradeability_using_generic_eternal_storage

It is an awesome solution to separate an implementation from a storage! Now we can change contract's implementation and keep it's storage.

We need only two additional contracts for this: https://github.com/varasev/poa-network-consensus-contracts/tree/master/contracts/eternal-storage

It is planned that EternalStorageProxy.upgradeTo function will be called from ProxyStorage contract when the voters agree with implementation changing in VotingToChangeProxyAddress contract.

We can also do this with other contracts soon.

(Feature) Make ProxyStorage upgradable

We must make the ProxyStorage contract upgradable because it is a crucial contract that connects all other contracts and we may want to change its implementation in the future.

I made a related commit in my repository today: varasev@e115d03

All tests are successful: https://travis-ci.org/varasev/poa-network-consensus-contracts/builds/373019590

The ability to change ProxyStorage implementation address was added in ProxyStorage's setContractAddress method. Note that we use this keyword to call upgradeTo method inside the contract: https://github.com/varasev/poa-network-consensus-contracts/blob/e115d03d3e59a697ce127422acfb4f8b9643d765/contracts/ProxyStorage.sol#L136

The upgradeTo method may be called only by ProxyStorage contract itself: https://github.com/varasev/poa-network-consensus-contracts/blob/e115d03d3e59a697ce127422acfb4f8b9643d765/contracts/eternal-storage/EternalStorageProxy.sol#L66

We can achieve this approach with the same this keyword in EternalStorageProxy constructor: https://github.com/varasev/poa-network-consensus-contracts/blob/e115d03d3e59a697ce127422acfb4f8b9643d765/contracts/eternal-storage/EternalStorageProxy.sol#L34

When we deploy EternalStorageProxy, we can set _proxyStorage constructor's parameter equal to zero. That means that we want EternalStorageProxy to use its own address to filter msg.sender in upgradeTo method.

So, no one can call ProxyStorage's upgradeTo method - it can be called only by ProxyStorage inside it as I shown above: https://github.com/varasev/poa-network-consensus-contracts/blob/e115d03d3e59a697ce127422acfb4f8b9643d765/contracts/ProxyStorage.sol#L136

In this way, ProxyStorage implementation may be changed only by voting because setContractAddress method may be called only by VotingToChangeProxy contract: https://github.com/varasev/poa-network-consensus-contracts/blob/e115d03d3e59a697ce127422acfb4f8b9643d765/contracts/ProxyStorage.sol#L118

(Refactoring) redundant check in calculation of max from 3 numbers

Smart-contract layer: VotingToManageEmissionFunds.sol
Problem: https://github.com/poanetwork/poa-network-consensus-contracts/blob/security-audit/contracts/VotingToManageEmissionFunds.sol#L241-L242 - it seems, the check, that max > 0 is redundant. max can be greater or equal 0.
Solution: suggested implementation:

function _max(uint256 a, uint256 b, uint256 c) private pure returns(uint256) {
    uint256 max = a;
    if (b > max) {
        max = b;
    }
    if (c > max) {
        max = c;
    }
    return max;
}

(Refactor) Remove currentValidatorsLength from PoaNetworkConsensus contract

We can remove currentValidatorsLength variable from PoaNetworkConsensus.sol because it duplicates .length property of currentValidators array.

getCurrentValidatorsLength() should be:

function getCurrentValidatorsLength() public view returns(uint256) {
    return currentValidators.length;
}

After that we should fix test/keys_manager_test.js and test/poa_network_consensus_test.js to use getCurrentValidatorsLength() instead of currentValidatorsLength().

onlyFirstTime is incorrect

In ValidatorMetadata.sol the modifier onlyFirstTime doesn't use _votingKey parameter. In it's body the getMiningByVotingKey function accepts msg.sender instead of _votingKey:

modifier onlyFirstTime(address _votingKey) {
    address miningKey = getMiningByVotingKey(msg.sender);
    Validator storage validator = validators[miningKey];
    require(validator.createdDate == 0);
    _;
}

The correct code must be:

modifier onlyFirstTime(address _votingKey) {
    address miningKey = getMiningByVotingKey(_votingKey);
    Validator storage validator = validators[miningKey];
    require(validator.createdDate == 0);
    _;
}

(Refactor) initMetadata, createMetadata, changeRequestForValidator use common patterns

Problem:
initMetadata, createMetadata, changeRequestForValidator functions use common pattern:

_setFirstName(true, _miningKey, _firstName);
_setLastName(true, _miningKey, _lastName);
_setLicenseId(true, _miningKey, _licenseId);
_setState(true, _miningKey, _state);
_setFullAddress(true, _miningKey, _fullAddress);
_setZipcode(true, _miningKey, _zipcode);
_setExpirationDate(true, _miningKey, _expirationDate);

Solution: could be combined to one subfunction

(Refactor) define hardcoded names of Registry properties pointers only once

Problem: For example, keccak256("initDisabled") is utilized in BallotsStorage.sol twice: here https://github.com/poanetwork/poa-network-consensus-contracts/blob/security-audit/contracts/BallotsStorage.sol#L30 and here https://github.com/poanetwork/poa-network-consensus-contracts/blob/security-audit/contracts/BallotsStorage.sol#L101

Solution: suggestion is to define it once in constant and then reuse this constant: bytes32 internal constant INIT_DISABLED = keccak256("initDisabled");

(Refactoring) make getTotalNumberOfValidators private

Smart-contract layer: BallotsStorage.sol
Problem: getTotalNumberOfValidators() is public. It is only used internal. We already have public function getCurrentValidatorsLength() in PoaNetworkConsensus.sol, which returns the number of validators.
Solution: let' make getTotalNumberOfValidators() private.

ValidatorMetadata and it's storage address in contracts.json

@rstormsf @vbaranov

migrations/2_deploy_contract.js saves contracts addresses into contracts.json.

Now we have ValidatorMetadata contract address and EternalStorageProxy address: varasev@d9aa31e

Is it OK? Or we have to save only EternalStorageProxy address?

For example:

let contracts = {
  ...
  "METADATA_ADDRESS": EternalStorageProxy.address,
  ...
}

instead of

let contracts = {
  ...
  "METADATA_ADDRESS": ValidatorMetadata.address,
  "ETERNAL_STORAGE_PROXY": EternalStorageProxy.address,
  ...
}

I think the former is better because we need to know only the storage address to use ValidatorMetadata.

Hardcoded MoC in PoaNetworkConsensus contract

Hi! Im playing with your PoaNetworkConsensus contract and I don't understand one step.
Also Parity gets stuck in the process. If I change the constructor from:

function PoaNetworkConsensus(address _masterOfCeremony, address[] validators) public {
        // TODO: When you deploy this contract, make sure you hardcode items below
        // Make sure you have those addresses defined in spec.json
        require(_masterOfCeremony != address(0));
        masterOfCeremony = _masterOfCeremony;
        currentValidators = [masterOfCeremony];
        .... 
}

To:

function PoaNetworkConsensus(address[] validators) public {
        // TODO: When you deploy this contract, make sure you hardcode items below
        // Make sure you have those addresses defined in spec.json
        masterOfCeremony = 0x....;
        require(masterOfCeremony != address(0));
        currentValidators = [masterOfCeremony];
        .... 
}

It compiles well and I'm able to put the bytecode in the spec.json as a precompiled contract.
Then I start the network with: parity --config basictoml.toml
When I execute this command parity is loading the .toml file forever with 99% of CPU usage.
The rest of the contract is the same.

I don't know what happens because every time I set up a PoA, if the precompiled contract works bad, parity throws an exception. Possibly I made a mistake with the code mentioned before but im not sure.
Thank you in advance and forgive me if I did not understand well the solidity code.

(Fix) Handle MoC miningKey removing/swapping

The current smart contracts implementations don't handle the case when MoC miningKey can be removed or swapped. It's necessary to add such handling.

Note, that MoC may only be removed after all of the 12 initial keys are activated.

getProxyThreshold and getBallotLimitPerValidator methods of BallotsStorage contract must take into account that MoC may be removed. The same applies to vote method of VotingToManageEmissionFunds contract.

swapValidatorKey method of PoaNetworkConsensus contract must change the value of masterOfCeremony variable in case of MoC's key is changing.

PoaNetworkConsensus contract should store isMasterOfCeremonyRemoved boolean flag.

Also, it's necessary to cover these changes with unit tests.

Can't compile PoaNetworkConsensusContract with Remix

When I try to setup my own POA Network, I'm to able to proceed with following step:

Open Remix in your browser, copy-paste code from flat/PoaNetworkConsensus_flat.sol, press "Start to compile".
On "Run" tab select "Javascript VM" as environment, "PoaNetworkConsensus" as your contract, in "Create" field paste MoC's address "0x..." and click "Create"

When I enter my MoC address Remix will never come back with a valid feedback. It just hangs.

Tested with Chrome 63 on MBP

(Fix) make BallotTypes enum global for all ballot types

Problem: ballot types for changing threshold and proxy are defined as numbers: https://github.com/poanetwork/poa-network-consensus-contracts/blob/security-audit/contracts/VotingToChangeMinThreshold.sol#L22 and https://github.com/poanetwork/poa-network-consensus-contracts/blob/security-audit/contracts/VotingToChangeProxyAddress.sol#L18

Solution: let's define BallotTypes enum from https://github.com/poanetwork/poa-network-consensus-contracts/blob/security-audit/contracts/VotingToChangeKeys.sol#L9 globally (for example, in VotingToChange abstract) for all types of ballots and use named ballot types instead of numbers.

(Feature) new ballot type: add 3 keys

Problem: The current validators should create 3 ballots to add a completely new validator to consensus: 1 ballot for each key. Validators should make 3 times more actions to create, vote and finalize it instead of doing this stuff in frames of one ballot.

Solution: Create new ballot type to add 3 keys in /VotingToChangeKeys.sol

(Fix) there is no event if funds are frozen

Smart-contract layer: EmissionFunds.sol or VotingToManageEmissionFunds.sol
Problem: there is no event is emitted on finalization if validators have voted to freeze funds.
Solution: add method to EmissionFunds.sol which will emit FundsFrozen(uint256 amount) or implement emittance in _finalize method of VotingToManageEmissionFunds.sol

(Fix) Remove storing of MoC address from `KeysManager`

Smart contract layer: KeysManager.sol

Problem: KeysManager contract stores duplicated masterOfCeremony address which is already stored in PoaNetworkConsensus contract.

Solution: remove storing of MoC address from KeysManager contract and read it from PoaNetworkConsensus contract instead.

(Refactor) collapse master and demo branch

Problem: we use master branch for network and demo branch for poa-test-setup. Demo branch differs from master with the limits for ballots.
Solution: consider to use one master branch with the option to configure demo setup.

changeRequest and changeRequestForValidator functions should check zipcode

In ValidatorMetadata.sol these functions should check _zipcode for zero because we see the same condition in onlyIfChangeExist function:

function onlyIfChangeExist(address _miningKey) public view returns(bool) {
    return pendingChanges[_miningKey].zipcode > 0;
}

I suggest to use

require(_zipcode > 0);

at the beginning of changeRequest and changeRequestForValidator.

(Fix) Eliminate solhint errors in refactored contracts

Problem: There are a lot of errors from solhint checks in refactored contracts in security-audit branch.

Example:

./contracts/BlockReward.sol
   1:17  warning  Compiler version must be fixed                                       compiler-fixed
   8:1   error    Contract has 17 states declarations but allowed no more than 15      max-states-count
   9:5   warning  Explicitly mark visibility of state                                  state-visibility
  21:5   warning  Explicitly mark visibility of state                                  state-visibility
  22:9   error    Expected indentation of 4 spaces but found 8                         indent
  22:9   warning  Explicitly mark visibility of state                                  state-visibility
  23:9   error    Expected indentation of 4 spaces but found 8                         indent
  23:9   warning  Explicitly mark visibility of state                                  state-visibility
  24:9   error    Expected indentation of 4 spaces but found 8                         indent
  24:9   warning  Explicitly mark visibility of state                                  state-visibility
  25:9   error    Definitions inside contract / library must be separated by one line  separate-by-one-line-in-contract
  25:9   error    Expected indentation of 4 spaces but found 8                         indent
  27:9   error    Definitions inside contract / library must be separated by one line  separate-by-one-line-in-contract
  27:34  error    Expected indentation of 4 spaces but found 33                        indent
  27:9   error    Expected indentation of 4 spaces but found 8                         indent
  27:9   warning  Explicitly mark visibility of state                                  state-visibility
  27:34  warning  Explicitly mark visibility of state                                  state-visibility
  28:9   warning  Explicitly mark visibility of state                                  state-visibility
  28:9   error    Expected indentation of 4 spaces but found 8                         indent
  29:9   error    Expected indentation of 4 spaces but found 8                         indent
  29:38  warning  Explicitly mark visibility of state                                  state-visibility
  29:24  error    Variable name must be in mixedCase                                   var-name-mixedcase
  29:9   warning  Explicitly mark visibility of state                                  state-visibility
  29:38  error    Expected indentation of 4 spaces but found 37                        indent
  30:9   warning  Explicitly mark visibility of state                                  state-visibility
  30:9   error    Expected indentation of 4 spaces but found 8                         indent
  31:9   error    Expected indentation of 4 spaces but found 8                         indent
  31:9   warning  Explicitly mark visibility of state                                  state-visibility
  32:9   warning  Explicitly mark visibility of state                                  state-visibility
  32:9   error    Expected indentation of 4 spaces but found 8                         indent
  33:5   error    Expected indentation of 0 spaces but found 4                         indent
  35:42  error    Expected indentation of 0 spaces but found 41                        indent
  35:57  error    Expected indentation of 0 spaces but found 56                        indent
  35:14  error    Expected indentation of 0 spaces but found 13                        indent
  35:53  error    Expected indentation of 0 spaces but found 52                        indent
  35:51  error    Expected indentation of 0 spaces but found 50                        indent
  35:50  error    Expected indentation of 0 spaces but found 49                        indent
  35:44  error    Expected indentation of 0 spaces but found 43                        indent
  35:20  error    Expected indentation of 0 spaces but found 19                        indent
  35:31  error    Expected indentation of 0 spaces but found 30                        indent
  35:29  error    Expected indentation of 0 spaces but found 28                        indent
  35:28  error    Expected indentation of 0 spaces but found 27                        indent
  35:21  error    Expected indentation of 0 spaces but found 20                        indent
  35:5   error    Expected indentation of 0 spaces but found 4                         indent
  36:9   error    Expected indentation of 0 spaces but found 8                         indent
  37:9   error    Expected indentation of 0 spaces but found 8                         indent
  38:25  error    Expected indentation of 0 spaces but found 24                        indent
  38:18  error    Expected indentation of 0 spaces but found 17                        indent
  38:17  error    Expected indentation of 0 spaces but found 16                        indent
  38:9   error    Expected indentation of 0 spaces but found 8                         indent
  38:38  error    Expected indentation of 0 spaces but found 37                        indent
  38:36  error    Expected indentation of 0 spaces but found 35                        indent
  38:29  error    Expected indentation of 0 spaces but found 28                        indent
  38:37  error    Expected indentation of 0 spaces but found 36                        indent
  38:27  error    Expected indentation of 0 spaces but found 26                        indent
  38:26  error    Expected indentation of 0 spaces but found 25                        indent
  39:5   error    Expected indentation of 0 spaces but found 4                         indent
  40:51  error    Expected indentation of 0 spaces but found 50                        indent
  40:16  error    Expected indentation of 0 spaces but found 15                        indent
  40:9   error    Expected indentation of 0 spaces but found 8                         indent
  40:28  error    Expected indentation of 0 spaces but found 27                        indent
  40:29  error    Expected indentation of 0 spaces but found 28                        indent
  40:17  error    Expected indentation of 0 spaces but found 16                        indent
  40:36  error    Expected indentation of 0 spaces but found 35                        indent
  40:39  error    Expected indentation of 0 spaces but found 38                        indent
  40:43  error    Expected indentation of 0 spaces but found 42                        indent
  40:44  error    Expected indentation of 0 spaces but found 43                        indent
  40:50  error    Expected indentation of 0 spaces but found 49                        indent
  41:9   error    Expected indentation of 0 spaces but found 8                         indent
  41:41  error    Expected indentation of 0 spaces but found 40                        indent
  41:40  error    Expected indentation of 0 spaces but found 39                        indent
  41:39  error    Expected indentation of 0 spaces but found 38                        indent
  41:36  error    Expected indentation of 0 spaces but found 35                        indent
  41:29  error    Expected indentation of 0 spaces but found 28                        indent
  41:28  error    Expected indentation of 0 spaces but found 27                        indent
  41:17  error    Expected indentation of 0 spaces but found 16                        indent
  41:16  error    Expected indentation of 0 spaces but found 15                        indent
  42:30  error    Expected indentation of 0 spaces but found 29                        indent
  42:21  error    Expected indentation of 0 spaces but found 20                        indent
  42:29  error    Expected indentation of 0 spaces but found 28                        indent
  42:28  error    Expected indentation of 0 spaces but found 27                        indent
  42:25  error    Expected indentation of 0 spaces but found 24                        indent
  42:23  error    Expected indentation of 0 spaces but found 22                        indent
  42:22  error    Expected indentation of 0 spaces but found 21                        indent
  42:17  error    Expected indentation of 0 spaces but found 16                        indent
  42:16  error    Expected indentation of 0 spaces but found 15                        indent
  42:9   error    Expected indentation of 0 spaces but found 8                         indent
  44:9   error    Expected indentation of 0 spaces but found 8                         indent
  44:42  error    Expected indentation of 0 spaces but found 41                        indent
  44:43  error    Expected indentation of 0 spaces but found 42                        indent
  44:41  error    Expected indentation of 0 spaces but found 40                        indent
  44:40  error    Expected indentation of 0 spaces but found 39                        indent
  44:27  error    Expected indentation of 0 spaces but found 26                        indent
  44:17  error    Expected indentation of 0 spaces but found 16                        indent
  44:29  error    Expected indentation of 0 spaces but found 28                        indent
  45:29  error    Expected indentation of 0 spaces but found 28                        indent
  45:47  error    Expected indentation of 0 spaces but found 46                        indent
  45:48  error    Expected indentation of 0 spaces but found 47                        indent
  45:57  error    Expected indentation of 0 spaces but found 56                        indent
  45:58  error    Expected indentation of 0 spaces but found 57                        indent
  45:9   error    Expected indentation of 0 spaces but found 8                         indent
  45:17  error    Expected indentation of 0 spaces but found 16                        indent
  45:27  error    Expected indentation of 0 spaces but found 26                        indent
  47:39  error    Expected indentation of 0 spaces but found 38                        indent
  47:37  error    Expected indentation of 0 spaces but found 36                        indent
  47:16  error    Expected indentation of 0 spaces but found 15                        indent
  47:17  error    Expected indentation of 0 spaces but found 16                        indent
  47:27  error    Expected indentation of 0 spaces but found 26                        indent
  47:30  error    Expected indentation of 0 spaces but found 29                        indent
  47:38  error    Expected indentation of 0 spaces but found 37                        indent
  47:9   error    Expected indentation of 0 spaces but found 8                         indent
  47:40  error    Expected indentation of 0 spaces but found 39                        indent
  47:41  error    Expected indentation of 0 spaces but found 40                        indent
  49:9   error    Expected indentation of 0 spaces but found 8                         indent
  49:17  error    Expected indentation of 0 spaces but found 16                        indent
  49:33  error    Expected indentation of 0 spaces but found 32                        indent
  49:36  error    Expected indentation of 0 spaces but found 35                        indent
  49:35  error    Expected indentation of 0 spaces but found 34                        indent
  51:27  error    Expected indentation of 0 spaces but found 26                        indent
  51:13  error    Expected indentation of 0 spaces but found 12                        indent
  51:70  error    Expected indentation of 0 spaces but found 69                        indent
  51:9   error    Expected indentation of 0 spaces but found 8                         indent
  51:68  error    Expected indentation of 0 spaces but found 67                        indent
  51:67  error    Expected indentation of 0 spaces but found 66                        indent
  51:64  error    Expected indentation of 0 spaces but found 63                        indent
  51:44  error    Expected indentation of 0 spaces but found 43                        indent
  51:41  error    Expected indentation of 0 spaces but found 40                        indent
  51:39  error    Expected indentation of 0 spaces but found 38                        indent
  51:38  error    Expected indentation of 0 spaces but found 37                        indent
  51:37  error    Expected indentation of 0 spaces but found 36                        indent
  51:30  error    Expected indentation of 0 spaces but found 29                        indent
  51:12  error    Expected indentation of 0 spaces but found 11                        indent
  52:32  error    Expected indentation of 0 spaces but found 31                        indent
  52:31  error    Expected indentation of 0 spaces but found 30                        indent
  52:29  error    Expected indentation of 0 spaces but found 28                        indent
  52:13  error    Expected indentation of 0 spaces but found 12                        indent
  53:9   error    Expected indentation of 0 spaces but found 8                         indent
  55:67  error    Expected indentation of 0 spaces but found 66                        indent
  55:68  error    Expected indentation of 0 spaces but found 67                        indent
  55:9   error    Expected indentation of 0 spaces but found 8                         indent
  55:16  error    Expected indentation of 0 spaces but found 15                        indent
  55:17  error    Expected indentation of 0 spaces but found 16                        indent
  55:19  error    Expected indentation of 0 spaces but found 18                        indent
  55:26  error    Expected indentation of 0 spaces but found 25                        indent
  55:36  error    Expected indentation of 0 spaces but found 35                        indent
  55:38  error    Expected indentation of 0 spaces but found 37                        indent
  55:42  error    Expected indentation of 0 spaces but found 41                        indent
  55:49  error    Expected indentation of 0 spaces but found 48                        indent
  55:50  error    Expected indentation of 0 spaces but found 49                        indent
  55:51  error    Expected indentation of 0 spaces but found 50                        indent
  55:52  error    Expected indentation of 0 spaces but found 51                        indent
  56:49  error    Expected indentation of 0 spaces but found 48                        indent
  56:9   error    Expected indentation of 0 spaces but found 8                         indent
  56:16  error    Expected indentation of 0 spaces but found 15                        indent
  56:17  error    Expected indentation of 0 spaces but found 16                        indent
  56:19  error    Expected indentation of 0 spaces but found 18                        indent
  56:26  error    Expected indentation of 0 spaces but found 25                        indent
  56:34  error    Expected indentation of 0 spaces but found 33                        indent
  56:36  error    Expected indentation of 0 spaces but found 35                        indent
  56:66  error    Expected indentation of 0 spaces but found 65                        indent
  56:65  error    Expected indentation of 0 spaces but found 64                        indent
  56:50  error    Expected indentation of 0 spaces but found 49                        indent
  56:40  error    Expected indentation of 0 spaces but found 39                        indent
  56:48  error    Expected indentation of 0 spaces but found 47                        indent
  56:47  error    Expected indentation of 0 spaces but found 46                        indent
  58:33  error    Expected indentation of 0 spaces but found 32                        indent
  58:9   error    Expected indentation of 0 spaces but found 8                         indent
  58:18  error    Expected indentation of 0 spaces but found 17                        indent
  58:19  error    Expected indentation of 0 spaces but found 18                        indent
  58:20  error    Expected indentation of 0 spaces but found 19                        indent
  58:22  error    Expected indentation of 0 spaces but found 21                        indent
  58:24  error    Expected indentation of 0 spaces but found 23                        indent
  59:22  error    Expected indentation of 0 spaces but found 21                        indent
  59:20  error    Expected indentation of 0 spaces but found 19                        indent
  59:18  error    Expected indentation of 0 spaces but found 17                        indent
  59:39  error    Expected indentation of 0 spaces but found 38                        indent
  59:17  error    Expected indentation of 0 spaces but found 16                        indent
  59:16  error    Expected indentation of 0 spaces but found 15                        indent
  59:9   error    Expected indentation of 0 spaces but found 8                         indent
  61:9   error    Expected indentation of 0 spaces but found 8                         indent
  61:29  error    Expected indentation of 0 spaces but found 28                        indent
  61:32  error    Expected indentation of 0 spaces but found 31                        indent
  61:33  error    Expected indentation of 0 spaces but found 32                        indent
  61:35  error    Expected indentation of 0 spaces but found 34                        indent
  61:13  error    Expected indentation of 0 spaces but found 12                        indent
  61:12  error    Expected indentation of 0 spaces but found 11                        indent
  62:22  error    Expected indentation of 0 spaces but found 21                        indent
  62:13  error    Expected indentation of 0 spaces but found 12                        indent
  62:41  error    Expected indentation of 0 spaces but found 40                        indent
  62:28  error    Expected indentation of 0 spaces but found 27                        indent
  62:26  error    Expected indentation of 0 spaces but found 25                        indent
  62:24  error    Expected indentation of 0 spaces but found 23                        indent
  62:23  error    Expected indentation of 0 spaces but found 22                        indent
  63:13  error    Expected indentation of 0 spaces but found 12                        indent
  63:45  error    Expected indentation of 0 spaces but found 44                        indent
  63:26  error    Expected indentation of 0 spaces but found 25                        indent
  63:22  error    Expected indentation of 0 spaces but found 21                        indent
  63:21  error    Expected indentation of 0 spaces but found 20                        indent
  63:20  error    Expected indentation of 0 spaces but found 19                        indent
  63:24  error    Expected indentation of 0 spaces but found 23                        indent
  64:9   error    Expected indentation of 0 spaces but found 8                         indent
  66:28  error    Expected indentation of 0 spaces but found 27                        indent
  66:26  error    Expected indentation of 0 spaces but found 25                        indent
  66:17  error    Expected indentation of 0 spaces but found 16                        indent
  66:36  error    Expected indentation of 0 spaces but found 35                        indent
  66:16  error    Expected indentation of 0 spaces but found 15                        indent
  66:9   error    Expected indentation of 0 spaces but found 8                         indent
  66:35  error    Expected indentation of 0 spaces but found 34                        indent
  67:5   error    Expected indentation of 0 spaces but found 4                         indent
  69:51  error    Expected indentation of 0 spaces but found 50                        indent
  69:41  error    Expected indentation of 0 spaces but found 40                        indent
  69:33  error    Expected indentation of 0 spaces but found 32                        indent
  69:32  error    Expected indentation of 0 spaces but found 31                        indent
  69:5   error    Expected indentation of 0 spaces but found 4                         indent
  69:14  error    Expected indentation of 0 spaces but found 13                        indent
  70:6   error    Expected indentation of 0 spaces but found 5                         indent
  70:1   error    Mixed tabs and spaces. Allowed only spaces                           no-mix-tabs-and-spaces
  71:1   error    Mixed tabs and spaces. Allowed only spaces                           no-mix-tabs-and-spaces
  71:6   error    Expected indentation of 0 spaces but found 5                         indent
  72:1   error    Mixed tabs and spaces. Allowed only spaces                           no-mix-tabs-and-spaces
  72:6   error    Expected indentation of 0 spaces but found 5                         indent
  72:14  error    Expected indentation of 0 spaces but found 13                        indent
  72:15  error    Expected indentation of 0 spaces but found 14                        indent
  72:22  error    Expected indentation of 0 spaces but found 21                        indent
  73:5   error    Expected indentation of 0 spaces but found 4                         indent
  74:46  error    Expected indentation of 0 spaces but found 45                        indent
  74:76  error    Expected indentation of 0 spaces but found 75                        indent
  74:75  error    Expected indentation of 0 spaces but found 74                        indent
  74:74  error    Expected indentation of 0 spaces but found 73                        indent
  74:73  error    Expected indentation of 0 spaces but found 72                        indent
  74:59  error    Expected indentation of 0 spaces but found 58                        indent
  74:58  error    Expected indentation of 0 spaces but found 57                        indent
  74:1   error    Mixed tabs and spaces. Allowed only spaces                           no-mix-tabs-and-spaces
  74:45  error    Expected indentation of 0 spaces but found 44                        indent
  74:31  error    Expected indentation of 0 spaces but found 30                        indent
  74:19  error    Expected indentation of 0 spaces but found 18                        indent
  74:6   error    Expected indentation of 0 spaces but found 5                         indent
  74:33  error    Expected indentation of 0 spaces but found 32                        indent
  75:54  error    Expected indentation of 0 spaces but found 53                        indent
  75:6   error    Expected indentation of 0 spaces but found 5                         indent
  75:13  error    Expected indentation of 0 spaces but found 12                        indent
  75:24  error    Expected indentation of 0 spaces but found 23                        indent
  75:25  error    Expected indentation of 0 spaces but found 24                        indent
  75:42  error    Expected indentation of 0 spaces but found 41                        indent
  75:1   error    Mixed tabs and spaces. Allowed only spaces                           no-mix-tabs-and-spaces
  75:43  error    Expected indentation of 0 spaces but found 42                        indent
  75:53  error    Expected indentation of 0 spaces but found 52                        indent
  76:5   error    Expected indentation of 0 spaces but found 4                         indent

✖ 248 problems (234 errors, 14 warnings)

Solution: let's eliminate them

(Refactor) validators && pendingChanges functions could use the same subfunction inside

Problem:
implementation of
validators function: https://github.com/poanetwork/poa-network-consensus-contracts/blob/security-audit/contracts/ValidatorMetadata.sol#L46
and
pendingChanges function: https://github.com/poanetwork/poa-network-consensus-contracts/blob/security-audit/contracts/ValidatorMetadata.sol#L70

have repeated content

Solution: create internal subfunction _validators(bool _pending, address _miningKey) instead

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.