TwentyOne

First Flight #29
Beginner FriendlyGameFiFoundrySolidity
100 EXP
View results
Submission Details
Severity: medium
Valid

Contract Lacks Mechanism to Initialize or Deposit Ether

Title

Contract Lacks Mechanism to Initialize or Deposit Ether


Summary

The TwentyOne contract lacks a mechanism to initialize with Ether or allow subsequent deposits. As a result, the contract starts with a zero balance upon deployment, which creates a critical issue for gameplay: when a user deposits 1 Ether to start a game, and if they win, the contract cannot pay out the promised 2 Ether due to insufficient funds.

To address this, the following solutions are proposed:

  1. Introduce a payable constructor to allow the deployer to fund the contract at the time of deployment.

  2. Add a receive() function to enable the contract to accept Ether deposits from other wallets during its lifecycle.

This is categorized as High Severity, as it prevents the core functionality of the game.


Vulnerability Details

  1. Root Cause

    • The contract is deployed with a zero balance because it does not provide a mechanism for the deployer or any external wallet to deposit Ether.

    • The startGame function requires the user to deposit 1 Ether, but the contract must already have sufficient funds to cover a potential payout of 2 Ether if the user wins.

    • Without an initial balance or the ability to deposit additional funds, the contract is unable to fulfill its payout obligations.

  2. Affected Code
    The contract lacks both a payable constructor and a receive() function:

    constructor() { // No way to initialize the contract with Ether }
  3. Behavior

    • Deployment Issue: The contract is deployed with a balance of zero Ether.

    • Gameplay Disruption: Users deposit 1 Ether to play the game but cannot receive the promised payout of 2 Ether due to the contract's insufficient balance.

    • Lack of Flexibility: The deployer cannot top up the contract balance post-deployment, further exacerbating the problem.


Impact

This vulnerability blocks the functionality of the TwentyOne contract and compromises the user experience. Without sufficient Ether in the contract:

  • Users cannot play the game or receive payouts, leading to a failed contract.

  • The deployer has no mechanism to address the issue by adding funds.


Tools Used

  • Static Code Analysis: Identified the absence of mechanisms to initialize or deposit Ether.

  • Deployment Testing: Verified that the contract is deployed with zero Ether.

  • Simulation: Tested game payouts with insufficient contract balance.


Recommendations

Solution 1: Add a Payable Constructor

Modify the contract to include a payable constructor. This allows the deployer to provide an initial balance during deployment. Example:

constructor() payable { // Optionally handle the initial balance }

Solution 2: Add a receive() Function

Include a receive() function to allow the contract to accept Ether deposits at any time:

receive() external payable { // Optionally log deposits or perform actions }

Revised Contract

Below is the updated contract with the proposed changes:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
contract TwentyOne {
// ... (existing code)
// Payable constructor for initial funding
constructor() payable {}
// Receive function to accept deposits
receive() external payable {
// Optional: Emit event for received funds
}
// ... (existing code)
}

Testing and Validation

  1. Deployment: Deploy the updated contract using the following command to provide an initial balance:

    forge create --value 10ether path/to/TwentyOne.sol:TwentyOne --private-key <deployer_private_key>
  2. Ether Transfer: Use a wallet or script to send Ether to the contract and confirm it is accepted:

    (bool success, ) = payable(address(twentyOne)).call{value: 5 ether}("");
    require(success, "Ether transfer failed");
  3. Payout Testing: Verify that the game can handle payouts after deployment with sufficient initial balance.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Contract Lacks Mechanism to Initialize or Deposit Ether

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.