How to use assembly codes around call forwarding?

I was hoping to gain some knowledge around specific assembly codes, particularly the ones used in the Instadapp project to forward user calls to their proxy integration contracts.

The function in question is:

/**
     * @dev Delegate the calls to Connector And this function is ran by cast().
     * @param _target Target to of Connector.
     * @param _data CallData of function in Connector.
    */
    function spell(address _target, bytes memory _data) internal {
        require(_target != address(0), "target-invalid");
        assembly {
            let succeeded := delegatecall(gas(), _target, add(_data, 0x20), mload(_data), 0, 0)

            switch iszero(succeeded)
                case 1 {
                    // throw if delegatecall failed
                    let size := returndatasize()
                    returndatacopy(0x00, 0x00, size)
                    revert(0x00, size)
                }
        }
    }

Specifically, what does this do, and how would one use it? I haven’t found actual docs explaining how delegatecall(), and _mload() function/parameters they take.

I do understand the delegatecall will return the status of the txn as a zero or 1 (and won’t auto-fail upon error) and the switch() checks if the transaction did fail (indicated by a zero return). Though I don’t know what returndatasize or returndatacopy does.

Thanks for any explanation/knowledge share. On a side-note, where are good sources to learn assembly? The official Solidity docs don’t do a great job in explanation.

1 Like

Hi @Dyno,

I don’t know that much about assembly unfortunately, but I would recommend having a read through the following posts (including the whole series if split into multiple parts).

Specifically looking at InstaDApp, you could have a look at the audit. You could also reach out to the team.

1 Like

Great, thanks for these resources @abcoathup!

1 Like