Skip to content

VIP: Restrict usage of msg fields in public functions #1199

@charles-cooper

Description

@charles-cooper

Simple Summary

Disallow using the msg context in public functions which are called internally.

Abstract

This is kind of a follow-up to the discussion in #901. The currently implemented behavior is to disallow msg.sender in private functions, forcing the caller to pass it as an explicit function argument. The behavior proposed here is to extend this restriction to public functions which are called internally, and also to extend it to the entire msg context. If a user really wants to call an internal @public function which accesses the msg context, they are forced to refactor the function to pass msg.sender explicitly (and optionally change it to @private).

Motivation

msg.sender can have different values depending on if the function call is generated from an external caller or an internal caller. For instance,

@public
def call1() -> address:
  return msg.sender
@private
def call2(addr: address) -> address:
  return addr  # Can't access `msg.sender` here, must pass as arg
@public
def call3() -> address:
  return call1()
@public
def call4() -> address:
  return call2(msg.sender)

In this example, call1 and call4 return the address of the caller, but call3 returns the address of this contract. This goes against Vyper's principle of auditability since extra context needs to be reasoned about when reading code. This proposal would force the above implementation of call1 to be changed to pass msg.sender as an argument, mimicking call2.

Additionally, the current behavior is an extra point of confusion for users coming from Solidity because Vyper's @public is more analogous to Solidity's external keyword than Solidity's public keyword (Solidity has a fine-grained distinction between public and external - public uses a jump which does not change the msg context, while external uses a message call).

Specification

In addition to disallowing msg.sender in private functions, additionally disallow any msg values (off the top of my head: msg.sender, msg.value, proposed msg.data) in internal calls to public functions by raising an exception.

Backwards Compatibility

msg.sender and friends are no longer allowed in public functions which are called internally.

Copyright

Copyright and related rights waived via CC0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions