diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 94eb5ec04c..baa8decacc 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -6,7 +6,7 @@
### Commit message
-Commit message for the final, squashed PR. (Optional, but reviewers will appreciate it! Please see [our commit message style guide](../../blob/master/docs/style-guide.rst#best-practices-1) for what we would ideally like to see in a commit message.)
+Commit message for the final, squashed PR. (Optional, but reviewers will appreciate it! Please see [our commit message style guide](../../master/docs/style-guide.rst#best-practices-1) for what we would ideally like to see in a commit message.)
### Description for the changelog
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index a3e9a195f6..c8d7f7d6c4 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,4 +1,4 @@
-name: Artifacts
+name: Build artifacts
on:
workflow_dispatch:
@@ -6,10 +6,11 @@ on:
tag:
default: ''
push:
- tags:
- - '*'
branches:
- master
+ pull_request:
+ release:
+ types: [published] # releases and pre-releases (release candidates)
defaults:
run:
@@ -20,10 +21,10 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ubuntu-latest, macos-latest]
+ os: [ubuntu-20.04, macos-latest]
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
with:
# grab the commit passed in via `tag`, if any
ref: ${{ github.event.inputs.tag }}
@@ -34,13 +35,15 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: "3.11"
+ cache: "pip"
- name: Generate Binary
run: >-
- pip install . &&
+ pip install --no-binary pycryptodome --no-binary cbor2 . &&
pip install pyinstaller &&
make freeze
+
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
@@ -50,7 +53,7 @@ jobs:
runs-on: windows-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
with:
# grab the commit passed in via `tag`, if any
ref: ${{ github.event.inputs.tag }}
@@ -61,6 +64,7 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: "3.11"
+ cache: "pip"
- name: Generate Binary
run: >-
@@ -72,3 +76,40 @@ jobs:
uses: actions/upload-artifact@v3
with:
path: dist/vyper.*
+
+ publish-release-assets:
+ needs: [windows-build, unix-build]
+ if: ${{ github.event_name == 'release' }}
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ with:
+ path: artifacts/
+
+ - name: Upload assets
+ # fun - artifacts are downloaded into "artifact/".
+ working-directory: artifacts/artifact
+ run: |
+ set -Eeuxo pipefail
+ for BIN_NAME in $(ls)
+ do
+ curl -L \
+ --no-progress-meter \
+ -X POST \
+ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\
+ -H "Content-Type: application/octet-stream" \
+ "https://uploads.github.com/repos/${{ github.repository }}/releases/${{ github.event.release.id }}/assets?name=${BIN_NAME/+/%2B}" \
+ --data-binary "@${BIN_NAME}"
+ done
+
+ # check build success for pull requests
+ build-success:
+ if: always()
+ runs-on: ubuntu-latest
+ needs: [windows-build, unix-build]
+ steps:
+ - name: check that all builds succeeded
+ if: ${{ contains(needs.*.result, 'failure') }}
+ run: exit 1
diff --git a/.github/workflows/era-tester.yml b/.github/workflows/era-tester.yml
index 6c15e6af07..3e0bb3e941 100644
--- a/.github/workflows/era-tester.yml
+++ b/.github/workflows/era-tester.yml
@@ -1,4 +1,4 @@
-name: era compiler tester
+name: Era compiler tester
# run the matter labs compiler test to integrate their test cases
# this is intended as a diagnostic / spot check to check that we
@@ -38,6 +38,7 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version[0] }}
+ cache: "pip"
- name: Get cache
id: get-cache
@@ -84,14 +85,33 @@ jobs:
**/era-compiler-tester
key: ${{ runner.os }}-${{ env.ERA_HASH }}-${{ env.ERA_VYPER_HASH }}
- - name: Install Vyper
+ - name: Build Vyper
run: |
+ set -Eeuxo pipefail
pip install .
+ echo "VYPER_VERSION=$(vyper --version | cut -f1 -d'+')" >> $GITHUB_ENV
+
+ - name: Install Vyper
+ run: |
mkdir era-compiler-tester/vyper-bin
- echo $(which vyper)
- cp $(which vyper) era-compiler-tester/vyper-bin/vyper-0.3.8
+ cp $(which vyper) era-compiler-tester/vyper-bin/vyper-${{ env.VYPER_VERSION }}
- - name: Run tester
+ - name: Run tester (fast)
+ # Run era tester with no LLVM optimizations
+ continue-on-error: true
+ if: ${{ github.ref != 'refs/heads/master' }}
run: |
cd era-compiler-tester
- cargo run --release --bin compiler-tester -- -v --path='tests/vyper/' --mode='M*B* 0.3.8'
+ cargo run --release --bin compiler-tester -- --path=tests/vyper/ --mode="M0B0 ${{ env.VYPER_VERSION }}"
+
+ - name: Run tester (slow)
+ # Run era tester across the LLVM optimization matrix
+ continue-on-error: true
+ if: ${{ github.ref == 'refs/heads/master' }}
+ run: |
+ cd era-compiler-tester
+ cargo run --release --bin compiler-tester -- --path=tests/vyper/ --mode="M*B* ${{ env.VYPER_VERSION }}"
+
+ - name: Mark as success
+ run: |
+ exit 0
diff --git a/.github/workflows/ghcr.yml b/.github/workflows/ghcr.yml
new file mode 100644
index 0000000000..a35a22e278
--- /dev/null
+++ b/.github/workflows/ghcr.yml
@@ -0,0 +1,75 @@
+name: Deploy docker image to ghcr
+
+# Deploy docker image to ghcr on pushes to master and all releases/tags.
+# Note releases to docker hub are managed separately in another process
+# (github sends webhooks to docker hub which triggers the build there).
+# This workflow is an alternative form of retention for docker images
+# which also allows us to tag and retain every single commit to master.
+
+on:
+ push:
+ branches:
+ - master
+ release:
+ types: [released]
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+ deploy-ghcr:
+
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ # need to fetch unshallow so that setuptools_scm can infer the version
+ fetch-depth: 0
+
+ - uses: actions/setup-python@v4
+ name: Install python
+ with:
+ python-version: "3.11"
+ cache: "pip"
+
+ - name: Generate vyper/version.py
+ run: |
+ pip install .
+ echo "VYPER_VERSION=$(PYTHONPATH=. python vyper/cli/vyper_compile.py --version)" >> "$GITHUB_ENV"
+
+ - name: generate tag suffix
+ if: ${{ github.event_name != 'release' }}
+ run: echo "VERSION_SUFFIX=-dev" >> "$GITHUB_ENV"
+
+ - name: Docker meta
+ id: meta
+ uses: docker/metadata-action@v4
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ tags: |
+ type=ref,event=tag
+ type=raw,value=${{ env.VYPER_VERSION }}${{ env.VERSION_SUFFIX }}
+ type=raw,value=dev,enable=${{ github.ref == 'refs/heads/master' }}
+ type=raw,value=latest,enable=${{ github.event_name == 'release' }}
+
+
+ - name: Login to ghcr.io
+ uses: docker/login-action@v2
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Build and push
+ uses: docker/build-push-action@v4
+ with:
+ context: .
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 5a8d989038..f268942e7d 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -1,11 +1,11 @@
-# This workflows will upload a Python Package using Twine when a release is created
+# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
-name: Publish
+name: Publish to PyPI
on:
release:
- types: [released]
+ types: [published] # releases and pre-releases (release candidates)
jobs:
@@ -18,7 +18,7 @@ jobs:
- name: Python
uses: actions/setup-python@v4
with:
- python-version: '3.x'
+ python-version: "3.11"
- name: Install dependencies
run: |
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index f90ff706ec..8d23368eb0 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -1,4 +1,4 @@
-name: Test
+name: Run test suite
on: [push, pull_request]
@@ -21,6 +21,7 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: "3.11"
+ cache: "pip"
- name: Install Dependencies
run: pip install .[lint]
@@ -46,6 +47,7 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: "3.11"
+ cache: "pip"
- name: Install Tox
run: pip install tox
@@ -63,6 +65,7 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: "3.11"
+ cache: "pip"
- name: Install Tox
run: pip install tox
@@ -75,11 +78,18 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- python-version: [["3.10", "310"], ["3.11", "311"]]
- # run in default (optimized) and --no-optimize mode
- flag: ["core", "no-opt"]
-
- name: py${{ matrix.python-version[1] }}-${{ matrix.flag }}
+ python-version: [["3.11", "311"]]
+ # run in modes: --optimize [gas, none, codesize]
+ opt-mode: ["gas", "none", "codesize"]
+ debug: [true, false]
+ # run across other python versions.# we don't really need to run all
+ # modes across all python versions - one is enough
+ include:
+ - python-version: ["3.10", "310"]
+ opt-mode: gas
+ debug: false
+
+ name: py${{ matrix.python-version[1] }}-opt-${{ matrix.opt-mode }}${{ matrix.debug && '-debug' || '' }}
steps:
- uses: actions/checkout@v1
@@ -88,12 +98,13 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version[0] }}
+ cache: "pip"
- name: Install Tox
run: pip install tox
- name: Run Tox
- run: TOXENV=py${{ matrix.python-version[1] }}-${{ matrix.flag }} tox -r -- --reruns 10 --reruns-delay 1 -r aR tests/
+ run: TOXENV=py${{ matrix.python-version[1] }} tox -r -- --optimize ${{ matrix.opt-mode }} ${{ matrix.debug && '--enable-compiler-debug-mode' || '' }} -r aR tests/
- name: Upload Coverage
uses: codecov/codecov-action@v1
@@ -130,18 +141,19 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: "3.11"
+ cache: "pip"
- name: Install Tox
run: pip install tox
# fetch test durations
# NOTE: if the tests get poorly distributed, run this and commit the resulting `.test_durations` file to the `vyper-test-durations` repo.
- # `TOXENV=fuzzing tox -r -- --store-durations --reruns 10 --reruns-delay 1 -r aR tests/`
+ # `TOXENV=fuzzing tox -r -- --store-durations -r aR tests/`
- name: Fetch test-durations
run: curl --location "https://raw.githubusercontent.com/vyperlang/vyper-test-durations/5982755ee8459f771f2e8622427c36494646e1dd/test_durations" -o .test_durations
- name: Run Tox
- run: TOXENV=fuzzing tox -r -- --splits 60 --group ${{ matrix.group }} --splitting-algorithm least_duration --reruns 10 --reruns-delay 1 -r aR tests/
+ run: TOXENV=fuzzing tox -r -- --splits 60 --group ${{ matrix.group }} --splitting-algorithm least_duration -r aR tests/
- name: Upload Coverage
uses: codecov/codecov-action@v1
@@ -171,6 +183,7 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: "3.11"
+ cache: "pip"
- name: Install Tox
run: pip install tox
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 739e977c96..b943b5d31d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,27 +1,33 @@
repos:
- repo: https://github.com/pycqa/isort
- rev: 5.9.3
+ rev: 5.13.2
hooks:
- id: isort
name: isort
- repo: https://github.com/psf/black
- rev: 21.9b0
+ rev: 23.12.0
hooks:
- id: black
name: black
-- repo: https://gitlab.com/pycqa/flake8
- rev: 3.9.2
+- repo: https://github.com/PyCQA/flake8
+ rev: 6.1.0
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v0.910
+ rev: v1.7.1
hooks:
- id: mypy
additional_dependencies:
- "types-setuptools"
+ args: # settings from tox.ini
+ - --install-types
+ - --non-interactive
+ - --follow-imports=silent
+ - --ignore-missing-imports
+ - --implicit-optional
default_language_version:
python: python3.10
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 1ad9000f53..e7f5fa079a 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -1,23 +1,20 @@
-# File: .readthedocs.yaml
-
version: 2
-# Set the version of Python and other tools you might need
build:
# TODO: update to `latest` once supported
# https://github.com/readthedocs/readthedocs.org/issues/8861
os: ubuntu-22.04
tools:
- python: "3.10"
+ python: "3.11"
-# Build from the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
-formats: all
-
+# We can't use "all" because "htmlzip" format is broken for now
+formats:
+ - epub
+ - pdf
-# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: requirements-docs.txt
diff --git a/Dockerfile b/Dockerfile
index bc5bb607d6..b4bfa6d3a4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,7 @@ ARG VCS_REF
LABEL org.label-schema.build-date=$BUILD_DATE \
org.label-schema.name="Vyper" \
org.label-schema.description="Vyper is an experimental programming language" \
- org.label-schema.url="https://vyper.readthedocs.io/en/latest/" \
+ org.label-schema.url="https://docs.vyperlang.org/en/latest/" \
org.label-schema.vcs-ref=$VCS_REF \
org.label-schema.vcs-url="https://github.com/vyperlang/vyper" \
org.label-schema.vendor="Vyper Team" \
diff --git a/FUNDING.yml b/FUNDING.yml
index 81e82160d0..efb9eb01b7 100644
--- a/FUNDING.yml
+++ b/FUNDING.yml
@@ -1 +1 @@
-custom: https://gitcoin.co/grants/200/vyper-smart-contract-language-2
+custom: https://etherscan.io/address/0x70CCBE10F980d80b7eBaab7D2E3A73e87D67B775
diff --git a/Makefile b/Makefile
index daa1c2bfc9..649b381012 100644
--- a/Makefile
+++ b/Makefile
@@ -17,11 +17,8 @@ dev-init:
test:
pytest
-mypy:
- tox -e mypy
-
lint:
- tox -e lint
+ tox -e lint,mypy
docs:
rm -f docs/vyper.rst
@@ -43,7 +40,7 @@ freeze: clean init
echo Generating binary...
export OS="$$(uname -s | tr A-Z a-z)" && \
export VERSION="$$(PYTHONPATH=. python vyper/cli/vyper_compile.py --version)" && \
- pyinstaller --clean --onefile vyper/cli/vyper_compile.py --name "vyper.$${VERSION}.$${OS}" --add-data vyper:vyper
+ pyinstaller --target-architecture=universal2 --clean --onefile vyper/cli/vyper_compile.py --name "vyper.$${VERSION}.$${OS}" --add-data vyper:vyper
clean: clean-build clean-docs clean-pyc clean-test
diff --git a/README.md b/README.md
index f17e693bf5..b14b7eaaf0 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,21 @@
+**Vyper compiler security audit competition starts 14th September with $150k worth of bounties.** [See the competition on CodeHawks](https://www.codehawks.com/contests/cll5rujmw0001js08menkj7hc) and find [more details in this blog post](https://mirror.xyz/0xBA41A04A14aeaEec79e2D694B21ba5Ab610982f1/WTZ3l3MLhTz9P4avq6JqipN5d4HJNiUY-d8zT0pfmXg).
-[![Build Status](https://github.com/vyperlang/vyper/workflows/Test/badge.svg)](https://github.com/vyperlang/vyper/actions)
-[![Documentation Status](https://readthedocs.org/projects/vyper/badge/?version=latest)](http://vyper.readthedocs.io/en/latest/?badge=latest "ReadTheDocs")
+[![Build Status](https://github.com/vyperlang/vyper/workflows/Test/badge.svg)](https://github.com/vyperlang/vyper/actions/workflows/test.yml)
+[![Documentation Status](https://readthedocs.org/projects/vyper/badge/?version=latest)](http://docs.vyperlang.org/en/latest/?badge=latest "ReadTheDocs")
[![Discord](https://img.shields.io/discord/969926564286459934.svg?label=%23vyper)](https://discord.gg/6tw7PTM7C2)
[![PyPI](https://badge.fury.io/py/vyper.svg)](https://pypi.org/project/vyper "PyPI")
-[![Docker](https://images.microbadger.com/badges/version/vyperlang/vyper.svg)](https://hub.docker.com/r/vyperlang/vyper "DockerHub")
+[![Docker](https://img.shields.io/docker/cloud/build/vyperlang/vyper)](https://hub.docker.com/r/vyperlang/vyper "DockerHub")
[![Coverage Status](https://codecov.io/gh/vyperlang/vyper/branch/master/graph/badge.svg)](https://codecov.io/gh/vyperlang/vyper "Codecov")
-[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/vyperlang/vyper.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/vyperlang/vyper/context:python)
+[![Language grade: Python](https://github.com/vyperlang/vyper/workflows/CodeQL/badge.svg)](https://github.com/vyperlang/vyper/actions/workflows/codeql.yml)
# Getting Started
-See [Installing Vyper](http://vyper.readthedocs.io/en/latest/installing-vyper.html) to install vyper.
+See [Installing Vyper](http://docs.vyperlang.org/en/latest/installing-vyper.html) to install vyper.
See [Tools and Resources](https://github.com/vyperlang/vyper/wiki/Vyper-tools-and-resources) for an additional list of framework and tools with vyper support.
-See [Documentation](http://vyper.readthedocs.io/en/latest/index.html) for the documentation and overall design goals of the Vyper language.
+See [Documentation](http://docs.vyperlang.org/en/latest/index.html) for the documentation and overall design goals of the Vyper language.
See [Learn.Vyperlang.org](https://learn.vyperlang.org/) for **learning Vyper by building a Pokémon game**.
See [try.vyperlang.org](https://try.vyperlang.org/) to use Vyper in a hosted jupyter environment!
@@ -22,7 +23,7 @@ See [try.vyperlang.org](https://try.vyperlang.org/) to use Vyper in a hosted jup
**Note: Vyper is beta software, use with care**
# Installation
-See the [Vyper documentation](https://vyper.readthedocs.io/en/latest/installing-vyper.html)
+See the [Vyper documentation](https://docs.vyperlang.org/en/latest/installing-vyper.html)
for build instructions.
# Compiling a contract
@@ -46,15 +47,32 @@ be a bit behind the latest version found in the master branch of this repository
## Testing (using pytest)
-(Complete [installation steps](https://vyper.readthedocs.io/en/latest/installing-vyper.html) first.)
+(Complete [installation steps](https://docs.vyperlang.org/en/latest/installing-vyper.html) first.)
```bash
make dev-init
python setup.py test
```
+## Developing (working on the compiler)
+
+A useful script to have in your PATH is something like the following:
+```bash
+$ cat ~/.local/bin/vyc
+#!/usr/bin/env bash
+PYTHONPATH=. python vyper/cli/vyper_compile.py "$@"
+```
+
+To run a python performance profile (to find compiler perf hotspots):
+```bash
+PYTHONPATH=. python -m cProfile -s tottime vyper/cli/vyper_compile.py "$@"
+```
+
+To get a call graph from a python profile, https://stackoverflow.com/a/23164271/ is helpful.
+
+
# Contributing
* See Issues tab, and feel free to submit your own issues
* Add PRs if you discover a solution to an existing issue
* For further discussions and questions, post in [Discussions](https://github.com/vyperlang/vyper/discussions) or talk to us on [Discord](https://discord.gg/6tw7PTM7C2)
-* For more information, see [Contributing](http://vyper.readthedocs.io/en/latest/contributing.html)
+* For more information, see [Contributing](http://docs.vyperlang.org/en/latest/contributing.html)
diff --git a/SECURITY.md b/SECURITY.md
index c7bdad4ee7..24e275f614 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -9,7 +9,7 @@ It is un-audited software, use with caution.
## Audit reports
Vyper is constantly changing and improving.
-This means the lastest version available may not be audited.
+This means the latest version available may not be audited.
We try to ensure the highest security code possible, but occasionally things slip through.
### Compiler Audits
@@ -48,7 +48,7 @@ https://github.com/vyperlang/vyper/security/advisories
If you think you have found a security vulnerability with a project that has used Vyper,
please report the vulnerability to the relevant project's security disclosure program prior
-to reporting to us. If one is not available, please email your vulnerability to security@vyperlang.org.
+to reporting to us. If one is not available, submit it at https://github.com/vyperlang/vyper/security/advisories.
**Please Do Not Log An Issue** mentioning the vulnerability.
diff --git a/docs/_static/css/dark.css b/docs/_static/css/dark.css
deleted file mode 100644
index cb96b428c8..0000000000
--- a/docs/_static/css/dark.css
+++ /dev/null
@@ -1,207 +0,0 @@
-/* links */
-
-a,
-a:visited {
- color: #aaddff;
-}
-
-
-/* code directives */
-
-.method dt,
-.class dt,
-.data dt,
-.attribute dt,
-.function dt,
-.classmethod dt,
-.exception dt,
-.descclassname,
-.descname {
- background-color: #2d2d2d !important;
-}
-
-.rst-content dl:not(.docutils) dt {
- color: #aaddff;
- border-top: solid 3px #525252;
- border-left: solid 3px #525252;
-}
-
-em.property {
- color: #888888;
-}
-
-
-/* tables */
-
-.rst-content table.docutils thead {
- color: #ddd;
-}
-
-.rst-content table.docutils td {
- border: 0px;
-}
-
-.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td {
- background-color: #5a5a5a;
-}
-
-
-/* inlined code highlights */
-
-.xref,
-.py-meth,
-.rst-content a code {
- color: #aaddff !important;
- font-weight: normal !important;
-}
-
-.rst-content code {
- color: #eee !important;
- font-weight: normal !important;
-}
-
-code.literal {
- background-color: #2d2d2d !important;
- border: 1px solid #6d6d6d !important;
-}
-
-code.docutils.literal.notranslate {
- color: #ddd;
-}
-
-
-/* code examples */
-
-pre {
- background: #222;
- color: #ddd;
- font-size: 150%;
- border-color: #333 !important;
-}
-
-.copybutton {
- color: #666 !important;
- border-color: #333 !important;
-}
-
-.highlight .go,
-.highlight .nb,
-.highlight .kn {
- /* text */
- color: #ddd;
- font-weight: normal;
-}
-
-.highlight .o,
-.highlight .p {
- /* comparators, parentheses */
- color: #bbb;
-}
-
-.highlight .c1 {
- /* comments */
- color: #888;
-}
-
-.highlight .bp {
- /* self */
- color: #fc3;
-}
-
-.highlight .mf,
-.highlight .mi,
-.highlight .kc {
- /* numbers, booleans */
- color: #c90;
-}
-
-.highlight .gt,
-.highlight .nf,
-.highlight .fm {
- /* functions */
- color: #7cf;
-}
-
-.highlight .nd {
- /* decorators */
- color: #f66;
-}
-
-.highlight .k,
-.highlight .ow {
- /* statements */
- color: #A7F;
- font-weight: normal;
-}
-
-.highlight .s2,
-.highlight .s1,
-.highlight .nt {
- /* strings */
- color: #5d6;
-}
-
-
-/* notes, warnings, hints */
-
-.hint .admonition-title {
- background: #2aa87c !important;
-}
-
-.warning .admonition-title {
- background: #cc4444 !important;
-}
-
-.admonition-title {
- background: #3a7ca8 !important;
-}
-
-.admonition,
-.note {
- background-color: #2d2d2d !important;
-}
-
-
-/* table of contents */
-
-.wy-nav-content-wrap {
- background-color: rgba(0, 0, 0, 0.6) !important;
-}
-
-.sidebar {
- background-color: #191919 !important;
-}
-
-.sidebar-title {
- background-color: #2b2b2b !important;
-}
-
-.wy-menu-vertical a {
- color: #ddd;
-}
-
-.wy-menu-vertical code.docutils.literal.notranslate {
- color: #404040;
- background: none !important;
- border: none !important;
-}
-
-.wy-nav-content {
- background: #3c3c3c;
- color: #dddddd;
-}
-
-.wy-menu-vertical li.on a,
-.wy-menu-vertical li.current>a {
- background: #a3a3a3;
- border-bottom: 0px !important;
- border-top: 0px !important;
-}
-
-.wy-menu-vertical li.current {
- background: #b3b3b3;
-}
-
-.toc-backref {
- color: grey !important;
-}
\ No newline at end of file
diff --git a/docs/_static/css/toggle.css b/docs/_static/css/toggle.css
deleted file mode 100644
index ebbd0658a1..0000000000
--- a/docs/_static/css/toggle.css
+++ /dev/null
@@ -1,77 +0,0 @@
-input[type=checkbox] {
- visibility: hidden;
- height: 0;
- width: 0;
- margin: 0;
-}
-
-.rst-versions .rst-current-version {
- padding: 10px;
- display: flex;
- justify-content: space-between;
-}
-
-.rst-versions .rst-current-version .fa-book,
-.rst-versions .rst-current-version .fa-v,
-.rst-versions .rst-current-version .fa-caret-down {
- height: 24px;
- line-height: 24px;
- vertical-align: middle;
-}
-
-.rst-versions .rst-current-version .fa-element {
- width: 80px;
- text-align: center;
-}
-
-.rst-versions .rst-current-version .fa-book {
- text-align: left;
-}
-
-.rst-versions .rst-current-version .fa-v {
- color: #27AE60;
- text-align: right;
-}
-
-label {
- margin: 0 auto;
- display: inline-block;
- justify-content: center;
- align-items: right;
- border-radius: 100px;
- position: relative;
- cursor: pointer;
- text-indent: -9999px;
- width: 50px;
- height: 21px;
- background: #000;
-}
-
-label:after {
- border-radius: 50%;
- position: absolute;
- content: '';
- background: #fff;
- width: 15px;
- height: 15px;
- top: 3px;
- left: 3px;
- transition: ease-in-out 200ms;
-}
-
-input:checked+label {
- background: #3a7ca8;
-}
-
-input:checked+label:after {
- left: calc(100% - 5px);
- transform: translateX(-100%);
-}
-
-html.transition,
-html.transition *,
-html.transition *:before,
-html.transition *:after {
- transition: ease-in-out 200ms !important;
- transition-delay: 0 !important;
-}
\ No newline at end of file
diff --git a/docs/_static/js/toggle.js b/docs/_static/js/toggle.js
deleted file mode 100644
index df131042b5..0000000000
--- a/docs/_static/js/toggle.js
+++ /dev/null
@@ -1,26 +0,0 @@
-document.addEventListener('DOMContentLoaded', function() {
-
- var checkbox = document.querySelector('input[name=mode]');
-
- function toggleCssMode(isDay) {
- var mode = (isDay ? "Day" : "Night");
- localStorage.setItem("css-mode", mode);
-
- var darksheet = $('link[href="_static/css/dark.css"]')[0].sheet;
- darksheet.disabled = isDay;
- }
-
- if (localStorage.getItem("css-mode") == "Day") {
- toggleCssMode(true);
- checkbox.setAttribute('checked', true);
- }
-
- checkbox.addEventListener('change', function() {
- document.documentElement.classList.add('transition');
- window.setTimeout(() => {
- document.documentElement.classList.remove('transition');
- }, 1000)
- toggleCssMode(this.checked);
- })
-
-});
\ No newline at end of file
diff --git a/docs/built-in-functions.rst b/docs/built-in-functions.rst
index 74e8560498..f2f6632906 100644
--- a/docs/built-in-functions.rst
+++ b/docs/built-in-functions.rst
@@ -14,14 +14,14 @@ Bitwise Operations
Perform a "bitwise and" operation. Each bit of the output is 1 if the corresponding bit of ``x`` AND of ``y`` is 1, otherwise it is 0.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(x: uint256, y: uint256) -> uint256:
return bitwise_and(x, y)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(31337, 8008135)
12353
@@ -34,14 +34,14 @@ Bitwise Operations
Return the bitwise complement of ``x`` - the number you get by switching each 1 for a 0 and each 0 for a 1.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(x: uint256) -> uint256:
return bitwise_not(x)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(0)
115792089237316195423570985008687907853269984665640564039457584007913129639935
@@ -54,14 +54,14 @@ Bitwise Operations
Perform a "bitwise or" operation. Each bit of the output is 0 if the corresponding bit of ``x`` AND of ``y`` is 0, otherwise it is 1.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(x: uint256, y: uint256) -> uint256:
return bitwise_or(x, y)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(31337, 8008135)
8027119
@@ -74,14 +74,14 @@ Bitwise Operations
Perform a "bitwise exclusive or" operation. Each bit of the output is the same as the corresponding bit in ``x`` if that bit in ``y`` is 0, and it is the complement of the bit in ``x`` if that bit in ``y`` is 1.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(x: uint256, y: uint256) -> uint256:
return bitwise_xor(x, y)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(31337, 8008135)
8014766
@@ -94,14 +94,14 @@ Bitwise Operations
Return ``x`` with the bits shifted ``_shift`` places. A positive ``_shift`` value equals a left shift, a negative value is a right shift.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(x: uint256, y: int128) -> uint256:
return shift(x, y)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(2, 8)
512
@@ -144,7 +144,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
Returns the address of the newly created proxy contract. If the create operation fails (for instance, in the case of a ``CREATE2`` collision), execution will revert.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo(target: address) -> address:
@@ -173,7 +173,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
Returns the address of the created contract. If the create operation fails (for instance, in the case of a ``CREATE2`` collision), execution will revert. If there is no code at ``target``, execution will revert.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo(target: address) -> address:
@@ -184,35 +184,40 @@ Vyper has three built-ins for contract creation; all three contract creation bui
The implementation of ``create_copy_of`` assumes that the code at ``target`` is smaller than 16MB. While this is much larger than the EIP-170 constraint of 24KB, it is a conservative size limit intended to future-proof deployer contracts in case the EIP-170 constraint is lifted. If the code at ``target`` is larger than 16MB, the behavior of ``create_copy_of`` is undefined.
-.. py:function:: create_from_blueprint(target: address, *args, value: uint256 = 0, code_offset=0, [, salt: bytes32]) -> address
+.. py:function:: create_from_blueprint(target: address, *args, value: uint256 = 0, raw_args: bool = False, code_offset: int = 3, [, salt: bytes32]) -> address
Copy the code of ``target`` into memory and execute it as initcode. In other words, this operation interprets the code at ``target`` not as regular runtime code, but directly as initcode. The ``*args`` are interpreted as constructor arguments, and are ABI-encoded and included when executing the initcode.
* ``target``: Address of the blueprint to invoke
* ``*args``: Constructor arguments to forward to the initcode.
* ``value``: The wei value to send to the new contract address (Optional, default 0)
- * ``code_offset``: The offset to start the ``EXTCODECOPY`` from (Optional, default 0)
+ * ``raw_args``: If ``True``, ``*args`` must be a single ``Bytes[...]`` argument, which will be interpreted as a raw bytes buffer to forward to the create operation (which is useful for instance, if pre- ABI-encoded data is passed in from elsewhere). (Optional, default ``False``)
+ * ``code_offset``: The offset to start the ``EXTCODECOPY`` from (Optional, default 3)
* ``salt``: A ``bytes32`` value utilized by the deterministic ``CREATE2`` opcode (Optional, if not supplied, ``CREATE`` is used)
Returns the address of the created contract. If the create operation fails (for instance, in the case of a ``CREATE2`` collision), execution will revert. If ``code_offset >= target.codesize`` (ex. if there is no code at ``target``), execution will revert.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo(blueprint: address) -> address:
arg1: uint256 = 18
- arg2: String = "some string"
+ arg2: String[32] = "some string"
return create_from_blueprint(blueprint, arg1, arg2, code_offset=1)
.. note::
To properly deploy a blueprint contract, special deploy bytecode must be used. The output of ``vyper -f blueprint_bytecode`` will produce bytecode which deploys an ERC-5202 compatible blueprint.
+.. note::
+
+ Prior to Vyper version ``0.4.0``, the ``code_offset`` parameter defaulted to ``0``.
+
.. warning::
- It is recommended to deploy blueprints with the ERC-5202 preamble ``0xFE7100`` to guard them from being called as regular contracts. This is particularly important for factories where the constructor has side effects (including ``SELFDESTRUCT``!), as those could get executed by *anybody* calling the blueprint contract directly. The ``code_offset=`` kwarg is provided to enable this pattern:
+ It is recommended to deploy blueprints with an `ERC-5202 `_ preamble like ``0xFE7100`` to guard them from being called as regular contracts. This is particularly important for factories where the constructor has side effects (including ``SELFDESTRUCT``!), as those could get executed by *anybody* calling the blueprint contract directly. The ``code_offset=`` kwarg is provided (and defaults to the ERC-5202 default of 3) to enable this pattern:
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo(blueprint: address) -> address:
@@ -226,7 +231,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
* ``to``: Destination address to call to
* ``data``: Data to send to the destination address
* ``max_outsize``: Maximum length of the bytes array returned from the call. If the returned call data exceeds this length, only this number of bytes is returned. (Optional, default ``0``)
- * ``gas``: The amount of gas to attach to the call. If not set, all remaining gas is forwarded.
+ * ``gas``: The amount of gas to attach to the call. (Optional, defaults to ``msg.gas``).
* ``value``: The wei value to send to the address (Optional, default ``0``)
* ``is_delegate_call``: If ``True``, the call will be sent as ``DELEGATECALL`` (Optional, default ``False``)
* ``is_static_call``: If ``True``, the call will be sent as ``STATICCALL`` (Optional, default ``False``)
@@ -240,7 +245,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
Returns ``success`` in a tuple with return value if ``revert_on_failure`` is set to ``False``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@payable
@@ -264,6 +269,10 @@ Vyper has three built-ins for contract creation; all three contract creation bui
assert success
return response
+ .. note::
+
+ Regarding "forwarding all gas", note that, while Vyper will provide ``msg.gas`` to the call, in practice, there are some subtleties around forwarding all remaining gas on the EVM which are out of scope of this documentation and could be subject to change. For instance, see the language in EIP-150 around "all but one 64th".
+
.. py:function:: raw_log(topics: bytes32[4], data: Union[Bytes, bytes32]) -> None
Provides low level access to the ``LOG`` opcodes, emitting a log without having to specify an ABI type.
@@ -271,7 +280,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
* ``topics``: List of ``bytes32`` log topics. The length of this array determines which opcode is used.
* ``data``: Unindexed event data to include in the log. May be given as ``Bytes`` or ``bytes32``.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo(_topic: bytes32, _data: Bytes[100]):
@@ -283,7 +292,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
* ``data``: Data representing the error message causing the revert.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo(_data: Bytes[100]):
@@ -303,7 +312,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
This function has been deprecated from version 0.3.8 onwards. The underlying opcode will eventually undergo breaking changes, and its use is not recommended.
- .. code-block:: python
+ .. code-block:: vyper
@external
def do_the_needful():
@@ -321,7 +330,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
The amount to send is always specified in ``wei``.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo(_receiver: address, _amount: uint256, gas: uint256):
@@ -334,14 +343,14 @@ Cryptography
Take two points on the Alt-BN128 curve and add them together.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(x: uint256[2], y: uint256[2]) -> uint256[2]:
return ecadd(x, y)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo([1, 2], [1, 2])
[
@@ -356,14 +365,14 @@ Cryptography
* ``point``: Point to be multiplied
* ``scalar``: Scalar value
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(point: uint256[2], scalar: uint256) -> uint256[2]:
return ecmul(point, scalar)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo([1, 2], 3)
[
@@ -379,9 +388,13 @@ Cryptography
* ``s``: second 32 bytes of signature
* ``v``: final 1 byte of signature
- Returns the associated address, or ``0`` on error.
+ Returns the associated address, or ``empty(address)`` on error.
+
+ .. note::
- .. code-block:: python
+ Prior to Vyper ``0.3.10``, the ``ecrecover`` function could return an undefined (possibly nonzero) value for invalid inputs to ``ecrecover``. For more information, please see `GHSA-f5x6-7qgp-jhf3 `_.
+
+ .. code-block:: vyper
@external
@view
@@ -393,7 +406,7 @@ Cryptography
@view
def foo(hash: bytes32, v: uint256, r:uint256, s:uint256) -> address:
return ecrecover(hash, v, r, s)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo('0x6c9c5e133b8aafb2ea74f524a5263495e7ae5701c7248805f7b511d973dc7055',
28,
@@ -408,14 +421,14 @@ Cryptography
* ``_value``: Value to hash. Can be a ``String``, ``Bytes``, or ``bytes32``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(_value: Bytes[100]) -> bytes32
return keccak256(_value)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(b"potato")
0x9e159dfcfe557cc1ca6c716e87af98fdcb94cd8c832386d0429b2b7bec02754f
@@ -426,14 +439,14 @@ Cryptography
* ``_value``: Value to hash. Can be a ``String``, ``Bytes``, or ``bytes32``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(_value: Bytes[100]) -> bytes32
return sha256(_value)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(b"potato")
0xe91c254ad58860a02c788dfb5c1a65d6a8846ab1dc649631c7db16fef4af2dec
@@ -447,14 +460,14 @@ Data Manipulation
If the input arguments are ``String`` the return type is ``String``. Otherwise the return type is ``Bytes``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(a: String[5], b: String[5], c: String[5]) -> String[100]:
return concat(a, " ", b, " ", c, "!")
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo("why","hello","there")
"why hello there!"
@@ -478,14 +491,14 @@ Data Manipulation
Returns the string representation of ``value``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(b: uint256) -> String[78]:
return uint2str(b)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(420)
"420"
@@ -496,18 +509,18 @@ Data Manipulation
* ``b``: ``Bytes`` list to extract from
* ``start``: Start point to extract from
- * ``output_type``: Type of output (``bytes32``, ``integer``, or ``address``). Defaults to ``bytes32``.
+ * ``output_type``: Type of output (``bytesM``, ``integer``, or ``address``). Defaults to ``bytes32``.
Returns a value of the type specified by ``output_type``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(b: Bytes[32]) -> address:
return extract32(b, 0, output_type=address)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo("0x0000000000000000000000009f8F72aA9304c8B593d555F12eF6589cC3A579A2")
"0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2"
@@ -522,14 +535,14 @@ Data Manipulation
If the value being sliced is a ``Bytes`` or ``bytes32``, the return type is ``Bytes``. If it is a ``String``, the return type is ``String``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(s: String[32]) -> String[5]:
return slice(s, 4, 5)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo("why hello! how are you?")
"hello"
@@ -543,14 +556,14 @@ Math
* ``value``: Integer to return the absolute value of
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(value: int256) -> int256:
return abs(value)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(-31337)
31337
@@ -561,32 +574,50 @@ Math
* ``value``: Decimal value to round up
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(x: decimal) -> int256:
return ceil(x)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(3.1337)
4
+.. py:function:: epsilon(typename) -> Any
+
+ Returns the smallest non-zero value for a decimal type.
+
+ * ``typename``: Name of the decimal type (currently only ``decimal``)
+
+ .. code-block:: vyper
+
+ @external
+ @view
+ def foo() -> decimal:
+ return epsilon(decimal)
+
+ .. code-block:: vyper
+
+ >>> ExampleContract.foo()
+ Decimal('1E-10')
+
.. py:function:: floor(value: decimal) -> int256
Round a decimal down to the nearest integer.
* ``value``: Decimal value to round down
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(x: decimal) -> int256:
return floor(x)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(3.1337)
3
@@ -595,14 +626,14 @@ Math
Return the greater value of ``a`` and ``b``. The input values may be any numeric type as long as they are both of the same type. The output value is of the same type as the input values.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(a: uint256, b: uint256) -> uint256:
return max(a, b)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(23, 42)
42
@@ -611,14 +642,14 @@ Math
Returns the maximum value of the numeric type specified by ``type_`` (e.g., ``int128``, ``uint256``, ``decimal``).
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo() -> int256:
return max_value(int256)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo()
57896044618658097711785492504343953926634992332820282019728792003956564819967
@@ -627,14 +658,14 @@ Math
Returns the lesser value of ``a`` and ``b``. The input values may be any numeric type as long as they are both of the same type. The output value is of the same type as the input values.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(a: uint256, b: uint256) -> uint256:
return min(a, b)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(23, 42)
23
@@ -643,14 +674,14 @@ Math
Returns the minimum value of the numeric type specified by ``type_`` (e.g., ``int128``, ``uint256``, ``decimal``).
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo() -> int256:
return min_value(int256)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo()
-57896044618658097711785492504343953926634992332820282019728792003956564819968
@@ -661,14 +692,14 @@ Math
This method is used to perform exponentiation without overflow checks.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(a: uint256, b: uint256) -> uint256:
return pow_mod256(a, b)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(2, 3)
8
@@ -679,14 +710,14 @@ Math
Return the square root of the provided decimal number, using the Babylonian square root algorithm.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(d: decimal) -> decimal:
return sqrt(d)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(9.0)
3.0
@@ -695,14 +726,14 @@ Math
Return the (integer) square root of the provided integer number, using the Babylonian square root algorithm. The rounding mode is to round down to the nearest integer. For instance, ``isqrt(101) == 10``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(x: uint256) -> uint256:
return isqrt(x)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(101)
10
@@ -711,14 +742,14 @@ Math
Return the modulo of ``(a + b) % c``. Reverts if ``c == 0``. As this built-in function is intended to provides access to the underlying ``ADDMOD`` opcode, all intermediate calculations of this operation are not subject to the ``2 ** 256`` modulo according to the EVM specifications.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(a: uint256, b: uint256, c: uint256) -> uint256:
return uint256_addmod(a, b, c)
- .. code-block:: python
+ .. code-block:: vyper
>>> (6 + 13) % 8
3
@@ -729,14 +760,14 @@ Math
Return the modulo from ``(a * b) % c``. Reverts if ``c == 0``. As this built-in function is intended to provides access to the underlying ``MULMOD`` opcode, all intermediate calculations of this operation are not subject to the ``2 ** 256`` modulo according to the EVM specifications.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(a: uint256, b: uint256, c: uint256) -> uint256:
return uint256_mulmod(a, b, c)
- .. code-block:: python
+ .. code-block:: vyper
>>> (11 * 2) % 5
2
@@ -747,7 +778,7 @@ Math
Add ``x`` and ``y``, without checking for overflow. ``x`` and ``y`` must both be integers of the same type. If the result exceeds the bounds of the input type, it will be wrapped.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
@@ -760,7 +791,7 @@ Math
return unsafe_add(x, y)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(1, 1)
2
@@ -778,7 +809,7 @@ Math
Subtract ``x`` and ``y``, without checking for overflow. ``x`` and ``y`` must both be integers of the same type. If the result underflows the bounds of the input type, it will be wrapped.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
@@ -791,7 +822,7 @@ Math
return unsafe_sub(x, y)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(4, 3)
1
@@ -810,7 +841,7 @@ Math
Multiply ``x`` and ``y``, without checking for overflow. ``x`` and ``y`` must both be integers of the same type. If the result exceeds the bounds of the input type, it will be wrapped.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
@@ -823,7 +854,7 @@ Math
return unsafe_mul(x, y)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(1, 1)
1
@@ -845,7 +876,7 @@ Math
Divide ``x`` and ``y``, without checking for division-by-zero. ``x`` and ``y`` must both be integers of the same type. If the denominator is zero, the result will (following EVM semantics) be zero.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
@@ -858,7 +889,7 @@ Math
return unsafe_div(x, y)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(1, 1)
1
@@ -883,14 +914,14 @@ Utilities
* ``_value``: Value for the ether unit. Any numeric type may be used, however the value cannot be negative.
* ``unit``: Ether unit name (e.g. ``"wei"``, ``"ether"``, ``"gwei"``, etc.) indicating the denomination of ``_value``. Must be given as a literal string.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(s: String[32]) -> uint256:
return as_wei_value(1.337, "ether")
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo(1)
1337000000000000000
@@ -903,14 +934,14 @@ Utilities
The EVM only provides access to the most recent 256 blocks. This function reverts if the block number is greater than or equal to the current block number or more than 256 blocks behind the current block.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo() -> bytes32:
return blockhash(block.number - 16)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo()
0xf3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
@@ -921,7 +952,7 @@ Utilities
* ``typename``: Name of the type, except ``HashMap[_KeyType, _ValueType]``
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
@@ -932,14 +963,14 @@ Utilities
Return the length of a given ``Bytes``, ``String`` or ``DynArray[_Type, _Integer]``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo(s: String[32]) -> uint256:
return len(s)
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo("hello")
5
@@ -953,14 +984,14 @@ Utilities
Returns a value of the type specified by ``output_type``.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
def foo() -> Bytes[4]:
return method_id('transfer(address,uint256)', output_type=Bytes[4])
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo()
0xa9059cbb
@@ -976,7 +1007,7 @@ Utilities
Returns a bytestring whose max length is determined by the arguments. For example, encoding a ``Bytes[32]`` results in a ``Bytes[64]`` (first word is the length of the bytestring variable).
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
@@ -985,7 +1016,7 @@ Utilities
y: Bytes[32] = b"234"
return _abi_encode(x, y, method_id=method_id("foo()"))
- .. code-block:: python
+ .. code-block:: vyper
>>> ExampleContract.foo().hex()
"c2985578"
@@ -1006,7 +1037,7 @@ Utilities
Returns the decoded value(s), with type as specified by `output_type`.
- .. code-block:: python
+ .. code-block:: vyper
@external
@view
diff --git a/docs/compiler-exceptions.rst b/docs/compiler-exceptions.rst
index 395ce448ed..29b8b5c96e 100644
--- a/docs/compiler-exceptions.rst
+++ b/docs/compiler-exceptions.rst
@@ -58,7 +58,7 @@ of the error within the code:
Raises when no valid type can be found for a literal value.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo():
@@ -70,7 +70,7 @@ of the error within the code:
Raises when using an invalid operator for a given type.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo():
@@ -82,7 +82,7 @@ of the error within the code:
Raises on an invalid reference to an existing definition.
- .. code-block:: python
+ .. code-block:: vyper
baz: int128
@@ -96,7 +96,7 @@ of the error within the code:
Raises when using an invalid literal value for the given type.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo():
@@ -132,7 +132,7 @@ of the error within the code:
Raises when attempting to access ``msg.value`` from within a function that has not been marked as ``@payable``.
- .. code-block:: python
+ .. code-block:: vyper
@public
def _foo():
@@ -174,7 +174,7 @@ of the error within the code:
Raises when attempting to perform an action between two or more objects with known, dislike types.
- .. code-block:: python
+ .. code-block:: vyper
@external
def foo(:
@@ -215,7 +215,7 @@ CompilerPanic
.. py:exception:: CompilerPanic
- ::
+ .. code:: shell
$ vyper v.vy
Error compiling: v.vy
diff --git a/docs/compiling-a-contract.rst b/docs/compiling-a-contract.rst
index 4a03347536..36b46497f9 100644
--- a/docs/compiling-a-contract.rst
+++ b/docs/compiling-a-contract.rst
@@ -20,20 +20,23 @@ vyper
To compile a contract:
-::
+.. code:: shell
$ vyper yourFileName.vy
Include the ``-f`` flag to specify which output formats to return. Use ``vyper --help`` for a full list of output options.
-::
+.. code:: shell
- $ vyper -f abi,bytecode,bytecode_runtime,ir,asm,source_map,method_identifiers yourFileName.vy
+ $ vyper -f abi,abi_python,bytecode,bytecode_runtime,interface,external_interface,ast,ir,ir_json,ir_runtime,hex-ir,asm,opcodes,opcodes_runtime,source_map,method_identifiers,userdoc,devdoc,metadata,combined_json,layout yourFileName.vy
+
+.. note::
+ The ``opcodes`` and ``opcodes_runtime`` output of the compiler has been returning incorrect opcodes since ``0.2.0`` due to a lack of 0 padding (patched via `PR 3735 `_). If you rely on these functions for debugging, please use the latest patched versions.
The ``-p`` flag allows you to set a root path that is used when searching for interface files to import. If none is given, it will default to the current working directory. See :ref:`searching_for_imports` for more information.
-::
+.. code:: shell
$ vyper -p yourProject yourProject/yourFileName.vy
@@ -45,7 +48,7 @@ Storage Layout
To display the default storage layout for a contract:
-::
+.. code:: shell
$ vyper -f layout yourFileName.vy
@@ -53,7 +56,7 @@ This outputs a JSON object detailing the locations for all state variables as de
To override the default storage layout for a contract:
-::
+.. code:: shell
$ vyper --storage-layout-file storageLayout.json yourFileName.vy
@@ -69,19 +72,19 @@ vyper-json
To compile from JSON supplied via ``stdin``:
-::
+.. code:: shell
$ vyper-json
To compile from a JSON file:
-::
+.. code:: shell
$ vyper-json yourProject.json
By default, the output is sent to ``stdout``. To redirect to a file, use the ``-o`` flag:
-::
+.. code:: shell
$ vyper-json -o compiled.json
@@ -99,6 +102,11 @@ See :ref:`searching_for_imports` for more information on Vyper's import system.
Online Compilers
================
+Try VyperLang!
+-----------------
+
+`Try VyperLang! `_ is a JupterHub instance hosted by the Vyper team as a sandbox for developing and testing contracts in Vyper. It requires github for login, and supports deployment via the browser.
+
Remix IDE
---------
@@ -108,25 +116,53 @@ Remix IDE
While the Vyper version of the Remix IDE compiler is updated on a regular basis, it might be a bit behind the latest version found in the master branch of the repository. Make sure the byte code matches the output from your local compiler.
+.. _optimization-mode:
+
+Compiler Optimization Modes
+===========================
+
+The vyper CLI tool accepts an optimization mode ``"none"``, ``"codesize"``, or ``"gas"`` (default). It can be set using the ``--optimize`` flag. For example, invoking ``vyper --optimize codesize MyContract.vy`` will compile the contract, optimizing for code size. As a rough summary of the differences between gas and codesize mode, in gas optimized mode, the compiler will try to generate bytecode which minimizes gas (up to a point), including:
+
+* using a sparse selector table which optimizes for gas over codesize
+* inlining some constants, and
+* trying to unroll some loops, especially for data copies.
+
+In codesize optimized mode, the compiler will try hard to minimize codesize by
+
+* using a dense selector table
+* out-lining code, and
+* using more loops for data copies.
+
+
+.. _evm-version:
Setting the Target EVM Version
==============================
-When you compile your contract code, you can specify the Ethereum Virtual Machine version to compile for, to avoid particular features or behaviours.
+When you compile your contract code, you can specify the target Ethereum Virtual Machine version to compile for, to access or avoid particular features. You can specify the version either with a source code pragma or as a compiler option. It is recommended to use the compiler option when you want flexibility (for instance, ease of deploying across different chains), and the source code pragma when you want bytecode reproducibility (for instance, when verifying code on a block explorer).
+
+.. note::
+ If the evm version specified by the compiler options conflicts with the source code pragma, an exception will be raised and compilation will not continue.
+
+For instance, the adding the following pragma to a contract indicates that it should be compiled for the "shanghai" fork of the EVM.
+
+.. code-block:: vyper
+
+ #pragma evm-version shanghai
.. warning::
- Compiling for the wrong EVM version can result in wrong, strange and failing behaviour. Please ensure, especially if running a private chain, that you use matching EVM versions.
+ Compiling for the wrong EVM version can result in wrong, strange, or failing behavior. Please ensure, especially if running a private chain, that you use matching EVM versions.
-When compiling via ``vyper``, include the ``--evm-version`` flag:
+When compiling via the ``vyper`` CLI, you can specify the EVM version option using the ``--evm-version`` flag:
-::
+.. code:: shell
$ vyper --evm-version [VERSION]
-When using the JSON interface, include the ``"evmVersion"`` key within the ``"settings"`` field:
+When using the JSON interface, you can include the ``"evmVersion"`` key within the ``"settings"`` field:
-.. code-block:: javascript
+.. code-block:: json
{
"settings": {
@@ -140,24 +176,31 @@ Target Options
The following is a list of supported EVM versions, and changes in the compiler introduced with each version. Backward compatibility is not guaranteed between each version.
-.. py:attribute:: byzantium
+.. py:attribute:: istanbul
- - The oldest EVM version supported by Vyper.
+ - The ``CHAINID`` opcode is accessible via ``chain.id``
+ - The ``SELFBALANCE`` opcode is used for calls to ``self.balance``
+ - Gas estimates changed for ``SLOAD`` and ``BALANCE``
-.. py:attribute:: constantinople
+.. py:attribute:: berlin
- - The ``EXTCODEHASH`` opcode is accessible via ``address.codehash``
- - ``shift`` makes use of ``SHL``/``SHR`` opcodes.
+ - Gas estimates changed for ``EXTCODESIZE``, ``EXTCODECOPY``, ``EXTCODEHASH``, ``SLOAD``, ``SSTORE``, ``CALL``, ``CALLCODE``, ``DELEGATECALL`` and ``STATICCALL``
+ - Functions marked with ``@nonreentrant`` are protected with different values (3 and 2) than contracts targeting pre-berlin.
+ - ``BASEFEE`` is accessible via ``block.basefee``
-.. py:attribute:: petersburg
+.. py:attribute:: paris
- - The compiler behaves the same way as with constantinople.
+ - ``block.difficulty`` is deprecated in favor of its new alias, ``block.prevrandao``.
-.. py:attribute:: istanbul (default)
+.. py:attribute:: shanghai (default)
- - The ``CHAINID`` opcode is accessible via ``chain.id``
- - The ``SELFBALANCE`` opcode is used for calls to ``self.balance``
- - Gas estimates changed for ``SLOAD`` and ``BALANCE``
+ - The ``PUSH0`` opcode is automatically generated by the compiler instead of ``PUSH1 0``
+
+.. py:attribute:: cancun (experimental)
+
+ - The ``transient`` keyword allows declaration of variables which live in transient storage
+ - Functions marked with ``@nonreentrant`` are protected with TLOAD/TSTORE instead of SLOAD/SSTORE
+ - The ``MCOPY`` opcode will be generated automatically by the compiler for most memory operations.
Compiler Input and Output JSON Description
@@ -174,7 +217,7 @@ Input JSON Description
The following example describes the expected input format of ``vyper-json``. Comments are of course not permitted and used here *only for explanatory purposes*.
-.. code-block:: javascript
+.. code-block:: json
{
// Required: Source code language. Must be set to "Vyper".
@@ -204,10 +247,11 @@ The following example describes the expected input format of ``vyper-json``. Com
},
// Optional
"settings": {
- "evmVersion": "istanbul", // EVM version to compile for. Can be byzantium, constantinople, petersburg or istanbul.
- // optional, whether or not optimizations are turned on
- // defaults to true
- "optimize": true,
+ "evmVersion": "shanghai", // EVM version to compile for. Can be istanbul, berlin, paris, shanghai (default) or cancun (experimental!).
+ // optional, optimization mode
+ // defaults to "gas". can be one of "gas", "codesize", "none",
+ // false and true (the last two are for backwards compatibility).
+ "optimize": "gas",
// optional, whether or not the bytecode should include Vyper's signature
// defaults to true
"bytecodeMetadata": true,
@@ -251,7 +295,7 @@ Output JSON Description
The following example describes the output format of ``vyper-json``. Comments are of course not permitted and used here *only for explanatory purposes*.
-.. code-block:: javascript
+.. code-block:: json
{
// The compiler version used to generate the JSON
diff --git a/docs/conf.py b/docs/conf.py
index 12af82b6e4..99ffe35a63 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,126 +1,44 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
# Vyper documentation build configuration file, created by
# sphinx-quickstart on Wed Jul 26 11:18:29 2017.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-# import os
-# import sys
-# sys.path.insert(0, os.path.abspath('.'))
-from recommonmark.parser import CommonMarkParser
-
-# TO DO - Create and Implement Vyper Lexer
-# def setup(sphinx):
-# sys.path.insert(0, os.path.abspath('./utils'))
-# from SolidityLexer import SolidityLexer
-# sphinx.add_lexer('Python', SolidityLexer())
-
-
-# -- General configuration ------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#
-# needs_sphinx = '1.0'
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
extensions = [
- "sphinx.ext.autodoc",
+ "sphinx_copybutton",
"sphinx.ext.intersphinx",
]
-# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
-
-# The suffix(es) of source filenames.
-# You can specify multiple suffix as a list of string:
-#
-source_suffix = [".rst", ".md"]
-
-# The master toctree document.
master_doc = "toctree"
# General information about the project.
project = "Vyper"
-copyright = "2017-2020 CC-BY-4.0 Vyper Team"
+copyright = "2017-2024 CC-BY-4.0 Vyper Team"
author = "Vyper Team (originally created by Vitalik Buterin)"
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = ""
-# The full version, including alpha/beta/rc tags.
-release = ""
-
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
-language = "python"
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-# This patterns also effect to html_static_path and html_extra_path
-exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = "sphinx"
-
-# If true, `todo` and `todoList` produce output, else they produce nothing.
-todo_include_todos = False
-
+language = "vyper"
# -- Options for HTML output ----------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-#
-html_theme = "sphinx_rtd_theme"
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#
-# html_theme_options = {}
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ["_static"]
-
-html_css_files = ["css/toggle.css", "css/dark.css"]
-
-html_js_files = ["js/toggle.js"]
-
-html_logo = "vyper-logo-transparent.svg"
-
-# Custom sidebar templates, must be a dictionary that maps document names
-# to template names.
-#
-# The default sidebars (for documents that don't match any pattern) are
-# defined by theme itself. Builtin themes are using these templates by
-# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
-# 'searchbox.html']``.
-#
-# html_sidebars = {}
-
+html_theme = "shibuya"
+html_theme_options = {
+ "accent_color": "purple",
+ "twitter_creator": "vyperlang",
+ "twitter_site": "vyperlang",
+ "twitter_url": "https://twitter.com/vyperlang",
+ "github_url": "https://github.com/vyperlang",
+}
+html_favicon = "logo.svg"
+html_logo = "logo.svg"
+
+# For the "Edit this page ->" link
+html_context = {
+ "source_type": "github",
+ "source_user": "vyperlang",
+ "source_repo": "vyper",
+}
# -- Options for HTMLHelp output ------------------------------------------
@@ -130,21 +48,6 @@
# -- Options for LaTeX output ---------------------------------------------
-latex_elements: dict = {
- # The paper size ('letterpaper' or 'a4paper').
- #
- # 'papersize': 'letterpaper',
- # The font size ('10pt', '11pt' or '12pt').
- #
- # 'pointsize': '10pt',
- # Additional stuff for the LaTeX preamble.
- #
- # 'preamble': '',
- # Latex figure (float) alignment
- #
- # 'figure_align': 'htbp',
-}
-
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
@@ -153,7 +56,7 @@
master_doc,
"Vyper.tex",
"Vyper Documentation",
- "Vyper Team (originally created by Vitalik Buterin)",
+ author,
"manual",
),
]
@@ -183,12 +86,8 @@
),
]
-source_parsers = {
- ".md": CommonMarkParser,
-}
-
intersphinx_mapping = {
"brownie": ("https://eth-brownie.readthedocs.io/en/stable", None),
"pytest": ("https://docs.pytest.org/en/latest/", None),
- "python": ("https://docs.python.org/3.8/", None),
+ "python": ("https://docs.python.org/3.10/", None),
}
diff --git a/docs/constants-and-vars.rst b/docs/constants-and-vars.rst
index 7f9c1408c5..00ce7a8ccc 100644
--- a/docs/constants-and-vars.rst
+++ b/docs/constants-and-vars.rst
@@ -56,7 +56,7 @@ Accessing State Variables
``self`` is used to access a contract's :ref:`state variables`, as shown in the following example:
-.. code-block:: python
+.. code-block:: vyper
state_var: uint256
@@ -76,7 +76,7 @@ Calling Internal Functions
``self`` is also used to call :ref:`internal functions` within a contract:
-.. code-block:: python
+.. code-block:: vyper
@internal
def _times_two(amount: uint256) -> uint256:
@@ -93,7 +93,7 @@ Custom Constants
Custom constants can be defined at a global level in Vyper. To define a constant, make use of the ``constant`` keyword.
-.. code-block:: python
+.. code-block:: vyper
TOTAL_SUPPLY: constant(uint256) = 10000000
total_supply: public(uint256)
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 6dc57b26c3..55b2694424 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -5,7 +5,7 @@ Contributing
Help is always appreciated!
-To get started, you can try `installing Vyper `_ in order to familiarize
+To get started, you can try `installing Vyper `_ in order to familiarize
yourself with the components of Vyper and the build process. Also, it may be
useful to become well-versed at writing smart-contracts in Vyper.
@@ -75,4 +75,4 @@ If you are making a larger change, please consult first with the `Vyper (Smart C
Although we do CI testing, please make sure that the tests pass for supported Python version and ensure that it builds locally before submitting a pull request.
-Thank you for your help!
+Thank you for your help!
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index fc8a472ff6..4e18a21bd8 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -10,7 +10,7 @@ Functions
Functions are executable units of code within a contract. Functions may only be declared within a contract's :ref:`module scope `.
-.. code-block:: python
+.. code-block:: vyper
@external
def bid():
@@ -30,7 +30,7 @@ External Functions
External functions (marked with the ``@external`` decorator) are a part of the contract interface and may only be called via transactions or from other contracts.
-.. code-block:: python
+.. code-block:: vyper
@external
def add_seven(a: int128) -> int128:
@@ -52,7 +52,7 @@ Internal Functions
Internal functions (marked with the ``@internal`` decorator) are only accessible from other functions within the same contract. They are called via the :ref:`self` object:
-.. code-block:: python
+.. code-block:: vyper
@internal
def _times_two(amount: uint256, two: uint256 = 2) -> uint256:
@@ -77,7 +77,7 @@ You can optionally declare a function's mutability by using a :ref:`decorator )`` decorator places a lock on a function, and all functions with the same ```` value. An attempt by an external contract to call back into any of these functions causes the transaction to revert.
+The ``@nonreentrant`` decorator places a global nonreentrancy lock on a function. An attempt by an external contract to call back into any other ``@nonreentrant`` function causes the transaction to revert.
-.. code-block:: python
+.. code-block:: vyper
@external
- @nonreentrant("lock")
+ @nonreentrant
def make_a_call(_addr: address):
# this function is protected from re-entrancy
...
-You can put the ``@nonreentrant()`` decorator on a ``__default__`` function but we recommend against it because in most circumstances it will not work in a meaningful way.
+You can put the ``@nonreentrant`` decorator on a ``__default__`` function but we recommend against it because in most circumstances it will not work in a meaningful way.
Nonreentrancy locks work by setting a specially allocated storage slot to a ```` value on function entrance, and setting it to an ```` value on function exit. On function entrance, if the storage slot is detected to be the ```` value, execution reverts.
You cannot put the ``@nonreentrant`` decorator on a ``pure`` function. You can put it on a ``view`` function, but it only checks that the function is not in a callback (the storage slot is not in the ```` state), as ``view`` functions can only read the state, not change it.
+You can view where the nonreentrant key is physically laid out in storage by using ``vyper`` with the ``-f layout`` option (e.g., ``vyper -f layout foo.vy``). Unless it is overriden, the compiler will allocate it at slot ``0``.
+
.. note::
A mutable function can protect a ``view`` function from being called back into (which is useful for instance, if a ``view`` function would return inconsistent state during a mutable function), but a ``view`` function cannot protect itself from being called back into. Note that mutable functions can never be called from a ``view`` function because all external calls out from a ``view`` function are protected by the use of the ``STATICCALL`` opcode.
@@ -123,9 +125,11 @@ You cannot put the ``@nonreentrant`` decorator on a ``pure`` function. You can p
A nonreentrant lock has an ```` value of 3, and a ```` value of 2. Nonzero values are used to take advantage of net gas metering - as of the Berlin hard fork, the net cost for utilizing a nonreentrant lock is 2300 gas. Prior to v0.3.4, the ```` and ```` values were 0 and 1, respectively.
+.. note::
+ Prior to 0.4.0, nonreentrancy keys took a "key" argument for fine-grained nonreentrancy control. As of 0.4.0, only a global nonreentrancy lock is available.
The ``__default__`` Function
---------------------------
+----------------------------
A contract can also have a default function, which is executed on a call to the contract if no other functions match the given function identifier (or if none was supplied at all, such as through someone sending it Eth). It is the same construct as fallback functions `in Solidity `_.
@@ -133,7 +137,7 @@ This function is always named ``__default__``. It must be annotated with ``@exte
If the function is annotated as ``@payable``, this function is executed whenever the contract is sent Ether (without data). This is why the default function cannot accept arguments - it is a design decision of Ethereum to make no differentiation between sending ether to a contract or a user address.
-.. code-block:: python
+.. code-block:: vyper
event Payment:
amount: uint256
@@ -165,11 +169,11 @@ Lastly, although the default function receives no arguments, it can still access
* the gas provided (``msg.gas``).
The ``__init__`` Function
------------------------
+-------------------------
``__init__`` is a special initialization function that may only be called at the time of deploying a contract. It can be used to set initial values for storage variables. A common use case is to set an ``owner`` variable with the creator the contract:
-.. code-block:: python
+.. code-block:: vyper
owner: address
@@ -194,7 +198,7 @@ Decorator Description
``@pure`` Function does not read contract state or environment variables
``@view`` Function does not alter contract state
``@payable`` Function is able to receive Ether
-``@nonreentrant()`` Function cannot be called back into during an external call
+``@nonreentrant`` Function cannot be called back into during an external call
=============================== ===========================================================
``if`` statements
@@ -202,7 +206,7 @@ Decorator Description
The ``if`` statement is a control flow construct used for conditional execution:
-.. code-block:: python
+.. code-block:: vyper
if CONDITION:
...
@@ -213,7 +217,7 @@ Note that unlike Python, Vyper does not allow implicit conversion from non-boole
You can also include ``elif`` and ``else`` statements, to add more conditional statements and a body that executes when the conditionals are false:
-.. code-block:: python
+.. code-block:: vyper
if CONDITION:
...
@@ -227,7 +231,7 @@ You can also include ``elif`` and ``else`` statements, to add more conditional s
The ``for`` statement is a control flow construct used to iterate over a value:
-.. code-block:: python
+.. code-block:: vyper
for i in :
...
@@ -239,7 +243,7 @@ Array Iteration
You can use ``for`` to iterate through the values of any array variable:
-.. code-block:: python
+.. code-block:: vyper
foo: int128[3] = [4, 23, 42]
for i in foo:
@@ -249,7 +253,7 @@ In the above, example, the loop executes three times with ``i`` assigned the val
You can also iterate over a literal array, as long as a common type can be determined for each item in the array:
-.. code-block:: python
+.. code-block:: vyper
for i in [4, 23, 42]:
...
@@ -264,23 +268,34 @@ Range Iteration
Ranges are created using the ``range`` function. The following examples are valid uses of ``range``:
-.. code-block:: python
+.. code-block:: vyper
for i in range(STOP):
...
``STOP`` is a literal integer greater than zero. ``i`` begins as zero and increments by one until it is equal to ``STOP``.
-.. code-block:: python
+.. code-block:: vyper
- for i in range(START, STOP):
+ for i in range(stop, bound=N):
...
-``START`` and ``STOP`` are literal integers, with ``STOP`` being a greater value than ``START``. ``i`` begins as ``START`` and increments by one until it is equal to ``STOP``.
+Here, ``stop`` can be a variable with integer type, greater than zero. ``N`` must be a compile-time constant. ``i`` begins as zero and increments by one until it is equal to ``stop``. If ``stop`` is larger than ``N``, execution will revert at runtime. In certain cases, you may not have a guarantee that ``stop`` is less than ``N``, but still want to avoid the possibility of runtime reversion. To accomplish this, use the ``bound=`` keyword in combination with ``min(stop, N)`` as the argument to ``range``, like ``range(min(stop, N), bound=N)``. This is helpful for use cases like chunking up operations on larger arrays across multiple transactions.
-.. code-block:: python
+Another use of range can be with ``START`` and ``STOP`` bounds.
- for i in range(a, a + N):
+.. code-block:: vyper
+
+ for i in range(START, STOP):
...
-``a`` is a variable with an integer type and ``N`` is a literal integer greater than zero. ``i`` begins as ``a`` and increments by one until it is equal to ``a + N``.
+Here, ``START`` and ``STOP`` are literal integers, with ``STOP`` being a greater value than ``START``. ``i`` begins as ``START`` and increments by one until it is equal to ``STOP``.
+
+Finally, it is possible to use ``range`` with runtime `start` and `stop` values as long as a constant `bound` value is provided.
+In this case, Vyper checks at runtime that `end - start <= bound`.
+``N`` must be a compile-time constant.
+
+.. code-block:: vyper
+
+ for i in range(start, end, bound=N):
+ ...
diff --git a/docs/event-logging.rst b/docs/event-logging.rst
index c6e20954f8..4f350d6459 100644
--- a/docs/event-logging.rst
+++ b/docs/event-logging.rst
@@ -10,7 +10,7 @@ Example of Logging
This example is taken from the `sample ERC20 contract `_ and shows the basic flow of event logging:
-.. code-block:: python
+.. code-block:: vyper
# Events of the token.
event Transfer:
@@ -59,21 +59,29 @@ Declaring Events
Let's look at an event declaration in more detail.
-.. code-block:: python
+.. code-block:: vyper
event Transfer:
sender: indexed(address)
receiver: indexed(address)
value: uint256
+The EVM currently has five opcodes for emitting event logs: ``LOG0``, ``LOG1``, ``LOG2``, ``LOG3``, and ``LOG4``.
+These opcodes can be used to create log records, where each log record consists of both **topics** and **data**.
+Topics are 32-byte ''words'' that are used to describe what is happening in an event.
+While topics are searchable, data is not.
+Event data is however not limited, which means that you can include large or complicated data like arrays or strings.
+Different opcodes (``LOG0`` through ``LOG4``) allow for different numbers of topics.
+For instance, ``LOG1`` includes one topic, ``LOG2`` includes two topics, and so on.
Event declarations look similar to struct declarations, containing one or more arguments that are passed to the event. Typical events will contain two kinds of arguments:
- * **Indexed** arguments, which can be searched for by listeners. Each indexed argument is identified by the ``indexed`` keyword. Here, each indexed argument is an address. You can have any number of indexed arguments, but indexed arguments are not passed directly to listeners, although some of this information (such as the sender) may be available in the listener's `results` object.
- * **Value** arguments, which are passed through to listeners. You can have any number of value arguments and they can have arbitrary names, but each is limited by the EVM to be no more than 32 bytes.
+ * **Indexed** arguments (topics), which can be searched for by listeners. Each indexed argument is identified by the ``indexed`` keyword. Here, each indexed argument is an address. You can have up to four indexed arguments (``LOG4``), but indexed arguments are not passed directly to listeners, although some of this information (such as the sender) may be available in the listener's `results` object.
+ * **Value** arguments (data), which are passed through to listeners. You can have any number of value arguments and they can have arbitrary names, but each is limited by the EVM to be no more than 32 bytes.
+Note that the first topic of a log record consists of the signature of the name of the event that occurred, including the types of its parameters.
It is also possible to create an event with no arguments. In this case, use the ``pass`` statement:
-.. code-block:: python
+.. code-block:: vyper
event Foo: pass
@@ -84,7 +92,7 @@ Once an event is declared, you can log (send) events. You can send events as man
Logging events is done using the ``log`` statement:
-.. code-block:: python
+.. code-block:: vyper
log Transfer(msg.sender, _to, _amount)
diff --git a/docs/index.rst b/docs/index.rst
index 76ad6fbd7d..8ee48cdb83 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,4 +1,4 @@
-.. image:: vyper-logo-transparent.svg
+.. image:: logo.svg
:width: 140px
:alt: Vyper logo
:align: center
@@ -29,7 +29,7 @@ Following the principles and goals, Vyper **does not** provide the following fea
* **Modifiers**: For example in Solidity you can define a ``function foo() mod1 { ... }``, where ``mod1`` can be defined elsewhere in the code to include a check that is done before execution, a check that is done after execution, some state changes, or possibly other things. Vyper does not have this, because it makes it too easy to write misleading code. ``mod1`` just looks too innocuous for something that could add arbitrary pre-conditions, post-conditions or state changes. Also, it encourages people to write code where the execution jumps around the file, harming auditability. The usual use case for a modifier is something that performs a single check before execution of a program; our recommendation is to simply inline these checks as asserts.
* **Class inheritance**: Class inheritance requires people to jump between multiple files to understand what a program is doing, and requires people to understand the rules of precedence in case of conflicts ("Which class's function ``X`` is the one that's actually used?"). Hence, it makes code too complicated to understand which negatively impacts auditability.
* **Inline assembly**: Adding inline assembly would make it no longer possible to search for a variable name in order to find all instances where that variable is read or modified.
-* **Function overloading**: This can cause lots of confusion on which function is called at any given time. Thus it's easier to write missleading code (``foo("hello")`` logs "hello" but ``foo("hello", "world")`` steals your funds). Another problem with function overloading is that it makes the code much harder to search through as you have to keep track on which call refers to which function.
+* **Function overloading**: This can cause lots of confusion on which function is called at any given time. Thus it's easier to write misleading code (``foo("hello")`` logs "hello" but ``foo("hello", "world")`` steals your funds). Another problem with function overloading is that it makes the code much harder to search through as you have to keep track on which call refers to which function.
* **Operator overloading**: Operator overloading makes writing misleading code possible. For example ``+`` could be overloaded so that it executes commands that are not visible at a first glance, such as sending funds the user did not want to send.
* **Recursive calling**: Recursive calling makes it impossible to set an upper bound on gas limits, opening the door for gas limit attacks.
* **Infinite-length loops**: Similar to recursive calling, infinite-length loops make it impossible to set an upper bound on gas limits, opening the door for gas limit attacks.
diff --git a/docs/installing-vyper.rst b/docs/installing-vyper.rst
index 2e2d51bd6e..8eaa93590a 100644
--- a/docs/installing-vyper.rst
+++ b/docs/installing-vyper.rst
@@ -76,8 +76,12 @@ Each tagged version of vyper is uploaded to `pypi uint256: view
@@ -20,7 +20,7 @@ The ``interface`` keyword is used to define an inline external interface:
The defined interface can then be used to make external calls, given a contract address:
-.. code-block:: python
+.. code-block:: vyper
@external
def test(foobar: FooBar):
@@ -28,7 +28,7 @@ The defined interface can then be used to make external calls, given a contract
The interface name can also be used as a type annotation for storage variables. You then assign an address value to the variable to access that interface. Note that casting an address to an interface is possible, e.g. ``FooBar()``:
-.. code-block:: python
+.. code-block:: vyper
foobar_contract: FooBar
@@ -42,7 +42,7 @@ The interface name can also be used as a type annotation for storage variables.
Specifying ``payable`` or ``nonpayable`` annotation indicates that the call made to the external contract will be able to alter storage, whereas the ``view`` ``pure`` call will use a ``STATICCALL`` ensuring no storage can be altered during execution. Additionally, ``payable`` allows non-zero value to be sent along with the call.
-.. code-block:: python
+.. code-block:: vyper
interface FooBar:
def calculate() -> uint256: pure
@@ -70,7 +70,7 @@ Keyword Description
The ``default_return_value`` parameter can be used to handle ERC20 tokens affected by the missing return value bug in a way similar to OpenZeppelin's ``safeTransfer`` for Solidity:
-.. code-block:: python
+.. code-block:: vyper
ERC20(USDT).transfer(msg.sender, 1, default_return_value=True) # returns True
ERC20(USDT).transfer(msg.sender, 1) # reverts because nothing returned
@@ -86,7 +86,7 @@ Interfaces are imported with ``import`` or ``from ... import`` statements.
Imported interfaces are written using standard Vyper syntax. The body of each function is ignored when the interface is imported. If you are defining a standalone interface, it is normally specified by using a ``pass`` statement:
-.. code-block:: python
+.. code-block:: vyper
@external
def test1():
@@ -98,7 +98,7 @@ Imported interfaces are written using standard Vyper syntax. The body of each fu
You can also import a fully implemented contract and Vyper will automatically convert it to an interface. It is even possible for a contract to import itself to gain access to its own interface.
-.. code-block:: python
+.. code-block:: vyper
import greeter as Greeter
@@ -118,7 +118,7 @@ Imports via ``import``
With absolute ``import`` statements, you **must** include an alias as a name for the imported package. In the following example, failing to include ``as Foo`` will raise a compile error:
-.. code-block:: python
+.. code-block:: vyper
import contract.foo as Foo
@@ -127,7 +127,7 @@ Imports via ``from ... import``
Using ``from`` you can perform both absolute and relative imports. You may optionally include an alias - if you do not, the name of the interface will be the same as the file.
-.. code-block:: python
+.. code-block:: vyper
# without an alias
from contract import foo
@@ -137,7 +137,7 @@ Using ``from`` you can perform both absolute and relative imports. You may optio
Relative imports are possible by prepending dots to the contract name. A single leading dot indicates a relative import starting with the current package. Two leading dots indicate a relative import from the parent of the current package:
-.. code-block:: python
+.. code-block:: vyper
from . import foo
from ..interfaces import baz
@@ -160,11 +160,11 @@ In the above example, the ``my_project`` folder is set as the root path. A contr
Built-in Interfaces
===================
-Vyper includes common built-in interfaces such as `ERC20 `_ and `ERC721 `_. These are imported from ``vyper.interfaces``:
+Vyper includes common built-in interfaces such as `ERC20 `_ and `ERC721 `_. These are imported from ``ethereum.ercs``:
-.. code-block:: python
+.. code-block:: vyper
- from vyper.interfaces import ERC20
+ from ethereum.ercs import ERC20
implements: ERC20
@@ -175,7 +175,7 @@ Implementing an Interface
You can define an interface for your contract with the ``implements`` statement:
-.. code-block:: python
+.. code-block:: vyper
import an_interface as FooBarInterface
diff --git a/docs/logo.svg b/docs/logo.svg
new file mode 100644
index 0000000000..d2c666074a
--- /dev/null
+++ b/docs/logo.svg
@@ -0,0 +1,4 @@
+
diff --git a/docs/natspec.rst b/docs/natspec.rst
index a6c2d932e4..90ad5d39b4 100644
--- a/docs/natspec.rst
+++ b/docs/natspec.rst
@@ -17,7 +17,7 @@ Vyper supports structured documentation for contracts and external functions usi
The compiler does not parse docstrings of internal functions. You are welcome to NatSpec in comments for internal functions, however they are not processed or included in the compiler output.
-.. code-block:: python
+.. code-block:: vyper
"""
@title A simulator for Bug Bunny, the most famous Rabbit
@@ -72,16 +72,16 @@ When parsed by the compiler, documentation such as the one from the above exampl
If the above contract is saved as ``carrots.vy`` then you can generate the documentation using:
-.. code::
+.. code:: shell
- vyper -f userdoc,devdoc carrots.vy
+ $ vyper -f userdoc,devdoc carrots.vy
User Documentation
------------------
The above documentation will produce the following user documentation JSON as output:
-.. code-block:: javascript
+.. code-block:: json
{
"methods": {
@@ -102,7 +102,7 @@ Developer Documentation
Apart from the user documentation file, a developer documentation JSON
file should also be produced and should look like this:
-.. code-block:: javascript
+.. code-block:: json
{
"author": "Warned Bros",
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index 89a528dc49..2572c2690d 100644
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -3,34 +3,212 @@
Release Notes
#############
+..
+ vim regexes:
+ first convert all single backticks to double backticks:
+ :'<,'>s/`/``/g
+ to convert links to nice rst links:
+ :'<,'>s/\v(https:\/\/github.com\/vyperlang\/vyper\/pull\/)(\d+)/(`#\2 <\1\2>`_)/g
+ ex. in: https://github.com/vyperlang/vyper/pull/3373
+ ex. out: (`#3373 `_)
+ for advisory links:
+ :'<,'>s/\v(https:\/\/github.com\/vyperlang\/vyper\/security\/advisories\/)([-A-Za-z0-9]+)/(`\2 <\1\2>`_)/g
+
+v0.3.10 ("Black Adder")
+***********************
+
+Date released: 2023-10-04
+=========================
+
+v0.3.10 is a performance focused release that additionally ships numerous bugfixes. It adds a ``codesize`` optimization mode (`#3493 `_), adds new vyper-specific ``#pragma`` directives (`#3493 `_), uses Cancun's ``MCOPY`` opcode for some compiler generated code (`#3483 `_), and generates selector tables which now feature O(1) performance (`#3496 `_).
+
+Breaking changes:
+-----------------
+
+- add runtime code layout to initcode (`#3584 `_)
+- drop evm versions through istanbul (`#3470 `_)
+- remove vyper signature from runtime (`#3471 `_)
+- only allow valid identifiers to be nonreentrant keys (`#3605 `_)
+
+Non-breaking changes and improvements:
+--------------------------------------
+
+- O(1) selector tables (`#3496 `_)
+- implement bound= in ranges (`#3537 `_, `#3551 `_)
+- add optimization mode to vyper compiler (`#3493 `_)
+- improve batch copy performance (`#3483 `_, `#3499 `_, `#3525 `_)
+
+Notable fixes:
+--------------
+
+- fix ``ecrecover()`` behavior when signature is invalid (`GHSA-f5x6-7qgp-jhf3 `_, `#3586 `_)
+- fix: order of evaluation for some builtins (`#3583 `_, `#3587 `_)
+- fix: memory allocation in certain builtins using ``msize`` (`#3610 `_)
+- fix: ``_abi_decode()`` input validation in certain complex expressions (`#3626 `_)
+- fix: pycryptodome for arm builds (`#3485 `_)
+- let params of internal functions be mutable (`#3473 `_)
+- typechecking of folded builtins in (`#3490 `_)
+- update tload/tstore opcodes per latest 1153 EIP spec (`#3484 `_)
+- fix: raw_call type when max_outsize=0 is set (`#3572 `_)
+- fix: implements check for indexed event arguments (`#3570 `_)
+- fix: type-checking for ``_abi_decode()`` arguments (`#3626 `__)
+
+Other docs updates, chores and fixes:
+-------------------------------------
+
+- relax restrictions on internal function signatures (`#3573 `_)
+- note on security advisory in release notes for versions ``0.2.15``, ``0.2.16``, and ``0.3.0`` (`#3553 `_)
+- fix: yanked version in release notes (`#3545 `_)
+- update release notes on yanked versions (`#3547 `_)
+- improve error message for conflicting methods IDs (`#3491 `_)
+- document epsilon builtin (`#3552 `_)
+- relax version pragma parsing (`#3511 `_)
+- fix: issue with finding installed packages in editable mode (`#3510 `_)
+- add note on security advisory for ``ecrecover`` in docs (`#3539 `_)
+- add ``asm`` option to cli help (`#3585 `_)
+- add message to error map for repeat range check (`#3542 `_)
+- fix: public constant arrays (`#3536 `_)
+
+
+v0.3.9 ("Common Adder")
+***********************
+
+Date released: 2023-05-29
+
+This is a patch release fix for v0.3.8. @bout3fiddy discovered a codesize regression for blueprint contracts in v0.3.8 which is fixed in this release. @bout3fiddy also discovered a runtime performance (gas) regression for default functions in v0.3.8 which is fixed in this release.
+
+Fixes:
+
+- initcode codesize blowup (`#3450 `_)
+- add back global calldatasize check for contracts with default fn (`#3463 `_)
+
+
+v0.3.8
+******
+
+Date released: 2023-05-23
+
+Non-breaking changes and improvements:
+
+- ``transient`` storage keyword (`#3373 `_)
+- ternary operators (`#3398 `_)
+- ``raw_revert()`` builtin (`#3136 `_)
+- shift operators (`#3019 `_)
+- make ``send()`` gas stipend configurable (`#3158 `_)
+- use new ``push0`` opcode (`#3361 `_)
+- python 3.11 support (`#3129 `_)
+- drop support for python 3.8 and 3.9 (`#3325 `_)
+- build for ``aarch64`` (`#2687 `_)
+
+Note that with the addition of ``push0`` opcode, ``shanghai`` is now the default compilation target for vyper. When deploying to a chain which does not support ``shanghai``, it is recommended to set ``--evm-version`` to ``paris``, otherwise it could result in hard-to-debug errors.
+
+Major refactoring PRs:
+
+- refactor front-end type system (`#2974 `_)
+- merge front-end and codegen type systems (`#3182 `_)
+- simplify ``GlobalContext`` (`#3209 `_)
+- remove ``FunctionSignature`` (`#3390 `_)
+
+Notable fixes:
+
+- assignment when rhs is complex type and references lhs (`#3410 `_)
+- uninitialized immutable values (`#3409 `_)
+- success value when mixing ``max_outsize=0`` and ``revert_on_failure=False`` (`GHSA-w9g2-3w7p-72g9 `_)
+- block certain kinds of storage allocator overflows (`GHSA-mgv8-gggw-mrg6 `_)
+- store-before-load when a dynarray appears on both sides of an assignment (`GHSA-3p37-3636-q8wv `_)
+- bounds check for loops of the form ``for i in range(x, x+N)`` (`GHSA-6r8q-pfpv-7cgj `_)
+- alignment of call-site posargs and kwargs for internal functions (`GHSA-ph9x-4vc9-m39g `_)
+- batch nonpayable check for default functions calldatasize < 4 (`#3104 `_, `#3408 `_, cf. `GHSA-vxmm-cwh2-q762 `_)
+
+Other docs updates, chores and fixes:
+
+- call graph stability (`#3370 `_)
+- fix ``vyper-serve`` output (`#3338 `_)
+- add ``custom:`` natspec tags (`#3403 `_)
+- add missing pc maps to ``vyper_json`` output (`#3333 `_)
+- fix constructor context for internal functions (`#3388 `_)
+- add deprecation warning for ``selfdestruct`` usage (`#3372 `_)
+- add bytecode metadata option to vyper-json (`#3117 `_)
+- fix compiler panic when a ``break`` is outside of a loop (`#3177 `_)
+- fix complex arguments to builtin functions (`#3167 `_)
+- add support for all types in ABI imports (`#3154 `_)
+- disable uadd operator (`#3174 `_)
+- block bitwise ops on decimals (`#3219 `_)
+- raise ``UNREACHABLE`` (`#3194 `_)
+- allow enum as mapping key (`#3256 `_)
+- block boolean ``not`` operator on numeric types (`#3231 `_)
+- enforce that loop's iterators are valid names (`#3242 `_)
+- fix typechecker hotspot (`#3318 `_)
+- rewrite typechecker journal to handle nested commits (`#3375 `_)
+- fix missing pc map for empty functions (`#3202 `_)
+- guard against iterating over empty list in for loop (`#3197 `_)
+- skip enum members during constant folding (`#3235 `_)
+- bitwise ``not`` constant folding (`#3222 `_)
+- allow accessing members of constant address (`#3261 `_)
+- guard against decorators in interface (`#3266 `_)
+- fix bounds for decimals in some builtins (`#3283 `_)
+- length of literal empty bytestrings (`#3276 `_)
+- block ``empty()`` for HashMaps (`#3303 `_)
+- fix type inference for empty lists (`#3377 `_)
+- disallow logging from ``pure``, ``view`` functions (`#3424 `_)
+- improve optimizer rules for comparison operators (`#3412 `_)
+- deploy to ghcr on push (`#3435 `_)
+- add note on return value bounds in interfaces (`#3205 `_)
+- index ``id`` param in ``URI`` event of ``ERC1155ownable`` (`#3203 `_)
+- add missing ``asset`` function to ``ERC4626`` built-in interface (`#3295 `_)
+- clarify ``skip_contract_check=True`` can result in undefined behavior (`#3386 `_)
+- add ``custom`` NatSpec tag to docs (`#3404 `_)
+- fix ``uint256_addmod`` doc (`#3300 `_)
+- document optional kwargs for external calls (`#3122 `_)
+- remove ``slice()`` length documentation caveats (`#3152 `_)
+- fix docs of ``blockhash`` to reflect revert behaviour (`#3168 `_)
+- improvements to compiler error messages (`#3121 `_, `#3134 `_, `#3312 `_, `#3304 `_, `#3240 `_, `#3264 `_, `#3343 `_, `#3307 `_, `#3313 `_ and `#3215 `_)
+
+These are really just the highlights, as many other bugfixes, docs updates and refactoring (over 150 pull requests!) made it into this release! For the full list, please see the `changelog `__. Special thanks to contributions from @tserg, @trocher, @z80dev, @emc415 and @benber86 in this release!
+
+New Contributors:
+
+- @omahs made their first contribution in (`#3128 `_)
+- @ObiajuluM made their first contribution in (`#3124 `_)
+- @trocher made their first contribution in (`#3134 `_)
+- @ozmium22 made their first contribution in (`#3149 `_)
+- @ToonVanHove made their first contribution in (`#3168 `_)
+- @emc415 made their first contribution in (`#3158 `_)
+- @lgtm-com made their first contribution in (`#3147 `_)
+- @tdurieux made their first contribution in (`#3224 `_)
+- @victor-ego made their first contribution in (`#3263 `_)
+- @miohtama made their first contribution in (`#3257 `_)
+- @kelvinfan001 made their first contribution in (`#2687 `_)
+
+
v0.3.7
******
Date released: 2022-09-26
-## Breaking changes:
+Breaking changes:
- chore: drop python 3.7 support (`#3071 `_)
- fix: relax check for statically sized calldata (`#3090 `_)
-## Non-breaking changes and improvements:
+Non-breaking changes and improvements:
-- fix: assert description in Crowdfund.finalize() (`#3058 `_)
+- fix: assert description in ``Crowdfund.finalize()`` (`#3058 `_)
- fix: change mutability of example ERC721 interface (`#3076 `_)
- chore: improve error message for non-checksummed address literal (`#3065 `_)
-- feat: isqrt built-in (`#3074 `_) (`#3069 `_)
-- feat: add `block.prevrandao` as alias for `block.difficulty` (`#3085 `_)
-- feat: epsilon builtin (`#3057 `_)
+- feat: ``isqrt()`` builtin (`#3074 `_) (`#3069 `_)
+- feat: add ``block.prevrandao`` as alias for ``block.difficulty`` (`#3085 `_)
+- feat: ``epsilon()`` builtin (`#3057 `_)
- feat: extend ecrecover signature to accept additional parameter types (`#3084 `_)
- feat: allow constant and immutable variables to be declared public (`#3024 `_)
- feat: optionally disable metadata in bytecode (`#3107 `_)
-## Bugfixes:
+Bugfixes:
- fix: empty nested dynamic arrays (`#3061 `_)
- fix: foldable builtin default args in imports (`#3079 `_) (`#3077 `_)
-## Additional changes and improvements:
+Additional changes and improvements:
- doc: update broken links in SECURITY.md (`#3095 `_)
- chore: update discord link in docs (`#3031 `_)
@@ -40,7 +218,7 @@ Date released: 2022-09-26
- chore: migrate lark grammar (`#3082 `_)
- chore: loosen and upgrade semantic version (`#3106 `_)
-# New Contributors
+New Contributors
- @emilianobonassi made their first contribution in `#3107 `_
- @unparalleled-js made their first contribution in `#3106 `_
@@ -65,6 +243,7 @@ Bugfixes:
v0.3.5
******
+**THIS RELEASE HAS BEEN PULLED**
Date released: 2022-08-05
@@ -167,7 +346,7 @@ Notable Fixes:
* Referencing immutables in constructor (`#2627 `_)
* Arrays of interfaces in for loops (`#2699 `_)
-Lots of optimizations, refactoring and other fixes made it into this release! For the full list, please see the `changelog `_.
+Lots of optimizations, refactoring and other fixes made it into this release! For the full list, please see the `changelog `__.
Special thanks to @tserg for typechecker fixes and significant testing of new features! Additional contributors to this release include @abdullathedruid, @hi-ogawa, @skellet0r, @fubuloubu, @onlymaresia, @SwapOperator, @hitsuzen-eth, @Sud0u53r, @davidhq.
@@ -213,6 +392,7 @@ Special thanks to @skellet0r for some major features in this release!
v0.3.0
*******
+⚠️ A critical security vulnerability has been discovered in this version and we strongly recommend using version `0.3.1 `_ or higher. For more information, please see the Security Advisory `GHSA-5824-cm3x-3c38 `_.
Date released: 2021-10-04
@@ -245,6 +425,7 @@ Special thanks to contributions from @skellet0r and @benjyz for this release!
v0.2.16
*******
+⚠️ A critical security vulnerability has been discovered in this version and we strongly recommend using version `0.3.1 `_ or higher. For more information, please see the Security Advisory `GHSA-5824-cm3x-3c38 `_.
Date released: 2021-08-27
@@ -269,6 +450,7 @@ Special thanks to contributions from @skellet0r, @sambacha and @milancermak for
v0.2.15
*******
+⚠️ A critical security vulnerability has been discovered in this version and we strongly recommend using version `0.3.1 `_ or higher. For more information, please see the Security Advisory `GHSA-5824-cm3x-3c38 `_.
Date released: 23-07-2021
@@ -281,6 +463,7 @@ Fixes:
v0.2.14
*******
+**THIS RELEASE HAS BEEN PULLED**
Date released: 20-07-2021
@@ -399,6 +582,7 @@ Fixes:
v0.2.6
******
+**THIS RELEASE HAS BEEN PULLED**
Date released: 10-10-2020
@@ -416,7 +600,7 @@ Fixes:
- Memory corruption issue when performing function calls inside a tuple or another function call (`#2186 `_)
- Incorrect function output when using multidimensional arrays (`#2184 `_)
-- Reduced ambiguity bewteen ``address`` and ``Bytes[20]`` (`#2191 `_)
+- Reduced ambiguity between ``address`` and ``Bytes[20]`` (`#2191 `_)
v0.2.5
******
@@ -500,7 +684,7 @@ Breaking changes:
- ``@public`` and ``@private`` function decorators have been renamed to ``@external`` and ``@internal`` (VIP `#2065 `_)
- The ``@constant`` decorator has been renamed to ``@view`` (VIP `#2040 `_)
- Type units have been removed (VIP `#1881 `_)
-- Event declaraion syntax now resembles that of struct declarations (VIP `#1864 `_)
+- Event declaration syntax now resembles that of struct declarations (VIP `#1864 `_)
- ``log`` is now a statement (VIP `#1864 `_)
- Mapping declaration syntax changed to ``HashMap[key_type, value_type]`` (VIP `#1969 `_)
- Interfaces are now declared via the ``interface`` keyword instead of ``contract`` (VIP `#1825 `_)
@@ -639,7 +823,7 @@ Some of the bug and stability fixes:
- Fixed stack valency issues in if and for statements (`#1665 `_)
- Prevent overflow when using ``sqrt`` on certain datatypes (`#1679 `_)
- Prevent shadowing of internal variables (`#1601 `_)
-- Reject unary substraction on unsigned types (`#1638 `_)
+- Reject unary subtraction on unsigned types (`#1638 `_)
- Disallow ``orelse`` syntax in ``for`` loops (`#1633 `_)
- Increased clarity and efficiency of zero-padding (`#1605 `_)
@@ -652,7 +836,7 @@ The following VIPs were implemented for Beta 13:
- Add ``vyper-json`` compilation mode (VIP `#1520 `_)
- Environment variables and constants can now be used as default parameters (VIP `#1525 `_)
-- Require unitialized memory be set on creation (VIP `#1493 `_)
+- Require uninitialized memory be set on creation (VIP `#1493 `_)
Some of the bug and stability fixes:
@@ -744,7 +928,7 @@ Here is the old changelog:
* **2019.03.04**: ``create_with_code_of`` has been renamed to ``create_forwarder_to``. (`#1177 `_)
* **2019.02.14**: Assigning a persistent contract address can only be done using the ``bar_contact = ERC20()`` syntax.
* **2019.02.12**: ERC20 interface has to be imported using ``from vyper.interfaces import ERC20`` to use.
-* **2019.01.30**: Byte array literals need to be annoted using ``b""``, strings are represented as `""`.
+* **2019.01.30**: Byte array literals need to be annotated using ``b""``, strings are represented as `""`.
* **2018.12.12**: Disallow use of ``None``, disallow use of ``del``, implemented ``clear()`` built-in function.
* **2018.11.19**: Change mapping syntax to use ``map()``. (`VIP564 `_)
* **2018.10.02**: Change the convert style to use types instead of string. (`VIP1026 `_)
diff --git a/docs/resources.rst b/docs/resources.rst
index 7f0d0600a9..c2b0e3e427 100644
--- a/docs/resources.rst
+++ b/docs/resources.rst
@@ -3,45 +3,48 @@
Other resources and learning material
#####################################
-Vyper has an active community. You can find third party tutorials,
-examples, courses and other learning material.
+Vyper has an active community. You can find third-party tutorials, examples, courses, and other learning material.
General
-------
-- `Ape Academy - Learn how to build vyper projects `__ by ApeWorX
-- `More Vyper by Example `__ by Smart Contract Engineer
-- `Vyper cheat Sheet `__
-- `Vyper Hub for development `__
-- `Vyper greatest hits smart contract examples `__
+- `Ape Academy – Learn how to build Vyper projects `_ by ApeWorX
+- `More Vyper by Example `_ by Smart Contract Engineer
+- `Vyper cheat Sheet `_
+- `Vyper Hub for development `_
+- `Vyper greatest hits smart contract examples `_
+- `A curated list of Vyper resources, libraries, tools, and more `_
Frameworks and tooling
----------------------
-- `ApeWorX - The Ethereum development framework for Python Developers, Data Scientists, and Security Professionals `__
-- `Foundry x Vyper - Foundry template to compile Vyper contracts `__
-- `Snekmate - Vyper smart contract building blocks `__
-- `Serpentor - A set of smart contracts tools for governance `__
-- `Smart contract development frameworks and tools for Vyper on Ethreum.org `__
+- `Titanoboa – An experimental Vyper interpreter with pretty tracebacks, forking, debugging features and more `_
+- `ApeWorX – The Ethereum development framework for Python Developers, Data Scientists, and Security Professionals `_
+- `VyperDeployer – A helper smart contract to compile and test Vyper contracts in Foundry `_
+- `🐍 snekmate – Vyper smart contract building blocks `_
+- `Serpentor – A set of smart contracts tools for governance `_
+- `Smart contract development frameworks and tools for Vyper on Ethereum.org `_
+- `Vyper Online Compiler - an online platform for compiling and deploying Vyper smart contracts `_
Security
--------
-- `VyperPunk - learn to secure and hack Vyper smart contracts `__
-- `VyperExamples - Vyper vulnerability examples `__
+- `VyperPunk – learn to secure and hack Vyper smart contracts `_
+- `VyperExamples – Vyper vulnerability examples `_
Conference presentations
------------------------
-- `Vyper Smart Contract Programming Language by Patrick Collins (2022, 30 mins) `__
-- `Python and DeFi by Curve Finance (2022, 15 mins) `__
-- `My experience with Vyper over the years by Benjamin Scherrey (2022, 15 mins) `__
-- `Short introduction to Vyper by Edison Que (3 mins) `__
+- `Vyper Smart Contract Programming Language by Patrick Collins (2022, 30 mins) `_
+- `Python and DeFi by Curve Finance (2022, 15 mins) `_
+- `My experience with Vyper over the years by Benjamin Scherrey (2022, 15 mins) `_
+- `Short introduction to Vyper by Edison Que (3 mins) `_
Unmaintained
------------
These resources have not been updated for a while, but may still offer interesting content.
-- `Awesome Vyper curated resources `__
-- `Brownie - Python framework for developing smart contracts (deprecated) `__
+- `Awesome Vyper curated resources `_
+- `Brownie – Python framework for developing smart contracts (deprecated) `_
+- `Foundry x Vyper – Foundry template to compile Vyper contracts `_
diff --git a/docs/scoping-and-declarations.rst b/docs/scoping-and-declarations.rst
index 7165ec6e4d..838720c25b 100644
--- a/docs/scoping-and-declarations.rst
+++ b/docs/scoping-and-declarations.rst
@@ -8,7 +8,7 @@ Variable Declaration
The first time a variable is referenced you must declare its :ref:`type `:
-.. code-block:: python
+.. code-block:: vyper
data: int128
@@ -25,7 +25,7 @@ Declaring Public Variables
Storage variables can be marked as ``public`` during declaration:
-.. code-block:: python
+.. code-block:: vyper
data: public(int128)
@@ -38,7 +38,7 @@ Declaring Immutable Variables
Variables can be marked as ``immutable`` during declaration:
-.. code-block:: python
+.. code-block:: vyper
DATA: immutable(uint256)
@@ -55,7 +55,7 @@ Tuple Assignment
You cannot directly declare tuple types. However, in certain cases you can use literal tuples during assignment. For example, when a function returns multiple values:
-.. code-block:: python
+.. code-block:: vyper
@internal
def foo() -> (int128, int128):
@@ -84,13 +84,13 @@ This can be performed when compiling via ``vyper`` by including the ``--storage
For example, consider upgrading the following contract:
-.. code-block:: python
+.. code-block:: vyper
# old_contract.vy
owner: public(address)
balanceOf: public(HashMap[address, uint256])
-.. code-block:: python
+.. code-block:: vyper
# new_contract.vy
owner: public(address)
@@ -101,7 +101,7 @@ This would cause an issue when upgrading, as the ``balanceOf`` mapping would be
This issue can be avoided by allocating ``balanceOf`` to ``slot1`` using the storage layout overrides. The contract can be compiled with ``vyper new_contract.vy --storage-layout-file new_contract_storage.json`` where ``new_contract_storage.json`` contains the following:
-.. code-block:: javascript
+.. code-block:: json
{
"owner": {"type": "address", "slot": 0},
@@ -130,7 +130,7 @@ Accessing Module Scope from Functions
Values that are declared in the module scope of a contract, such as storage variables and functions, are accessed via the ``self`` object:
-.. code-block:: python
+.. code-block:: vyper
a: int128
@@ -148,7 +148,7 @@ Name Shadowing
It is not permitted for a memory or calldata variable to shadow the name of an immutable or constant value. The following examples will not compile:
-.. code-block:: python
+.. code-block:: vyper
a: constant(bool) = True
@@ -157,7 +157,7 @@ It is not permitted for a memory or calldata variable to shadow the name of an i
# memory variable cannot have the same name as a constant or immutable variable
a: bool = False
return a
-.. code-block:: python
+.. code-block:: vyper
a: immutable(bool)
@@ -174,7 +174,7 @@ Function Scope
Variables that are declared within a function, or given as function input arguments, are visible within the body of that function. For example, the following contract is valid because each declaration of ``a`` only exists within one function's body.
-.. code-block:: python
+.. code-block:: vyper
@external
def foo(a: int128):
@@ -190,14 +190,14 @@ Variables that are declared within a function, or given as function input argume
The following examples will not compile:
-.. code-block:: python
+.. code-block:: vyper
@external
def foo(a: int128):
# `a` has already been declared as an input argument
a: int128 = 21
-.. code-block:: python
+.. code-block:: vyper
@external
def foo(a: int128):
@@ -215,7 +215,7 @@ Block Scopes
Logical blocks created by ``for`` and ``if`` statements have their own scope. For example, the following contract is valid because ``x`` only exists within the block scopes for each branch of the ``if`` statement:
-.. code-block:: python
+.. code-block:: vyper
@external
def foo(a: bool) -> int128:
@@ -226,7 +226,7 @@ Logical blocks created by ``for`` and ``if`` statements have their own scope. Fo
In a ``for`` statement, the target variable exists within the scope of the loop. For example, the following contract is valid because ``i`` is no longer available upon exiting the loop:
-.. code-block:: python
+.. code-block:: vyper
@external
def foo(a: bool) -> int128:
@@ -236,7 +236,7 @@ In a ``for`` statement, the target variable exists within the scope of the loop.
The following contract fails to compile because ``a`` has not been declared outside of the loop.
-.. code-block:: python
+.. code-block:: vyper
@external
def foo(a: bool) -> int128:
diff --git a/docs/statements.rst b/docs/statements.rst
index 02854adffd..34f15828a1 100644
--- a/docs/statements.rst
+++ b/docs/statements.rst
@@ -13,7 +13,7 @@ break
The ``break`` statement terminates the nearest enclosing ``for`` loop.
-.. code-block:: python
+.. code-block:: vyper
for i in [1, 2, 3, 4, 5]:
if i == a:
@@ -26,7 +26,7 @@ continue
The ``continue`` statement begins the next cycle of the nearest enclosing ``for`` loop.
-.. code-block:: python
+.. code-block:: vyper
for i in [1, 2, 3, 4, 5]:
if i != a:
@@ -40,7 +40,7 @@ pass
``pass`` is a null operation — when it is executed, nothing happens. It is useful as a placeholder when a statement is required syntactically, but no code needs to be executed:
-.. code-block:: python
+.. code-block:: vyper
# this function does nothing (yet!)
@@ -53,7 +53,7 @@ return
``return`` leaves the current function call with the expression list (or None) as a return value.
-.. code-block:: python
+.. code-block:: vyper
return RETURN_VALUE
@@ -69,7 +69,7 @@ log
The ``log`` statement is used to log an event:
-.. code-block:: python
+.. code-block:: vyper
log MyEvent(...)
@@ -89,7 +89,7 @@ raise
The ``raise`` statement triggers an exception and reverts the current call.
-.. code-block:: python
+.. code-block:: vyper
raise "something went wrong"
@@ -100,7 +100,7 @@ assert
The ``assert`` statement makes an assertion about a given condition. If the condition evaluates falsely, the transaction is reverted.
-.. code-block:: python
+.. code-block:: vyper
assert x > 5, "value too low"
@@ -108,7 +108,7 @@ The error string is not required. If it is provided, it is limited to 1024 bytes
This method's behavior is equivalent to:
-.. code-block:: python
+.. code-block:: vyper
if not cond:
raise "reason"
diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst
index 8eb2c1da78..561f3000dd 100644
--- a/docs/structure-of-a-contract.rst
+++ b/docs/structure-of-a-contract.rst
@@ -9,16 +9,51 @@ This section provides a quick overview of the types of data present within a con
.. _structure-versions:
+Pragmas
+=======
+
+Vyper supports several source code directives to control compiler modes and help with build reproducibility.
+
Version Pragma
-==============
+--------------
+
+The version pragma ensures that a contract is only compiled by the intended compiler version, or range of versions. Version strings use `NPM `_ style syntax. Starting from v0.4.0 and up, version strings will use `PEP440 version specifiers `_.
+
+As of 0.3.10, the recommended way to specify the version pragma is as follows:
+
+.. code-block:: vyper
+
+ #pragma version ^0.3.0
+
+.. note::
+
+ Both pragma directive versions ``#pragma`` and ``# pragma`` are supported.
+
+The following declaration is equivalent, and, prior to 0.3.10, was the only supported method to specify the compiler version:
+
+.. code-block:: vyper
+
+ # @version ^0.3.0
+
+
+In the above examples, the contract will only compile with Vyper versions ``0.3.x``.
+
+Optimization Mode
+-----------------
+
+The optimization mode can be one of ``"none"``, ``"codesize"``, or ``"gas"`` (default). For example, adding the following line to a contract will cause it to try to optimize for codesize:
+
+.. code-block:: vyper
+
+ #pragma optimize codesize
-Vyper supports a version pragma to ensure that a contract is only compiled by the intended compiler version, or range of versions. Version strings use `NPM