Skip to content

VIP: Reentrant Lock Decorator #1204

@jacqueswww

Description

@jacqueswww

Simple Summary

Add a decorator called @nonreentrant to be used on all functions that handle funds and at the discretion of the developer.

Abstract

Using a lock around a function call one can prevent a function doing send / external call with value to do a re-entrant call.

Motivation

Re-entrancy is super difficult to detect as a programmer, Vyper should make it simple not to introduce or hard to get wrong.

As an extra security measure it is encouraged to force the usage of @nonreentrant on functions that are sending funds, either with the value= parameter or the send() function. This is just an extra layer of protection, however attacks are still possible if a function uses state-setting and fund moving in separate transactions.

Specification

Using a unique identifier per function (derivitive of method_id), we can set a lock per function. See https://github.com/protofire/zeppelin-solidity/blob/master/contracts/ReentrancyGuard.sol.

In pseudo vyper code this would be the equivelant of something like:

locks: map(bytes32, bool)

def withdraw():
    assert self.locks[method_id('withdraw()', bytes32)] == False
    self.locks[method_id('withdraw()', bytes32)] = True
     # Body of code.
    self.locks[method_id('withdraw()', bytes32)] = False

Backwards Compatibility

This will effect backwards compatibility if this becomes a forced decorator, if only an optional decorator it will not effect backwards compatibility.

Dependencies

Optional Implementation of @nonreentrant: None (5200 gas per application)
Forced implementation of @nonreentrant: Net-Gas Metering (400 gas per application, well worth it!)

Copyright

Copyright and related rights waived via CC0

Metadata

Metadata

Assignees

No one assigned

    Labels

    VIP: ApprovedVIP ApprovedVIP: DiscussionUsed to denote VIPs and more complex issues that are waiting discussion in a meeting

    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