ApeWorX / ApeWorX/eth-abi

Using an enum in library ABI causes a ParseError

Open
#146 0 comments 0 reactions 0 assignees View on GitHub
Needs Review p3
Dominant language
Python
Stars
256
Forks
117
Avg merge
4m
Merged PRs (30d)
1

Description

## What was wrong?

`eth-abi` fails to properly parse/use the ABI generated by `solc` for a library. One example of this is that for contracts the `type` of an enum is reported as an integer type (`uint8` if enum has 256 of less entries) while for libraries it's `enum L.E` (where `L` is a library name and `E` is some enum).

An attempt to use such an `enum` with `eth-abi` results in an error:
```
ParseError: Parse error at '.E' (column 3) in type string '(L.E)'
```

### Code that produced the error
Repro using [Brownie](https://github.com/eth-brownie).
Assuming you have it installed, just run these commands in shell in an empty directory:
```bash
brownie init

cat << EOF > contracts/L.sol
pragma solidity =0.7.1;

library L {
enum BOOL {NO, YES}

function f(BOOL b) public pure returns (BOOL) {
return b;
}
}
EOF

cat << EOF > scripts/trigger_bug.py
from brownie import L, accounts
l = L.deploy({'from': accounts[0]})
l.f(1)
EOF

brownie compile
brownie run trigger_bug
```

### Full error output

```sh
Brownie v1.11.10 - Python development framework for Ethereum

FProject is the active project.

Launching 'ganache-cli --accounts 10 --hardfork istanbul --gasLimit 12000000 --mnemonic brownie --port 8545'...
Transaction sent: 0x5723c43998c3eaad6eabeb2e840843db80b028a4e024a7ea7fe96f6ec0dad640
Gas price: 0.0 gwei Gas limit: 12000000
L.constructor confirmed - Block: 1 Gas used: 90940 (0.76%)
L deployed at: 0x3194cBDC3dbcd3E11a07892e7bA5c3394048Cc87

File "brownie/_cli/run.py", line 49, in main
return_value = run(args[""], method_name=args[""] or "main")
File "brownie/project/scripts.py", line 52, in run
module = _import_from_path(script)
File "brownie/project/scripts.py", line 110, in _import_from_path
_import_cache[import_str] = importlib.import_module(import_str)
File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "
l.f(1)
File "brownie/network/contract.py", line 1232, in __call__
return self.call(*args, block_identifier=block_identifier)
File "brownie/network/contract.py", line 1033, in call
tx.update({"to": self._address, "data": self.encode_input(*args)})
File "brownie/network/contract.py", line 1113, in encode_input
data = format_input(self.abi, args)
File "brownie/convert/normalize.py", line 16, in format_input
abi_types = _get_abi_types(abi["inputs"])
File "brownie/convert/normalize.py", line 112, in _get_abi_types
tuple_type = parse(type_str)
File "eth_abi/grammar.py", line 125, in parse
raise ParseError(e.text, e.pos, e.expr)
ParseError: Parse error at '.BOOL' (column 3) in type string '(L.BOOL)'
Terminating local RPC client...
```

### Environment
```sh
Python version:
3.8.6 (default, Sep 30 2020, 04:00:38)
[GCC 10.2.0]

Operating System: Linux-5.9.1-arch1-1-x86_64-with-glibc2.2.5

pip freeze result:
aiohttp==3.6.2
aiohttp-socks==0.4.2
aiorpcX==0.18.4
alabaster==0.7.12
anki==2.1.26
ankirspy==2.1.26
ansible==2.10.1
ansible-base==2.10.2
appdirs==1.4.4
aqt==2.1.26
argcomplete==1.11.1
argh==0.26.2
asn1crypto==1.4.0
async-timeout==3.0.1
attrs==20.2.0
Babel==2.8.0
backcall==0.2.0
bcrypt==3.2.0
beautifulsoup4==4.9.3
bitstring==3.1.7
btrfsutil==1.2.0
CacheControl==0.12.6
certifi==2020.6.20
cffi==1.14.3
chardet==3.0.4
click==7.1.2
colorama==0.4.4
contextlib2==0.6.0.post1
cryptography==3.1.1
decorator==4.4.2
discid==1.2.0
distlib==0.3.1
distro==1.5.0
dnspython==2.0.0
docutils==0.16
ecdsa==0.16.0
Electrum==4.0.3
file-magic==0.4.0
filelock==3.0.12
fuse-python==1.0.0
git-cola==3.7
grpcio==1.34.0.dev0
gunicorn==20.0.4
html5lib==1.1
idna==2.10
imagesize==1.2.0
importlib-metadata==2.0.0
iotop==0.6
ipdb==0.13.4
ipython==7.18.1
ipython-genutils==0.1.0
isc==2.0
jedi==0.17.2
Jinja2==2.11.2
jmespath==0.10.0
jsonrpclib-pelix==0.4.1
jsonschema==3.2.0
lensfun==0.3.95
libmsym==0.2.4
louis==3.15.0
lxml==4.6.1
Markdown==3.3
MarkupSafe==1.1.1
meld==3.20.2
mps-youtube==0.2.8
msgpack==1.0.0
multidict==4.7.6
mutagen==1.45.1
namcap==3.2.10
numpy==1.19.2
opensnitch-ui==1.0.1
ordered-set==4.0.2
packaging==20.4
pafy==0.5.5
paramiko==2.7.2
parso==0.7.1
pathtools==0.1.2
pbkdf2==1.3
pep517==0.8.2
pexpect==4.8.0
picard==2.5
pickleshare==0.7.5
Pillow==7.2.0
pipenv==2020.8.13
pipx==0.15.6.0
ply==3.11
progress==1.5
prompt-toolkit==3.0.8
protobuf==3.12.4
ptyprocess==0.6.0
pwquality==1.4.4
pyaes==1.6.1
pyalpm==0.9.1
PyAudio==0.2.11
pycairo==1.20.0
pycparser==2.20
pycryptodomex==3.9.7
pyelftools==0.26
pyenchant==3.1.1
Pygments==2.7.2
PyGObject==3.38.0
pyinotify==0.9.6
PyNaCl==1.4.0
pyparsing==2.4.7
PyQt5==5.15.1
PyQt5-sip==12.8.1
PyQtWebEngine==5.15.1
pyrsistent==0.17.3
PySocks==1.7.1
pyspread==1.99.4
python-dateutil==2.8.1
python-slugify==4.0.1
pytz==2020.1
pyxattr==0.7.1
PyYAML==5.3.1
qrcode==6.1
ranger-fm==1.9.3
rednotebook==2.20
requests==2.24.0
resolvelib==0.4.0
retrying==1.3.3
s3cmd==2.1.0
Send2Trash==1.5.0
six==1.15.0
snowballstemmer==2.0.0
soupsieve==2.0.1
Sphinx==3.2.1
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==1.0.3
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.4
stevedore==3.2.2
team==1.0
text-unidecode==1.3
toml==0.10.1
traitlets==4.3.3
typing-extensions==3.7.4.3
urllib3==1.25.10
userpath==1.4.1
virtualenv==20.0.32
virtualenv-clone==0.5.4
virtualenvwrapper==4.8.4
watchdog==0.10.3
wcwidth==0.2.5
webencodings==0.5.1
websocket-client==0.57.0
yarl==1.5.1
youtube-dl==2020.9.20
zipp==3.3.2
```

## How can it be fixed?

The inconsistent ABI for libraries is actually a problem in the compiler and is likely to be fixed in the near future (feedback welcome in https://github.com/ethereum/solidity/issues/9278). It affects other tools too: https://github.com/ethereum-ts/TypeChain/issues/216, https://github.com/ethers-io/ethers.js/issues/1126.

In the meantime (and for older versions when it's fixed), tools need to handle it differently than in contracts.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.