1

Is it possible to use Solidity assembly to create a fallback function that makes a DELEGATECALL to another contract, and then uses assembly to correctly store the return value of the DELEGATECALL in the appropriate registers, so that the fallback function effectively returns this value?

This is useful so that I can make a contract that behaves exactly like another contract, while maintaining the clones interoperability with solidity features.

-- EDIT --

Ok I've done some more research, and it seems like it should be possible to use assembly to push to the returndata of the EVM stack, but I can't find any particularly good documentation for the Ethereum VM that has the info I need. Where is the returndata in memory? What is the best way to write to it? Etc.

2

Check out the fallback function.

https://github.com/rob-Hitchens/TrustlessUpgrades/blob/master/contracts/Proxy.sol

    function () external payable {
        address implementationAddress = userImplementation(msg.sender);
        //solium-disable-next-line security/no-inline-assembly
        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0, calldatasize)
            let result := delegatecall(gas, implementationAddress, ptr, calldatasize, 0, 0)
            let size := returndatasize
            returndatacopy(ptr, 0, size)

            switch result
            case 0 { revert(ptr, size) }
            default { return(ptr, size) }
        }
    }

Disclaimer:

This code is inspired by others who were, no doubt, inspired by others. No testing of any kind and no warranty of any kind.

It's a proxy pattern for upgradeable contracts. It:

  • Uses a fallback as a catch-all for implementation contract functions - gets them all.
  • Uses delgatecall to forward the calldata to an implementation contract
  • Copies the response to returndata
  • Reverts if the implementation wanted to revert (returned fail). That replicates the called function's intended behaviour.

Hope it helps.

  • This certainly looks like what I need. Going to test and then accept this answer. – OneChillDude Feb 11 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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