shierve / nem-voting

nem library that implements voting functions in typescript into an npm module
MIT License
9 stars 3 forks source link

NIP-0002 review #2

Open ghost opened 6 years ago

ghost commented 6 years ago

private polls

When the poll is private, you specify the poll creator,

pollIndex:{"private":true,"creator":"TATWKUGFW5RABZZGHP3AXMISRHTTCZI643VFMA62"}

What happens if someone hardcodes other address? which are the implications?

address A creates => index poll B and specifies as creator address C.

address generation

Poll Account:

For the poll account we need two strings: the creator public key as an hex string and the poll title. Then we get the public key by doing SHA3-256(publicKey | pollTitle), where | represents string concatenation. This gives us a public key that we can convert easily to an address, as described in the original NEM technical specification.

I suggest use Keccak hash algorithm instead of SHA3 in the public net to maintain the coherence.

whitelist (only for whitelist polls):

The whitelist message contains a whitelist with people who is allowed to vote.

whitelist:["TCCXQPJNPXAZFKV2IZHIFLAGTSN42WPNAQI6XGK3"]

have you a limit of whitelist address? in case it's split in multiple transactions, how is it solved?

multisig voting

Voting from a multisig account is also a transaction with 0xem and 0 mosaics, but it includes a message by default, which tells cosigners what poll and option this transaction is for. The message in NanoWallet looks like this: vote for poll TBR6KPJ2PMUXVWIDLYAUAY52XBU7KDOVTWYLBTUN with option "yes"

Is it worth? Using a multisig transaction is expensier, should it be solved in the application side to share the cosigners which poll are you voing to instead? or should it be optional? in case I'm the owner of the multisig, I already know what I'm doing.

Attacks

Latest versions implement a smarter system that filters out any transaction that transfers xem or mosaics. Since all exchanges have a minimum amount for withdrawal, you cannot withdraw 0 xem and thus you can not create a valid vote from the exchange's address.

I am not sure that all of them have that restriction, but seems possible. We have to check it.

The solution to this attack is to always validate a poll before voting on it. Validating consists of checking that all the option addresses have been correctly derived from the Poll account as described in the poll creation section. This is secure since to break validation Alice would need to find a collision on SHA-3, which would break much more important things than the NEM voting system, the safety of NEM itself relies on SHA-3, as do many other cryptocurrencies.

Doesn't the security relay in the client side? I mean, that the clients that implement the voting-system agrees in the checking before announcing?

message structure

not important nor critial, the message schema has redundant characters if we use a library to read from the polls.

poll:{"title":"title","type":0,"doe":1607772120000,"address":"TBR6KPJ2PMUXVWIDLYAUAY52XBU7KDOVTWYLBTUN"}

the JSONformat adds the object key for each attribute required, adding a fee for the creator, which it's not desirable.

For now it's OK, but we should take care about this in the next upgrade.

shierve commented 6 years ago

Private polls

if the creator of a private poll index sends the address of somebody else then it means only polls sent by that address should be showed on that index.

Address generation

As far as I know I am using the same version of sha that nem-sdk uses, but I will check

Whitelist

Whitelist polls are limited by the amount of addresses that you can put in a nem message, it is rarelly used and it is going to be deprecated once that historical info about mosaics is abailable and POW mosaic voting can be implemented.

multisig voting

maybe in a future version we can make it so that the message is optional, but the message is a feature that was asked for by some users for clarity. It is possible to check this information for a transaction every time, but for example in nanowallet there is no way to know if a transaction is a vote, so it would have to be checked for every 0xem transaction.

Attacks

  1. I don't know of any single exchange that does not have that restriction. If there is it would be interesting to know, but I don't think it would be smart for an exchange, because if 0xem withdrawals are allowed then you can drain all of their xem from transaction fees. (maybe it is possible if they make you pay for fees). In the beginning there was a blacklist with all the exchange addresses. But this was very messy since you need to update every time a new exchage appeared or added xem. Also maybe some exchanges change address and maybe we don't notice. In the future if an exchange appears that allows 0xem withdrawals maybe we can create a blacklist just for those ones.
  2. Since the polls are sent to a public blockchain there is no way to avoid people from sending malicious polls, so the responsability is in the voter to check if the poll he wants to vote for is valid. Of course you have to trust the implementation to do this for you, but it is the same way that you trust a wallet that they will not send your private key to their servers. The way that it is done in NanoWallet for example, if you click on the index on a poll and the format is invalid then nanowallet will tell you and won't let you vote.

    Message structure

    I have thought about this. The information could be serialized much more efficiently. In future versions it may be changed if we find a good solution. The advantage of a format like json is that it is human readable. When somebody creates a poll they want to know which address pertains to which option, so that they can announce the addresses of the poll. In the future if we implement a more compact format then we need to give to the creator all the information they need for announcing the transaction when they create the poll.