Solidity Exercise - Idiot Betting Game

Posted by Bourne's Blog - A Full-stack & Web3 Developer on May 14, 2024

Idiot Betting Game

This exercise assumes you know how block.timestamp works.

  • Whoever deposits the most ether into a contract wins all the ether if no-one else deposits after an hour.
    1. bet function allows users to deposit ether into the contract. If the deposit is higher than the previous highest deposit, the endTime is updated by current time + 1 hour, the highest deposit and winner are updated.
    2. claimPrize function can only be called by the winner after the betting period has ended. It transfers the entire balance of the contract to the winner.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.13;

contract IdiotBettingGame {
    /*
        This exercise assumes you know how block.timestamp works.
        - Whoever deposits the most ether into a contract wins all the ether if no-one 
          else deposits after an hour.
        1. `bet` function allows users to deposit ether into the contract. 
           If the deposit is higher than the previous highest deposit, the endTime is 
           updated by current time + 1 hour, the highest deposit and winner are updated.
        2. `claimPrize` function can only be called by the winner after the betting 
           period has ended. It transfers the entire balance of the contract to the winner.
    */

    function bet() public payable {
        // your code here
    }

    function claimPrize() public {
        // your code here
    }
}

Problem Analysis

We need three variables to storage the winner(address), the highest bet amount, and the end time.

Then, we can update the new winner, highest bet and end time when a higher bet occurs; otherwise, do nothing.

For claimPrize function, we need to ensure the caller is equal the winner, and current time is later than endTime. Then, transfer the balance to the winner address.

Coding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    address public winner;
    uint public endTime;
    uint256 public highestBet = 0;

    function bet() public payable {
        // your code here
        if (msg.value > highestBet) {
            highestBet = msg.value;
            endTime = block.timestamp + 1 hours;
            winner = msg.sender;
        }
    }

    function claimPrize() public {
        // your code here
        require(block.timestamp > endTime, "you need at least 1 hour to claim prize.");
        require(winner == msg.sender, "Only winner can claim the prize");
        payable(winner).transfer(address(this).balance);
    }

Test

1
2
3
4
5
6
7
8
9
10
11
12
13
➜  IdiotBetting git:(main) ✗ forge test -vvv
[⠊] Compiling...
[⠒] Compiling 19 files with Solc 0.8.25
[⠑] Solc 0.8.25 finished in 612.82ms
Compiler run successful!

Ran 2 tests for test/IdiotBetting.t.sol:IdiotBettingTest
[PASS] testBetAndClaim() (gas: 136606)
[PASS] testBetAndClaim1() (gas: 158277)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 5.82ms (2.07ms CPU time)

Ran 1 test suite in 147.60ms (5.82ms CPU time): 2 tests passed, 0 failed, 0 skipped (2 total tests)

Great.

Reference: Solidity Exercise - IdiotBettingGame