Modifiers Ordering
| Property | Value |
|---|---|
| Rule Code | NTX12 |
| Severity | Style |
Background
Vyper allows multiple decorators on functions to specify visibility (@external, @internal, @deploy), mutability (@pure, @view, @nonpayable, @payable), and security properties (@nonreentrant, @reentrant). While the compiler accepts these decorators in any order, maintaining a consistent ordering improves code readability and makes the function's properties immediately clear to readers.
Purpose
Enforces a consistent ordering of function modifiers in Vyper contracts. The recommended order is:
- Visibility decorators first (@external, @internal, @deploy)
- Mutability decorators second (@pure, @view, @nonpayable, @payable)
- Security decorators last (@nonreentrant)
Example
# Non-compliant - incorrect ordering
@view
@external # visibility should come before mutability
def get_balance() -> uint256:
return self.balance
@nonreentrant
@external # visibility should come before security
@payable
def deposit():
self.balance += msg.value
# Compliant - correct ordering
@external # visibility first
@view # mutability second
def get_balance_correct() -> uint256:
return self.balance
@external # visibility first
@payable # mutability second
@nonreentrant # security last
def deposit_correct():
self.balance += msg.value
# Functions without explicit visibility (defaults to internal)
# Non-compliant
@nonreentrant
@view # mutability should come before security
def internal_func() -> uint256:
return self.balance
# Compliant
@view # mutability first
@nonreentrant # security second
def internal_func_correct() -> uint256:
return self.balance