Giter Site home page Giter Site logo

apeworx / ape-vyper Goto Github PK

View Code? Open in Web Editor NEW
25.0 4.0 9.0 279 KB

Vyper compiler plugin for the Ape Framework, using VVM

Home Page: https://www.apeworx.io/

License: Apache License 2.0

Python 93.23% Vyper 6.77%
python smart-contracts vyper compiler web3 vyper-contracts ethereum apewworx ape

ape-vyper's People

Contributors

antazoey avatar dtdang avatar fubuloubu avatar lost-theory avatar mikeshultz avatar ninjagod1251 avatar notpeopling2day avatar sabotagebeats avatar shadeundertree avatar z80dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ape-vyper's Issues

Alternative to vyper install as a library

Overview

having vyper installed as a library causes problems in environments where you need a different version than the one we are using.

Specification

two choices:

  1. make vyper an extra and the flattener a more conditional feature
  2. copy in the functionality from vyper as a lib and ship it with ape-vyper to bypass all problems altogether (bit of a SPIKE)

Dependencies

Include links to any open issues that must be resolved before this feature can be implemented.

Very long compile time [APE-1588]

Environment information

  • ape and plugin versions:
$ ape --version
0.6.26

$ ape plugins list
Core Plugins
  accounts
  cache
  compile
  console
  ethereum
  geth
  init
  networks
  plugins
  pm
  run
  test
Installed Plugins
  etherscan        0.6.10
  foundry          0.6.19
  ganache          0.6.9
  infura           0.6.5
  tokens           0.6.2
  vyper            0.6.13
  • Python Version: 3.10.13
  • Vyper Version: 0.3.9
  • OS: macOS

What went wrong?

New Ape user, moving from brownie. I had a Vyper contract I had previously deployed using Brownie that I wanted to update/enhance. I copied it into /contracts/ and ran ape compile. It took nearly 90 minutes for it to compile after I left it running. I have tried other contracts and they compile fine. This specific contract is roughly 1000 lines. Fair number of if/else conditionals, converts and slices. Main use case is a fallback function that accepts packed calldata directly which then gets sliced up and manipulated.

Per Discord discussion I tried manually compiling using Vyper like so:

vyper contracts/filename.vy took ~ 5 seconds
/Users/xxx/.vvm/vyper-0.3.9 contracts/filename.vy took ~ 5 seconds

So the contract compiles fine using vyper or the .vvm binary, but not using ape compile.

How can it be fixed?

No idea :)

Plugin does not load

Tried using Python 3.8 and 3.9, latest ape.

$ ape plugins add vyper
WARNING: $GITHUB_ACCESS_TOKEN not set, skipping 2nd class plugins
Install unknown 3rd party plugin 'ape_vyper'? [y/N]: y
INFO: Installing ape_vyper...
$ ape plugins list
WARNING: Error loading plugin package 'ape_vyper'
WARNING: $GITHUB_ACCESS_TOKEN not set, skipping 2nd class plugins
INFO: No plugins installed
$ ape compile
WARNING: Error loading plugin package 'ape_vyper'
WARNING: No compilers detected for the following extensions: .vy

I don't have this issue with solidity

Imported Interfaces not correctly captured

Environment information

  • ape and plugin versions: ape 0.2.7

  • vyper (plugin) 0.2.0

  • Python Version: 3.9.5

  • OS: osx

What went wrong?

I have the following tree structure:

.
├── ape-config.yaml
├── contracts
│   ├── MyContract.vy
│   └── interfaces
│       └── IFace.vy
├── scripts
└── tests

And the following files:

MyContract.vy

# @version ^0.3.3
import interfaces.IFace as IFace


@external
@view
def read_contract(some_address: address) -> uint256:
    myContract: IFace = IFace(some_address)
    return myContract.read_stuff()

IFace.vy

@view
@external
def read_stuff() -> uint256:
    pass

When I run:

vyper contracts/MyContract.vy

I get an expected bytecode output.

However, when I run

ape compile

I get:

INFO: Compiling 'MyContract.vy'.
INFO: Compiling 'interfaces/IFace.vy'.
ERROR: (VyperCompileError) vyper.exceptions.FunctionDeclarationException: Missing or unmatched return statements in function 'read_stuff'
  contract "/DIR/vyper-4o0sj3w3.vy", line 3:0 
       2 @external
  ---> 3 def read_stuff() -> uint256:
  -------^
       4     pass

