From a29b49d422f6979be2b9c6c80aa583a60b1ccb7f Mon Sep 17 00:00:00 2001 From: sudo rm -rf --no-preserve-root / Date: Tue, 31 Dec 2024 01:01:47 +0100 Subject: [PATCH] chore[docs]: abi function signature for default arguments (#4415) this commit adds a note on how the function selector is calculated if default arguments are used. --- docs/control-structures.rst | 11 ++++++++++- docs/interfaces.rst | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 32fb80882a..6304637728 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -48,7 +48,16 @@ External functions (marked with the ``@external`` decorator) are a part of the c A Vyper contract cannot call directly between two external functions. If you must do this, you can use an :ref:`interface `. .. note:: - For external functions with default arguments like ``def my_function(x: uint256, b: uint256 = 1)`` the Vyper compiler will generate ``N+1`` overloaded function selectors based on ``N`` default arguments. + For external functions with default arguments like ``def my_function(x: uint256, b: uint256 = 1)`` the Vyper compiler will generate ``N+1`` overloaded function selectors based on ``N`` default arguments. Consequently, the ABI signature for a function (this includes interface functions) excludes optional arguments when their default values are used in the function call. + + .. code-block:: vyper + + from ethereum.ercs import IERC4626 + + @external + def foo(x: IERC4626): + extcall x.withdraw(0, self, self) # keccak256("withdraw(uint256,address,address)")[:4] = 0xb460af94 + extcall x.withdraw(0) # keccak256("withdraw(uint256)")[:4] = 0x2e1a7d4d .. _structure-functions-internal: diff --git a/docs/interfaces.rst b/docs/interfaces.rst index 9737d3c567..22a0874fa7 100644 --- a/docs/interfaces.rst +++ b/docs/interfaces.rst @@ -120,6 +120,10 @@ This imports the defined interface from the vyper file at ``an_interface.vyi`` ( Prior to v0.4.0, ``implements`` required that events defined in an interface were re-defined in the "implementing" contract. As of v0.4.0, this is no longer required because events can be used just by importing them. Any events used in a contract will automatically be exported in the ABI output. +.. note:: + + An interface function with default parameters (e.g. ``deposit(assets: uint256, receiver: address = msg.sender)``) implies that the contract being interfaced with supports these default arguments via the ABI-encoded function signatures (e.g. ``keccak256("deposit(uint256,address)")[:4]`` and ``keccak256("deposit(uint256)")[:4]``). It is the responsibility of the callee to implement the behavior associated with these defaults. + Standalone Interfaces =====================