drlecks / Ethereum-Contracts

A set of real world usable contracts
Apache License 2.0
35 stars 4 forks source link

Stack Lottery is not random or secure at all! #1

Closed erikdubbelboer closed 6 years ago

erikdubbelboer commented 6 years ago

In the Stack Lottery contract the winner is chosen when numtickets == maxTickets. Both of these variables can easily be read so someone can just wait until numtickets == maxTickets - 1 to "buy" their ticket.

Even though the numtickets and maxTickets variables are private, you can still get their current values.

Let's look at your live version: http://lottery.powdercode.com/

At the time of writing this ticket maxTickets (the 0th variable in your contract) is:

web3.eth.getStorageAt('0x1e217ADC6a6ADC16E248af109Ab7EFA4d1bb252D', 0, function() { console.log(arguments[1]); })
> 0x0000000000000000000000000000000000000000000000000000000000000011

So 17.

And numtickets (the 5th variable in your contract) is:

web3.eth.getStorageAt('0x1e217ADC6a6ADC16E248af109Ab7EFA4d1bb252D', 5, function() { console.log(arguments[1]); })
> 0x0000000000000000000000000000000000000000000000000000000000000000

So 0.

So luckily nobody was stupid enough to play this game yet :)

drlecks commented 6 years ago

Your arguments are right, but I don't agree with your conclusion.

The aim of this lottery was to avoid using RNG, so yes... it's not random. And the fact that you know how many tickets are bought does not give more advantage than looking the contract at Etherscan or creating a contract to watch the lottery state.

If you think that security is the same as fairness, I can agree that technical knowledge in blockchain will increase your odds. there are several threads on Reddit discussing RNG where we ended talking about this lottery system and how it's based more on strategy than simple luck.

I want to clarify that this contract is more case study. although I deployed it, It should not be brought to a broad audience or make a commercial use just as it is. I'll edit the readme file to avoid more confusion.

erikdubbelboer commented 6 years ago

Why would it not give me an advantage? Or do you mean everyone has the same advantage? Why would anyone buy a ticket if numtickets isn’t maxTickets - 1?

Besides it’s not fair at all as currently a miner could 100% win as they could just mine a transaction where they always buy the last ticket.

drlecks commented 6 years ago

If you think that security is the same as fairness, I can agree that technical knowledge in blockchain will increase your odds.

Here I'm saying that you can gain advantage if you understand how the contract works. I'm also saying that you found a way to "read the contract" but there are other ways that also give you that information, even with a simpler way.

Why would anyone buy a ticket if numtickets isn’t maxTickets - 1?

That's not the correct question. If maxTickets = 10 and numTickets = 8 I can place 2 consecutive tickets ans still make huge benefit, you could make profit with only 2/3 tickets on the stack. It all depends on how much you want to wait and how much you want to win. Buying a ticket knowing that numTickets = 0 is not so smart.

As I said, it may not be the most fair lottery system as you can increase your chances by understanding the code. But a miner does not have more advantage than other wise users.

erikdubbelboer commented 6 years ago

Since miners are able to include any transaction they want and are able to order the transactions in any way they want they can always insert a transaction from themselves that buys the last ticket. So if miners want to they can always win this lottery.

Note: I'm not saying individual miners can, I'm saying all miners together can.

drlecks commented 6 years ago

Discussion ended. Closing.