[24597] Failed to execute script 'vyper_compile' due to unhandled exception!

I have also tried it with this tree structure:

.
├── ape-config.yaml
├── contracts
│   └── MyContract.vy
├── interfaces
│   └── IFace.vy
├── scripts
└── tests

And I get:

INFO: Compiling 'MyContract.vy'.
ERROR: (VyperCompileError) FileNotFoundError:  Cannot locate interface 'interfaces/IFace{.vy,.json}'
[24680] Failed to execute script 'vyper_compile' due to unhandled exception!

Can we please fix?

Add support for dependencies

Overview

Currently, the Vyper plugin has no support for using dependencies. It would be much more useful if it did.

Specification

Vyper v0.3.2 and above has support for directly loading from ethPM manifests, so it would be really cool not to have to recompile anything at all to use dependencies like this, including contracts from the local project (like Solidity contracts). For earlier versions of Vyper, they can still load .vy and json ABI files, so (limited) support should be added for those too

Dependencies

vyperlang/vvm#9

Refactor to use VVM `compile_files`

Elevator pitch:

Use vvm.compile_files instead of vvm.compile_source

Value:

Currently we use compile_source which places the files into a temporary path, which makes errors much harder to parse. This change will show the correct file that generated the error

Dependencies:

Might be nicer to use alongside ApeWorX/ape#660

Design approach:

Just switch the methods

Task list:

  • Switch up the methods
  • Do a ton of testing on different Vyper repos (Yearn-vaults, Curve DAO contracts)
  • (optional) release update alongside core ape iterator refactor

Estimated completion date:

1 week

Design review:

Do not signoff unless:

    1. agreed the tasks and design approach will achieve acceptance, and
    1. the work can be completed by one person within the SLA.
      Design reviewers should consider simpler approaches to achieve goals.

(Please leave a comment to sign off)

Plugin doesn't work with beta versions of Vyper

Environment information

  • ape and plugin versions:
$ ape --version
0.1.5

$ ape plugins list
Installed Plugins:
  vyper       0.1.0
  • Python Version: 3.9.9
  • OS: linux

What went wrong?

Attempted to install a project that uses older Vyper versions:

dependencies:
  - name: curve
    github: curvefi/curve-contract
    branch: master

Which raises the following error:

$ ape compile
INFO: Cloning branch 'master' from 'curve-contract'.
...
ERROR: (VyperCompileError) vyper.exceptions.VersionException: line 1:0 Version specification "0.1.0b16" is not compatible with compiler version "0.3.1"
[9032] Failed to execute script 'vyper_compile' due to unhandled exception!

How can it be fixed?

All version selection to work with b16 tags

Using installed package version of Vyper when not asked

Environment information

  • ape and plugin versions:
$ ape --version
# ...copy and paste result of above command here...

$ ape plugins list
# ...copy and paste result of above command here...
  • Python Version: x.x.x
  • OS: osx/linux/win

What went wrong?

ERROR: Unable to load project. Reason: vyper.exceptions.VersionException: line 1:0 Version specification "0.3.1" is not compatible with compiler version "0.3.2"

How can it be fixed?

shutil.which("vyper") is catching the installed version, not the one that is suggested from the pass-through of version checking (use None if vyper_version is not self.installed_version)

Dev-messages regression with vyper 0.3.9 [APE-1261]

Environment information

  • ape and plugin versions:
$ ape --version
0.6.13

$ ape plugins list
Installed Plugins:
  tokens       0.6.2
  foundry      0.6.9
  etherscan    0.6.8
  ens          0.6.1
  vyper        0.6.9
  • Python Version: Python 3.11.4
  • OS: macOS

What went wrong?

Reverts with dev-messages work with vyper 0.3.7 and stopped working with vyper 0.3.9.

with ape.reverts(dev_message="dev: admin only"):
    ...

bug: ImportError: cannot import name 'Abort' from 'ape.utils'

Environment information

  • ape and plugin versions:
$ ape --version
0.1.0a26.dev27+g780346e.d20211101

$ ape plugins list
WARNING: Error loading plugin package 'ape_vyper'.
        ImportError: cannot import name 'Abort' from 'ape.utils'

  • Python Version: Python 3.8.9
  • OS: WSL2 Ubuntu 20.04 with Pyenv

What went wrong?

ape vyper no longer works
ImportError: cannot import name 'Abort' from 'ape.utils'

$ape compile
WARNING: Error loading plugin package 'ape_vyper'.
        ImportError: cannot import name 'Abort' from 'ape.utils' ****

