Skip to content

Conversation

sandbubbles
Copy link
Collaborator

@sandbubbles sandbubbles commented Nov 23, 2024

What I did

Forbid calling __default__ by staticcall and extcall. Depends on #4090.
Edit: Added dependency on the PR.

How I did it

In validate functions check the attribute name if present.

How to verify it

Commit message

This commit forbids `extcall` and `staticcall`s to `__default__`. This
was not possible before the introduction of `__interface__()` and
`__at__()`; however, now that we have the possibility of casting
a module to its interface, it is possible to actually call the
`__default__()` function, which generates a "normal" ABI-encoded
call including the method id for `__default__()`. That could cause a
selector collision with a different function at target, and also leads
to confusing behavior (`__default__` gets called when no selector
matches).

The error message recommends the user to use `raw_call()` for this
use case.

Description for the changelog

Cute Animal Picture

Put a link to a cute animal picture inside the parenthesis-->

@@ -19,7 +19,7 @@
)
from vyper.semantics.data_locations import DataLocation
from vyper.semantics.types.base import TYPE_T, VyperType, is_type_t
from vyper.semantics.types.function import ContractFunctionT
from vyper.semantics.types.function import ContractFunctionT, MemberFunctionT

Check failure

Code scanning / CodeQL

Module-level cyclic import Error

'ContractFunctionT' may not be defined if module
vyper.semantics.types.function
is imported before module
vyper.semantics.types.module
, as the
definition
of ContractFunctionT occurs after the cyclic
import
of vyper.semantics.types.module.
'ContractFunctionT' may not be defined if module
vyper.semantics.types.function
is imported before module
vyper.semantics.types.module
, as the
definition
of ContractFunctionT occurs after the cyclic
import
of vyper.semantics.types.module.
@@ -19,7 +19,7 @@
)
from vyper.semantics.data_locations import DataLocation
from vyper.semantics.types.base import TYPE_T, VyperType, is_type_t
from vyper.semantics.types.function import ContractFunctionT
from vyper.semantics.types.function import ContractFunctionT, MemberFunctionT

Check failure

Code scanning / CodeQL

Module-level cyclic import Error

'MemberFunctionT' may not be defined if module
vyper.semantics.types.function
is imported before module
vyper.semantics.types.module
, as the
definition
of MemberFunctionT occurs after the cyclic
import
of vyper.semantics.types.module.
'MemberFunctionT' may not be defined if module
vyper.semantics.types.function
is imported before module
vyper.semantics.types.module
, as the
definition
of MemberFunctionT occurs after the cyclic
import
of vyper.semantics.types.module.
@cyberthirst cyberthirst added this to the v0.4.2 milestone Mar 17, 2025
@charles-cooper charles-cooper added release - tentative items still being considered for release inclusion release - must release blocker and removed release - tentative items still being considered for release inclusion labels Mar 17, 2025
@cyberthirst
Copy link
Collaborator

we disallow default in interfaces, which is another argument to forbid the call

vyper.exceptions.FunctionDeclarationException: Default functions cannot appear in interfaces

  contract "tests/custom/test.vy:5", line 5:4 
       4 interface i:
  ---> 5     def __default__(): payable
  -----------^
       6

Copy link

codecov bot commented Mar 19, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 92.36%. Comparing base (d9444fb) to head (e1aeebd).
Report is 85 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #4371   +/-   ##
=======================================
  Coverage   92.36%   92.36%           
=======================================
  Files         123      123           
  Lines       17527    17531    +4     
  Branches     2958     2959    +1     
=======================================
+ Hits        16189    16193    +4     
  Misses        934      934           
  Partials      404      404           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@external
def bar():
foo:int128 = 0
foo = staticcall lib1.__at__(self).__default__()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should also test the interface variant:

@external
def bar():
    foo:int128 = 0
    foo = staticcall lib1.__interface__(self).__default__()

Copy link
Member

@charles-cooper charles-cooper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is looking good. can we rebase to prune the commits from #4090? i think it branches off after commit 341d4b6

@charles-cooper charles-cooper force-pushed the fix/hide-default-in-interface branch from 19c0d14 to 13e7421 Compare March 25, 2025 09:25
@charles-cooper
Copy link
Member

lgtm. @cyberthirst anything else you want to see?

@charles-cooper charles-cooper changed the title fix[lang]: forbid calling __default__ fix[lang]: forbid calling __default__` Mar 25, 2025
@charles-cooper charles-cooper changed the title fix[lang]: forbid calling __default__` fix[lang]!: forbid calling __default__ Mar 25, 2025
@charles-cooper charles-cooper merged commit 4b32292 into vyperlang:master Mar 25, 2025
163 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release - must release blocker
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants