Cyfrin / foundry-smart-contract-lottery-cu

48 stars 42 forks source link

Smart-Contract-Lottery: Deployment failing with MustBeSubOwner error in VRFCoordinatorV2Mock::addConsumer #30

Closed shrutic11 closed 1 year ago

shrutic11 commented 1 year ago

I have found the issue but I am not sure how to fix this. Someone please let me know what am I missing?

When I am trying to deploy the contract using

forge script script/DeployRaffleLottery.s.sol --rpc-url http://127.0.0.1:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast

The msg.sender is one of the anvil accounts (0)0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266

However, it is the deployer contract address that calls the createSubscription, fundSubscription, and addConsumer contracts/functions. There's a check in the addConsumer function of the VRFCoordinatorV2Mock


function addConsumer(uint64 _subId, address _consumer) external override onlySubOwner(_subId) {
    if (s_consumers[_subId].length == MAX_CONSUMERS) {
      revert TooManyConsumers();
    }

 modifier onlySubOwner(uint64 _subId) {
    address owner = s_subscriptions[_subId].owner;
    if (owner == address(0)) {
      revert InvalidSubscription();
    }
    if (msg.sender != owner) {
      revert MustBeSubOwner(owner);
    }
    _;
  }

And since, even though I am running the command with an anvil user, the addConsumer function is being called by the deploy Script address, hence the mismatch.

Here's the error:


    │   ├─ [853] VRFCoordinatorV2Mock::addConsumer(1, RaffleLottery: [0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9]) 
    │   │   └─ ← "MustBeSubOwner(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)"
    │   └─ ← "MustBeSubOwner(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)"
    └─ ← "MustBeSubOwner(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)"

== Logs ==
  Creating new subscription on:  31337
  msg.sender in deploy with broadcast run:  0x5b73C5498c1E3b4dbA84de0F1833c4a029d90519
  Congratulations! Your new subscription id is:  1
  Please update the new subscription id in the HelperConfig.sol.
  Funding subscription:  1
  Using VRFCoordinator:  0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
  On chain id:  31337
  msg.sender in add consumer:  0x5b73C5498c1E3b4dbA84de0F1833c4a029d90519
  Adding RaffleLottery Contract: 0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9
  subscription id:  1
  on chain:  31337
Error: 
Custom Error d8a3fb52:(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)

Due to this issue, my setUp is failing, hence the test. And if I run my test, just as Patrick showed in the video, the expected user is the default sender 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38, and the actual caller is the deploy smart contract.

How can I make this work? In an idea situation, it is the owner (the smart contract deployer's )responsibility to do all the funding and adding consumer stuff. So, how can I transfer control from the deploy script to the owner when calling these functions?

shrutic11 commented 1 year ago

This issue got resolved after I wrapped the the .addConsumer function between vm.startBroadcast vm.stopBroadcast

Interactions.s.sol:

function addConsumer(
        address mostRecentRaffleContract,
        address vrfCoordinator,
        uint64 subId
    ) public {
        console.log("msg.sender in add consumer: ", msg.sender);
        console.log("Adding RaffleLottery Contract:", mostRecentRaffleContract);
        console.log("subscription id: ", subId);
        console.log("on chain: ", block.chainid);

        vm.startBroadcast();
        VRFCoordinatorV2Mock(vrfCoordinator).addConsumer(
            subId,
            mostRecentRaffleContract
        );
        vm.stopBroadcast();
    }
kyawthetkt commented 6 months ago

Thanks @shrutic11 , it DOES help.