Handle Vyper exceptions

Currently, if the compiler has an error, it raises a compiler exception with a full stack trace from vvm

$ ape compile
INFO: Compiling 'contracts/Auction.vy'
Traceback (most recent call last):
  File "bin/ape", line 8, in <module>
    sys.exit(cli())
  File "site-packages/click/core.py", line 1137, in __call__
    return self.main(*args, **kwargs)
  File "site-packages/click/core.py", line 1062, in main
    rv = self.invoke(ctx)
  File "site-packages/click/core.py", line 1668, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "site-packages/click/core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "site-packages/ape_compile/_cli.py", line 74, in cli
    contract_types = project.load_contracts(use_cache)
  File "site-packages/ape/managers/project.py", line 117, in load_contracts
    contract_types.update(self.compilers.compile(list(needs_compiling)))
  File "site-packages/ape/managers/compilers.py", line 49, in compile
    for contract_type in self.registered_compilers[extension].compile(paths_to_compile):
  File "site-packages/ape_vyper/compiler.py", line 99, in compile
    result = vvm.compile_source(
  File "site-packages/vvm/main.py", line 64, in compile_source
    compiler_data = _compile(
  File "site-packages/vvm/main.py", line 128, in _compile
    stdoutdata, stderrdata, command, proc = wrapper.vyper_wrapper(
  File "site-packages/vvm/wrapper.py", line 137, in vyper_wrapper
    raise VyperError(
vvm.exceptions.VyperError: An error occurred during execution
> command: `~/.vvm/vyper-0.2.12 /tmp/vyper-k_k_lubq.vy -f combined_json`
> return code: `255`
> stdout:
Error compiling: /tmp/vyper-k_k_lubq.vy

> stderr:
vyper.exceptions.UndeclaredDefinition: '_to' has not been declared
  contract "/tmp/vyper-k_k_lubq.vy", function "bid", line 333:11 
       332     # Throws if `_to` is zero address
  ---> 333     assert _to != ZERO_ADDRESS
  --------------------^
       334     # Add NFT. Throws if `_tokenId` is owned by someone

[30586] Failed to execute script vyper_compile

Catch and handle this exception and only display the relevant text from stderr, e.g. the result should look more like:

$ ape compile
INFO: Compiling 'contracts/Auction.vy'

vyper.exceptions.UndeclaredDefinition: '_to' has not been declared
  contract "/tmp/vyper-k_k_lubq.vy", function "bid", line 333:11 
       332     # Throws if `_to` is zero address
  ---> 333     assert _to != ZERO_ADDRESS
  --------------------^
       334     # Add NFT. Throws if `_tokenId` is owned by someone

Also note that the contract file path is using a temporary path, which isn't that great for debugging... but this might just be an VVM oddity.

default evm version to paris [APE-1268]

What went wrong?

push0 rollout went bad, with many networks not supporting the latest evm version yet, possibly resulting in potentially broken deploys.

How can it be fixed?

instead of latest (shanghai), it would be better to default to paris unless explicitly overriden by a user who knows what they are doing.

Compilation failure when importing own interface

Environment information

  • ape and plugin versions:
$ ape --version
0.8.5

$ ape plugins list
Installed Plugins
  etherscan    0.8.0
  foundry      0.8.0
  vyper        0.8.1
  • Python Version: 3.12.4
  • OS: GNU/Linux

What went wrong?

ape compile

produces

Traceback (most recent call last):
  File "/home/ramana/.local/pipx/venvs/eth-ape/lib/python3.12/site-packages/ape_vyper/compiler.py", line 386, in _get_imports
    sub_imports = self._get_imports((full_path,), project=project, handled=handled)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ramana/.local/pipx/venvs/eth-ape/lib/python3.12/site-packages/ape_vyper/compiler.py", line 386, in _get_imports
    sub_imports = self._get_imports((full_path,), project=project, handled=handled)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ramana/.local/pipx/venvs/eth-ape/lib/python3.12/site-packages/ape_vyper/compiler.py", line 386, in _get_imports
    sub_imports = self._get_imports((full_path,), project=project, handled=handled)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  [Previous line repeated 993 more times]
  File "/home/ramana/.local/pipx/venvs/eth-ape/lib/python3.12/site-packages/ape_vyper/compiler.py", line 298, in _get_imports
    dependencies = self.get_dependencies(project=pm)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ramana/.local/pipx/venvs/eth-ape/lib/python3.12/site-packages/ape_vyper/compiler.py", line 488, in get_dependencies
    config = self.get_config(project=pm)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ramana/.local/pipx/venvs/eth-ape/lib/python3.12/site-packages/ape/api/compiler.py", line 65, in get_config
    return config.model_validate(data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ramana/.local/pipx/venvs/eth-ape/lib/python3.12/site-packages/pydantic/main.py", line 551, in model_validate
    return cls.__pydantic_validator__.validate_python(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 1 validation error for VyperConfig
  Value error, error getting value for field "version" from source "DotEnvSettingsSource" [type=value_error, input_value={'version': None, 'evm_ve... 'import_remapping': []}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.7/v/value_error

where contracts/test.vy contains

#pragma version ~=0.4.0

import test as TestInterface

@deploy
def __init__():
  pass

Use Clean Vyper Installation Path When Running Tests

Currently vvm will utilize the default installation path of ~/.vvm (on *nix) when ape-vyper tests are running.

This means that the tests may run differently based on the running system's current vyper installations, and that the user's installed vyper versions will be different after the tests have been run.

To rectify this we can use an autouse, session scoped test fixture to set the environment variable specified vvm.install.VVM_BINARY_PATH_VARIABLE to a temporary directory. This way the tests will start with a clean slate, and will only install compilers in a temporary directory that won't interfere with the user's installation (or vice versa).

At the end of the test suite the temporary directory can be removed

Vyper contract flattener [APE-872]

Overview

Would be nice to have a contract flattener for vyper, since currently right now Etherscan doesn't allow verification using vyper with multiple files

Specification

First, add a function like from ape_vyper.flatten import flattener that would take a path (and an optional base path) and flatten that file then output the flattened file as a string

Second, add ape vyper CLI extension where ape vyper flatten PATH flattens a particular file from a user's contracts/ folder for them, and prints out the results

Dependencies

n/a

How to tell which version of vyper to use?

Environment information

  • ape and plugin versions:
    vyper 0.2.0
    ape 0.2.7
    vyper 0.3.3+commit.48e326f

  • Python Version: 3.9.5

  • OS: osx

What went wrong?

Please include information like:

I have a contract that looks like this:

a: uint80

When I run ape compile I get:

INFO: Compiling 'MyContract.vy'.
ERROR: (VyperCompileError) vyper.exceptions.UnknownType: No builtin or user-defined type named 'uint80'
  contract "/DIR/vyper-wcbpnrwq.vy", line 26:3 
       25 #     return price
  ---> 26 a: uint80
  -----------^
       27

[19956] Failed to execute script vyper_compile

How can I tell it to use 0.3.3 of vyper?

support vyper 0.3.10 [APE-1462]

Environment information

  • ape and plugin versions:
$ ape --version
# 0.6.22

$ ape plugins list
# Installed Plugins
  alchemy      0.6.5
  arbitrum     0.6.4
  etherscan    0.6.10
  hardhat      0.6.13
  ledger       0.6.2
  optimism     0.6.4
  polygon      0.6.6
  vyper        0.6.11

Third-party Plugins
  gnosis       0.2.0
  • Python Version: 3.10.4
  • OS: macOS

What went wrong?

ERROR: (VyperCompileError) CurveStableSwapMetaNG.vy
StructureException:compiler options indicate optimization mode OptimizationLevel.GAS, but source pragma indicates OptimizationLevel.CODESIZE.

The preamble:

# @version 0.3.10
#pragma optimize codesize

To reproduce: run ape compile with anything as long as the contract says optimise codesize.

How can it be fixed?

It seems there is a collision in the input_json.

here is the problem:

version_settings: Dict = {"optimize": True}

Plugin does not handle yanked packages

For context, we yanked Vyper v0.2.13, so this might be an issue here. I am trying to compile an empty file (where no compiler version is specified) so something strange here is happening.

$ ape compile
INFO: Compiling 'contracts/Auction.vy'
Traceback (most recent call last):
  File "bin/ape", line 8, in <module>
    sys.exit(cli())
  File "site-packages/click/core.py", line 1137, in __call__
    return self.main(*args, **kwargs)
  File "site-packages/click/core.py", line 1062, in main
    rv = self.invoke(ctx)
  File "site-packages/click/core.py", line 1668, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "site-packages/click/core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "site-packages/ape_compile/_cli.py", line 74, in cli
    contract_types = project.load_contracts(use_cache)
  File "site-packages/ape/managers/project.py", line 117, in load_contracts
    contract_types.update(self.compilers.compile(list(needs_compiling)))
  File "site-packages/ape/managers/compilers.py", line 49, in compile
    for contract_type in self.registered_compilers[extension].compile(paths_to_compile):
  File "site-packages/ape_vyper/compiler.py", line 97, in compile
    result = vvm.compile_source(
  File "site-packages/vvm/main.py", line 64, in compile_source
    compiler_data = _compile(
  File "site-packages/vvm/main.py", line 126, in _compile
    vyper_binary = get_executable(vyper_version)
  File "site-packages/vvm/install.py", line 109, in get_executable
    raise VyperNotInstalled(
vvm.exceptions.VyperNotInstalled: vyper 0.2.13 has not been installed. Use vvm.install_vyper('0.2.13') to install.

commit checks throw typeerror

deploymentBytecode=Bytecode(result["bytecode"]), # type: ignore

        for path, result in vvm.compile_files(contract_filepaths).items():
            contract_types.append(
                ContractType(
                    # NOTE: Vyper doesn't have internal contract type declarations, so use filename
                    contractName=Path(path).stem,
                    sourceId=path,
>                   deploymentBytecode=Bytecode(result["bytecode"]),  # type: ignore
                    runtimeBytecode=Bytecode(result["bytecode_runtime"]),  # type: ignore
                    abi=result["abi"],
                    userdoc=result["userdoc"],
                    devdoc=result["devdoc"],
                )
            )
E           TypeError: string indices must be integers

ape_vyper/compiler.py:101: TypeError

Compiler errors not displayed when there is a compilation issue

I was debugging what the cause behind this issue was:

$ ape compile                                                                                                                                      
INFO: Compiling 'contracts/ApePiece.vy'.                                                                                                                                                   
ERROR: (VyperInstallError) Unable to install Vyper version: 0.3.1.

It turned out to be a legitimate bug! However, due to how this code works, it's not displaying the bug properly, just showing something about the it not being able to install the version of Vyper it's currently using:

except Exception as err:
new_err = VyperInstallError(vyper_version)
if hasattr(err, "stderr_data"):
new_err.message += f"\n\t{err.stderr_data}" # type: ignore
raise new_err from err

Was thinking why it was necessary to catch this exception? Is it just so err inherits from CompilerError? Can this be done another way so it any compiler errors look transparent to the user?

This is the actual error that should be displayed (which I access when I debugged):

$ ape compile                                                                                                                                      
INFO: Compiling 'contracts/ApePiece.vy'.                                                                                                                                                   
> .../site-packages/ape_vyper/compiler.py(140)compile()                                                                           
-> new_err = VyperInstallError(vyper_version)
(Pdb) print(err.stderr_data)
vyper.exceptions.StateAccessViolation: not allowed to query contract or environment variables in pure functions
  contract "/tmp/vyper-6dd2eazp.vy", function "_tokenIdToString", line 132:8 
       131     return concat(
  ---> 132         self._digitToString(digit1),
  -----------------^
       133         self._digitToString(digit2),

[20400] Failed to execute script 'vyper_compile' due to unhandled exception!

Related: would be nice to use vvm.compile_files so we get the actual source filename in there.

(VyperInstallError) Unable to install Vyper [APE-673]

Environment information

  • ape and plugin versions:
    eth-ape==0.6.3
    ape-vyper==0.6.1
ape --version

[notice] A new release of pip is available: 23.0 -> 23.0.1
[notice] To update, run: pip install --upgrade pip
0.6.3
ape plugins list

[notice] A new release of pip is available: 23.0 -> 23.0.1
[notice] To update, run: pip install --upgrade pip
Installed Plugins:
  vyper       0.6.1
  • Python Version: 3.10.9
  • OS: macOS

MBP M2 Pro / Ventura 13.2

What went wrong?

When I run ape compile, i get the following error :

ape compile

[notice] A new release of pip is available: 23.0 -> 23.0.1
[notice] To update, run: pip install --upgrade pip
INFO: Compiling 'Token.vy'.
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 8.41M/8.41M [00:02<00:00, 2.81MiB/s]
ERROR: (VyperInstallError) Unable to install Vyper version: '0.2.16'.

I tried to compile the brownie vyper token mix contract : here the link

How can it be fixed?

I tried to change the vyper contract version to 0.3.7, same error.

No idea at the moment i'm stuck.

thanks for your help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.