Programming Project - Phase 2

Hi @Daniel_Fuchs

Yes provable_api works with the testnet if you have issues check the status here:

Sometime the smart contract is down

2 Likes

As it is related to this project, just letting everyone know that Chainlink has released their VRF (verifiable random function) oracle solution.

Once I have successfully implemented the provable solution, I will be creating a new version of the coinflip dapp using this oracle.I have attached the developer notes below:

3 Likes

Hi,

Here is the result of my project.

Video:

Github:

Thanks a lot I enjoyed/learned a lot from the courses @filip ,

JSD.

2 Likes

Finished the project on my own (did not watch the help video).
Learned a lot, but the hardest challenge or better to say the greatest mistake was to use msg.sender in the callback function. The msg.sender function is of course not the msg.sender address from the Dapp, but from the “centralized server”. That was the hardest thing for me :smiley:
I did not check for every test cases, but I think i covered the most ones. What I didn´t consider are the public or private declaration of variable and functions. For easy development purposes most of them are public. And of course, the frontend is not very nice :smiley:
Here are some screenshots.

My frontend and my smart contract can be found on github:
https://github.com/KryptoDr/Ethereum_201

4 Likes

Hello @filip, hello the community, this is my project :
There’s 3 versions :
*the pseudorandomn number
*an emultaion of the oracle process (with a pseudorandom number)
*and the last one (on the video) with the oracle
To follow up the security course, i make the dapp upgradeable.


and the presentation, sorry the video is long due to the waiting time for Tx

I made two repo on github, the first one is my old project. Impossible to deploy this old one with my coinflip version 3 (with oracle)
So i tried to modify the gas, the version of node, to decrease the bytecode… one week without underst anding. Finally i create the new one and same problem : “contract run out of gas” at deployment.
I found that the issue is the commented lines below, in the __callback :

//if (provable_randomDS_proofVerify__returnCode(_queryId, _result, _proof) != 0) {
//     abortFlip(user);
 //}
 //else {
          uint256 randomNumber = uint256(keccak256(abi.encodePacked(_result)));
          uint256 result = randomNumber % 2;
          emit evtBetResume(user, "Result received, evaluation of the bet...", randomNumber);
          resumeFlip(result, user);
 //}

by removing these lines, the problem is gone.

I looked all of your projects in the forum… good job!
I’m a newbie in web programming so bear with me please :sweat_smile:

3 Likes

Hi @jsd

Nice job using the event handler, your project is working well except few things.
There is some details in your contract that you can improve and a big security issue.

The details first:


  1. Here you don’t need an else statement as filpResult is already set to false.
        if(latestNumber == betOn) {
             flipResult = true;
             addPlayerBalance(playerAddress, amountToWin);
        } else {
            flipResult = false;
        }

  1. You are using safeMath and this is really nice but you didn’t use it everywhere:
latestNumber = uint256(keccak256(abi.encodePacked(_result))) % 2;
balance += msg.value;

this one will lead to a buffer underflow

balance -= toTransfer;

  1. The variable “balance” and your contract balance are not sync because of the gas used by the provable Api you need to take this value in consideration.

  1. I don’t have the same interface than the one you are showing in the video did you push the last version of your project in github ?


  1. THE IMPORTANT one now there is a vulnerability in your contract:

This function shouldn’t be public.

function addPlayerBalance(address playerAddress, uint amount) public

So i stole your contract funds :kissing_heart:

This is the contract i used to stole your funds

https://github.com/gabkk/exploit_smart_contract/blob/master/vuln1/ExploitContract.sol

I added 2 eth in this contract;
You have a way to get your ETH back if you read this contract, take it as a small exercise :wink:
Protecting your founds is the most important point when coding smart contract.

2 Likes

Hi @KryptoDr

:partying_face: it’s working well, no bugs well done.

You can optimize a bit your code to make it cheaper to execute and deploy

Why are you double checking you don’t trust modifiers :wink: ?

