Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements directive behave inconsistently with default parameters #3170

Open
trocher opened this issue Dec 5, 2022 · 4 comments
Open

Implements directive behave inconsistently with default parameters #3170

trocher opened this issue Dec 5, 2022 · 4 comments
Labels
bug - typechecker issue with typechecker

Comments

@trocher
Copy link
Contributor

trocher commented Dec 5, 2022

Version Information

  • vyper Version (output of vyper --version): 0.3.8+commit.6020b8bb
  • OS: OSX
  • Python Version (output of python --version): 3.8.0

What's your issue about?

While Vyper allows defaults to be mentioned in interfaces, the concrete default values are ignored and the only thing done by the presence of such values in the interface is to adds an overload of the given function.

Mixing such interfaces with the implements directive lead to some inconsistent behaviours.

  • When using the implements directive with an interface declaring a function with default arguments, it is enough for the contract implementing it to define the "long overload", for example, the following contract compiles although the function goo() is not implemented (note that a call to test() would then revert)
interface A:
    def goo(a:uint16=32)-> uint16:nonpayable

implements: A

@external
def goo(a:uint16)->uint16:
    return a

@external
def test() -> uint16:
    d:A = A(self)
    return d.goo()
  • On the other side, if the interface is declaring a function with no arguments for example, an implementation having a function with default arguments would not pass the implements directive as the short overload is somehow not taken into account. To illustrate, this contract would not compile because of the implements.
interface A:
    def goo()-> uint16:nonpayable

implements: A

@external
def goo(a:uint16=6)->uint16:
    return a
@trocher trocher changed the title Implements directive behave inconsistently with defaults parameters Implements directive behave inconsistently with default parameters Dec 5, 2022
@fubuloubu
Copy link
Member

Some good finds today

@pcaversaccio
Copy link
Collaborator

Can confirm the inconsistent behavior. Let me document another example, the ERC721 interface: If you do something like the following (without data: Bytes[1024]=b""), the compiler will not throw even though the overloaded function of safeTransferFrom (without data payload) is not implemented and therefore the contract doesn't implement the ERC721 interface completely:

from vyper.interfaces import ERC721
implements: ERC721

@external
@payable
def safeTransferFrom(owner: address, to: address, token_id: uint256, data: Bytes[1024]):
    ...

So the implements keyword is not ensuring feature completeness in a sense.

@fubuloubu
Copy link
Member

btw, it should be allowed to use = ... for defaults, so you don't have to specify a specific value (should the value be enforced if present?)

@charles-cooper
Copy link
Member

btw, it should be allowed to use = ... for defaults, so you don't have to specify a specific value (should the value be enforced if present?)

That's a good point. Maybe we should always enforce defaults to be ... in interfaces

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug - typechecker issue with typechecker
Projects
None yet
Development

No branches or pull requests

4 participants