Vyper theorytheory 0/50 · 0%
Security patterns · hard

42. Proxies and upgradability with Vyper

Vyper contracts are immutable — upgrade patterns work around a fixed address.

A deployed Vyper contract's logic can never change in place. To 'upgrade', teams deploy a lightweight proxy contract that `delegatecall`s into a separate, replaceable logic contract — though Vyper itself intentionally has no `delegatecall` builtin at the language level for regular use, so proxies are typically minimal, heavily audited pieces (e.g. EIP-1167 minimal proxies) rather than something you hand-roll casually.

# create_minimal_proxy_to deploys an EIP-1167 clone pointing at `target`
@external
def clone(target: address) -> address:
    return create_minimal_proxy_to(target)

Because upgrade proxies concentrate enormous power (the ability to change all logic), any upgrade path should have a timelock and, ideally, a way for the community/users to see pending changes before they take effect.

Check your understanding

  1. 1. Can a deployed Vyper contract's bytecode change after deployment?

  2. 2. What builtin lets you deploy a minimal EIP-1167 clone?

  3. 3. Why should upgrade paths include a timelock?