TwentyOne

First Flight #29
Beginner FriendlyGameFiFoundrySolidity
100 EXP
View results
Submission Details
Severity: low
Invalid

CASINO Address Lacks Initial Balance for Ether Transfer

Summary

In the provided script TwentyOne.s.sol, the CASINO address attempts to transfer Ether to the TwentyOne contract during the execution of the run function. However, as observed in the logs, the CASINO address has no balance, leading to an OutOfFunds error during the Ether transfer. This issue can be resolved by pre-funding the CASINO and USER addresses with an initial Ether balance and adjusting the transfer logic.

The proposed solution includes:

  1. Using vm.deal to allocate Ether to the CASINO and USER addresses.

  2. Switching to a low-level call for robust Ether transfer logic.


Vulnerability Details

  1. Root Cause
    The CASINO address, defined as address(1), does not have any Ether balance assigned during the script setup. Consequently, when it attempts to fund the TwentyOne contract, the transaction fails due to insufficient funds.

  2. Affected Code
    In the run function:

    function run() public {
    vm.prank(CASINO);
    console.log("Casino Balance: ", CASINO.balance);
    payable(address(twentyOne)).transfer(10 ether);
    console.log("Funded contract with 10 ether.");
    }
  3. Behavior

    • Without initial funding, the CASINO address cannot transfer Ether, resulting in a Revert during execution.

    • The script fails to simulate the intended funding behavior, blocking further testing or deployment.


Impact

This issue prevents the simulation of Ether transfers to the TwentyOne contract, blocking development and testing workflows. The absence of initial funding for test accounts disrupts the intended functionality of the script.


Tools Used

  • Foundry Script Execution: Verified the failure during the forge script run.

  • Console Logging: Monitored the CASINO.balance to confirm the absence of Ether.

  • Low-Level Call Testing: Confirmed alternative approaches for robust transfer logic.


Recommendations

Solution 1: Assign Initial Ether Balance

Use the vm.deal function in the setUp method to assign a starting balance to both the CASINO and USER addresses. This ensures the addresses have sufficient Ether for subsequent operations. Update the setUp function as follows:

uint256 STARTING_AMOUNT = 20 ether;
function setUp() public {
// Deploy the TwentyOne contract
twentyOne = new TwentyOne();
console.log("TwentyOne contract deployed at:", address(twentyOne));
vm.deal(CASINO, STARTING_AMOUNT);
vm.deal(USER, STARTING_AMOUNT);
}

Solution 2: Use Low-Level Call for Ether Transfer

Replace the transfer statement with a low-level call for robust error handling. This ensures that if the transfer fails for any reason, the script can continue execution or gracefully handle the failure. Update the run function as follows:

function run() public {
vm.prank(CASINO);
console.log("Casino Balance: ", CASINO.balance);
// Use low-level call for Ether transfer
(bool success, ) = payable(address(twentyOne)).call{value: 10 ether}("");
if (!success) {
console.log("Ether transfer to TwentyOne contract failed.");
return;
}
console.log("Funded contract with 10 ether.");
}

Testing and Deployment

  1. After implementing the above changes, run the script with forge script to confirm the absence of errors.

  2. Ensure that the balances of CASINO and USER are sufficient before executing further test scenarios.

  3. Use console logs to validate the Ether transfer.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

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