Source on GitHub

Smart Contract Address


Source on GitHub

Smart Contract Address


Testing and Issues

You can test this entry and submit issues during the testing period of the Blockchain Contest, Stage 2 contest.

Entries with serious issues will not be able to win the contest, but even minor issues might be important for overall results.




Both of my contracts are implemented with maximal versatility in mind. There's many options to tweak, and contracts' code can be extended to support even more features (both contracts support code upgrade).

Below are the short descriptions about each of the contracts. You can find more details in their READMEs on Github.
The first one is a platform to conduct auctions or just simple trades. The owner can create any number of open or blind auctions (or just items to sell), and everyone can participate in them.

There's three types of auctions supported: one open (English auction) and two blind (first-price and second-price sealed-bid).

Auctions can have an initial price, a minimum bid difference, a buyout price, a bidding fee and a time limit. For simple trading, there's a stock size option.
The second contract is intended to be a gaming platform (like a virtual casino). For now, there's two game types: a lottery and a Blackjack, but many more can potentially reuse the base code. Similarly to the auction system, the owner can create any number of games with different parameters and start/end times.

For lottery, you can fine-tune the exact number and probabilities of the prizes, as well as the amount of tickets to be sold. Blackjack supports configuring "hit on soft 17" rule.

In the future, this contract can be extended to support off-chain player-dealer interactions and inter-player interactions (with later on-chain validation).
There were some bug reports (below in the issues section), which were fixed after the contest end. To prevent any confusion, all those fixes are committed to separate branches named "post-contest-fixes":

Be sure to check them out before writing new issues.
You have not added any comments yet...
by rating


How come the auction is blind if all transactions and contract state are perfectly visible on the blockchain?
Hip Hyena Dec 23, 2019 at 15:36
Good question!

This achieved with the following trick: participants provide only hashes of their actual bid values. Within some time interval after the end of the auction they can present those values (and the contract validates that their hashes are indeed equal to the ones provided before).

This means that everyone needs to send some fixed sum to the auction, and when all bids are revealed, the difference between it and the actual winning bid is returned to the winner (the whole sum is returned to everyone else).
So there is reserved_balance variable where you track grams that cannot be withdrawn because you need to return them back to participants.

During check_blind_bids where you check the state of blind auction, and send money back to those who lost you do not decrease reserved_balance for winner (only by difference with second place). In case of english auction you did that in external message handler.

So reserved_balance will be higher than it should be preventing owner from withdrawing the money.

Am I right?

PS: I think it was a mistake mixing several types of auctions into a single contract.
Hip Hyena Dec 24, 2019 at 06:03
After inspecting the code, I confirmed that there was indeed a bug there. It's fixed now:

Thank you for your report!

Also, can you elaborate, why do you think supporting multiple types of auctions is a bad idea? I can imagine a platform wanting to conduct both open and blind auctions at the same time, which would be impossible with a single-type auction contract.
There is an option to buyout auction item. In that case other participants of blind auction do not get their money back, because dictionary with their bids is reset (or auction removed if nothing in stock).
Hip Hyena Dec 24, 2019 at 06:21
Confirmed this bug, added a fix:

Thank you for your report!
Nothing prevents me from sending bid disclosure message several times (incrementing seqno) to drain contract out of funds.
Hip Hyena Dec 24, 2019 at 06:29
That's true. Added a check verifying that a bid is not yet decrypted before accepting the message:

Thank you!
When returning money to previous bidder of english auction (during next bid or cancelation) you load uint for worchain id instead of int. Masterchain will be deserialized as workchain 255 and will crash later in send_money when attempted to be stored back into int.

But during completion it's correctly loaded as int, and so bid from masterchain automatically wins the auction blocking everyone else from overbidding it.
Hip Hyena Dec 24, 2019 at 06:36
Thank you for noticing this vulnerability! Previously I was (mistakenly) using uints for workchain all throughout the code, but then I fixed all occurrences. Somehow missed this one.

About lottery game.

Dictionary of participants is indexed by public key. The authenticity of that public key is taken for granted. Public key isn't required to make a move (lottery_raffle can be performed by anyone) or to withdraw (that is done automatically).

It is allowed to increase stake later with additional message. When participant's entry_amount is stored back it uses address of current internal message, which might not be the same that was stored previously.

So to steal money, all I need is to send second internal message with same public key as someone else.
Hip Hyena Dec 24, 2019 at 06:50
There was indeed a problem with overwriting original participant's address, fixed it:

However, the public key is used to validate all external messages (triggering lottery_raffle/making moves): each external message should be signed, so the one who signs it should access not only the public, but the private key too.

Thank you for your interest in my entries and for your thorough inspection of the code. Your feedback is very valuable. Keep those bug reports coming!
About that overwriting address. I meant that I can steal lottery tickets, and although I couldn't raffle lottery then. I can use another address + key (also controlled by me) to raffle it.
Hip Hyena Dec 24, 2019 at 21:06
Ah, I see. Yep, that's possible. You'd probably would not even need to do that — some other participant will trigger a raffle anyway.

Anyway, stealing tickets should not be possible now (but anyone can basically "gift" them to the owner of the public key :).
> Also, can you elaborate, why do you think supporting multiple types of auctions is a bad idea? I can imagine a platform wanting to conduct both open and blind auctions at the same time, which would be impossible with a single-type auction contract.

Platform can direct users to different contract addresses depending on auction type. I would go as far as single contract per auction item.
Hip Hyena Dec 24, 2019 at 21:14
That's a possible alternative. However, I would prefer an idea of "one service - one address" rather than "one part of a service - one address".

This way a user can explore all current auctions/trades knowing just one bit of information — contract's address (that's why I decided to add a text "comment" field, for example). Otherwise it would require either an off-chain list of those addresses or storing them in another contract.
> That's true. Added a check verifying that a bid is not yet decrypted before accepting the message.

That isn't enough. I can send actual_amount that is higher than received_amount. Bid will not be decrypted, and I can replay that message again.
Hip Hyena Dec 26, 2019 at 21:41
Great submission. I believe in both, gambling and auctions!
Nobody added any issues yet...