Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SMRT] Nothing is reverted when requestRandomWords is called #11966

Open
RomThpt opened this issue Feb 8, 2024 · 0 comments
Open

[SMRT] Nothing is reverted when requestRandomWords is called #11966

RomThpt opened this issue Feb 8, 2024 · 0 comments

Comments

@RomThpt
Copy link

RomThpt commented Feb 8, 2024

Description
When my smart contract is calling requestRandomWords, it reverts but it's revert with a blank character.
I'm using forge 0.2.0.

CoinFlip.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";

contract CoinFlip is VRFConsumerBaseV2 {
    /////////////////
    /*   Errors   */
    ////////////////
    error CoinFlip__InsufficientBetAmount();
    error CoinFlip__TransferFailed();
    ////////////////
    /*   Events   */
    ////////////////
    event FlipRequested();
    event CoinFlippedAndWon(uint256 indexed requestId, uint256 indexed amount, address player);

    /////////////////////////
    /*   State Variables   */
    /////////////////////////
    enum Side {
        HEADS,
        TAILS
    }

    Side private s_choice;

    /* Constants */
    uint256 private constant MINIMUM_BET = 0.01 ether;
    uint32 private constant NUM_WORDS = 1;
    uint16 private constant REQUEST_CONFIRMATIONS = 3;

    /* Immutable state variables */
    bytes32 private immutable i_keyHash;
    VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
    address private immutable i_link;
    uint64 private immutable i_subId;
    uint32 private immutable i_callbackGasLimit;

    /////////////////////
    /*     Functions   */
    /////////////////////

    /* Constructor */
    constructor(address _vrfCoordinator, address _link, bytes32 _keyHash, uint64 _subId, uint32 _callbackGasLimit)
        VRFConsumerBaseV2(_vrfCoordinator)
    {
        i_vrfCoordinator = VRFCoordinatorV2Interface(_vrfCoordinator);
        i_link = _link;
        i_keyHash = _keyHash;
        i_subId = _subId;
        i_callbackGasLimit = _callbackGasLimit;
    }

    /*
    @notice Flip the coin
    @dev This function is called by the player to flip the coin
    @param _choice The side the player is betting on
    */
    function flip(Side _choice) external payable returns (uint256 requestId) {
        if (msg.value <= MINIMUM_BET) {
            revert CoinFlip__InsufficientBetAmount();
        }
        s_choice = _choice;
        requestId = i_vrfCoordinator.requestRandomWords(
            i_keyHash, //gasLane
            i_subId,
            REQUEST_CONFIRMATIONS,
            i_callbackGasLimit,
            NUM_WORDS
        );

        emit FlipRequested();
        return requestId;
    }

    function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
        if (Side(randomWords[0] % 2) == s_choice) {
            // Player wins
            // Transfer the winnings to the player
            (bool success,) = payable(msg.sender).call{value: address(this).balance * 2}("");
            if (!success) {
                revert CoinFlip__TransferFailed();
            }
            emit CoinFlippedAndWon(requestId, address(this).balance, msg.sender);
        }
    }
}

CoinFlipTest.t.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {Test,console} from "forge-std/Test.sol";
import {CoinFlip} from "../../src/CoinFlip.sol";
import {DeployCoinFlip} from "../../script/DeployCoinFlip.s.sol";
import {HelperConfig} from "../../script/HelperConfig.s.sol";

contract CoinFlipTest is Test {
    event FlipRequested();

    CoinFlip coinFlip;
    HelperConfig helperConfig;

    address vrfCoordinator;
    address link;
    bytes32 keyHash;
    uint64 subId;
    uint32 callbackGasLimit;

    address public PLAYER = makeAddr("player");
    uint256 public STARTING_BALANCE = 10 ether;

    function setUp() public {
        DeployCoinFlip deployer = new DeployCoinFlip();
        (coinFlip, helperConfig) = deployer.run(); //run the deploy script
        (vrfCoordinator, link, keyHash, subId, callbackGasLimit) = helperConfig.activeNetwork();
    }

    function testFlipWithInsuffisantBetAmount() public {
        vm.prank(PLAYER);
        vm.expectRevert(CoinFlip.CoinFlip__InsufficientBetAmount.selector);
        coinFlip.flip(CoinFlip.Side.HEADS);
    }

    function testFlip() public {
        hoax(PLAYER, STARTING_BALANCE);
        // vm.expectEmit(true, false, false, false, address(coinFlip));
        // emit FlipRequested();
        uint256 requestId = coinFlip.flip{value: 1 ether}(CoinFlip.Side.HEADS);
        console.log(requestId);
    }
}

