vyper icon indicating copy to clipboard operation
vyper copied to clipboard

`raw_call` cannot return values that it doesnt know it should return

Open bout3fiddy opened this issue 11 months ago • 1 comments

Version Information

  • vyper Version (output of vyper --version): 0.3.10
  • OS: osx
  • Python Version (output of python --version): 3.10.4

What's your issue about?

In the following snippet:

implementation: constant(address) = 0xsomething

@external
def __default__() -> uint256:
    result: uint256 = convert(raw_call(implementation, msg.data, max_outsize=32, is_delegate_call=True), uint256)
    return result

If implementation address has the following code:

@external
@view
def foo() -> uint256:
    return 0

@external
@view
def bar() -> address:
    return empty(address)

I can only call foo() through the parent contract but not bar() since the __default__() method of the parent contract can only return uint256. It also needs to be able to return address to allow returning whatever bar() of the code at implementation address returns.

How can it be fixed?

Vyper should pass the bytes data as-is. This would probably require a new feature in the language.

bout3fiddy avatar Mar 14 '24 14:03 bout3fiddy

in this particular example i think you could actually just use bytes32, as it is byte-compatible across all primitive types.

but in general, the issue is that the ABI requires by convention that return types are wrapped in a tuple, and the encoding of the wrapped type may be different from the encoding from the type itself (e.g. bytes vs (bytes)). so a potential solution is to have a builtin which returns the bytes directly instead of ABI encoding them.

charles-cooper avatar Mar 14 '24 14:03 charles-cooper