function sendFund() public payable costs(1 ether){
  require(msg.value >= 1 ether);

function FlipTheCoin(bool head_player, bool tail_player) public payable costs(0.1 ether){
require(msg.value > 0);

This function is private but it’s not called anywhere else in your contract so you can’t withdraw ?
function withdrawAll() private

what is status used for ?

player_info[player_id_address[_queryId]].status=0;

you can simplify your contract a lot by just saying
head is 0 and tail is 1
instead of true or false

your main function will just take

function FlipTheCoin(bool value)

I can’t play the jackpot value i guess because of your worst_case_balance variable
You should display the correct amount in the frontend

Also you need to check the call to the provable api you need to deduce this amount of your smart contract it cost you 0.004 eth per call and you are not taking it in consideration

1 Like

Hey,

thank you very much for your feedback.
Regarding the trust modifier: Yes, thats totally correct. I did not think about it. But my way of thinking was when writing the smart contract: Better one check too many than too few…
The withdrawAll was just a gimmick function, I just implemented it for fun :smiley: But yeah it should be public. In the beginning I wanted to show a nice funny animation of Ivan and Filip that someone stole all the funds when the owner of the contract call this function. I forgot to delete this :slight_smile:

The status was just for testing purpose to check how the program runs through the if else conditions in the __callback function. Forgot to delete it.

Regarding the 0,1: Yes, totally agree. In the beginning I thought I need both because of the frontend design which decides whether you choose Ivan or Filip. Later on, I realized that I can do this with just one, but I was happy that I finished now the program. This is why I said there is a lot room for optimization :slight_smile:

My idea of the wort case balance was to prevent an empty jackpot when lots of people play at the same time and I am also calculating the worst case balance with a factor 2.0 and not 1.9, because I did not know how to deduce the amount of calling provable API. It was just designed for playing safe that in no case a player plays and the jackpot is empty.

Regarding the 0.004 eth per call: Yes I wanted to do this, but how do I know the cost of the call? I wanted also to pay the current player for this call but I did not know how to do this. Would be nice if you can explain to me how to do both things (Determination of the cost calling the provable API and make the player to pay for it.).

Again, thank you for your feedback.

You can use this function to get the api price

provable_getPrice("RANDOM")

Then deduce this price to your contract balance.

1 Like

How can I make the user pay for calling the update function?
I have another question regarding the smart contract balance. Did you mean I should show the actual smart contract balance as jackpot? This would be not correct because there are still the unclaimed prizes which should be not displayed in the jackpot.

You can tell your users that you will deduct the price of the oracle to their bet for each call

uint betValue = msg.value - provable_getPrice("RANDOM");

or you can implement a reserve in your contract that you will use to pay for the api call.
When this reserve is empty your smart contract will not be usable, you can add a require :wink:

Regarding the jackpot, my case was a bit weird because as you can see in my screenshot the jackpot was 0.55 and i can’t bet 0.51 was the unclaimed prize higher than 0.04 ?

2 Likes

While trying to request 1 ETHER from the MetaMask Ether Faucet (which I have done several times before), I am now getting the message ::

Error: MetaMask Tx Signature: User denied transaction signature.

Are you familiar with this message? Why is my request for ETHER denied?

Thank you.

This is my finished project, deployed on ropsten and working as intended. The integration of the oracle went better than expected and got it working on ropsten in no time.

Overall it was a fun experience and I enjoyed the class. Learned a lot and liked the hands on approach. Good job @filip !

Next up, smart contract security course

1 Like

You clicked perhaps on “1 ether” instead of “request 1 ether frome faucet” without paying attention and you rejected the Tx (sending 1eth to the faucet)

Hi @gabba,

Lesson learned.

I have push again the code it should good now (https://github.com/jsd/CoinFlip).

For the small exercise, I had to reproduce the same hack on a different address, but here is the code to recover the account balance:

pragma solidity 0.5.12;

import "https://github.com/gabkk/exploit_smart_contract/blob/master/vuln1/ExploitContract.sol";
import "./Ownable.sol";


contract ExploitContractImpl  is Ownable{
    
    address payable private coinFlipAddress = 0xBEe987B9451d8B632BE521AB6D09B4FE538e3E10;
    ExploitContract instance = new ExploitContract(coinFlipAddress); 
    
   
    //1.- Run attack first  
    function runAttack() public onlyOwner {
        instance.attack();
    }
    
     //2.- Close child instance contract and remove code the Blockchain.
    function closeContractInstrance() public onlyOwner {
        instance.close(); 
    } 
    
    //3.- Close main contract and restore fund to the origin address.
    function recoverBalance() public onlyOwner {
        selfdestruct(coinFlipAddress);
    }
    
    //helper function to display instance contrcat balance.
    function displayContractBalance() public view returns  (uint){
         return instance.displayContractBalance();
    } 
    
    //helper function to display this contract balance.
    function displayThisContractBalance() public view returns(uint){
        return address(this).balance;
    }
    
    //default fallback function
    function() external payable { }
    
}

Thank you again,

2 Likes

Try this faucet if you have any issues with metamask faucet
https://faucet.ropsten.be/

2 Likes

Great project , congratz

No you are not eheh this is not a newbie project well done :+1:

2 Likes

Hi @MoneyPrinterGoBrrr

Few comments, you are not checking if the message value is greater than 0, you are not checking the price of the provable api call. By sending multiple transaction with a value of 0 i can make your contract spending a his eth for 0.

The balance of your contract is not update correctly.
Here i had an issue with your contract i was able to play but it seems you was not able to pay for the callback

Why do you have this function in your smart contract and you are not using it ?

function compareStrings (string memory a, string memory b) public pure returns (bool)
function randomize(uint modulus) public view returns (uint)

Otherwise your contract is working well and you are using the event handler the right way. For a final project it’s a bit short less than 80 lines :wink: i m sure you can implement many other functionalities

1 Like

Thanks you very much Gabba!
It encourages me to continue my efforts. :grinning:

Hi Gabba,

Thank you for taking the time to hack my project and provide feedback. That’s the best way to learn, making mistakes and fixing them :slight_smile:

Will implement the fixes this weekend.

As for the length of the project it is on the short side but since it’s a project that has been done before by others there is no real added value for the community therefore it’s not very motivational for me. Ideally I would like to work on a project that could contribute in some way and learn at the same time.

Thanks again!