DeployCoinFlip.s.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {Script} from "forge-std/Script.sol";
import {CoinFlip} from "../src/CoinFlip.sol";
import {HelperConfig} from "./HelperConfig.s.sol";

contract DeployCoinFlip is Script {
    function run() external returns (CoinFlip, HelperConfig) {
        HelperConfig helperConfig = new HelperConfig();
        (address vrfCoordinator, address link, bytes32 keyHash, uint64 subId, uint32 callbackGasLimit) =
            helperConfig.activeNetwork();

        vm.startBroadcast();
        CoinFlip coinFlip = new CoinFlip(vrfCoordinator, link, keyHash, subId, callbackGasLimit);
        vm.stopBroadcast();
        return (coinFlip, helperConfig);
    }
}

HelperConfig.s.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {Script} from "forge-std/Script.sol";
import {VRFCoordinatorV2Mock} from "@chainlink/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol";

contract HelperConfig is Script {
    struct NetworkConfig {
        address vrfCoordinator;
        address link;
        bytes32 keyHash;
        uint64 subId;
        uint32 callbackGasLimit;
    }

    NetworkConfig public activeNetwork;

    uint96 baseFee = 0.25 ether;
    uint96 gasPriceLink = 1e9;

    constructor() {
        if (block.chainid == 11155111) {
            activeNetwork = getSepoliaEthConfig();
        } else {
            activeNetwork = getOrCreateAnvilConfig();
        }
    }

    function getSepoliaEthConfig() public pure returns (NetworkConfig memory) {
        return NetworkConfig({
            vrfCoordinator: 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625,
            link: 0x779877A7B0D9E8603169DdbD7836e478b4624789,
            keyHash: 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c,
            subId: 8119,
            callbackGasLimit: 500000
        });
    }

    function getOrCreateAnvilConfig() public returns (NetworkConfig memory) {
        if (activeNetwork.vrfCoordinator == address(0)) {
            return activeNetwork;
        }
        vm.startBroadcast();
        VRFCoordinatorV2Mock vrfCoordinator = new VRFCoordinatorV2Mock(baseFee, gasPriceLink);
        vm.stopBroadcast();
        return NetworkConfig({
            vrfCoordinator: address(vrfCoordinator),
            link: 0x779877A7B0D9E8603169DdbD7836e478b4624789,
            keyHash: 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c,
            subId: 0,
            callbackGasLimit: 500000
        });
    }
}

Steps to Reproduce
forge test --mt testFlip -vvvvv --fork-url $SEPOLIA_TESTNET

Returned error

[FAIL. Reason: ] testFlip() (gas: 32112)
Traces:
  [6275867] CoinFlipTest::setUp()
    ├─ [3927161] → new DeployCoinFlip@0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
    │   └─ ← 19503 bytes of code
    ├─ [2194211] DeployCoinFlip::run()
    │   ├─ [1840802] → new HelperConfig@0x104fBc016F4bb334D775a19E8A6510109AC63E00
    │   │   └─ ← 8529 bytes of code
    │   ├─ [795] HelperConfig::activeNetwork() [staticcall]
    │   │   └─ ← 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625, 0x779877A7B0D9E8603169DdbD7836e478b4624789, 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c, 8119, 500000 [5e5]
    │   ├─ [0] VM::startBroadcast()
    │   │   └─  ()
    │   ├─ [280223] → new CoinFlip@0x90193C961A926261B756D1E5bb255e67ff9498A1
    │   │   └─ ← 1396 bytes of code
    │   ├─ [0] VM::stopBroadcast()
    │   │   └─  ()
    │   └─ ← CoinFlip: [0x90193C961A926261B756D1E5bb255e67ff9498A1], HelperConfig: [0x104fBc016F4bb334D775a19E8A6510109AC63E00]
    ├─ [795] HelperConfig::activeNetwork() [staticcall]
    │   └─ ← 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625, 0x779877A7B0D9E8603169DdbD7836e478b4624789, 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c, 8119, 500000 [5e5]
    └─  ()

  [32112] CoinFlipTest::testFlip()
    ├─ [0] VM::deal(player: [0x44E97aF4418b7a17AABD8090bEA0A471a366305C], 10000000000000000000 [1e19])
    │   └─  ()
    ├─ [0] VM::prank(player: [0x44E97aF4418b7a17AABD8090bEA0A471a366305C])
    │   └─  ()
    ├─ [12741] CoinFlip::flip{value: 1000000000000000000}(0)
    │   ├─ [7390] 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625::requestRandomWords(0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c, 8119, 3, 500000 [5e5], 1)
    │   │   └─ ← 
    │   └─ ← 
    └─ ← 
@RomThpt RomThpt changed the title [SMRT] <replace with issue title> [SMRT] Nothing is reverted when requestRandomWords is called Feb 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant