1

I'm trying to reason how a factory can make calls to a child contract that is owned by an EOA.

The goal of this project is to make a StoreFactory contract that allows anyone to deploy their own Store contract. The merchant that deploys the store should be the owner and should be the only one who can withdraw ETH from purchases. The following is some psuedocode that I'm trying to fix to enable this flow.

After a little research, I believe I need to use delegatecall, but I'm not sure.

StoreFactory:

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

import "./Store.sol";

contract StoreFactory {
    uint256 id;
    mapping(uint256 => Store) storeMapping;
    
    function createStore() public {
        Store store = new Store();
        store.transferOwnership(msg.sender());
        storeMapping[id] = child;
        id++;
    }

    function depositEth(uint256 _id) public {
        storeMapping[_id].depositEth();
    }

    function withdrawEth(uint256 _id) public {
        storeMapping[_id].withdrawEth();
    }
}

Store (child) contract:

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

import "openzeppelin-contracts/contracts/access/Ownable.sol";

contract Store is Ownable {

    function depositEth() public payable {}

    function withdrawEth() public onlyOwner {
        uint amount = address(this).balance;
        (bool success, ) = msg.sender.call{value: amount}("");
        require(success, "Failed to send Ether");
    }
    
}

If the factory is making the calls, how can funds be withdrawn by the original EOA account who created the store? This is what I'm trying to accomplish.

1 Answer 1

0

Why do you want msg.sender to be the owner of the child contract? And also, who msg.sender is supposed to be here? Is it you (as in, the designer of the protocol), or a user? If its you, well i suggest you don't do that, and have the factory own the childs. If it's a user, well you could still do that, but it would make sense to want to have them to be the contract owner too.

In that case you could do something like :

Factory :

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

import "./Child.sol";


contract ChildFactory {
    uint256 id;
    mapping(uint256 => Child) childMapping;
    
    function createChild() public {
        Child child = new Child(address(this));
        child.transferOwnership(msg.sender);
        childMapping[id] = child;
        id++;
    }

    function depositEth(uint256 _id) public {
        childMapping[_id].depositEth();
    }

    function withdrawEth(uint256 _id) public {
        require(msg.sender == childMapping[_id].owner());
        childMapping[_id].factoryWithdrawEth(msg.sender);
    }
}

Child :

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

import "openzeppelin-contracts/contracts/access/Ownable.sol";

contract Child is Ownable {

    address factory;

    constructor(address _factory) {
        factory = _factory;
    }
    
    function depositEth() public payable {}

    function ownerWithdraw() public onlyOwner {
        _withdrawEth(msg.sender);
    }

    function factoryWithdrawEth(address to)  public {
        require(msg.sender == factory);
        _withdrawEth(to);
    }

    function _withdrawEth(address account) internal {
        uint amount = address(this).balance;
        (bool success, ) = payable(account).call{value: amount}("");
        require(success, "Failed to send Ether");
    }
    
}

2
  • 1
    Apologies, I was running a fever when I wrote this. Let me edit my question to try and clarify. To answer your questions here: Why do you want msg.sender to be the owner of the child contract? In the actual dapp I'm trying to build, msg.sender is supposed to be a merchant and the child contract will be their store handling invoices and I only want the merchant to be able to withdraw the ETH from their store. Who msg.sender is supposed to be here? Is it you (as in, the designer of the protocol), or a user? Msg.sender is the merchant (store owner), I want anyone to be able to use the Factory
    – soyboy
    Commented Sep 5, 2022 at 17:12
  • 1
    Your solution solves my problem tho, thank you!
    – soyboy
    Commented Sep 6, 2022 at 4:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.