0

I'm calling a contract like so:

PartyRegistry(partyClone).initialize(
            msg.sender,
            partyInfo,
            stableCoin,
            initialDeposit,
            PLATFORM_ADDRESS
        );

And the contract that I'm calling doesn't have an initialize function explicitly defined but instead has a fallback function that does a delegatecall to a contract that does have the initialize function:

fallback () payable external {
        address target = logic_contract;
        console.log("before delegate call");
    assembly {
            let ptr := mload(0x40)
        calldatacopy(ptr, 0, calldatasize())
        let result := delegatecall(gas(), target, ptr, calldatasize(), 0, 0)
        let size := returndatasize()
        returndatacopy(ptr, 0, size)
        switch result
        case 0 { revert(ptr, size) }
        case 1 { return(ptr, size) }
    }
        console.log("after delegate call");
    }

However I'm unable to call initialize and am getting this error:

TypeError: Member "initialize" not found or not visible after argument-dependent lookup in contract PartyRegistry.
  --> contracts/legacy/PartyFactory.sol:99:9:
   |
99 |         PartyRegistry(partyClone).initialize(
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Error HH600: Compilation failed

How do I make sure that initialize is called and goes to the fallback function that ultimately calls initialize with delegatecall?

PartyRegistry is:

contract PartyRegistry is PartyStorage, Ownable {
    address public logic_contract;
    
    function setLogicContract(address _c) public onlyOwner returns (bool success) {
        logic_contract = _c;
    return true;
    }

    fallback () payable external {
        address target = logic_contract;
        console.log("before delegate call");
    assembly {
            let ptr := mload(0x40)
        calldatacopy(ptr, 0, calldatasize())
        let result := delegatecall(gas(), target, ptr, calldatasize(), 0, 0)
        let size := returndatasize()
        returndatacopy(ptr, 0, size)
        switch result
        case 0 { revert(ptr, size) }
        case 1 { return(ptr, size) }
    }
        console.log("after delegate call");
    }

    receive () payable external {}

}

The function initialize looks like this:

      function initialize(
        address creator,
        partyinfo memory _partyinfo,
        address dasset,
        uint256 initialdeposit,
        address platform
    ) external payable initializer {...}
4
  • Could you show the definition of PartyRegistry ?
    – hroussille
    Feb 3, 2022 at 15:35
  • updated with PartyRegistry Feb 4, 2022 at 4:33
  • Can you share the function definition of the initialize function too? Will need its parameters to use it here.
    – pbsh
    Feb 4, 2022 at 7:58
  • Updated with initialize Feb 4, 2022 at 10:17

1 Answer 1

1

To interact with the PartyRegistry contract via its fallback function, we'll need to create an interface with the initialize function.

interface IAnotherContract {
    function initialize(
        address creator,
        partyinfo memory _partyinfo,
        address dasset,
        uint256 initialdeposit,
        address platform
    ) external payable;
}

Now to call PartyRegistry, call initialize function using the IAnotherContract interface instead of PartyContract interface.

IAnotherContract(partyClone).initialize(
    msg.sender,
    partyInfo,
    stableCoin,
    initialDeposit,
    PLATFORM_ADDRESS
);

What's happening here is by using the right interface, we tell solidity how to encode the function parameters properly while making the call to PartyRegistry contract.

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.